0, "monday" => 1, "tuesday" => 2, "wednesday" => 3, "thursday" => 4, "friday" => 5, "saturday" => 6); $weeks = array("first" => 1, "second" => 2, "third" => 3, "fourth" => 4, "last" => -1); if ($month == -1) $month = date ("n"); // No month provided, use current month if ($year == -1) $year = date("Y"); // No year provided, use current year // Day of week is a string, look it up in the weekdays list if (!is_numeric($dayOfWeek)) { foreach ($weekdays as $dayName => $dayNum) { if (strtolower($dayOfWeek) == substr($dayName,0,strlen($dayOfWeek))) { $dayOfWeek = $dayNum; break; } } } if ($dayOfWeek < 0 || $dayOfWeek > 6) return false; if (!is_numeric($week)) $week = $weeks[$week]; if ($week == -1) { $lastday = date("t", mktime(0,0,0,$month,1,$year)); $tmp = (date("w",mktime(0,0,0,$month,$lastday,$year)) - $dayOfWeek) % 7; if ($tmp < 0) $tmp += 7; $day = $lastday - $tmp; } else { $tmp = ($dayOfWeek - date("w",mktime(0,0,0,$month,1,$year))) % 7; if ($tmp < 0) $tmp += 7; $day = (7 * $week) - 6 + $tmp; } return mktime(0,0,0,$month,$day,$year); } /** * Converts a datetime value from a MySQL datetime format to a Unix timestamp. */ function mktimestamp ($datetime) { $h = $mn = $s = 0; list($Y, $M, $D, $h, $mn, $s) = sscanf($datetime,"%d-%d-%d %d:%d:%d"); return mktime($h, $mn, $s, $M, $D, $Y); } /** * Converts a Unix timestamp value to a datetime format suitable for entry in a * MySQL record. */ function mkdatetime ($timestamp) { return date("Y-m-d H:i:s",$timestamp); } /** * Returns the corresponding 24-hour $hour based on a 12-hour based $hour * and the AM (Ante Meridiem) / PM (Post Meridiem) $meridiem. */ function mk24hour ($hour, $meridiem) { if ($hour < 12 && $meridiem == "PM") return $hour + 12; if ($hour == 12 && $meridiem == "AM") return 0; return $hour; } /** * Returns a string of the number of years, months, days, hours, * minutes and even seconds from a specified date ($date). */ function readableTime($date, $long = false) { $secs = time() - $date; if (!$secs) return false; $i = 0; $j = 1; $desc = array(1 => 'second', 60 => 'minute', 3600 => 'hour', 86400 => 'day', 604800 => 'week', 2628000 => 'month', 31536000 => 'year'); while (list($k,) = each($desc)) $breaks[] = $k; sort($breaks); while ($i < count($breaks) && $secs >= $breaks[$i]) $i++; $i--; $break = $breaks[$i]; $val = intval($secs / $break); $retval = $val . ' ' . $desc[$break] . ($val>1?'s':''); if ($long && $i > 0) { $rest = $secs % $break; $break = $breaks[--$i]; $rest = intval($rest/$break); if ($rest > 0) { $resttime = $rest.' '.$desc[$break].($rest > 1?'s':''); $retval .= ", $resttime"; } } return $retval; } function duration ($start,$end) { return ceil(($end - $start) / 86400); } /** * Sends an e-mail message in the format of a specified e-mail * template ($template) file providing variable substitution * for variables appearing in the template as a bracketed * [variable] with data from the coinciding $data['variable'] * or $_POST['variable'] */ function shopp_email ($template,$data=array()) { if (strpos($template,"\r\n") !== false) $f = explode("\r\n",$template); else { if (file_exists($template)) $f = file($template); else new ShoppError(__("Could not open the email template because the file does not exist or is not readable.","Shopp"),'email_template',SHOPP_ADMIN_ERR,array('template'=>$template)); } $replacements = array( "$" => "\\\$", // Treat $ signs as literals "€" => "€", // Fix euro symbols "¥" => "¥", // Fix yen symbols "£" => "£", // Fix pound symbols "¤" => "¤" // Fix generic currency symbols ); $debug = false; $in_body = false; $headers = ""; $message = ""; $protected = array("from","to","subject","cc","bcc"); while ( list($linenum,$line) = each($f) ) { $line = rtrim($line); // Data parse if ( preg_match_all("/\[(.+?)\]/",$line,$labels,PREG_SET_ORDER) ) { while ( list($i,$label) = each($labels) ) { $code = $label[1]; if (empty($data)) $string = $_POST[$code]; else $string = $data[$code]; $string = str_replace(array_keys($replacements),array_values($replacements),$string); if (isset($string) && !is_array($string)) $line = preg_replace("/\[".$code."\]/",$string,$line); } } // Header parse if ( preg_match("/^(.+?):\s(.+)$/",$line,$found) && !$in_body ) { $header = $found[1]; $string = $found[2]; if (in_array(strtolower($header),$protected)) // Protect against header injection $string = str_replace(array("\r","\n"),"",urldecode($string)); if ( strtolower($header) == "to" ) $to = $string; else if ( strtolower($header) == "subject" ) $subject = $string; else $headers .= $line."\n"; } // Catches the first blank line to begin capturing message body if ( empty($line) ) $in_body = true; if ( $in_body ) $message .= $line."\n"; } if (!$debug) return mail($to,$subject,$message,$headers); else { echo "
";
		echo "To: $to\n";
		echo "Subject: $subject\n\n";
		echo "Message:\n$message\n";
		echo "Headers:\n";
		print_r($headers);
		echo "
";
		exit();		
	}
}

/**
 * Generates an RSS-compliant string from an associative 
 * array ($data) with a specific RSS-structure. */
function shopp_rss ($data) {
	$xmlns = '';
	if (is_array($data['xmlns']))
		foreach ($data['xmlns'] as $key => $value)
			$xmlns .= ' xmlns:'.$key.'="'.$value.'"';

	$xml = "\n";
	$xml .= "\n";
	$xml .= "\n";

	$xml .= ''."\n";
	$xml .= "".$data['title']."\n";
	$xml .= "".$data['description']."\n";
	$xml .= "".htmlentities($data['link'])."\n";
	$xml .= "en-us\n";
	$xml .= "Copyright ".date('Y').", ".$data['sitename']."\n";
	
	if (is_array($data['items'])) {
		foreach($data['items'] as $item) {
			$xml .= "\n";
			foreach ($item as $key => $value) {
				$attrs = '';
				if (is_array($value)) {
					$data = $value;
					$value = '';
					foreach ($data as $name => $content) {
						if (empty($name)) $value = $content;
						else $attrs .= ' '.$name.'="'.$content.'"';
					}
				}
				if (!empty($value)) $xml .= "<$key$attrs>$value\n";
				else $xml .= "<$key$attrs />\n";
			}
			$xml .= "\n";
		}
	}
	
	$xml .= "\n";
	$xml .= "\n";
	
	return $xml;
}

function shopp_image () {
	$db =& DB::get();
	require("model/Asset.php");
	$table = DatabaseObject::tablename(Settings::$table);
	$settings = $db->query("SELECT name,value FROM $table WHERE name='image_storage' OR name='image_path'",AS_ARRAY);
	foreach ($settings as $setting) ${$setting->name} = $setting->value;

	if (isset($_GET['shopp_image'])) $image = $_GET['shopp_image'];
	elseif (preg_match('/\/images\/(\d+).*$/',$_SERVER['REQUEST_URI'],$matches)) 
		$image = $matches[1];

	if (empty($image)) die();
	$Asset = new Asset($image);
	header('Last-Modified: '.date('D, d M Y H:i:s', $Asset->created).' GMT'); 
	header("Content-type: ".$Asset->properties['mimetype']);
	header("Content-Disposition: inline; filename=".$Asset->name.""); 
	header("Content-Description: Delivered by WordPress/Shopp ".SHOPP_VERSION);
	if ($image_storage == "fs") {
		header ("Content-length: ".@filesize(trailingslashit($image_path).$Asset->name)); 
		readfile(trailingslashit($image_path).$Asset->name);
	} else {
		header ("Content-length: ".strlen($Asset->data)); 
		echo $Asset->data;
	} 
	exit();
}

function shopp_catalog_css () {
	$db =& DB::get();
	$table = DatabaseObject::tablename(Settings::$table);
	$settings = $db->query("SELECT name,value FROM $table WHERE name='gallery_thumbnail_width' OR name='row_products' OR name='row_products' OR name='gallery_small_width' OR name='gallery_small_height'",AS_ARRAY);
	foreach ($settings as $setting) ${$setting->name} = $setting->value;

	$pluginuri = WP_PLUGIN_URL."/".basename(dirname(dirname(__FILE__)))."/";
	$pluginuri = force_ssl($pluginuri);

	if (!isset($row_products)) $row_products = 3;
	$products_per_row = floor((100/$row_products));
	
	ob_start();
	include("ui/styles/catalog.css");
	$file = ob_get_contents();
	ob_end_clean();
	header ("Content-type: text/css");
	header ("Content-Disposition: inline; filename=catalog.css"); 
	header ("Content-Description: Delivered by WordPress/Shopp ".SHOPP_VERSION);
	header ("Content-length: ".strlen($file)); 
	echo $file;
	exit();
}

function shopp_settings_js ($dir="shopp") {
	$db =& DB::get();
	$table = DatabaseObject::tablename(Settings::$table);
	$settings = $db->query("SELECT name,value FROM $table WHERE name='base_operations'",AS_ARRAY);
	foreach ($settings as $setting) ${$setting->name} = $setting->value;
	$base_operations = unserialize($base_operations);
	
	$path = array(PLUGINDIR,$dir,'lang');
	load_plugin_textdomain('Shopp', join(DIRECTORY_SEPARATOR,$path));
	
	ob_start();
	include("ui/behaviors/settings.js");
	$file = ob_get_contents();
	ob_end_clean();
	header ("Content-type: text/javascript");
	header ("Content-Disposition: inline; filename=settings.js"); 
	header ("Content-Description: Delivered by WordPress/Shopp ".SHOPP_VERSION);
	header ("Content-length: ".strlen($file)); 
	echo $file;
	exit();
}

/**
 * Formats a number into a standardized telephone number format */
function phone ($num) {
	if (empty($num)) return "";
	$num = preg_replace("/[A-Za-z\-\s\(\)]/","",$num);
	
	if (strlen($num) == 7) sscanf($num, "%3s%4s", $prefix, $exchange);
	if (strlen($num) == 10) sscanf($num, "%3s%3s%4s", $area, $prefix, $exchange);
	if (strlen($num) == 11) sscanf($num, "%1s%3s%3s%4s",$country, $area, $prefix, $exchange);
	//if (strlen($num) > 11) sscanf($num, "%3s%3s%4s%s", $area, $prefix, $exchange, $ext);
	
	$string = "";
	$string .= (isset($country))?"$country ":"";
	$string .= (isset($area))?"($area) ":"";
	$string .= (isset($prefix))?$prefix:"";
	$string .= (isset($exchange))?"-$exchange":"";
	$string .= (isset($ext))?" x$ext":"";
	return $string;

}

/**
 * Determines if the current client is a known web crawler bot */
function is_robot() {
	$bots = array("Googlebot","TeomaAgent","Zyborg","Gulliver","Architext spider","FAST-WebCrawler","Slurp","Ask Jeeves","ia_archiver","Scooter","Mercator","crawler@fast","Crawler","InfoSeek sidewinder","Lycos_Spider_(T-Rex)","Fluffy the Spider","Ultraseek","MantraAgent","Moget","MuscatFerret","VoilaBot","Sleek Spider","KIT_Fireball","WebCrawler");
	foreach($bots as $bot) {
		if (strpos(strtolower($_SERVER['HTTP_USER_AGENT']),strtolower($bot))) return true;
	}
	return false;
}

function shopp_prereqs () {
	$errors = array();
	// Check PHP version, this won't appear much since syntax errors in earlier
	// PHP releases will cause this code to never be executed
	if (!version_compare(PHP_VERSION, '5.0','>=')) 
		$errors[] = __("Shopp requires PHP version 5.0+.  You are using PHP version ").PHP_VERSION;

	if (version_compare(PHP_VERSION, '5.1.3','==')) 
		$errors[] = __("Shopp will not work with PHP version 5.1.3 because of a critical bug in complex POST data structures.  Please upgrade PHP to version 5.1.4 or higher.");
		
	// Check WordPress version
	if (!version_compare(get_bloginfo('version'),'2.6','>='))
		$errors[] = __("Shopp requires WordPress version 2.6+.  You are using WordPress version ").get_bloginfo('version');
	
	// Check for cURL
	if( !function_exists("curl_init") &&
	      !function_exists("curl_setopt") &&
	      !function_exists("curl_exec") &&
	      !function_exists("curl_close") ) $errors[] = __("Shopp requires the cURL library for processing transactions securely. Your web hosting environment does not currently have cURL installed (or built into PHP).");
	
	// Check for GD
	if (!function_exists("gd_info")) $errors[] = __("Shopp requires the GD image library with JPEG support for generating gallery and thumbnail images.  Your web hosting environment does not currently have GD installed (or built into PHP).");
	else {
		$gd = gd_info();
		if (!$gd['JPG Support'] && !$gd['JPEG Support']) $errors[] = __("Shopp requires JPEG support in the GD image library.  Your web hosting environment does not currently have a version of GD installed that has JPEG support.");
	}
	
	if (!empty($errors)) {
		$string .= '';
		
		foreach ($errors as $error) $string .= "

$error

"; $string .= '

'.__('Sorry! You will not be able to use Shopp. For more information, see the online Shopp documentation.').'

'; trigger_error($string,E_USER_ERROR); exit(); } return true; } if( !function_exists('esc_url') ) { /** * Checks and cleans a URL. From WordPress 2.8.0+ Included for WordPress 2.7 Users of Shopp * * A number of characters are removed from the URL. If the URL is for displaying * (the default behaviour) amperstands are also replaced. The 'esc_url' filter * is applied to the returned cleaned URL. * * @since 2.8.0 * @uses esc_url() * @uses wp_kses_bad_protocol() To only permit protocols in the URL set * via $protocols or the common ones set in the function. * * @param string $url The URL to be cleaned. * @param array $protocols Optional. An array of acceptable protocols. * Defaults to 'http', 'https', 'ftp', 'ftps', 'mailto', 'news', 'irc', 'gopher', 'nntp', 'feed', 'telnet' if not set. * @return string The cleaned $url after the 'cleaned_url' filter is applied. */ function esc_url( $url, $protocols = null ) { return clean_url( $url, $protocols, 'display' ); } } function shopp_debug ($object) { global $Shopp; ob_start(); print_r($object); $result = ob_get_contents(); ob_end_clean(); $Shopp->_debug->objects .= "

".str_replace("\n","
",$result); } function _object_r ($object) { global $Shopp; ob_start(); print_r($object); $result = ob_get_contents(); ob_end_clean(); return $result; } function shopp_pagename ($page) { global $is_IIS; $prefix = strpos($page,"index.php/"); if ($prefix !== false) return substr($page,$prefix+10); else return $page; } function shopp_redirect ($uri) { if (class_exists('ShoppError')) new ShoppError('Redirecting to: '.$uri,'shopp_redirect',SHOPP_DEBUG_ERR); wp_redirect($uri); exit(); } function get_filemeta ($file) { if (!file_exists($file)) return false; if (!is_readable($file)) return false; $meta = false; $string = ""; $f = @fopen($file, "r"); if (!$f) return false; while (!feof($f)) { $buffer = fgets($f,80); if (preg_match("/\/\*/",$buffer)) $meta = true; if ($meta) $string .= $buffer; if (preg_match("/\*\//",$buffer)) break; } fclose($f); return $string; } /** * Recursively searches directories and one-level deep of * sub-directories for files with a specific extension * NOTE: Files are saved to the $found parameter, * an array passed by reference, not a returned value */ function find_files ($extension, $directory, $root, &$found) { if (is_dir($directory)) { $Directory = @dir($directory); if ($Directory) { while (( $file = $Directory->read() ) !== false) { if (substr($file,0,1) == "." || substr($file,0,1) == "_") continue; // Ignore .dot files and _directories if (is_dir($directory.DIRECTORY_SEPARATOR.$file) && $directory == $root) // Scan one deep more than root find_files($extension,$directory.DIRECTORY_SEPARATOR.$file,$root, $found); // but avoid recursive scans if (substr($file,strlen($extension)*-1) == $extension) $found[] = substr($directory,strlen($root)).DIRECTORY_SEPARATOR.$file; // Add the file to the found list } return true; } } return false; } if (!function_exists('json_encode')) { function json_encode ($a = false) { if (is_null($a)) return 'null'; if ($a === false) return 'false'; if ($a === true) return 'true'; if (is_scalar($a)) { if (is_float($a)) { // Always use "." for floats. return floatval(str_replace(",", ".", strval($a))); } if (is_string($a)) { static $jsonReplaces = array(array("\\", "/", "\n", "\t", "\r", "\b", "\f", '"'), array('\\\\', '\\/', '\\n', '\\t', '\\r', '\\b', '\\f', '\"')); return '"' . str_replace($jsonReplaces[0], $jsonReplaces[1], $a) . '"'; } else return $a; } $isList = true; for ($i = 0, reset($a); $i < count($a); $i++, next($a)) { if (key($a) !== $i) { $isList = false; break; } } $result = array(); if ($isList) { foreach ($a as $v) $result[] = json_encode($v); return '[' . join(',', $result) . ']'; } else { foreach ($a as $k => $v) $result[] = json_encode($k).':'.json_encode($v); return '{' . join(',', $result) . '}'; } } } /** * List files and directories inside the specified path */ if(!function_exists('scandir')) { function scandir($dir, $sortorder = 0) { if(is_dir($dir) && $dirlist = @opendir($dir)) { $files = array(); while(($file = readdir($dirlist)) !== false) $files[] = $file; closedir($dirlist); ($sortorder == 0) ? asort($files) : rsort($files); return $files; } else return false; } } function filter_dotfiles ($name) { return (substr($name,0,1) != "."); } /** * Checks an object for a declared property * if() checks to see if the function is already available (as in PHP 5) */ if (!function_exists('property_exists')) { function property_exists($object, $property) { return array_key_exists($property, get_object_vars($object)); } } if (!function_exists('attribute_escape_deep')) { function attribute_escape_deep($value) { $value = is_array($value) ? array_map('attribute_escape_deep', $value) : attribute_escape($value); return $value; } } function auto_ranges ($avg,$max,$min) { $ranges = array(); if ($avg == 0 || $max == 0) return $ranges; $power = floor(log10($avg)); $scale = pow(10,$power); $median = round($avg/$scale)*$scale; $range = $max-$min; if ($range == 0) return $ranges; $steps = floor($range/$scale); if ($steps > 7) $steps = 7; elseif ($steps < 2) { $scale = $scale/2; $steps = ceil($range/$scale); if ($steps > 7) $steps = 7; elseif ($steps < 2) $steps = 2; } $base = $median-($scale*floor(($steps-1)/2)); for ($i = 0; $i < $steps; $i++) { $range = array("min" => 0,"max" => 0); if ($i == 0) $range['max'] = $base; else if ($i+1 >= $steps) $range['min'] = $base; else $range = array("min" => $base, "max" => $base+$scale); $ranges[] = $range; if ($i > 0) $base += $scale; } return $ranges; } function floatvalue($value, $format=true) { $value = preg_replace("/[^\d,\.]/","",$value); // Remove any non-numeric string data $value = preg_replace("/,/",".",$value); // Replace commas with periods $value = preg_replace("/[^0-9\.]/","", $value); // Get rid of everything but numbers and periods $value = preg_replace("/\.(?=.*\..*$)/s","",$value); // Replace all but the last period $value = preg_replace('#^([-]*[0-9\.,\' ]+?)((\.|,){1}([0-9-]{1,2}))*$#e', "str_replace(array('.', ',', \"'\", ' '), '', '\\1') . '.' . sprintf('%02d','\\4')", $value); if($format) return number_format(floatval($value),2); else return floatval($value); } /** * sort_tree * Sorts a heirarchical tree of data */ function sort_tree ($items,$parent=0,$key=-1,$depth=-1) { $depth++; $result = array(); if ($items) { foreach ($items as $item) { if ($item->parent == $parent) { $item->parentkey = $key; $item->depth = $depth; $result[] = $item; $children = sort_tree($items, $item->id, count($result)-1, $depth); $result = array_merge($result,$children); // Add children in as they are found } } } $depth--; return $result; } /** * file_mimetype * Tries a variety of methods to determine a file's mimetype */ function file_mimetype ($file,$name=false) { if (!$name) $name = basename($file); if (function_exists('finfo_open')) { // Try using PECL module $f = finfo_open(FILEINFO_MIME); list($mime,$charset) = explode(";",finfo_file($f, $file)); finfo_close($f); new ShoppError('File mimetype detection (finfo_open): '.$mime,false,SHOPP_DEBUG_ERR); return $mime; } elseif (class_exists('finfo')) { // Or class $f = new finfo(FILEINFO_MIME); new ShoppError('File mimetype detection (finfo class): '.$f->file($file),false,SHOPP_DEBUG_ERR); return $f->file($file); } elseif (strlen($mime=trim(@shell_exec('file -bI "'.escapeshellarg($file).'"')))!=0) { new ShoppError('File mimetype detection (shell file command): '.$mime,false,SHOPP_DEBUG_ERR); // Use shell if allowed return trim($mime); } elseif (strlen($mime=trim(@shell_exec('file -bi "'.escapeshellarg($file).'"')))!=0) { new ShoppError('File mimetype detection (shell file command, alt options): '.$mime,false,SHOPP_DEBUG_ERR); // Use shell if allowed return trim($mime); } elseif (function_exists('mime_content_type') && $mime = mime_content_type($file)) { // Try with magic-mime if available new ShoppError('File mimetype detection (mime_content_type()): '.$mime,false,SHOPP_DEBUG_ERR); return $mime; } else { if (!preg_match('/\.([a-z0-9]{2,4})$/i', $name, $extension)) return false; switch (strtolower($extension[1])) { // misc files case 'txt': return 'text/plain'; case 'htm': case 'html': case 'php': return 'text/html'; case 'css': return 'text/css'; case 'js': return 'application/javascript'; case 'json': return 'application/json'; case 'xml': return 'application/xml'; case 'swf': return 'application/x-shockwave-flash'; // images case 'jpg': case 'jpeg': case 'jpe': return 'image/jpg'; case 'png': case 'gif': case 'bmp': case 'tiff': return 'image/'.strtolower($matches[1]); case 'tif': return 'image/tif'; case 'svg': case 'svgz': return 'image/svg+xml'; // archives case 'zip': return 'application/zip'; case 'rar': return 'application/x-rar-compressed'; case 'exe': case 'msi': return 'application/x-msdownload'; case 'tar': return 'application/x-tar'; case 'cab': return 'application/vnd.ms-cab-compressed'; // audio/video case 'flv': return 'video/x-flv'; case 'mpeg': case 'mpg': case 'mpe': return 'video/mpeg'; case 'mp4s': return 'application/mp4'; case 'mp3': return 'audio/mpeg3'; case 'wav': return 'audio/wav'; case 'aiff': case 'aif': return 'audio/aiff'; case 'avi': return 'video/msvideo'; case 'wmv': return 'video/x-ms-wmv'; case 'mov': case 'qt': return 'video/quicktime'; // ms office case 'doc': case 'docx': return 'application/msword'; case 'xls': case 'xlt': case 'xlm': case 'xld': case 'xla': case 'xlc': case 'xlw': case 'xll': return 'application/vnd.ms-excel'; case 'ppt': case 'pps': return 'application/vnd.ms-powerpoint'; case 'rtf': return 'application/rtf'; // adobe case 'pdf': return 'application/pdf'; case 'psd': return 'image/vnd.adobe.photoshop'; case 'ai': case 'eps': case 'ps': return 'application/postscript'; // open office case 'odt': return 'application/vnd.oasis.opendocument.text'; case 'ods': return 'application/vnd.oasis.opendocument.spreadsheet'; } return false; } } /** * Returns a list marked-up as drop-down menu options */ function menuoptions ($list,$selected=null,$values=false,$extend=false) { if (!is_array($list)) return ""; $string = ""; // Extend the options if the selected value doesn't exist if ((!in_array($selected,$list) && !isset($list[$selected])) && $extend) $string .= ""; foreach ($list as $value => $text) { if ($values) { if ($value == $selected) $string .= ""; else $string .= ""; } else { if ($text == $selected) $string .= ""; else $string .= ""; } } return $string; } function scan_money_format ($format) { $f = array( "cpos" => true, "currency" => "", "precision" => 0, "decimals" => "", "thousands" => "" ); $ds = strpos($format,'#'); $de = strrpos($format,'#')+1; $df = substr($format,$ds,($de-$ds)); if ($df == "#,##,###.##") $f['indian'] = true; $f['cpos'] = true; if ($de == strlen($format)) $f['currency'] = substr($format,0,$ds); else { $f['currency'] = substr($format,$de); $f['cpos'] = false; } $i = 0; $dd = 0; $dl = array(); $sdl = ""; $uniform = true; while($i < strlen($df)) { $c = substr($df,$i++,1); if ($c != "#") { if(empty($sdl)) $sdl = $c; else if($sdl != $c) $uniform = false; $dl[] = $c; $dd = 0; } else $dd++; } if(!$uniform) $f['precision'] = $dd; if (count($dl) > 1) { if ($dl[0] == "t") { $f['thousands'] = $dl[1]; $f['precision'] = 0; } else { $f['decimals'] = $dl[count($dl)-1]; $f['thousands'] = $dl[0]; } } else $f['decimals'] = $dl[0]; return $f; } function money ($amount,$format=false) { global $Shopp; $locale = $Shopp->Settings->get('base_operations'); if (!$format) $format = $locale['currency']['format']; if (empty($format['currency'])) $format = array("cpos"=>true,"currency"=>"$","precision"=>2,"decimals"=>".","thousands" => ","); if (isset($format['indian'])) $number = indian_number($amount,$format); else $number = number_format($amount, $format['precision'], $format['decimals'], $format['thousands']); if ($format['cpos']) return $format['currency'].$number; else return $number.$format['currency']; } function percentage ($amount,$format=false) { global $Shopp; $locale = $Shopp->Settings->get('base_operations'); if (!$format) { $format = $locale['currency']['format']; $format['precision'] = 0; } if (!$format) $format = array("precision"=>1,"decimals"=>".","thousands" => ","); if (isset($format['indian'])) return indian_number($amount,$format); return number_format(round($amount), $format['precision'], $format['decimals'], $format['thousands']).'%'; } function indian_number ($number,$format=false) { if (!$format) $format = array("precision"=>1,"decimals"=>".","thousands" => ","); $d = explode(".",$number); $number = ""; $digits = substr($d[0],0,-3); // Get rid of the last 3 if (strlen($d[0]) > 3) $number = substr($d[0],-3); else $number = $d[0]; for ($i = 0; $i < (strlen($digits) / 2); $i++) $number = substr($digits,(-2*($i+1)),2).((strlen($number) > 0)?$format['thousands'].$number:$number); if ($format['precision'] > 0) $number = $number.$format['decimals'].substr(number_format('0.'.$d[1],$format['precision']),2); return $number; } function floatnum ($number) { $number = preg_replace("/,/",".",$number); // Replace commas with periods $number = preg_replace("/[^0-9\.]/","", $number); // Get rid of everything but numbers and periods $number = preg_replace("/\.(?=.*\..+$)/s","",$number); // Replace all but the last period return $number; } function value_is_true ($value) { switch (strtolower($value)) { case "yes": case "true": case "1": case "on": return true; default: return false; } } function valid_input ($type) { $inputs = array("text","hidden","checkbox","radio","button","submit"); if (in_array($type,$inputs) !== false) return true; return false; } function _d($format,$timestamp=false) { $tokens = array( 'D' => array('Mon' => __('Mon','Shopp'),'Tue' => __('Tue','Shopp'), 'Wed' => __('Wed','Shopp'),'Thu' => __('Thu','Shopp'), 'Fri' => __('Fri','Shopp'),'Sat' => __('Sat','Shopp'), 'Sun' => __('Sun','Shopp')), 'l' => array('Monday' => __('Monday','Shopp'),'Tuesday' => __('Tuesday','Shopp'), 'Wednesday' => __('Wednesday','Shopp'),'Thursday' => __('Thursday','Shopp'), 'Friday' => __('Friday','Shopp'),'Saturday' => __('Saturday','Shopp'), 'Sunday' => __('Sunday','Shopp')), 'F' => array('January' => __('January','Shopp'),'February' => __('February','Shopp'), 'March' => __('March','Shopp'),'April' => __('April','Shopp'), 'May' => __('May','Shopp'),'June' => __('June','Shopp'), 'July' => __('July','Shopp'),'August' => __('August','Shopp'), 'September' => __('September','Shopp'),'October' => __('October','Shopp'), 'November' => __('November','Shopp'),'December' => __('December','Shopp')), 'M' => array('Jan' => __('Jan','Shopp'),'Feb' => __('Feb','Shopp'), 'Mar' => __('Mar','Shopp'),'Apr' => __('Apr','Shopp'), 'May' => __('May','Shopp'),'Jun' => __('Jun','Shopp'), 'Jul' => __('Jul','Shopp'),'Aug' => __('Aug','Shopp'), 'Sep' => __('Sep','Shopp'),'Oct' => __('Oct','Shopp'), 'Nov' => __('Nov','Shopp'),'Dec' => __('Dec','Shopp')) ); if (!$timestamp) $date = date($format); else $date = date($format,$timestamp); foreach ($tokens as $token => $strings) { if ($pos = strpos($format,$token) === false) continue; $string = (!$timestamp)?date($token):date($token,$timestamp); $date = str_replace($string,$strings[$string],$date); } return $date; } function shopp_taxrate ($override=null,$taxprice=true) { global $Shopp; $rated = false; $taxrate = 0; $base = $Shopp->Settings->get('base_operations'); if ($base['vat']) $rated = true; if (!is_null($override)) $rated = (value_is_true($override)); if (!value_is_true($taxprice)) $rated = false; if ($rated) $taxrate = $Shopp->Cart->taxrate(); return $taxrate; } function inputattrs ($options,$allowed=array()) { if (!is_array($options)) return ""; if (empty($allowed)) { $allowed = array("accesskey","alt","checked","class","disabled","format", "minlength","maxlength","readonly","required","size","src","tabindex", "title","value"); } $string = ""; $classes = ""; if (isset($options['label'])) $options['value'] = $options['label']; foreach ($options as $key => $value) { if (!in_array($key,$allowed)) continue; switch($key) { case "class": $classes .= " $value"; break; case "disabled": $classes .= " disabled"; $string .= ' disabled="disabled"'; break; case "readonly": $classes .= " readonly"; $string .= ' readonly="readonly"'; break; case "required": $classes .= " required"; break; case "minlength": $classes .= " min$value"; break; case "format": $classes .= " $value"; break; default: $string .= ' '.$key.'="'.$value.'"'; } } $string .= ' class="'.trim($classes).'"'; return $string; } function build_query_request ($request=array()) { $query = ""; foreach ($request as $name => $value) { if (strlen($query) > 0) $query .= "&"; $query .= "$name=$value"; } return $query; } function readableFileSize($bytes,$precision=1) { $units = array(__("bytes","Shopp"),"KB","MB","GB","TB","PB"); $sized = $bytes*1; if ($sized == 0) return $sized; $unit = 0; while ($sized > 1024 && ++$unit) $sized = $sized/1024; return round($sized,$precision)." ".$units[$unit]; } // From WP 2.7.0 for backwards compatibility function shopp_print_column_headers( $type, $id = true ) { global $wp_version; if (version_compare($wp_version,"2.7.0",">=")) return print_column_headers($type,$id); $type = str_replace('.php', '', $type); $columns = shopp_get_column_headers( $type ); $hidden = array(); $styles = array(); foreach ( $columns as $column_key => $column_display_name ) { $class = ' class="manage-column'; $class .= " column-$column_key"; if ( 'cb' == $column_key ) $class .= ' check-column'; elseif ( in_array($column_key, array('posts', 'comments', 'links')) ) $class .= ' num'; $class .= '"'; $style = ''; if ( in_array($column_key, $hidden) ) $style = 'display:none;'; if ( isset($styles[$type]) && isset($styles[$type][$column_key]) ) $style .= ' ' . $styles[$type][$column_key]; $style = ' style="' . $style . '"'; ?> > =")) return register_column_headers($screen,$columns); global $_wp_column_headers; if ( !isset($_wp_column_headers) ) $_wp_column_headers = array(); $_wp_column_headers[$screen] = $columns; } // Adapted from WP 2.7.0 for backwards compatibility function shopp_get_column_headers($page) { global $_wp_column_headers; if ( !isset($_wp_column_headers) ) $_wp_column_headers = array(); // Store in static to avoid running filters on each call if ( isset($_wp_column_headers[$page]) ) return $_wp_column_headers[$page]; return array(); } function copy_shopp_templates ($src,$target) { $builtin = array_filter(scandir($src),"filter_dotfiles"); foreach ($builtin as $template) { $target_file = $target.DIRECTORY_SEPARATOR.$template; if (!file_exists($target_file)) { $src_file = file_get_contents($src.DIRECTORY_SEPARATOR.$template); $file = fopen($target_file,'w'); $src_file = preg_replace('/^<\?php\s\/\*\*\s+(.*?\s)*?\*\*\/\s\?>\s/','',$src_file); fwrite($file,$src_file); fclose($file); chmod($target_file,0666); } } } /** * Determines if the requested page is a Shopp page or if it matches a given Shopp page * * @param string $page (optional) Page name to look for in Shopp's page registry * @return boolean * @author Jonathan Davis **/ function is_shopp_page ($page=false) { global $Shopp,$wp_query; if ($wp_query->post->post_type != "page") return false; $pages = $Shopp->Settings->get('pages'); // Detect if the requested page is a Shopp page if (!$page) { foreach ($pages as $page) if ($page['id'] == $wp_query->post->ID) return true; return false; } // Determine if the visitor's requested page matches the provided page if (!isset($pages[strtolower($page)])) return false; $page = $pages[strtolower($page)]; if ($page['id'] == $wp_query->post->ID) return true; return false; } function is_shopp_secure () { return (isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on"); } function template_path ($path) { if (DIRECTORY_SEPARATOR == "\\") $path = str_replace("/","\\",$path); return $path; } function gateway_path ($file) { return basename(dirname($file)).DIRECTORY_SEPARATOR.basename($file); } function force_ssl ($url) { if(isset($_SERVER['HTTPS']) && $_SERVER["HTTPS"] == "on") $url = str_replace('http://', 'https://', $url); return $url; } if ( !function_exists('sys_get_temp_dir')) { // For PHP 5 (pre-5.2.1) function sys_get_temp_dir() { if (!empty($_ENV['TMP'])) return realpath($_ENV['TMP']); if (!empty($_ENV['TMPDIR'])) return realpath( $_ENV['TMPDIR']); if (!empty($_ENV['TEMP'])) return realpath( $_ENV['TEMP']); $tempfile = tempnam(uniqid(rand(),TRUE),''); if (file_exists($tempfile)) { unlink($tempfile); return realpath(dirname($tempfile)); } } } class FTPClient { var $connected = false; var $log = array(); var $remapped = false; function FTPClient ($host, $user, $password) { $this->connect($host, $user, $password); if ($this->connected) ftp_pasv($this->connection,true); else return false; return true; } /** * Connects to the FTP server */ function connect($host, $user, $password) { $this->connection = @ftp_connect($host,0,20); if (!$this->connection) return false; $this->connected = @ftp_login($this->connection,$user,$password); if (!$this->connected) return false; return true; } /** * update() * Recursively copies files from a src $path to the $remote path */ function update ($path,$remote) { if (is_dir($path)){ $path = trailingslashit($path); // $this->log[] = "The source path is $path"; $files = scandir($path); $remote = trailingslashit($remote); // $this->log[] = "The destination path is $remote"; } else { $files = array(basename($path)); $path = trailingslashit(dirname($path)); // $this->log[] = "The source path is $path"; $remote = trailingslashit(dirname($remote)); // $this->log[] = "The destination path is $remote"; } if (!$this->remapped) $remote = $this->remappath($remote); // $this->log[] = "The remapped destination path is $remote"; $excludes = array(".",".."); foreach ((array)$files as $file) { if (in_array($file,$excludes)) continue; if (is_dir($path.$file)) { if (!@ftp_chdir($this->connection,$remote.$file)) $this->mkdir($remote.$file); $this->update($path.$file,$remote.$file); } else $this->put($path.$file,$remote.$file); } return $this->log; } /** * delete() * Delete the target file, recursively delete directories */ function delete ($file) { if (empty($file)) return false; if (!$this->isdir($file)) return @ftp_delete($this->connection, $file); $files = $this->scan($file); if (!empty($files)) foreach ($files as $target) $this->delete($target); return @ftp_rmdir($this->connection, $file); } /** * put() * Copies the target file to the remote location */ function put ($file,$remote) { if (@ftp_put($this->connection,$remote,$file,FTP_BINARY)) return @ftp_chmod($this->connection, 0644, $remote); else $this->log[] = "Could not move the file from $file to $remote"; } /** * mkdir() * Makes a new remote directory with correct permissions */ function mkdir ($path) { if (@ftp_mkdir($this->connection,$path)) @ftp_chmod($this->connection,0755,$path); else $this->log[] = "Could not create the directory $path"; } /** * mkdir() * Gets the current directory */ function pwd () { return ftp_pwd($this->connection); } /** * scan() * Gets a list of files in a directory/current directory */ function scan ($path=false) { if (!$path) $path = $this->pwd(); return @ftp_nlist($this->connection,$path); } /** * isdir() * Determines if the file is a directory or a file */ function isdir ($file=false) { if (!$file) $file = $this->pwd(); if (@ftp_size($this->connection, $file) == '-1') return true; // Directory else return false; // File } /** * remappath() * Remap a given path to the root path of the FTP server * to take into account root jails common in FTP setups */ function remappath ($path) { $files = $this->scan(); foreach ($files as $file) { $filepath = trailingslashit($this->pwd()).basename($file); if (!$this->isdir($filepath)) continue; $index = strrpos($path,$filepath); if ($index !== false) { $this->remapped = true; return substr($path,$index); } } // No remapping needed return $path; } } if (function_exists('date_default_timezone_set')) date_default_timezone_set(get_option('timezone_string')); shopp_prereqs(); // Run by default at include ?>