<commit_before><?php
	/*
	Copyright (C) 2014 <NAME>
	
	This file is part of Audemium ERP.  Audemium ERP is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    Audemium ERP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License along with Audemium ERP.  If not, see <http://www.gnu.org/licenses/>.
	*/

	/* formatCurrency */
	function formatCurrency($amount, $displayZero = false) {
		global $SETTINGS;
		
		if (empty($amount) && $displayZero == false) {
			$return = '';
		}
		elseif ($amount < 0) {
			$temp = $SETTINGS['currencySymbol'].number_format(abs($amount), 2, $SETTINGS['decimalFormat'], $SETTINGS['thousandsSeparator']);
			$return = ($SETTINGS['negativeCurrencyFormat'] == 0) ? '-'.$temp : '('.$temp.')';
		}
		else {
			$return = $SETTINGS['currencySymbol'].number_format($amount, 2, $SETTINGS['decimalFormat'], $SETTINGS['thousandsSeparator']);
		}
		
		return $return;
	}
	
	/* formatDate */
	function formatDate($unixTS) {
		global $SETTINGS;
		
		return date($SETTINGS['dateFormat'], $unixTS);
	}
	
	/* formatDateTime */
	function formatDateTime($unixTS) {
		global $SETTINGS;
		
		return date($SETTINGS['dateTimeFormat'], $unixTS);
	}
	
	/* getName */
	function getName($type, $id) {
		$factoryItem = Factory::createItem($type);
		return htmlspecialchars($factoryItem->getName($type, $id), ENT_QUOTES | ENT_HTML5, 'UTF-8');
	}
	
	/* getLinkedName */
	function getLinkedName($type, $id) {
		return '<a href="item.php?type='.$type.'&id='.$id.'">'.getName($type, $id).'</a>';
	}
	
	/* addChange */
	function addChange($type, $id, $employeeID, $action, $data) {
		//$action must be either A (add), E (edit) or D (delete)
		global $dbh;
	
		$sth = $dbh->prepare(
			'INSERT INTO changes (type, id, employeeID, changeTime, action, data)
			VALUES(:type, :id, :employeeID, UNIX_TIMESTAMP(), :action, :data)');
		$sth->execute([':type' => $type, ':id' => $id, ':employeeID' => $employeeID, ':action' => $action, ':data' => $data]);
	}
	
	/* parseValue */
	function parseValue($type, $item) {
		//htmlspecialchars is in the object function
		global $TYPES;
		
		$factoryItem = Factory::createItem($type);
		$parsed = $factoryItem->parseValue($type, $item);
		foreach ($parsed as $field => $value) {
			if (isset($TYPES[$type]['fields'][$field]) && $TYPES[$type]['fields'][$field]['verifyData'][1] == 'id') {
				$parsed[$field] = (!is_null($value)) ? getLinkedName($TYPES[$type]['fields'][$field]['verifyData'][2], $value) : '';
			}
		}
		
		return $parsed;
	}
	
	/* parseSubTypeValue */
	function parseSubTypeValue($type, $subType, $action, $item, $format) {
		//unlike in parseValue, values are linked in $factoryItem->parseSubTypeValue because it sometimes returns a string, and therefore this function couldn't fix up each piece
		//like parseValue, htmlspecialchars is in the object function
		//$action must be A, E or D if $format is 'str', but can be null if $format is 'arr'
		
		$factoryItem = Factory::createItem($type);
		$parsed = $factoryItem->parseSubTypeValue($subType, $action, $item, $format);
		
		return $parsed;
	}
	
	/* parseHistory */
	function parseHistory($type, $changes) {
		global $TYPES;
		
		foreach ($changes as $changeKey => $change) {
			$dataStr = '';
			if ($change['data'] == '') {
				$dataStr = 'Item deleted.';
			}
			else {
				$data = json_decode($change['data'], true);
				if (isset($data['subType'])) {
					$subType = $data['subType'];
					unset($data['subType']);
					$dataStr .= parseSubTypeValue($type, $subType, $change['action'], $data, 'str');
				}
				else {
					$parsed = parseValue($type, $data);
					if ($type == 'discount' && isset($data['hideType'])) {
						//special change code to hide discountType if it was artificially added
						unset($parsed['hideType']);
						unset($parsed['discountType']);
					}
					foreach ($parsed as $key => $value) {
						$dataStr .= '<b>'.$TYPES[$type]['fields'][$key]['formalName'].':</b> '.$value.' ';
					}
				}
			}
			
			$changes[$changeKey]['data'] = $dataStr;
		}
		
		return $changes;
	}
	
	/* verifyData */
	function verifyData($type, $subType, $data) {
		global $dbh;
		global $TYPES;
		$return = ['status' => 'success'];
		
		$fields = ($subType === null) ? $TYPES[$type]['fields'] : $TYPES[$type]['subTypes'][$subType]['fields'];
		foreach ($data as $key => $value) {
			if (!isset($fields[$key]['verifyData'])) {
				$return['status'] = 'fail';
				$return[$key] = 'Could not verify data';
			}
			else {
				$attributes = $fields[$key]['verifyData'];
				//determine if the field is required
				if (is_array($attributes[0]) === true) {
					$required = ($data[$attributes[0][0]] == $attributes[0][1]) ? true : false;
				}
				else {
					$required = ($attributes[0] == 1) ? true : false;
				}
				
				if ($required == true && $value == '' && $key != 'managerID') {
					//UI will only let someone choose a blank manager if it's allowed, but technically this won't verify it
					$return['status'] = 'fail';
					$return[$key] = 'Required';
				}
				elseif ($value != '') {
					//this section gets hit if there is some value, regardless of $required
					if ($attributes[1] == 'str') {
						if (strlen($value) > $attributes[2]) {
							$return['status'] = 'fail';
							$return[$key] = 'Must be '.$attributes[2].' or fewer characters';
						}
					}
					if ($attributes[1] == 'int') {
						if (!filter_var($value, FILTER_VALIDATE_INT, ['min_range' => 0, 'max_range' => $attributes[2]])) {
							$return['status'] = 'fail';
							$return[$key] = 'Must be an integer';
						}
					}
					if ($attributes[1] == 'id') {
						$sth = $dbh->prepare(
							'SELECT  '.$TYPES[$attributes[2]]['idName'].'<commit_msg>Fixed the format of the options argument in filter_var.<commit_after><?php
	/*
	Copyright (C) 2014 <NAME>
	
	This file is part of Audemium ERP.  Audemium ERP is free software: you can redistribute it and/or modify it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

    Audemium ERP is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License along with Audemium ERP.  If not, see <http://www.gnu.org/licenses/>.
	*/

	/* formatCurrency */
	function formatCurrency($amount, $displayZero = false) {
		global $SETTINGS;
		
		if (empty($amount) && $displayZero == false) {
			$return = '';
		}
		elseif ($amount < 0) {
			$temp = $SETTINGS['currencySymbol'].number_format(abs($amount), 2, $SETTINGS['decimalFormat'], $SETTINGS['thousandsSeparator']);
			$return = ($SETTINGS['negativeCurrencyFormat'] == 0) ? '-'.$temp : '('.$temp.')';
		}
		else {
			$return = $SETTINGS['currencySymbol'].number_format($amount, 2, $SETTINGS['decimalFormat'], $SETTINGS['thousandsSeparator']);
		}
		
		return $return;
	}
	
	/* formatDate */
	function formatDate($unixTS) {
		global $SETTINGS;
		
		return date($SETTINGS['dateFormat'], $unixTS);
	}
	
	/* formatDateTime */
	function formatDateTime($unixTS) {
		global $SETTINGS;
		
		return date($SETTINGS['dateTimeFormat'], $unixTS);
	}
	
	/* getName */
	function getName($type, $id) {
		$factoryItem = Factory::createItem($type);
		return htmlspecialchars($factoryItem->getName($type, $id), ENT_QUOTES | ENT_HTML5, 'UTF-8');
	}
	
	/* getLinkedName */
	function getLinkedName($type, $id) {
		return '<a href="item.php?type='.$type.'&id='.$id.'">'.getName($type, $id).'</a>';
	}
	
	/* addChange */
	function addChange($type, $id, $employeeID, $action, $data) {
		//$action must be either A (add), E (edit) or D (delete)
		global $dbh;
	
		$sth = $dbh->prepare(
			'INSERT INTO changes (type, id, employeeID, changeTime, action, data)
			VALUES(:type, :id, :employeeID, UNIX_TIMESTAMP(), :action, :data)');
		$sth->execute([':type' => $type, ':id' => $id, ':employeeID' => $employeeID, ':action' => $action, ':data' => $data]);
	}
	
	/* parseValue */
	function parseValue($type, $item) {
		//htmlspecialchars is in the object function
		global $TYPES;
		
		$factoryItem = Factory::createItem($type);
		$parsed = $factoryItem->parseValue($type, $item);
		foreach ($parsed as $field => $value) {
			if (isset($TYPES[$type]['fields'][$field]) && $TYPES[$type]['fields'][$field]['verifyData'][1] == 'id') {
				$parsed[$field] = (!is_null($value)) ? getLinkedName($TYPES[$type]['fields'][$field]['verifyData'][2], $value) : '';
			}
		}
		
		return $parsed;
	}
	
	/* parseSubTypeValue */
	function parseSubTypeValue($type, $subType, $action, $item, $format) {
		//unlike in parseValue, values are linked in $factoryItem->parseSubTypeValue because it sometimes returns a string, and therefore this function couldn't fix up each piece
		//like parseValue, htmlspecialchars is in the object function
		//$action must be A, E or D if $format is 'str', but can be null if $format is 'arr'
		
		$factoryItem = Factory::createItem($type);
		$parsed = $factoryItem->parseSubTypeValue($subType, $action, $item, $format);
		
		return $parsed;
	}
	
	/* parseHistory */
	function parseHistory($type, $changes) {
		global $TYPES;
		
		foreach ($changes as $changeKey => $change) {
			$dataStr = '';
			if ($change['data'] == '') {
				$dataStr = 'Item deleted.';
			}
			else {
				$data = json_decode($change['data'], true);
				if (isset($data['subType'])) {
					$subType = $data['subType'];
					unset($data['subType']);
					$dataStr .= parseSubTypeValue($type, $subType, $change['action'], $data, 'str');
				}
				else {
					$parsed = parseValue($type, $data);
					if ($type == 'discount' && isset($data['hideType'])) {
						//special change code to hide discountType if it was artificially added
						unset($parsed['hideType']);
						unset($parsed['discountType']);
					}
					foreach ($parsed as $key => $value) {
						$dataStr .= '<b>'.$TYPES[$type]['fields'][$key]['formalName'].':</b> '.$value.' ';
					}
				}
			}
			
			$changes[$changeKey]['data'] = $dataStr;
		}
		
		return $changes;
	}
	
	/* verifyData */
	function verifyData($type, $subType, $data) {
		global $dbh;
		global $TYPES;
		$return = ['status' => 'success'];
		
		$fields = ($subType === null) ? $TYPES[$type]['fields'] : $TYPES[$type]['subTypes'][$subType]['fields'];
		foreach ($data as $key => $value) {
			if (!isset($fields[$key]['verifyData'])) {
				$return['status'] = 'fail';
				$return[$key] = 'Could not verify data';
			}
			else {
				$attributes = $fields[$key]['verifyData'];
				//determine if the field is required
				if (is_array($attributes[0]) === true) {
					$required = ($data[$attributes[0][0]] == $attributes[0][1]) ? true : false;
				}
				else {
					$required = ($attributes[0] == 1) ? true : false;
				}
				
				if ($required == true && $value == '' && $key != 'managerID') {
					//UI will only let someone choose a blank manager if it's allowed, but technically this won't verify it
					$return['status'] = 'fail';
					$return[$key] = 'Required';
				}
				elseif ($value != '') {
					//this section gets hit if there is some value, regardless of $required
					if ($attributes[1] == 'str') {
						if (strlen($value) > $attributes[2]) {
							$return['status'] = 'fail';
							$return[$key] = 'Must be '.$attributes[2].' or fewer characters';
						}
					}
					if ($attributes[1] == 'int') {
						if (!filter_var($value, FILTER_VALIDATE_INT, ['options' => ['min_range' => 0, 'max_range' => $attributes[2]]])) {
							$return['status'] = 'fail';
							$return[$key] = 'Must be a positive integer';
						}
					}
					if ($attributes[1] == 'id') {
						$sth = $dbh->prepare(
							'SELECT  '.$TYPES[$attributes[2]]['idName'].'
{'fraction_non_alphanumeric': 0.1845563627458983, 'fraction_numerical': 0.004571055424047016, 'mean_word_length': 3.7068766807529774, 'pattern_counts': {'":': 0, '<': 19, '<?xml version=': 0, '>': 56, 'https://': 0, 'lorem ipsum': 0, 'www.': 2, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '1814243', 'n_tokens_mistral': 4614, 'n_tokens_neox': 3959, 'n_words': 1065}