403Webshell
Server IP : 80.87.202.40  /  Your IP : 216.73.216.169
Web Server : Apache
System : Linux rospirotorg.ru 5.14.0-539.el9.x86_64 #1 SMP PREEMPT_DYNAMIC Thu Dec 5 22:26:13 UTC 2024 x86_64
User : bitrix ( 600)
PHP Version : 8.2.27
Disable Function : NONE
MySQL : OFF |  cURL : ON |  WGET : ON |  Perl : ON |  Python : OFF |  Sudo : ON |  Pkexec : ON
Directory :  /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/wbs24.ozonexport/lib/

Upload File :
current_dir [ Writeable] document_root [ Writeable]

 

Command :


[ Back ]     

Current File : /home/bitrix/ext_www/rospirotorg.ru/bitrix/modules/wbs24.ozonexport/lib/CalcExpression.php
<?php
namespace Wbs24\Ozonexport;

/**
 * Класс вычисляет значение по формуле, также умеет обрабатывать простое тернарное выражение (условие ? выражение1 : выражение2)
 * Под условием могут подразумеваться простые логические сравнения > < = !=, а также проверка на булево значение
 */
class CalcExpression
{
    public function run($initialStatement)
    {
        if ($this->isContainCompare($initialStatement)) {
            list($condition, $statements) = explode('?', $initialStatement);
            list($statement1, $statement2) = explode(':', $statements);
            $conditionResult = $this->getConditionResult($condition);
            $statement = $conditionResult ? $statement1 : $statement2;
        } else {
            $statement = $initialStatement;
        }
        $result = $this->calc($statement);

        return $result;
    }

    protected function isContainCompare($statement)
    {
        return (
            substr_count($statement, '?') == 1
            && substr_count($statement, ':') == 1
            && strpos($statement, '?') < strpos($statement, ':')
        );
    }

    protected function getConditionResult($condition)
    {
        $operators = [
            '>=',
            '<=',
            '>',
            '<',
            '!=',
            '=',
        ];
        $result = null;

        foreach ($operators as $operator) {
            if (substr_count($condition, $operator) == 1) {
                list($left, $right) = explode($operator, $condition);
                $leftResult = $this->calc($left);
                $rightResult = $this->calc($right);
                switch ($operator) {
                    case '>=':
                        $result = ($leftResult >= $rightResult);
                        break;
                    case '<=':
                        $result = ($leftResult <= $rightResult);
                        break;
                    case '>':
                        $result = ($leftResult > $rightResult);
                        break;
                    case '<':
                        $result = ($leftResult < $rightResult);
                        break;
                    case '!=':
                        $result = ($leftResult != $rightResult);
                        break;
                    case '=':
                        $result = ($leftResult == $rightResult);
                        break;
                }
                break;
            }
        }

        if ($result === null) $result = ($this->calc($condition) > 0) ? true : false;

        return $result;
    }

    // модифицированный вариант с https://ru.stackoverflow.com/questions/454598/
    protected function calc($statement)
    {
        $result = false;

        if (!is_string($statement)) {
            return $result; // Wrong type
        }
        $calcQueue = [];
        $operStack = [];
        $operPriority = [
            '(' => 0,
            ')' => 0,
            '+' => 1,
            '-' => 1,
            '*' => 2,
            '/' => 2,
        ];
        $token = '';
        foreach (str_split($statement) as $char) {
            // Если цифра, то собираем из цифр число
            if (
                ($char >= '0' && $char <= '9')
                || (is_numeric($token) && strpos($token, '.') === false && $char == '.')
            ) {
                $token .= $char;
            } else {
                // Если число накопилось, сохраняем в очереди вычисления
                if (strlen($token)) {
                    array_push($calcQueue, $token);
                    $token = '';
                }
                // Если найденный символ - операция (он есть в списке приоритетов)
                if (isset($operPriority[$char])) {
                    if (')' == $char) {
                        // Если символ - закрывающая скобка, переносим операции из стека в очередь вычисления пока не встретим открывающую скобку
                        while (!empty($operStack)) {
                            $oper = array_pop($operStack);
                            if ('(' == $oper) {
                                break;
                            }
                            array_push($calcQueue, $oper);
                        }
                        if ('(' != $oper) {
                            // Упс! А открывающей-то не было
                            return $result; // Unexpected ")"
                        }
                    } else {
                        // Встретили операцию кроме скобки. Переносим операции с меньшим приоритетом в очередь вычисления
                        while (!empty($operStack) && '(' != $char) {
                            $oper = array_pop($operStack);
                            if ($operPriority[$char] > $operPriority[$oper]) {
                                array_push($operStack, $oper);
                                break;
                            }
                            if ('(' != $oper) {
                                array_push($calcQueue, $oper);
                            }
                        }
                        // Кладем операцию на стек операций
                        array_push($operStack, $char);
                    }
                } elseif (strpos(' ', $char) !== false) {
                    // Игнорируем пробелы (можно добавить что еще игнорируем)
                } else {
                    // Встретили что-то непонятное (мы так не договаривались)
                    return $result; // Unexpected symbol
                }
            }
        }
        // Вроде все разобрали, но если остались циферки добавляем их в очередь вычисления
        if (strlen($token)) {
            array_push($calcQueue, $token);
            $token = '';
        }
        // ... и оставшиеся в стеке операции
        if (!empty($operStack)) {
            while ($oper = array_pop($operStack)) {
                if ('(' == $oper) {
                    // ... кроме открывающих скобок. Это верный признак отсутствующей закрывающей
                    return $result; // Unexpected "("
                }
                array_push($calcQueue, $oper);
            }
        }
        $calcStack = array();
        // Теперь вычисляем все то, что напарсили
        foreach ($calcQueue as $token) {
            switch ($token) {
            case '+':
                $arg2 = array_pop($calcStack);
                $arg1 = array_pop($calcStack);
                array_push($calcStack, $arg1 + $arg2);
                break;
            case '-':
                $arg2 = array_pop($calcStack);
                $arg1 = array_pop($calcStack);
                array_push($calcStack, $arg1 - $arg2);
                break;
            case '*':
                $arg2 = array_pop($calcStack);
                $arg1 = array_pop($calcStack);
                array_push($calcStack, $arg1 * $arg2);
                break;
            case '/':
                $arg2 = array_pop($calcStack);
                $arg1 = array_pop($calcStack);
                array_push($calcStack, $arg1 / $arg2);
                break;
            default:
                array_push($calcStack, $token);
            }
        }

        return array_pop($calcStack);
    }
}

Youez - 2016 - github.com/yon3zu
LinuXploit