public function infoBox($title, $msg = '', $marker = '+') { $len = ps_strlen($title); $line = pad_left('', $len + 4, $marker); $str = "\n{$line}\n{$marker} {$title} {$marker}\n{$line}\n{$msg}\n"; $this->info($str); }
public static function safeShortText($string) { check_condition($string, 'Пустое сообщение'); check_condition(!TexTools::hasTex($string), 'Короткое сообщение не может содержать формулы'); check_condition(ps_strlen($string) <= 255, 'Текст не должен превышать 255 символов'); $string = htmlspecialchars($string); $string = nl2brr($string); return normalize_string($string); }
public static function validateShortText($data, $required = true, $maxLen = SHORT_TEXT_MAXLEN) { if (isEmpty($data)) { return $required ? 'required' : false; } if (ps_strlen($data) > $maxLen) { return 'maxlength'; } if (TexTools::hasTex($data)) { return 'notex'; } return self::censure($data); }
/** * Метод определяет сущность из библиотеки по переданным параметрам. * Может быть задан любой из параметров. * * @return FoldedEntity */ public function defineFoldedEntity($type, $ident, $text) { $this->LOGGER->info(); $this->LOGGER->info("Определяем элемент по параметрам: [{$type}|{$ident}|{$text}]"); if ($type && $ident) { $this->LOGGER->info('Быстрый поиск по типу и идентификатору'); $folding = Handlers::getInstance()->getLibManager($type, false); return $folding ? $folding->getFoldedEntity($ident) : null; } $items = LibBean::inst()->getLibItemsSearchAmong($type, $ident, $text); $count = is_array($items) ? count($items) : 0; if ($count == 0) { $this->LOGGER->info('В базе нет подходящих сущностей'); return null; } if ($count == 1) { $this->LOGGER->info('В базе найдена одна подходящая сущность: ' . $items[0]['grup'] . '-' . $items[0]['ident'] . ' (' . $items[0]['name'] . ')'); return Handlers::getInstance()->getLibManager($items[0]['grup'])->getFoldedEntity($items[0]['ident']); } $this->LOGGER->info('В базе найдено {} подходящих сущностей, начинаем выбор...', $count); /* * В базе есть несколько сущностей, удовлетворяющих нашим условиям. * Мы должны выбрать наиболее близкую по тексту ссылки. */ /** * Минимальная длина последовательности общих совпадающих символов, при которой можно считать, * что мы нашли элемент библиотеки по тексту. * Она не может быть больше длины текста, заданного в ссылке. */ $takeMinLen = min(5, ps_strlen($text)); $cnt = 0; $lastItem = null; $lastItemMaxlen = null; $lastItemCommonCharsCnt = null; foreach ($items as $item) { $nowItemMaxlen = StringUtils::getCommonMaxSequenceLen($text, $item['name']); if ($nowItemMaxlen < $takeMinLen) { continue; } if (!$lastItemMaxlen || $lastItemMaxlen < $nowItemMaxlen) { $cnt = 1; $lastItem = $item; $lastItemMaxlen = $nowItemMaxlen; continue; } if ($lastItemMaxlen == $nowItemMaxlen) { if (!is_numeric($lastItemCommonCharsCnt)) { $lastItemCommonCharsCnt = StringUtils::getCommonCharsCount($text, $lastItem['name']); } $nowItemCommonCharsCnt = StringUtils::getCommonCharsCount($text, $item['name']); if ($nowItemCommonCharsCnt > $lastItemCommonCharsCnt) { //Одинаковая длина общей последовательности букв, но у текущего элемента больше общих букв $lastItem = $item; $lastItemMaxlen = $nowItemMaxlen; $lastItemCommonCharsCnt = $nowItemCommonCharsCnt; } else { if ($nowItemCommonCharsCnt == $lastItemCommonCharsCnt) { //Одинаковая длина одинаковой последовательности букв и кол-ва общих букв ++$cnt; } } } } $this->LOGGER->info('По окончанию выборки найдено совпадений: ' . $cnt); return $cnt == 1 ? Handlers::getInstance()->getLibManager($lastItem['grup'])->getFoldedEntity($lastItem['ident']) : null; }
/** * Распечатывает текущее состояние дерева зависимости в лог. * При этом в дереве отмечаются всегда только полностью проверенные сущности. * Если, например, группа зависит от таблиц БД, которые были провалидированы, но при этом * сама группа отмечена, как валидная, то мы увидим подобную картину: * +GALLERY: | Сущности базы: | ps_gallery | ps_gallery_images */ private function logTrees($caption, $doLog = true) { if (!$doLog || !$this->LOGGER->isEnabled()) { return; //--- } $this->LOGGER->infoBox($caption); $GROUPS = PSCache::getCacheGroups(); $hasPrintedGroups = false; foreach ($GROUPS as $group) { $isGroupPrinted = false; foreach ($this->TREE_DEP as $type => $groups2entitys) { if (!array_key_exists($group, $groups2entitys)) { continue; } $valGr = !$this->isGroupValidatable($group); $valType = !$valGr && !$this->isTypeValidateble($type); if ($hasPrintedGroups && !$isGroupPrinted) { $this->LOGGER->info(); } if (!$isGroupPrinted) { $isGroupPrinted = true; $hasPrintedGroups = true; $this->LOGGER->info("\t" . ($valGr ? '+' : '|') . $group . ':'); } else { $this->LOGGER->info("\t|"); } $this->LOGGER->info("\t" . ($valType ? '+' : '|') . "\t{$type}:"); foreach ($groups2entitys[$group] as $child) { $varChild = !$valGr && !$valType && !in_array($child, $this->getChildsForValidate($type, $group)); $this->LOGGER->info("\t" . ($varChild ? '+' : '|') . "\t\t{$child}"); } } } $this->LOGGER->info(pad_left('', ps_strlen($caption) + 4, '+')); $this->LOGGER->info(); }
private static function getCountCharsImpl($str) { $count = array(); for ($index = 0; $index < ps_strlen($str); $index++) { $char = ps_charat($str, $index); $count[$char] = 1 + array_get_value($char, $count, 0); } return $count; }
private function doSolve($rebus) { $this->LOGGER->info("Обрабатываем ребус: [{$rebus}], пропускать первые символы={$this->SCIP_FIRST_CHARS}"); $this->COMBINATIONS = array(); check_condition($rebus, "Пустой ребус"); $eqCnt = substr_count($rebus, '='); check_condition($eqCnt == 1, "Знак равенства '=' встретился {$eqCnt} раз"); $this->LOGGER->info("Приведённый вид: [{$rebus}]"); $enCh = array(); $ruCh = array(); for ($i = 0; $i < ps_strlen($rebus); $i++) { //русский символ $letter = ps_charat($rebus, $i); if ($this->isRuChar($letter)) { if (!array_key_exists($letter, $ruCh)) { $ruCh[$letter] = null; } continue; } if ($this->isEnChar($letter)) { //английский символ if (!in_array($letter, $enCh)) { $enCh[] = $letter; } continue; } } $this->LOGGER->info('Русские символы: ' . print_r($ruCh, true)); $this->LOGGER->info('Английские символы: ' . print_r($enCh, true)); foreach ($ruCh as $ch => $value) { for ($i = 0; $i < strlen($this->EN); $i++) { $letter = substr($this->EN, $i, 1); if (!in_array($letter, $enCh)) { $enCh[] = $letter; $ruCh[$ch] = $letter; break; } } } $this->LOGGER->info('После привязки: '); $this->LOGGER->info('Русские символы: ' . print_r($ruCh, true)); $this->LOGGER->info('Английские символы: ' . print_r($enCh, true)); $enCharsCnt = count($enCh); check_condition($enCharsCnt > 0, 'Нет символов для перебора'); check_condition($enCharsCnt <= 10, "Слишком много переменных: {$enCharsCnt}"); $rebus = PsStrings::replaceMap($rebus, $ruCh); $this->LOGGER->info("Подготовленный ребус: [{$rebus}]"); $this->LOGGER->info("Всего символов для перебора: {$enCharsCnt}"); $this->LOGGER->info('Возможных комбинаций: ' . $this->variantsCnt($enCharsCnt)); $this->REBUS = $rebus; $this->EXPR = str_replace('=', '-', $rebus); $hasBefore = false; for ($i = 0; $i < strlen($rebus); $i++) { $char = substr($rebus, $i, 1); if ($this->isEnChar($char)) { //Символ перебора if (!$hasBefore) { $this->FIRST_CHARS[] = $char; $hasBefore = true; } } else { $hasBefore = false; } } $this->LOGGER->info('Начинаем перебор...'); $numbers = array(0 => false, 1 => false, 2 => false, 3 => false, 4 => false, 5 => false, 6 => false, 7 => false, 8 => false, 9 => false); $secundomer = Secundomer::startedInst(); for ($i = 0; $i <= 9; $i++) { $letter = reset($enCh); if ($this->isScip($i, $letter)) { continue; } $next = next($enCh); $numbers[$i] = $letter; $this->doCheckIteration($enCh, $next, $numbers); $numbers[$i] = false; } $secundomer->stop(); $parsed = DatesTools::inst()->parseSeconds(round($secundomer->getTotalTime())); $min = $parsed['mf']; $sec = pad_zero_left($parsed['s'], 2); $parsed = "{$min}:{$sec}"; $combCnt = count($this->COMBINATIONS); $this->LOGGER->info("Перебор закончен. Обработано операций: {$this->cnt}, найдено решений: {$combCnt}."); $this->LOGGER->info("Общее время обработки: {$parsed}."); return $this->COMBINATIONS; }