Page Menu
Home
In-Portal Phabricator
Search
Configure Global Search
Log In
Files
F1125090
in-portal
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Flag For Later
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Thu, Sep 4, 5:45 AM
Size
48 KB
Mime Type
text/x-diff
Expires
Sat, Sep 6, 5:45 AM (2 h, 27 m)
Engine
blob
Format
Raw Data
Handle
727019
Attached To
rINP In-Portal
in-portal
View Options
Index: branches/5.2.x/core/kernel/globals.php
===================================================================
--- branches/5.2.x/core/kernel/globals.php (revision 16856)
+++ branches/5.2.x/core/kernel/globals.php (revision 16857)
@@ -1,1295 +1,1306 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2009 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
use Symfony\Component\VarDumper\Cloner\VarCloner;
use Symfony\Component\VarDumper\Dumper\CliDumper;
use Symfony\Component\VarDumper\Dumper\HtmlDumper;
defined('FULL_PATH') or die('restricted access!');
class kUtil {
// const KG_TO_POUND = 2.20462262;
const POUND_TO_KG = 0.45359237;
/**
* Escape text as HTML.
*
* @see escape
*/
const ESCAPE_HTML = 'html';
/**
* Escape text as JavaScript.
*
* @see escape
*/
const ESCAPE_JS = 'js';
/**
* Escape text as Url.
*/
const ESCAPE_URL = 'url';
/**
* Don't escape anything.
*/
const ESCAPE_RAW = 'raw';
/**
* Current escape strategy.
*
* @var string
* @see escape
*/
public static $escapeStrategy = self::ESCAPE_HTML;
/**
* Checks, that given array is associative.
*
* @param array $array Array.
*
* @return bool
* @access public
*/
public static function isAssoc($array)
{
return array_keys($array) !== range(0, count($array) - 1);
}
/**
* Similar to array_merge_recursive but keyed-valued are always overwritten.
* Priority goes to the 2nd array.
*
* @param mixed $array1 Array 1.
* @param mixed $array2 Array 2.
*
* @return array
*/
public static function array_merge_recursive($array1, $array2)
{
if ( !is_array($array1) || !is_array($array2) ) {
return $array2;
}
foreach ( $array2 as $array2_key => $array2_value ) {
if ( isset($array1[$array2_key]) ) {
$array1[$array2_key] = self::array_merge_recursive($array1[$array2_key], $array2_value);
}
else {
$array1[$array2_key] = $array2_value;
}
}
return $array1;
}
/**
* Prepend a reference to an element to the beginning of an array.
* Renumbers numeric keys, so $value is always inserted to $array[0]
*
* @param $array array
* @param $value mixed
* @return int
* @access public
*/
public static function array_unshift_ref(&$array, &$value)
{
$return = array_unshift($array,'');
$array[0] =& $value;
return $return;
}
/**
* Rename key in associative array, maintaining keys order
*
* @param Array $array Associative Array
* @param mixed $old Old key name
* @param mixed $new New key name
* @access public
*/
public static function array_rename_key(&$array, $old, $new)
{
$new_array = Array ();
foreach ($array as $key => $val) {
$new_array[ $key == $old ? $new : $key] = $val;
}
$array = $new_array;
}
/**
* Same as print_r, but outputs result on screen or in debugger report (when in debug mode)
*
* @param Array $data
* @param string $label
* @param bool $on_screen
* @access public
*/
public static function print_r($data, $label = '', $on_screen = false)
{
$is_debug = false;
if ( class_exists('kApplication') && !$on_screen ) {
$application =& kApplication::Instance();
$is_debug = $application->isDebugMode();
}
if ( $is_debug && isset($application) ) {
if ( $label ) {
$application->Debugger->appendHTML('<strong>' . $label . '</strong>');
}
$application->Debugger->dumpVars($data);
}
else {
if ( $label ) {
echo '<strong>' . $label . '</strong><br/>';
}
echo '<pre>', print_r($data, true), '</pre>';
}
}
/**
* Define constant if it was not already defined before
*
* @param string $const_name
* @param string $const_value
* @access public
*/
public static function safeDefine($const_name, $const_value)
{
if ( !defined($const_name) ) {
define($const_name, $const_value);
}
}
/**
* Instantiate kSystemConfig class once and store locally
*
* @access public
*/
public static function getSystemConfig()
{
static $system_config;
if ( !isset($system_config) ) {
$system_config = new kSystemConfig();
}
return $system_config;
}
/**
* Same as "include_once", but also profiles file includes in debug mode and DBG_PROFILE_INCLUDES constant is set
*
* @param string $file
* @access public
*/
public static function includeOnce($file)
{
global $debugger;
if ( defined('DEBUG_MODE') && DEBUG_MODE && isset($debugger) && defined('DBG_PROFILE_INCLUDES') && DBG_PROFILE_INCLUDES ) {
if ( in_array($file, get_included_files()) ) {
return ;
}
global $debugger;
/*$debugger->IncludeLevel++;
$before_mem = memory_get_usage();*/
$debugger->ProfileStart('inc_'.crc32($file), $file);
include_once($file);
$debugger->ProfileFinish('inc_'.crc32($file));
$debugger->profilerAddTotal('includes', 'inc_'.crc32($file));
/*$used_mem = memory_get_usage() - $before_mem;
$debugger->IncludeLevel--;
$debugger->IncludesData['file'][] = str_replace(FULL_PATH, '', $file);
$debugger->IncludesData['mem'][] = $used_mem;
$debugger->IncludesData['time'][] = $used_time;
$debugger->IncludesData['level'][] = $debugger->IncludeLevel;*/
}
else {
include_once($file);
}
}
/**
* Checks if given string is a serialized array
*
* @param string $string
* @return bool
* @access public
*/
public static function IsSerialized($string)
{
if ( is_array($string) ) {
return false;
}
return preg_match('/a:([\d]+):{/', $string);
}
/**
* Generates password of given length
*
* @param int $length
* @return string
* @access public
*/
public static function generatePassword($length = 10)
{
$pass_length = $length;
$p1 = Array ('b','c','d','f','g','h','j','k','l','m','n','p','q','r','s','t','v','w','x','y','z');
$p2 = Array ('a','e','i','o','u');
$p3 = Array ('1','2','3','4','5','6','7','8','9');
$p4 = Array ('(','&',')',';','%'); // if you need real strong stuff
// how much elements in the array
// can be done with a array count but counting once here is faster
$s1 = 21;// this is the count of $p1
$s2 = 5; // this is the count of $p2
$s3 = 9; // this is the count of $p3
$s4 = 5; // this is the count of $p4
// possible readable combinations
$c1 = '121'; // will be like 'bab'
$c2 = '212'; // will be like 'aba'
$c3 = '12'; // will be like 'ab'
$c4 = '3'; // will be just a number '1 to 9' if you dont like number delete the 3
//$c5 = '4'; // uncomment to active the strong stuff
$comb = '4'; // the amount of combinations you made above (and did not comment out)
for ($p = 0; $p < $pass_length;) {
mt_srand((double)microtime() * 1000000);
$strpart = mt_rand(1, $comb);
// checking if the stringpart is not the same as the previous one
if ($strpart != $previous) {
$pass_structure .= ${'c' . $strpart};
// shortcutting the loop a bit
$p = $p + mb_strlen(${'c' . $strpart});
}
$previous = $strpart;
}
// generating the password from the structure defined in $pass_structure
for ($g = 0; $g < mb_strlen($pass_structure); $g++) {
mt_srand((double)microtime() * 1000000);
$sel = mb_substr($pass_structure, $g, 1);
$pass .= ${'p' . $sel}[ mt_rand(0,-1+${'s'.$sel}) ];
}
return $pass;
}
/**
* submits $url with $post as POST
*
* @param string $url
* @param mixed $data
* @param Array $headers
* @param string $request_type
* @param Array $curl_options
* @return string
* @access public
* @deprecated
*/
public static function curl_post($url, $data, $headers = NULL, $request_type = 'POST', $curl_options = NULL)
{
$application =& kApplication::Instance();
/** @var kCurlHelper $curl_helper */
$curl_helper = $application->recallObject('CurlHelper');
if ($request_type == 'POST') {
$curl_helper->SetRequestMethod(kCurlHelper::REQUEST_METHOD_POST);
}
$curl_helper->SetRequestData($data);
if (!is_null($headers)) {
// not an associative array, so don't use kCurlHelper::SetHeaders method
$curl_helper->setOptions( Array (CURLOPT_HTTPHEADER => $headers) );
}
if (is_array($curl_options)) {
$curl_helper->setOptions($curl_options);
}
$curl_helper->followLocation = false;
$ret = $curl_helper->Send($url);
$GLOBALS['curl_errorno'] = $curl_helper->lastErrorCode;
$GLOBALS['curl_error'] = $curl_helper->lastErrorMsg;
return $ret;
}
/**
* Checks if constant is defined and has positive value
*
* @param string $const_name
* @return bool
* @access public
*/
public static function constOn($const_name)
{
return defined($const_name) && constant($const_name);
}
/**
* Converts KG to Pounds
*
- * @param float $kg
- * @param bool $pounds_only
- * @return float
- * @access public
+ * @param float $kg Kilograms.
+ * @param boolean $pounds_only Calculate as pounds only.
+ *
+ * @return array
+ * @throws InvalidArgumentException When the $kg argument isn't a number.
*/
public static function Kg2Pounds($kg, $pounds_only = false)
{
- $major = floor( round($kg / self::POUND_TO_KG, 3) );
+ if ( !is_numeric($kg) ) {
+ throw new InvalidArgumentException('The $kg argument isn\'t a number.');
+ }
+
+ $major = floor(round($kg / self::POUND_TO_KG, 3));
$minor = abs(round(($kg - $major * self::POUND_TO_KG) / self::POUND_TO_KG * 16, 2));
- if ($pounds_only) {
+ if ( $pounds_only ) {
$major += round($minor * 0.0625, 2);
$minor = 0;
}
+
return array($major, $minor);
}
/**
* Converts Pounds to KG
*
- * @param float $pounds
- * @param float $ounces
+ * @param float $pounds Pounds.
+ * @param float $ounces Ounces.
+ *
* @return float
- * @access public
+ * @throws InvalidArgumentException When either the $pounds or $ounces argument isn't a number.
*/
public static function Pounds2Kg($pounds, $ounces = 0.00)
{
+ if ( !is_numeric($pounds) || !is_numeric($ounces) ) {
+ throw new InvalidArgumentException('Either the $pounds or $ounces argument isn\'t a number.');
+ }
+
return round(($pounds + ($ounces / 16)) * self::POUND_TO_KG, 5);
}
/**
* Formats file/memory size in nice way
*
* @param int $bytes
* @return string
* @access public
*/
public static function formatSize($bytes)
{
if ($bytes >= 1099511627776) {
$return = round($bytes / 1024 / 1024 / 1024 / 1024, 2);
$suffix = "TB";
} elseif ($bytes >= 1073741824) {
$return = round($bytes / 1024 / 1024 / 1024, 2);
$suffix = "GB";
} elseif ($bytes >= 1048576) {
$return = round($bytes / 1024 / 1024, 2);
$suffix = "MB";
} elseif ($bytes >= 1024) {
$return = round($bytes / 1024, 2);
$suffix = "KB";
} else {
$return = $bytes;
$suffix = "Byte";
}
$return .= ' '.$suffix;
return $return;
}
/**
* Enter description here...
*
* @param resource $filePointer the file resource to write to
* @param Array $data the data to write out
* @param string $delimiter the field separator
* @param string $enclosure symbol to enclose field data to
* @param string $recordSeparator symbols to separate records with
* @access public
*/
public static function fputcsv($filePointer, $data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
{
fwrite($filePointer, self::getcsvline($data, $delimiter, $enclosure, $recordSeparator));
}
/**
* Enter description here...
*
* @param Array $data the data to write out
* @param string $delimiter the field separator
* @param string $enclosure symbol to enclose field data to
* @param string $recordSeparator symbols to separate records with
* @return string
* @access public
*/
public static function getcsvline($data, $delimiter = ',', $enclosure = '"', $recordSeparator = "\r\n")
{
ob_start();
$fp = fopen('php://output', 'w');
fputcsv($fp, $data, $delimiter, $enclosure);
fclose($fp);
$ret = ob_get_clean();
if ( $recordSeparator != "\n" ) {
return substr($ret, 0, -1) . $recordSeparator;
}
return $ret;
}
/**
* Allows to replace #section# within any string with current section
*
* @param string $string
* @return string
* @access public
*/
public static function replaceModuleSection($string)
{
$application =& kApplication::Instance();
$module_section = $application->RecallVar('section');
if ($module_section) {
// substitute section instead of #section# parameter in title preset name
$module_section = explode(':', $module_section);
$section = preg_replace('/(configuration|configure)_(.*)/i', '\\2', $module_section[count($module_section) == 2 ? 1 : 0]);
$string = str_replace('#section#', mb_strtolower($section), $string);
}
return $string;
}
/**
* Checks, that user IP address is within allowed range
*
* @param string $ip_list semi-column (by default) separated ip address list
* @param string $separator ip address separator (default ";")
*
* @return bool
* @access public
*/
public static function ipMatch($ip_list, $separator = ';')
{
if ( php_sapi_name() == 'cli' ) {
return false;
}
$ip_match = false;
$ip_addresses = $ip_list ? explode($separator, $ip_list) : Array ();
$application =& kApplication::Instance();
$client_ip = $application->getClientIp();
foreach ($ip_addresses as $ip_address) {
if ( self::netMatch($ip_address, $client_ip) ) {
$ip_match = true;
break;
}
}
return $ip_match;
}
/**
* Checks, that given ip belongs to given subnet
*
* @param string $network
* @param string $ip
* @return bool
* @access public
*/
public static function netMatch($network, $ip)
{
$network = trim($network);
$ip = trim($ip);
if ( preg_replace('#[\da-f.:\-/]#i', '', $network) != '' ) {
$network = gethostbyname($network);
}
// Comparing two ip addresses directly.
if ( $network === $ip ) {
return true;
}
// Compare only with networks of the same IP specification.
if ( filter_var($ip, FILTER_VALIDATE_IP, FILTER_FLAG_IPV4) ) {
$filter_option = FILTER_FLAG_IPV4;
}
else {
$filter_option = FILTER_FLAG_IPV6;
}
// IP address range specified.
$delimiter_pos = strpos($network, '-');
if ( $delimiter_pos !== false ) {
$from = trim(substr($network, 0, $delimiter_pos));
$to = trim(substr($network, $delimiter_pos + 1));
if ( !filter_var($from, FILTER_VALIDATE_IP, $filter_option)
|| !filter_var($to, FILTER_VALIDATE_IP, $filter_option)
) {
return false;
}
if ( $filter_option === FILTER_FLAG_IPV4 ) {
$ip = ip2long($ip);
return $ip >= ip2long($from) && $ip <= ip2long($to);
}
$ip = inet_pton($ip);
return $ip >= inet_pton($from) && $ip <= inet_pton($to);
}
// Single subnet specified (CIDR).
if ( strpos($network, '/') !== false ) {
$ip_arr = explode('/', $network);
// Alternate form of the "194.1.4/24".
if ( ($filter_option === FILTER_FLAG_IPV4) && !preg_match('@\d*\.\d*\.\d*\.\d*@', $ip_arr[0]) ) {
$ip_arr[0] .= '.0';
}
if ( !filter_var($ip_arr[0], FILTER_VALIDATE_IP, $filter_option) ) {
return false;
}
if ( $filter_option === FILTER_FLAG_IPV4 ) {
$network_long = ip2long($ip_arr[0]);
$x = ip2long($ip_arr[1]);
$mask = long2ip($x) == $ip_arr[1] ? $x : (0xffffffff << (32 - $ip_arr[1]));
$ip_long = ip2long($ip);
return ($ip_long & $mask) == ($network_long & $mask);
}
$subnet_hex = unpack('H*', inet_pton($ip_arr[0]))[1]; // 32 bytes, but 16 hex symbols.
$ip_hex = unpack('H*', inet_pton($ip))[1]; // 32 bytes, but 16 hex symbols.
$mask = $ip_arr[1] / 4; // The "4" is the size of each hex symbol in bits.
$subnet_hex = hex2bin(str_pad(substr($subnet_hex, 0, $mask), 32, '0'));
$ip_hex = hex2bin(str_pad(substr($ip_hex, 0, $mask), 32, '0'));
return $subnet_hex === $ip_hex;
}
return false;
}
/**
* Returns mime type corresponding to given file
* @param string $file
* @return string
* @access public
*/
public static function mimeContentType($file)
{
$ret = self::vendorMimeContentType($file);
if ( $ret ) {
// vendor-specific mime types override any automatic detection
return $ret;
}
if ( function_exists('finfo_open') && function_exists('finfo_file') ) {
$mime_magic_resource = finfo_open(FILEINFO_MIME_TYPE);
if ( $mime_magic_resource ) {
$ret = finfo_file($mime_magic_resource, $file);
finfo_close($mime_magic_resource);
}
}
elseif ( function_exists('mime_content_type') ) {
$ret = mime_content_type($file);
}
return $ret ? $ret : self::mimeContentTypeByExtension($file);
}
/**
* Determines vendor-specific mime type from a given file
*
* @param string $file
* @return bool
* @access public
* @static
*/
public static function vendorMimeContentType($file)
{
$file_extension = mb_strtolower(pathinfo(self::removeTempExtension($file), PATHINFO_EXTENSION));
$mapping = Array (
'docx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
'dotx' => 'application/vnd.openxmlformats-officedocument.wordprocessingml.template',
'docm' => 'application/vnd.ms-word.document.macroEnabled.12',
'dotm' => 'application/vnd.ms-word.template.macroEnabled.12',
'xlsx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
'xltx' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.template',
'xlsm' => 'application/vnd.ms-excel.sheet.macroEnabled.12',
'xltm' => 'application/vnd.ms-excel.template.macroEnabled.12',
'xlam' => 'application/vnd.ms-excel.addin.macroEnabled.12',
'xlsb' => 'application/vnd.ms-excel.sheet.binary.macroEnabled.12',
'pptx' => 'application/vnd.openxmlformats-officedocument.presentationml.presentation',
'potx' => 'application/vnd.openxmlformats-officedocument.presentationml.template',
'ppsx' => 'application/vnd.openxmlformats-officedocument.presentationml.slideshow',
'ppam' => 'application/vnd.ms-powerpoint.addin.macroEnabled.12',
'pptm' => 'application/vnd.ms-powerpoint.presentation.macroEnabled.12',
'potm' => 'application/vnd.ms-powerpoint.template.macroEnabled.12',
'ppsm' => 'application/vnd.ms-powerpoint.slideshow.macroEnabled.12'
);
return isset($mapping[$file_extension]) ? $mapping[$file_extension] : false;
}
/**
* Detects mime type of the file purely based on it's extension
*
* @param string $file
* @return string
* @access public
*/
public static function mimeContentTypeByExtension($file)
{
$file_extension = mb_strtolower(pathinfo(self::removeTempExtension($file), PATHINFO_EXTENSION));
$mapping = '(xls:application/excel)(hqx:application/macbinhex40)(doc,dot,wrd:application/msword)(pdf:application/pdf)
(pgp:application/pgp)(ps,eps,ai:application/postscript)(ppt:application/powerpoint)(rtf:application/rtf)
(tgz,gtar:application/x-gtar)(gz:application/x-gzip)(php,php3:application/x-httpd-php)(js:application/x-javascript)
(ppd,psd:application/x-photoshop)(swf,swc,rf:application/x-shockwave-flash)(tar:application/x-tar)(zip:application/zip)
(mid,midi,kar:audio/midi)(mp2,mp3,mpga:audio/mpeg)(ra:audio/x-realaudio)(wav:audio/wav)(bmp:image/bitmap)(bmp:image/bitmap)
(gif:image/gif)(iff:image/iff)(jb2:image/jb2)(jpg,jpe,jpeg:image/jpeg)(jpx:image/jpx)(png:image/png)(tif,tiff:image/tiff)
(wbmp:image/vnd.wap.wbmp)(xbm:image/xbm)(css:text/css)(txt:text/plain)(htm,html:text/html)(xml:text/xml)
(mpg,mpe,mpeg:video/mpeg)(qt,mov:video/quicktime)(avi:video/x-ms-video)(eml:message/rfc822)
(sxw:application/vnd.sun.xml.writer)(sxc:application/vnd.sun.xml.calc)(sxi:application/vnd.sun.xml.impress)
(sxd:application/vnd.sun.xml.draw)(sxm:application/vnd.sun.xml.math)
(odt:application/vnd.oasis.opendocument.text)(oth:application/vnd.oasis.opendocument.text-web)
(odm:application/vnd.oasis.opendocument.text-master)(odg:application/vnd.oasis.opendocument.graphics)
(odp:application/vnd.oasis.opendocument.presentation)(ods:application/vnd.oasis.opendocument.spreadsheet)
(odc:application/vnd.oasis.opendocument.chart)(odf:application/vnd.oasis.opendocument.formula)
(odi:application/vnd.oasis.opendocument.image)';
if ( preg_match('/[\(,]' . $file_extension . '[,]{0,1}.*?:(.*?)\)/s', $mapping, $regs) ) {
return $regs[1];
}
return 'application/octet-stream';
}
/**
* Strips ".tmp" suffix (added by flash uploader) from a filename
*
* @param string $file
* @return string
* @access public
* @static
*/
public static function removeTempExtension($file)
{
return preg_replace('/(_[\d]+)?\.tmp$/', '', $file);
}
/**
* Return param value and removes it from params array
*
* @param string $name
* @param Array $params
* @param bool $default
* @return string
*/
public static function popParam($name, &$params, $default = false)
{
if ( isset($params[$name]) ) {
$value = $params[$name];
unset($params[$name]);
return $value;
}
return $default;
}
/**
* Generate subpath from hashed value
*
* @param string $name
* @param int $levels
* @return string
*/
public static function getHashPathForLevel($name, $levels = 2)
{
if ( $levels == 0 ) {
return '';
}
else {
$path = '';
$hash = md5($name);
for ($i = 0; $i < $levels; $i++) {
$path .= substr($hash, $i, 1) . '/';
}
return $path;
}
}
/**
* Calculates the crc32 polynomial of a string (always positive number)
*
* @param string $str
* @return int
*/
public static function crc32($str)
{
return sprintf('%u', crc32($str));
}
/**
* Returns instance of DateTime class with date set based on timestamp
*
* @static
* @param int $timestamp
* @return DateTime
* @access public
*/
public static function dateFromTimestamp($timestamp)
{
if ( version_compare(PHP_VERSION, '5.3.0', '<') ) {
$date = new DateTime('@' . $timestamp);
$date->setTimezone(new DateTimeZone(date_default_timezone_get()));
}
else {
$date = new DateTime();
$date->setTimestamp($timestamp);
}
return $date;
}
/**
* Returns timestamp from given DateTime class instance
*
* @static
* @param DateTime $date_time
* @return int|string
* @access public
*/
public static function timestampFromDate(DateTime $date_time)
{
if ( version_compare(PHP_VERSION, '5.3.0', '<') ) {
return $date_time->format('U');
}
return $date_time->getTimestamp();
}
/**
* Generates random numeric id
*
* @static
* @return string
* @access public
*/
public static function generateId()
{
list($usec, $sec) = explode(' ', microtime());
$id_part_1 = substr($usec, 4, 4);
$id_part_2 = mt_rand(1, 9);
$id_part_3 = substr($sec, 6, 4);
$digit_one = substr($id_part_1, 0, 1);
if ( $digit_one == 0 ) {
$digit_one = mt_rand(1, 9);
$id_part_1 = preg_replace('/^0/', '', $id_part_1);
$id_part_1 = $digit_one . $id_part_1;
}
return $id_part_1 . $id_part_2 . $id_part_3;
}
/**
* Changes script resource limits. Omitted argument results in limit removal.
*
* @static
* @param string|int $memory_limit
* @param int $time_limit
* @return void
* @access public
*/
public static function setResourceLimit($memory_limit = null, $time_limit = null)
{
set_time_limit(isset($time_limit) ? $time_limit : 0);
ini_set('memory_limit', isset($memory_limit) ? $memory_limit : -1);
}
/**
* Escapes a string.
*
* @param string $text Text to escape.
* @param string $strategy Escape strategy.
*
* @return string
* @throws InvalidArgumentException When unknown escape strategy is given.
*/
public static function escape($text, $strategy = null)
{
if ( !isset($strategy) ) {
$strategy = self::$escapeStrategy;
}
if ( strpos($strategy, '+') !== false ) {
$previous_strategy = '';
$strategies = explode('+', $strategy);
foreach ($strategies as $current_strategy) {
// apply default strategy
if ( $current_strategy == '' ) {
$current_strategy = self::$escapeStrategy;
}
// don't double-escape
if ( $current_strategy != $previous_strategy ) {
$text = self::escape($text, $current_strategy);
$previous_strategy = $current_strategy;
}
}
return $text;
}
if ( $strategy == self::ESCAPE_HTML ) {
return htmlspecialchars($text, ENT_QUOTES, CHARSET);
}
if ( $strategy == self::ESCAPE_JS ) {
// TODO: consider using "addcslashes", because "addslashes" isn't really for JavaScript escaping (according to docs)
$text = addslashes($text);
$text = str_replace(array("\r", "\n"), array('\r', '\n'), $text);
$text = str_replace('</script>', "</'+'script>", $text);
return $text;
}
if ( $strategy == self::ESCAPE_URL ) {
return rawurlencode($text);
}
if ( $strategy == self::ESCAPE_RAW ) {
return $text;
}
throw new InvalidArgumentException(sprintf('Unknown escape strategy "%s"', $strategy));
}
/**
* Unescapes a string.
*
* @param string $text Text to unescape.
* @param string $strategy Escape strategy.
*
* @return string
* @throws InvalidArgumentException When unknown escape strategy is given.
*/
public static function unescape($text, $strategy = null)
{
if ( !isset($strategy) ) {
$strategy = self::$escapeStrategy;
}
if ( strpos($strategy, '+') !== false ) {
$previous_strategy = '';
$strategies = explode('+', $strategy);
foreach ($strategies as $current_strategy) {
// apply default strategy
if ( $current_strategy == '' ) {
$current_strategy = self::$escapeStrategy;
}
// don't double-unescape
if ( $current_strategy != $previous_strategy ) {
$text = self::unescape($text, $current_strategy);
$previous_strategy = $current_strategy;
}
}
return $text;
}
if ( $strategy == self::ESCAPE_HTML ) {
return htmlspecialchars_decode($text, ENT_QUOTES);
}
if ( $strategy == self::ESCAPE_JS ) {
// TODO: consider using "stripcslashes", because "stripslashes" isn't really for JavaScript unescaping (according to docs)
$text = str_replace("</'+'script>", '</script>', $text);
$text = str_replace(array('\r', '\n'), array("\r", "\n"), $text);
$text = stripslashes($text);
return $text;
}
if ( $strategy == self::ESCAPE_URL ) {
return rawurldecode($text);
}
if ( $strategy == self::ESCAPE_RAW ) {
return $text;
}
throw new InvalidArgumentException(sprintf('Unknown escape strategy "%s"', $strategy));
}
/**
* Mark a method as deprecated and inform when it has been used.
*
* The current behavior is to trigger a user deprecation notice in Debug Mode.
* This method is to be used in every method that is deprecated.
*
* @param string $method The method that was called.
* @param string $version The version that deprecated the method.
* @param string|null $replacement The method that should have been called.
*
* @return void
*/
public static function deprecatedMethod($method, $version, $replacement = null)
{
$application =& kApplication::Instance();
if ( !$application->isDebugMode() ) {
return;
}
$msg = '%1$s is <strong>deprecated</strong> since version %2$s';
if ( !is_null($replacement) ) {
@trigger_error(sprintf($msg . '! Use %3$s instead.', $method, $version, $replacement), E_USER_DEPRECATED);
}
else {
@trigger_error(sprintf($msg . ' with no alternative available.', $method, $version), E_USER_DEPRECATED);
}
}
/**
* Mark a method argument as deprecated and inform when it has been used.
*
* This method is to be used whenever a deprecated method argument is used.
* Before this method is called, the argument must be checked for whether it was
* used by comparing it to its default value or evaluating whether it is empty.
* For example:
*
* if ( !$deprecated ) {
* kUtil::deprecatedArgument(__METHOD__, '5.2.2');
* }
*
* The current behavior is to trigger a user deprecation notice in Debug Mode.
*
* @param string $method The method that was called.
* @param string $version The version that deprecated the argument used.
* @param string|null $message A message regarding the change.
*
* @return void
*/
public static function deprecatedArgument($method, $version, $message = null)
{
$application =& kApplication::Instance();
if ( !$application->isDebugMode() ) {
return;
}
$msg = '%1$s was called with an argument that is <strong>deprecated</strong> since version %2$s';
if ( !is_null($message) ) {
@trigger_error(sprintf($msg . '! %3$s', $method, $version, $message), E_USER_DEPRECATED);
}
else {
@trigger_error(sprintf($msg . ' with no alternative available.', $method, $version), E_USER_DEPRECATED);
}
}
/**
* Parse ini size
*
* @param string $size Size.
*
* @return integer
*/
public static function parseIniSize($size)
{
$result = (int)$size;
$size = strtolower($size);
if ( strpos($size, 'k') ) {
return $result * 1024;
}
if ( strpos($size, 'm') ) {
return $result * 1024 * 1024;
}
if ( strpos($size, 'g') ) {
return $result * 1024 * 1024 * 1024;
}
return $result;
}
/**
* Returns colorized var dump.
*
* @param mixed $var Variable.
* @param string $context Context.
* @param boolean $return Return value.
*
* @return string|void
*/
public static function varDumpColorized($var, $context, $return = true)
{
static $dumper, $cloner, $context_streams = array();
if ( $dumper === null && $cloner === null ) {
$cloner = new VarCloner();
$dumper = PHP_SAPI == 'cli' ? new CliDumper() : new HtmlDumper();
if ( $dumper instanceof HtmlDumper ) {
// Use $dumper->setTheme('light'); instead in later version of VarDumper library.
$light_theme = array(
'default' => implode(
' ',
array(
'background:none;',
'color:#CC7832;',
'line-height:1.2em;',
'font:12px Menlo, Monaco, Consolas, monospace;',
'word-wrap: break-word;',
'white-space: pre-wrap;',
'position:relative;',
'z-index:99999;',
'word-break: break-all;',
)
),
'num' => 'font-weight:bold; color:#1299DA',
'const' => 'font-weight:bold',
'str' => 'font-weight:bold; color:#629755;',
'note' => 'color:#6897BB',
'ref' => 'color:#6E6E6E',
'public' => 'color:#262626',
'protected' => 'color:#262626',
'private' => 'color:#262626',
'meta' => 'color:#B729D9',
'key' => 'color:#789339',
'index' => 'color:#1299DA',
'ellipsis' => 'color:#CC7832',
'ns' => 'user-select:none;',
);
$dumper->setStyles($light_theme);
}
else {
if ( \function_exists('stream_isatty') && stream_isatty(STDOUT) ) {
$dumper->setColors(true);
}
if ( \function_exists('posix_isatty') && posix_isatty(STDOUT) ) {
$dumper->setColors(true);
}
}
}
if ( !array_key_exists($context, $context_streams) ) {
$context_streams[$context] = fopen('php://memory', 'r+b');
}
$stream = $context_streams[$context];
rewind($stream);
$dumper->dump($cloner->cloneVar($var), $stream);
// Don't close the stream !!!
$ret = stream_get_contents($stream, ftell($stream), 0);
if ( $return ) {
return $ret;
}
echo $ret;
}
}
/**
* Returns array value if key exists
* Accepts infinite number of parameters
*
* @param Array $array searchable array
* @param int $key array key
* @return string
*/
function getArrayValue(&$array, $key)
{
$ret = isset($array[$key]) ? $array[$key] : false;
if ( $ret && func_num_args() > 2 ) {
for ($i = 2; $i < func_num_args(); $i++) {
$cur_key = func_get_arg($i);
$ret = getArrayValue($ret, $cur_key);
if ( $ret === false ) {
break;
}
}
}
return $ret;
}
if ( !function_exists('parse_ini_string') ) {
/**
* Equivalent for "parse_ini_string" function available since PHP 5.3.0
*
* @param string $ini
* @param bool $process_sections
* @param int $scanner_mode
* @return Array
*/
function parse_ini_string($ini, $process_sections = false, $scanner_mode = NULL)
{
# Generate a temporary file.
$tempname = tempnam('/tmp', 'ini');
$fp = fopen($tempname, 'w');
fwrite($fp, $ini);
$ini = parse_ini_file($tempname, !empty($process_sections));
fclose($fp);
@unlink($tempname);
return $ini;
}
}
if ( !function_exists('memory_get_usage') ) {
// PHP 4.x and compiled without --enable-memory-limit option
function memory_get_usage() { return -1; }
}
if ( !function_exists('imagecreatefrombmp') ) {
// just in case if GD will add this function in future
function imagecreatefrombmp($filename)
{
//Ouverture du fichier en mode binaire
if (! $f1 = fopen($filename,"rb")) return FALSE;
//1 : Chargement des ent�tes FICHIER
$FILE = unpack("vfile_type/Vfile_size/Vreserved/Vbitmap_offset", fread($f1,14));
if ($FILE['file_type'] != 19778) return FALSE;
//2 : Chargement des ent�tes BMP
$BMP = unpack('Vheader_size/Vwidth/Vheight/vplanes/vbits_per_pixel'.
'/Vcompression/Vsize_bitmap/Vhoriz_resolution'.
'/Vvert_resolution/Vcolors_used/Vcolors_important', fread($f1,40));
$BMP['colors'] = pow(2,$BMP['bits_per_pixel']);
if ($BMP['size_bitmap'] == 0) $BMP['size_bitmap'] = $FILE['file_size'] - $FILE['bitmap_offset'];
$BMP['bytes_per_pixel'] = $BMP['bits_per_pixel']/8;
$BMP['bytes_per_pixel2'] = ceil($BMP['bytes_per_pixel']);
$BMP['decal'] = ($BMP['width']*$BMP['bytes_per_pixel']/4);
$BMP['decal'] -= floor($BMP['width']*$BMP['bytes_per_pixel']/4);
$BMP['decal'] = 4-(4*$BMP['decal']);
if ($BMP['decal'] == 4) $BMP['decal'] = 0;
//3 : Chargement des couleurs de la palette
$PALETTE = array();
if ($BMP['colors'] < 16777216)
{
$PALETTE = unpack('V'.$BMP['colors'], fread($f1,$BMP['colors']*4));
}
//4 : Cr�ation de l'image
$IMG = fread($f1,$BMP['size_bitmap']);
$VIDE = chr(0);
$res = imagecreatetruecolor($BMP['width'],$BMP['height']);
$P = 0;
$Y = $BMP['height']-1;
while ($Y >= 0)
{
$X=0;
while ($X < $BMP['width'])
{
if ($BMP['bits_per_pixel'] == 24)
$COLOR = unpack("V",substr($IMG,$P,3).$VIDE);
elseif ($BMP['bits_per_pixel'] == 16)
{
$COLOR = unpack("n",substr($IMG,$P,2));
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 8)
{
$COLOR = unpack("n",$VIDE.substr($IMG,$P,1));
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 4)
{
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
if (($P*2)%2 == 0) $COLOR[1] = ($COLOR[1] >> 4) ; else $COLOR[1] = ($COLOR[1] & 0x0F);
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
elseif ($BMP['bits_per_pixel'] == 1)
{
$COLOR = unpack("n",$VIDE.substr($IMG,floor($P),1));
if (($P*8)%8 == 0) $COLOR[1] = $COLOR[1] >>7;
elseif (($P*8)%8 == 1) $COLOR[1] = ($COLOR[1] & 0x40)>>6;
elseif (($P*8)%8 == 2) $COLOR[1] = ($COLOR[1] & 0x20)>>5;
elseif (($P*8)%8 == 3) $COLOR[1] = ($COLOR[1] & 0x10)>>4;
elseif (($P*8)%8 == 4) $COLOR[1] = ($COLOR[1] & 0x8)>>3;
elseif (($P*8)%8 == 5) $COLOR[1] = ($COLOR[1] & 0x4)>>2;
elseif (($P*8)%8 == 6) $COLOR[1] = ($COLOR[1] & 0x2)>>1;
elseif (($P*8)%8 == 7) $COLOR[1] = ($COLOR[1] & 0x1);
$COLOR[1] = $PALETTE[$COLOR[1]+1];
}
else
return FALSE;
imagesetpixel($res,$X,$Y,$COLOR[1]);
$X++;
$P += $BMP['bytes_per_pixel'];
}
$Y--;
$P+=$BMP['decal'];
}
//Fermeture du fichier
fclose($f1);
return $res;
}
}
Index: branches/5.2.x/core/kernel/utility/formatters/unit_formatter.php
===================================================================
--- branches/5.2.x/core/kernel/utility/formatters/unit_formatter.php (revision 16856)
+++ branches/5.2.x/core/kernel/utility/formatters/unit_formatter.php (revision 16857)
@@ -1,131 +1,131 @@
<?php
/**
* @version $Id$
* @package In-Portal
* @copyright Copyright (C) 1997 - 2011 Intechnic. All rights reserved.
* @license GNU/GPL
* In-Portal is Open Source software.
* This means that this software may have been modified pursuant
* the GNU General Public License, and as distributed it includes
* or is derivative of works licensed under the GNU General Public License
* or other free or open source software licenses.
* See http://www.in-portal.org/license for copyright notices and details.
*/
defined('FULL_PATH') or die('restricted access!');
class kUnitFormatter extends kFormatter {
/**
* The method is supposed to alter config options or cofigure object in some way based on its usage of formatters
* The methods is called for every field with formatter defined when configuring item.
* Could be used for adding additional VirtualFields to an object required by some special Formatter
*
* @param string $field_name
* @param array $field_options
* @param kDBBase $object
*/
function PrepareOptions($field_name, &$field_options, &$object)
{
if( !isset($field_options['master_field']) )
{
/** @var LanguagesItem $regional */
$regional = $this->Application->recallObject('lang.current');
$add_fields = Array();
$options_a = Array('type' => 'int','error_field' => $field_name,'master_field' => $field_name,'format' => '%d' );
$options_b = Array('type' => 'double','error_field' => $field_name,'master_field' => $field_name,'format' => '%0.2f' );
switch( $regional->GetDBField('UnitSystem') )
{
case 2: // US/UK
$field_options_copy = $field_options;
unset($field_options_copy['min_value_exc']);
$add_fields[$field_name.'_a'] = kUtil::array_merge_recursive($field_options_copy, $options_a);
$add_fields[$field_name.'_b'] = kUtil::array_merge_recursive($field_options_copy, $options_b);
break;
default:
}
$add_fields = kUtil::array_merge_recursive($add_fields, $object->getVirtualFields());
$object->setVirtualFields($add_fields);
}
}
/**
* Used for split fields like timestamp -> date, time
* Called from DBItem Validate (before validation) to get back master field value from its sub_fields
*
* @param string $field
* @param mixed $value
* @param Array $options
* @param kDBItem $object
*/
function UpdateMasterFields($field, $value, &$options, &$object)
{
if ( isset($options['master_field']) || ($value == -1) ) {
// for infinity setting, otherwise infinity is incorrectly converted back to Kg
return ;
}
/** @var LanguagesItem $regional */
$regional = $this->Application->recallObject('lang.current');
if ( $regional->GetDBField('UnitSystem') == 2 ) {
// US/UK
$major = $this->TypeCast($object->GetDBField($field . '_a'), $options);
$minor = $this->TypeCast($object->GetDBField($field . '_b'), $options);
if ( $major === '' && $minor === '' ) {
$value = null;
}
elseif ( $major === null && $minor === null ) {
$fields = $object->getFields();
unset($fields[$field]);
$object->setFields($fields);
return;
}
else {
- $value = kUtil::Pounds2Kg($major, $minor);
+ $value = kUtil::Pounds2Kg((float)$major, (float)$minor);
}
}
$object->SetDBField($field, $value);
}
/**
* Used for split fields like timestamp -> date, time
* Called from DBItem to update sub fields values after loading item
*
* @param string $field
* @param string $value
* @param Array $options
* @param kDBItem $object
* @return void
* @access public
*/
public function UpdateSubFields($field, $value, &$options, &$object)
{
if ( !isset($options['master_field']) ) {
/** @var LanguagesItem $regional */
$regional = $this->Application->recallObject('lang.current');
if ( $regional->GetDBField('UnitSystem') == 2 ) {
// US/UK
if ( $value === null ) {
$major = null;
$minor = null;
}
else {
- list($major, $minor) = kUtil::Kg2Pounds($value);
+ list($major, $minor) = kUtil::Kg2Pounds((float)$value);
// $major = floor( $value / 0.5 );
// $minor = ($value - $major * 0.5) * 32;
}
$object->SetDBField($field . '_a', $major);
$object->SetDBField($field . '_b', $minor);
}
}
}
-}
\ No newline at end of file
+}
Index: branches/5.2.x/core/tests/Unit/kernel/globalsTest.php
===================================================================
--- branches/5.2.x/core/tests/Unit/kernel/globalsTest.php (revision 16856)
+++ branches/5.2.x/core/tests/Unit/kernel/globalsTest.php (revision 16857)
@@ -1,63 +1,125 @@
<?php
/**
* The class name must match the file name for Phabricator-invoked PHPUnit to run this test.
*
* TODO: Once "globals.php" file is renamed we can rename this class/filename as well.
*/
class globalsTest extends AbstractTestCase // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
{
/**
* @dataProvider netMatchDataProvider
*/
public function testNetMatch($network, $ip, $expected)
{
$this->assertSame($expected, kUtil::netMatch($network, $ip));
}
public static function netMatchDataProvider()
{
$ip_from_host = gethostbyname('www.in-portal.org');
return array(
// Hosts.
array('www.in-portal.org', $ip_from_host, true),
array('www.yahoo.com', $ip_from_host, false),
// IPv4 address vs IPv4 network.
array('1.2.3.4', '1.2.3.4', true),
array('1.2.3.4', '1.2.3.5', false),
array('1.2.3.32-1.2.3.54', '1.2.3.40', true),
array('1.2.3.32-1.2.3.54', '1.2.3.64', false),
array('1.2.3.32/27', '1.2.3.35', true),
array('1.2.3.32/27', '1.2.3.64', false),
array('1.2.3/27', '1.2.3.5', true),
array('1.2.3/27', '1.2.3.33', false),
array('1.2.3.32/255.255.255.224', '1.2.3.35', true),
array('1.2.3.32/255.255.255.224', '1.2.3.64', false),
array('1.2.3.32/27', '1.2.3.4.6', false),
// IPv6 address vs IPv6 network.
array('971a:6ff4:3fe8::7085:f498:fc5a:9893', '971a:6ff4:3fe8::7085:f498:fc5a:9893', true),
array('971a:6ff4:3fe8::7085:f498:fc5a:9893', '971a:6ff4:3fe8::7085:f498:fc5a:9895', false),
array('971a:6ff4:3fe8::9893-971a:6ff4:3fe8::9895', '971a:6ff4:3fe8::9894', true),
array('971a:6ff4:3fe8::9893-971a:6ff4:3fe8::9895', '971a:6ff4:3fe8::9896', false),
array('971a:6ff4:3fe8::9893/64', '971a:6ff4:3fe8::9895', true),
array('971a:6ff4:3fe8::9893/64', '971a:6ff4:3fe9::9895', false),
// IPv6 address vs IPv4 network.
array('1.2.3.4', '971a:6ff4:3fe8::7085:f498:fc5a:9893', false),
array('1.2.3.32-1.2.3.54', '971a:6ff4:3fe8::7085:f498:fc5a:9893', false),
array('1.2.3.32/27', '971a:6ff4:3fe8::7085:f498:fc5a:9893', false),
array('1.2.3/27', '971a:6ff4:3fe8::7085:f498:fc5a:9893', false),
array('1.2.3.32/255.255.255.224', '971a:6ff4:3fe8::7085:f498:fc5a:9893', false),
// IPv4 address vs IPv6 network.
array('971a:6ff4:3fe8::7085:f498:fc5a:9893', '1.2.3.4', false),
array('971a:6ff4:3fe8::9893-971a:6ff4:3fe8::9895', '1.2.3.4', false),
array('971a:6ff4:3fe8::9893/64', '1.2.3.4', false),
);
}
+ /**
+ * @dataProvider validKg2PoundsDataProvider
+ */
+ public function testValidKg2Pounds($kg, $pounds_only, $expected_pounds, $expected_ounces)
+ {
+ list($pounds, $ounces) = kUtil::Kg2Pounds($kg, $pounds_only);
+ $this->assertSame($expected_pounds, $pounds);
+ $this->assertSame($expected_ounces, $ounces);
+ }
+
+ public static function validKg2PoundsDataProvider()
+ {
+ return array(
+ 'pounds_only=false' => array(0.68039, false, 1.0, 8.0),
+ 'pounds_only=true' => array(0.68039, true, 1.5, 0),
+ );
+ }
+
+ public function testExceptionKg2Pounds()
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('The $kg argument isn\'t a number.');
+ kUtil::Kg2Pounds(null);
+ }
+
+ /**
+ * @dataProvider validPounds2KgDataProvider
+ */
+ public function testValidPounds2Kg($pounds, $ounces, $expected)
+ {
+ $this->assertSame($expected, kUtil::Pounds2Kg($pounds, $ounces));
+ }
+
+ public static function validPounds2KgDataProvider()
+ {
+ return array(
+ 'pounds <> 0, ounces <> 0' => array(1.0, 8.0, 0.68039),
+ 'pounds <> 0, ounces = 0' => array(1.5, 0.0, 0.68039),
+ 'pounds = 0, ounces <> 0' => array(0.0, 8.0, 0.2268),
+ 'pounds = 0, ounces = 0' => array(0.0, 0.0, 0.0),
+ );
+ }
+
+ /**
+ * @dataProvider exceptionPounds2KgDataProvider
+ */
+ public function testExceptionPounds2Kg($pounds, $ounces)
+ {
+ $this->expectException(InvalidArgumentException::class);
+ $this->expectExceptionMessage('Either the $pounds or $ounces argument isn\'t a number.');
+ kUtil::Pounds2Kg($pounds, $ounces);
+ }
+
+ public static function exceptionPounds2KgDataProvider()
+ {
+ return array(
+ 'pounds non-numeric, ounces numeric' => array(null, 8),
+ 'pounds numeric, ounces non-numeric' => array(1, null),
+ 'both pounds and ounces non-numeric' => array(null, null),
+ );
+ }
+
}
Index: branches/5.2.x/core/tests/Unit/kernel/utility/formatters/unit_formatterTest.php
===================================================================
--- branches/5.2.x/core/tests/Unit/kernel/utility/formatters/unit_formatterTest.php (nonexistent)
+++ branches/5.2.x/core/tests/Unit/kernel/utility/formatters/unit_formatterTest.php (revision 16857)
@@ -0,0 +1,67 @@
+<?php
+
+/**
+ * The class name must match the file name for Phabricator-invoked PHPUnit to run this test.
+ *
+ * TODO: Once "unit_formatter.php" file is renamed we can rename this class/filename as well.
+ */
+final class unit_formatterTest extends AbstractTestCase // phpcs:ignore Squiz.Classes.ValidClassName.NotCamelCaps
+{
+
+ /**
+ * Fixture of the kDBItem class.
+ *
+ * @var kDBItem
+ */
+ protected $dbItemFixture;
+
+ /**
+ * @before
+ */
+ protected function setUpTest()
+ {
+ $db_item = new kDBItem();
+ $db_item->Init('stop-word', ''); // Existing unit used for the "ValidatorClass" unit config option to work.
+ $db_item->SetFieldOptions('SampleField', array());
+ $db_item->SetFieldOptions('SampleField_a', array());
+ $db_item->SetFieldOptions('SampleField_b', array());
+
+ $this->dbItemFixture = $db_item;
+
+ /** @var LanguagesItem $regional */
+ $regional = $this->Application->recallObject('lang.current');
+ $regional->SetDBField('UnitSystem', 2);
+ }
+
+ public function testNonNumericUpdateSubFields()
+ {
+ $unit_formatter = new kUnitFormatter();
+ $options = array();
+ $unit_formatter->UpdateSubFields('SampleField', 'non-numeric', $options, $this->dbItemFixture);
+ $this->assertSame(0.0, $this->dbItemFixture->GetDBField('SampleField_a'));
+ $this->assertSame(0.0, $this->dbItemFixture->GetDBField('SampleField_b'));
+ }
+
+ /**
+ * @dataProvider nonNumericUpdateMasterFieldsDataProvider
+ */
+ public function testNonNumericUpdateMasterFields($pounds, $ounces, $expected)
+ {
+ $unit_formatter = new kUnitFormatter();
+ $options = array();
+ $this->dbItemFixture->SetDBField('SampleField_a', $pounds);
+ $this->dbItemFixture->SetDBField('SampleField_b', $ounces);
+ $unit_formatter->UpdateMasterFields('SampleField', 'non-numeric', $options, $this->dbItemFixture);
+ $this->assertSame($expected, $this->dbItemFixture->GetDBField('SampleField'));
+ }
+
+ public static function nonNumericUpdateMasterFieldsDataProvider()
+ {
+ return array(
+ 'pounds numeric, ounces non-numeric' => array(1.5, 'non-numeric', 0.68039),
+ 'pounds non-numeric, ounces numeric' => array('non-numeric', 24, 0.68039),
+ 'both pounds and ounces non-numeric' => array('non-numeric', 'non-numeric', 0.0),
+ );
+ }
+
+}
Event Timeline
Log In to Comment