<?php
	// tomekk
        // http://tomekk.org/
        // GPL - http://www.gnu.org/copyleft/gpl.html
	// changes:
	// ---- 20.11.2016:
	// input behavior mode - 1 (default mode)
	// * when input arg not match declared option, $in->g['foo'] will be set to FALSE
	// * when input arg is not set (example: index.php) $in->g['foo'] will not exist
	// * when input arg is set but is empty (example: index.php?foo=) $in->g['foo] will be set to NULL
	// input behavior mode - 2 (set @ sign at the: '@-variable')
	// * when input arg not match declared option, $in->g['foo'] will be set to NULL
	// * when input arg is not set (example: index.php) $in->g['foo'] will be set to NULL
	// * when input arg is set but is empty (example: index.php?foo=) $in->g['foo] will be set to NULL
	// now _ means toLower, (, before)
	// ^_@- are now reserved chars, do not use them in var names
	// tiny code fix (added trim() below $method[$var])

	class pgin
	{
		// separate arrays for GET and POST
		var $p = array(); // post array
		var $g = array(); // get array
		var $set_enc = ''; // force encoding for mb_strto*() and htmlspecialchars

		// some defines at the start
		function pgin( $pgin_set_enc = 'default' )
		{
			define('HSC', 'html_special_chars');
		        define('NR', 'numbers');
		        define('LT', 'letters');
		        define('LTNR', 'letters_numbers');
		        define('CSR', 'custom_regexp');
		        define('ALLC', 'all_chars');

			// set enc
			if ($pgin_set_enc != 'default')
			{
				$this->set_enc = $pgin_set_enc;
			} else {
				$this->set_enc = mb_internal_encoding(); // default for mb_strto*() etc.
			}
		}

		// main parse function (input args)
		function parse( $src, $vars )
		{
			// temp array for vars
			$parsed_out = array();

			// which method?
			switch ($src)
			{
				case 'p':
					$method = $_POST;
					break;
				case 'g':
					$method = $_GET;
					break;
			}
	
			// only GET or POST
			if (isset($method))
			{
				// each declared var
				foreach ($vars as $var => $type)
				{
					// what to do with the data - switches
					$data_format = '';

					// quick check if we need to do smth with the data
					// and remove our special format chars for further processing
					if (strpos($var, '^') !==  FALSE) // upper
					{
						$var = str_replace('^', '', $var);
						$data_format .= 'u';
					}
					
					if (strpos($var, '_') !==  FALSE) // lower
					{
						$var = str_replace(',', '', $var);
						$data_format .= 'l';
					}
					
					if (strpos($var, '-') !==  FALSE) // trim
					{
						$var = str_replace('-', '', $var);
						$data_format .= 't';
					}

					if (strpos($var, '@') !==  FALSE) // change input behavior mode
					{
						$var = str_replace('@', '', $var);
						$input_mode_two = true;
					}

					// only for custom_regexp - extracts key as type and value as pattern
					if (is_array($type))
					{
						$csr_key = key($type);
						$csr = $type[$csr_key]; // regexp pattern
						$type = $csr_key;
					}

					// input array arg is set, so go on
					if (isset($method[$var]))
					{
						// if input arg is not empty, trim it before - do not allow ?foo=
						if (trim($method[$var]) != '')
						{
							// default when not match
							if (isset($input_mode_two))
							{
								$parsed_out[$var] = NULL;
							} else {
								$parsed_out[$var] = FALSE;
							}

							// clean, format input data
							if (strpos($data_format, 'u') !== FALSE) $method[$var] = mb_strtoupper($method[$var], $this->set_enc);
							if (strpos($data_format, 'l') !== FALSE) $method[$var] = mb_strtolower($method[$var], $this->set_enc);
							if (strpos($data_format, 't') !== FALSE) $method[$var] = trim($method[$var]);

							// switch through types, overwrite $parsed_out[$var] when match
							switch ($type)
							{
								case 'html_special_chars':
									$parsed_out[$var] = htmlspecialchars($method[$var], ENT_QUOTES, $this->set_enc);
									break;
								case 'numbers':
									if (preg_match("/^[0-9]+$/D", $method[$var])) $parsed_out[$var] = $method[$var];
									break;
								case 'letters':
									if (preg_match("/^[a-z]+$/Di", $method[$var])) $parsed_out[$var] = $method[$var];
									break;
								case 'letters_numbers':
									if (preg_match("/^[a-z0-9]+$/Di", $method[$var])) $parsed_out[$var] = $method[$var];
									break;
								case 'custom_regexp':
									if (preg_match($csr, $method[$var])) $parsed_out[$var] = $method[$var];
									break;
								case 'all_chars':
									$parsed_out[$var] = $method[$var];
									break;
							}
						} else {
							// set null when empty
							$parsed_out[$var] = NULL;
						}
					} else {
						// set to NULL when not exists and mode two is set
						if (isset($input_mode_two))
						{
							$parsed_out[$var] = NULL;
						}
					}
				}

				// assign proper output array
				($src == 'p') ? $this->p = $parsed_out : $this->g = $parsed_out;
			}
		}
	}
?>
