Your IP : 172.28.240.42


Current Path : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/
Upload File :
Current File : /var/www/html/clients/amz.e-nk.ru/bitrix/modules/main/classes/general/php_parser.php

<?
class PHPParser
{
	function ReplString($str, $arAllStr)
	{
		if(preg_match("'^\x01([0-9]+)\x02$'s", $str))
			return preg_replace("'\x01([0-9]+)\x02'es", "\$arAllStr['\\1']", $str);
		if(strval(floatVal($str)) == $str)
			return preg_replace("'\x01([0-9]+)\x02'es", "'\"'.\$arAllStr['\\1'].'\"'", $str);
		elseif($str=="")
			return "";
		else
			return "={".preg_replace("'\x01([0-9]+)\x02'es", "'\"'.\$arAllStr['\\1'].'\"'", $str)."}";
	}

	function GetParams($params)
	{
		$arParams = Array();
		$sk = 0;
		$param_tmp = "";
		for($i=0; $i<strlen($params); $i++)
		{
			$ch = substr($params, $i, 1);
			if($ch=="(")
				$sk++;
			elseif($ch==")")
				$sk--;
			elseif($ch=="," && $sk==0)
			{
				$arParams[] = $param_tmp;
				$param_tmp = "";
				continue;
			}

			if($sk<0)
				break;

			$param_tmp .= $ch;
		}
		if($param_tmp!="")
			$arParams[] = $param_tmp;
		return $arParams;
	}

	function GetParamsRec($params, &$arAllStr, &$arResult)
	{
		if (strtolower(substr($params, 0, 6)) == 'array(')
		{
			$arParams = PHPParser::GetParams(substr($params, 6));

			for ($i = 0; $i < count($arParams); $i++)
			{
				$el = $arParams[$i];
				$p = strpos($el, "=>");
				if ($p === False)
				{
					PHPParser::GetParamsRec($el, $arAllStr, $arResult[]);
				}
				else
				{
					$el_ind = PHPParser::ReplString(substr($el, 0, $p), $arAllStr);
					$el_val = substr($el, $p + 2);

					PHPParser::GetParamsRec($el_val, $arAllStr, $arResult[$el_ind]);
				}
			}
		}
		else
		{
			$arResult = PHPParser::ReplString($params, $arAllStr);
		}
	}

	// Parse string and check if it is a component call. Return call params array
	function CheckForComponent($str)
	{
		if(substr($str, 0, 5)=="<?"."php")
			$str = substr($str, 5);
		else
			$str = substr($str, 2);

		$str = substr($str, 0, -2);

		$bSlashed = false;
		$bInString = false;
		$arAllStr = Array();
		$new_str = "";
		$i=-1;
		while($i<strlen($str)-1)
		{
			$i++;
			$ch = substr($str, $i, 1);
			if(!$bInString)
			{
				if($string_tmp!="")
				{
					$arAllStr[] = $string_tmp;
					$string_tmp = "";
					$new_str .= chr(1).(count($arAllStr)-1).chr(2);
				}

				//ïðîâåðÿåì ÷òî íå íà÷èíàåòñÿ êîììåíòàðèé
				if($ch == "/" && $i+1<strlen($str))
				{
					$ti = 0;
					if(substr($str, $i+1, 1)=="*" && ($ti = strpos($str, "*/", $i+2))!==false)
						$ti += 2;
					elseif(substr($str, $i+1, 1)=="/" && ($ti = strpos($str, "\n", $i+2))!==false)
						$ti += 1;

					if($ti)
						$i = $ti;

					continue;
				} // if($ch == "/" && $i+1<strlen($filesrc))

				if($ch == " " || $ch == "\r" || $ch == "\n" || $ch == "\t")
					continue;
			} // if(!$bInString)

			if($bInString && $ch == "\\" && !$bSlashed)
			{
				$bSlashed = true;
				continue;
			}

			if($ch == "\"" || $ch == "'")
			{
				if($bInString)
				{
					if(!$bSlashed && $quote_ch == $ch)
					{
						$bInString = false;
						continue;
					}
				}
				else
				{
					$bInString = true;
					$quote_ch = $ch;
					continue;
				}
			}
			elseif($bInString && $ch == "\\")
				$bSlashed = true;

			$bSlashed = false;
			if($bInString)
			{
				$string_tmp .= $ch;
				continue;
			}

			$new_str .= $ch;
		} // while($i<strlen($filesrc)-1)

		if($pos = strpos($new_str, "("))
		{
			$func_name = substr($new_str, 0, $pos+1);
			if(preg_match("/^(\\\$[A-Z_][A-Z0-9_]*)(\s*=\s*)/i", $func_name, $arMatch))
			{
				$var_name = $arMatch[1];
				$func_name = substr($func_name, strlen($arMatch[0]));
			}
			else
			{
				$var_name = "";
			}
			$func_name = preg_replace("'\\\$GLOBALS\[(\"|\')(.+?)(\"|\')\]'s", "\$\\2", $func_name);
			switch(strtoupper($func_name))
			{
			case '$APPLICATION->INCLUDEFILE(':
				$params = substr($new_str, $pos+1);
				$arParams = PHPParser::GetParams($params);
				$arIncludeParams = Array();

				if(strtolower(substr($arParams[1], 0, 6))=='array(')
				{
					$arParams2 = PHPParser::GetParams(substr($arParams[1], 6));
					for($i=0; $i<count($arParams2); $i++)
					{
						$el = $arParams2[$i];
						$p = strpos($el, "=>");
						$el_ind = PHPParser::ReplString(substr($el, 0, $p), $arAllStr);
						$el_val = substr($el, $p+2);
						if(strtolower(substr($el_val, 0, 6))=='array(')
						{
							$res_ar = Array();
							$arParamsN = PHPParser::GetParams(substr($el_val, 6));
							for($j = 0; $j<count($arParamsN); $j++)
								$res_ar[] = PHPParser::ReplString($arParamsN[$j], $arAllStr);

							$arIncludeParams[$el_ind] = $res_ar;
						}
						else
							$arIncludeParams[$el_ind] = PHPParser::ReplString($el_val, $arAllStr);
					}
				}

				return Array(
						"SCRIPT_NAME"=>PHPParser::ReplString($arParams[0], $arAllStr),
						"PARAMS"=>$arIncludeParams,
						"VARIABLE"=>$var_name,
						);
			}
		}
		return false;
	}

	function GetComponentParams($instruction, $arAllStr)
	{
		if ($pos = strpos($instruction, "("))
		{
			$func_name = substr($instruction, 0, $pos + 1);
			if (preg_match("/^(\\\$[A-Z_][A-Z0-9_]*)(\s*=\s*)/i", $func_name, $arMatch))
			{
				$var_name = $arMatch[1];
				$func_name = substr($func_name, strlen($arMatch[0]));
			}
			else
			{
				$var_name = "";
			}

			$params = substr($instruction, $pos + 1);
			$arParams = PHPParser::GetParams($params);

			$arIncludeParams = array();
			$arFuncParams = array();
			PHPParser::GetParamsRec($arParams[2], $arAllStr, $arIncludeParams);
			PHPParser::GetParamsRec($arParams[4], $arAllStr, $arFuncParams);

			return array(
				"COMPONENT_NAME" => PHPParser::ReplString($arParams[0], $arAllStr),
				"TEMPLATE_NAME" => PHPParser::ReplString($arParams[1], $arAllStr),
				"PARAMS" => $arIncludeParams,
				"PARENT_COMP" => $arParams[3],
				"VARIABLE" => $var_name,
				"FUNCTION_PARAMS" => $arFuncParams,
			);
		}
	}

	function ParseScript($scriptContent)
	{
		$arComponents = array();
		$componentNumber = -1;

		$bInComponent = False;
		$bInPHP = False;

		$bInString = False;
		$quoteChar = "";
		$bSlashed = False;

		$string = False;
		$instruction = "";

		$scriptContentLength = StrLen($scriptContent);
		$ind = -1;
		while ($ind < $scriptContentLength - 1)
		{
			$ind++;
			$ch = SubStr($scriptContent, $ind, 1);

			if ($bInPHP)
			{
				if (!$bInString)
				{
					if (!$bInComponent && StrLen($instruction) > 0)
					{
						if (preg_match("#^\s*((\\\$[A-Z_][A-Z0-9_]*)\s*=)?\s*\\\$APPLICATION->IncludeComponent\s*\(#is", $instruction, $arMatches))
						{
							$arAllStr = array();
							$bInComponent = True;
							$componentNumber++;

							$arMatches[0] = LTrim($arMatches[0]);
							$arComponents[$componentNumber] = array(
								"START" => ($ind - StrLen($arMatches[0])),
								"END" => False,
								"DATA" => array()
							);
						}
					}
					if ($string !== False)
					{
						if ($bInComponent)
						{
							$arAllStr[] = $string;
							$instruction .= Chr(1).(Count($arAllStr) - 1).Chr(2);
						}
						$string = False;
					}
					if ($ch == ";")
					{
						//echo "<font color=\"#6600FF\">".$instruction."</font><br>";
						if ($bInComponent)
						{
							$bInComponent = False;
							$arComponents[$componentNumber]["END"] = $ind + 1/* - 1*/;
							$arComponents[$componentNumber]["DATA"] = PHPParser::GetComponentParams(preg_replace("#[ \r\n\t]#", "", $instruction), $arAllStr);
						}
						$instruction = "";
						continue;
					}
					if ($ch == "/" && $ind < $scriptContentLength - 2)
					{
						if (SubStr($scriptContent, $ind + 1, 1) == "/")
						{
							$endPos = StrPos($scriptContent, "\n", $ind + 2);

							if ($endPos === False)
								$ind = $scriptContentLength - 1;
							else
								$ind = $endPos;

							continue;
						}
						elseif (SubStr($scriptContent, $ind + 1, 1) == "*")
						{
							$endPos = StrPos($scriptContent, "*/", $ind + 2);

							if ($endPos === False)
								$ind = $scriptContentLength - 1;
							else
								$ind = $endPos + 1;

							continue;
						}
					}

					if ($ch == "\"" || $ch == "'")
					{
						$bInString = True;
						$string = "";
						$quoteChar = $ch;
						continue;
					}

					if ($ch == "?" && $ind < $scriptContentLength - 2 && SubStr($scriptContent, $ind + 1, 1) == ">")
					{
						$ind += 1;
						if ($bInComponent)
						{
							//echo "<font color=\"#6600FF\">".$instruction."</font><br>";
							$bInComponent = False;
							$arComponents[$componentNumber]["END"] = $ind - 1;
							$arComponents[$componentNumber]["DATA"] = PHPParser::GetComponentParams(preg_replace("#[ \r\n\t]#", "", $instruction), $arAllStr);
						}
						$instruction = "";
						$bInPHP = False;
						continue;
					}

					$instruction .= $ch;

					if ($ch == " " || $ch == "\r" || $ch == "\n" || $ch == "\t")
						continue;

					/*
					if ($bInComponent)
					{
						if ($ch == ",")
						{

							if ($parenthesesLevel == 1)
							{
								$arComponents[$componentNumber]["DATA"][$callParam] = $string;
								$callParam++;
							}
							else
							{

							}
						}
						elseif ($ch == "(")
						{
							$parenthesesLevel++;
						}
						elseif ($ch == ")")
						{
							$parenthesesLevel--;
						}
					}
					*/
				}
				else
				{
					if ($ch == "\\" && !$bSlashed)
					{
						$bSlashed = True;
						continue;
					}
					if ($ch == $quoteChar && !$bSlashed)
					{
						$bInString = False;
						continue;
					}
					$bSlashed = False;

					$string .= $ch;
				}

				if ($bInComponent)
				{

				}
			}
			else
			{
				if ($ch == "<")
				{
					if ($ind < $scriptContentLength - 5 && SubStr($scriptContent, $ind + 1, 4) == "?php")
					{
						$bInPHP = True;
						$ind += 4;
					}
					elseif ($ind < $scriptContentLength - 2 && SubStr($scriptContent, $ind + 1, 1) == "?")
					{
						$bInPHP = True;
						$ind += 1;
					}
				}
			}
		}

		return $arComponents;
	}

	// Components 2. Parse string and check if it is a component call. Return call params array
	function CheckForComponent2($str)
	{
		if (SubStr($str, 0, 5) == "<?"."php")
			$str = SubStr($str, 5);
		else
			$str = SubStr($str, 2);

		$str = SubStr($str, 0, -2);

		$bSlashed = false;
		$bInString = false;
		$arAllStr = Array();
		$new_str = "";
		$string_tmp = "";
		$i = -1;
		while ($i < StrLen($str) - 1)
		{
			$i++;
			$ch = SubStr($str, $i, 1);
			if (!$bInString)
			{
				if ($string_tmp != "")
				{
					$arAllStr[] = $string_tmp;
					$string_tmp = "";
					$new_str .= Chr(1).(Count($arAllStr) - 1).Chr(2);
				}

				//ïðîâåðÿåì ÷òî íå íà÷èíàåòñÿ êîììåíòàðèé
				if ($ch == "/" && $i+1 < StrLen($str))
				{
					$ti = 0;
					if (SubStr($str, $i+1, 1) == "*" && ($ti = StrPos($str, "*/", $i+2)) !== false)
						$ti += 1;
					elseif (SubStr($str, $i+1, 1)=="/" && ($ti = StrPos($str, "\n", $i+2)) !== false)
						$ti += 0;

					if ($ti)
						$i = $ti;

					continue;
				} // if($ch == "/" && $i+1<strlen($filesrc))

				if ($ch == " " || $ch == "\r" || $ch == "\n" || $ch == "\t")
					continue;
			} // if(!$bInString)

			if ($bInString && $ch == "\\" && !$bSlashed)
			{
				$bSlashed = true;
				continue;
			}

			if ($ch == "\"" || $ch == "'")
			{
				if ($bInString)
				{
					if (!$bSlashed && $quote_ch == $ch)
					{
						$bInString = false;
						continue;
					}
				}
				else
				{
					$bInString = true;
					$quote_ch = $ch;
					continue;
				}
			}
			elseif ($bInString && $ch == "\\")
				$bSlashed = true;

			$bSlashed = false;
			if ($bInString)
			{
				$string_tmp .= $ch;
				continue;
			}

			$new_str .= $ch;
		} // while($i<strlen($filesrc)-1)

		if ($pos = strpos($new_str, "("))
		{
			$func_name = substr($new_str, 0, $pos + 1);
			if (preg_match("/^(\\\$[A-Z_][A-Z0-9_]*)(\s*=\s*)/i", $func_name, $arMatch))
			{
				$var_name = $arMatch[1];
				$func_name = substr($func_name, strlen($arMatch[0]));
			}
			else
			{
				$var_name = "";
			}

			$func_name = preg_replace("'\x01([0-9]+)\x02'es", "\$arAllStr['\\1']", $func_name);
			$func_name = preg_replace("'\\\$GLOBALS\[(.+?)\]'s", "\$\\1", $func_name);

			switch (strtoupper($func_name))
			{
				case '$APPLICATION->INCLUDECOMPONENT(':
					$params = substr($new_str, $pos + 1);
					$arParams = PHPParser::GetParams($params);

					$arIncludeParams = array();
					$arFuncParams = array();
					PHPParser::GetParamsRec($arParams[2], $arAllStr, $arIncludeParams);
					PHPParser::GetParamsRec($arParams[4], $arAllStr, $arFuncParams);

					return array(
						"COMPONENT_NAME" => PHPParser::ReplString($arParams[0], $arAllStr),
						"TEMPLATE_NAME" => PHPParser::ReplString($arParams[1], $arAllStr),
						"PARAMS" => $arIncludeParams,
						"PARENT_COMP" => $arParams[3],
						"VARIABLE" => $var_name,
						"FUNCTION_PARAMS" => $arFuncParams,
					);
			}
		}
		return false;
	}

	// Parse file and return all PHP blocks in array
	function ParseFile($filesrc)
	{
		$arScripts = Array();
		$p = 0;
		$nLen = strlen($filesrc);
		while(($p = strpos($filesrc, "<?", $p))!==false)
		{
			$i = $p+2;
			$bSlashed = false;
			$bInString = false;
			while($i < $nLen-1)
			{
				$i++;
				$ch = substr($filesrc, $i, 1);
				if(!$bInString)
				{
					//ïðîâåðÿåì ÷òî íå íà÷èíàåòñÿ êîììåíòàðèé
					if($ch == "/" && $i+1 < $nLen)
					{
						//íàéäåì ïîçèöèþ îêîí÷àíèÿ php
						$posnext = strpos($filesrc, "?>", $i);
						if($posnext===false)
						{
							//îêîí÷àíèÿ íåò - çíà÷èò ñêðèïò íåçàêîí÷åí
							$p = $nLen;
							break;
						}
						$posnext += 2;

						$ti = 0;
						if(substr($filesrc, $i+1, 1)=="*" && ($ti = strpos($filesrc, "*/", $i+2))!==false)
							$ti += 2;
						elseif(substr($filesrc, $i+1, 1)=="/" && ($ti = strpos($filesrc, "\n", $i+2))!==false)
							$ti += 1;

						if($ti)
						{
							// íàøëè íà÷àëî($i) è êîíåö êîììåíòàðèÿ ($ti)
							// ïðîâåðèì ÷òî ðàíüøå êîíåö ñêðèïòà èëè êîíåö êîììåíòàðèÿ (íàïðèìåð â îäíîé ñòðîêå "//comment ? >")
							if($ti>$posnext && substr($filesrc, $i+1, 1)!="*")
							{
								// ñêðèïò çàêîí÷èëñÿ ðàíüøå êîììåíòàðèÿ
								// âûðåæåì ñêðèïò
								$arScripts[] = Array($p, $posnext, substr($filesrc, $p, $posnext-$p));
								$p = $posnext;
								break;
							}
							else
							{
								// êîììåíòàðèé çàêîí÷èëñÿ ðàíüøå ñêðèïòà
								$i = $ti - 1;
							}
						}
						continue;
					} // if($ch == "/" && $i+1 < $nLen)

					if($ch == "?" && $i+1 < $nLen && substr($filesrc, $i+1, 1)==">")
					{
						$i = $i+2;
						$arScripts[] = Array($p, $i, substr($filesrc, $p, $i-$p));
						$p = $i+1;
						break;
					}
				} // if(!$bInString)

				if($bInString && $ch == "\\" && !$bSlashed)
				{
					$bSlashed = true;
					continue;
				}

				if($ch == "\"" || $ch == "'")
				{
					if($bInString)
					{
						if(!$bSlashed && $quote_ch == $ch)
							$bInString = false;
					}
					else
					{
						$bInString = true;
						$quote_ch = $ch;
					}
				}
				elseif($bInString && $ch == "\\")
					$bSlashed = true;

				$bSlashed = false;
			} // while($i < $nLen-1)
			if($i >= $nLen)
				break;
			$p = $i;
		} // while(($p = strpos("<"."?", $filesrc))!==false)
		return $arScripts;
	}

	function PreparePHP($str)
	{
		if(substr($str, 0, 2) == "={" && substr($str, -1, 1)=="}" && strlen($str)>3)
			return substr($str, 2, -1);

		return '"'.EscapePHPString($str).'"';
	}

	// Return PHP string of component call params
	function ReturnPHPStr($arVals, $arParams)
	{
		$res = "";
		$un = md5(uniqid(""));
		$i=0;
		foreach($arVals as $key=>$val)
		{
			$i++;
			$comm = (strlen($arParams[$key]["NAME"])>0?"$un|$i|// ".$arParams[$key]["NAME"]:"");
			$res .= "\r\n\t\"".$key."\"\t=>\t";
			if(is_array($val) && count($val)>1)
				$res .= "Array(".$comm."\r\n";

			if(is_array($val) && count($val)>1)
			{
				$zn = '';
				foreach($val as $p)
				{
					if($zn!='') $zn.=",\r\n";
					$zn .= "\t\t\t\t\t".PHPParser::PreparePHP($p);
				}
				$res .= $zn."\r\n\t\t\t\t),";
			}
			elseif(is_array($val))
			{
				$res .= "Array(".PHPParser::PreparePHP($val[0])."),".$comm;
			}
			else
				$res .= PHPParser::PreparePHP($val).",".$comm;
		}

		$max = 0;
		$lngth = Array();
		for($j=1; $j<=$i; $j++)
		{
			$p = strpos($res, "$un|$j|");
			$pn = strrpos(substr($res, 0, $p), "\n");
			$l = ($p-$pn);
			$lngth[$j] = $l;
			if($max<$l)
				$max = $l;
		}

		for($j=1; $j<=$i; $j++)
			$res = str_replace($un."|$j|", str_repeat("\t", intval(($max-$lngth[$j]+7)/8)), $res);

		return Trim($res, " \t,\r\n");
	}


	function ReturnPHPStrRec($arVal, $level, $comm="")
	{
		$result = "";
		$pref = str_repeat("\t", $level);
		if (is_array($arVal))
		{
			$result .= "array(".(($level==1) ? $comm : "")."\r\n";
			foreach ($arVal as $key => $value)
				$result .= $pref."\t".((IntVal($key)."|" == $key."|") ? $key : PHPParser::PreparePHP($key))." => ".PHPParser::ReturnPHPStrRec($value, $level + 1);
			$result .= $pref."),\r\n";
		}
		else
		{
			$result .= PHPParser::PreparePHP($arVal).",".(($level==1) ? $comm : "")."\r\n";
		}
		return $result;
	}

	// Components 2. Return PHP string of component call params
	function ReturnPHPStr2($arVals, $arParams=array())
	{
		$res = "";
		$i = 0;

		foreach($arVals as $key => $val)
		{
			$i++;
			$comm = (strlen($arParams[$key]["NAME"])>0? "\t// ".$arParams[$key]["NAME"]:"");
			$res .= "\t\"".EscapePHPString($key)."\" => ";
			$res .= PHPParser::ReturnPHPStrRec($val, 1, $comm);
		}

		return Trim($res, " \t,\r\n");
	}

	function FindComponent($component_name, $filesrc, $src_line)
	{
		/* parse source file for PHP code */
		$arComponents = PHPParser::ParseScript($filesrc);

		/* identify the component by line number */
		$arComponent = False;
		for ($i = 0, $cnt = count($arComponents); $i < $cnt; $i++)
		{
			$nLineFrom = substr_count(substr($filesrc, 0, $arComponents[$i]["START"]), "\n") + 1;
			$nLineTo = substr_count(substr($filesrc, 0, $arComponents[$i]["END"]), "\n") + 1;

			if ($nLineFrom <= $src_line && $nLineTo >= $src_line)
			{
				if ($arComponents[$i]["DATA"]["COMPONENT_NAME"] == $component_name)
				{
					$arComponent = $arComponents[$i];
					break;
				}
			}
			if ($nLineTo > $src_line)
				break;
		}
		return $arComponent;
	}
}
?>