/** * Основной метод, получающий склонение слова по падежам. * Подсмотрено здесь: http://forum.dklab.ru/viewtopic.php?p=169151 * * @param type $word - склоняемое слово * @return type - массив, в котором 0 - исходная форма слова, 1...6 - номера падежей. */ private function loadInflectionImpl($word) { $this->PROFILER->start('Loading word inflection'); $cont = file_get_contents('http://export.yandex.ru/inflect.xml?name=' . rawurlencode($word)); $this->PROFILER->stop(); if ($cont) { $pattern = "/<inflection case=\"(\\d)\">(.+?)<\\/inflection>/si"; preg_match_all($pattern, $cont, $matches); //Проверим, что вернулось 6 падежей if (array_key_exists(1, $matches) && array_key_exists(2, $matches) && count($matches[1]) == 6 && count($matches[2]) == 6) { return array(0 => $word) + array_combine($matches[1], $matches[2]); } } return null; }
/** * В конструкторе зарегистрируем все страницы */ protected final function __construct() { $class = get_called_class(); $basic = __CLASS__ == $class; //Логгер $this->LOGGER = PsLogger::inst(__CLASS__); $this->LOGGER->info('USING {} PLUGIN PROVIDER: {}', $basic ? 'SDK' : 'CUSTOM', $class); //Стартуем профайлер $this->PROFILER = PsProfiler::inst(__CLASS__); $this->PROFILER->start('Loading plugins'); //Регистрируем фолдинги SDK $this->LOGGER->info(); $this->LOGGER->info('PLUGINS SDK:'); $this->registerSdkSmartyPlugins(); //Если используем не SDK провайдер, вызываем регистратор if (!$basic) { $this->LOGGER->info(); $this->LOGGER->info('PLUGINS PROJECT:'); $this->registerProjectSmartyPlugins(); } //Останавливаем профайлер $sec = $this->PROFILER->stop(); //Логируем $this->LOGGER->info(); $this->LOGGER->info('COLLECTING TIME: {} sec', $sec->getTotalTime()); }
/** * Предварительная обработка страницы - самое время выполнить сабмит формы, редирект и остальные подобные вещи */ private final function postProcess() { //Проверим и сменим состояние $this->changeState(self::STATE_STARTED, self::STATE_FINISHED); //Устанавливаем контекст $BUILDER_CTXT = PageBuilderContext::getInstance(); //Проверим, что наш контекст не был сброшен check_condition(__CLASS__ == $BUILDER_CTXT->getContextIdent(), 'Unexpected ' . get_class($BUILDER_CTXT) . ': ' . $BUILDER_CTXT->getContextIdent()); //Получим параметры страницы $pagePrams = new PageParams($BUILDER_CTXT->finalizeTplContent(null)); //Сброим контекст, он нам больше не нужен $BUILDER_CTXT->dropContext(); try { //Вызываем завершающую обработку страницы $result = $this->postProcessImpl($pagePrams, RequestArrayAdapter::inst()); //Останавливаем профайлер $sec = $this->PROFILER->stop(); //Отлогируем $this->LOGGER->info('Page build done in {} sec', $sec->getTime()); //Вернём return $result; //--- } catch (Exception $ex) { $this->PROFILER->stop(false); throw $ex; } }
/** * В конструкторе зарегистрируем все страницы */ protected final function __construct() { //Инициализируем хранилище, чтобы честно замерять время создания регистрации самих экземпляров FoldedStorage::init(); $class = get_called_class(); $basic = __CLASS__ == $class; //Логгер $this->LOGGER = PsLogger::inst(__CLASS__); $this->LOGGER->info('USING {} STORAGE: {}', $basic ? 'SDK' : 'CUSTOM', $class); //Стартуем профайлер $this->PROFILER = PsProfiler::inst(__CLASS__); $this->PROFILER->start('Loading folding insts'); //Регистрируем фолдинги SDK $this->LOGGER->info(); $this->LOGGER->info('FOLDINGS SDK:'); $this->registerSdkFoldings(); //Если используем не SDK провайдер, вызываем регистратор if (!$basic) { $this->LOGGER->info(); $this->LOGGER->info('FOLDINGS PROJECT:'); $this->registerProjectFoldings(); } //Отсортируем фолдинги по идентификаторам ksort($this->FOLDINGS); //Останавливаем профайлер $sec = $this->PROFILER->stop(); //Логируем $this->LOGGER->info(); $this->LOGGER->info('COLLECTING TIME: {} sec', $sec->getTotalTime()); }
private function getOldestResourceFile($ident) { if (array_key_exists($ident, $this->OLDEST)) { return $this->OLDEST[$ident]; } $this->assertExistsEntity($ident); $this->LOGGER->info("Loading oldest resource file for entity [{$ident}]."); $this->PROFILER->start(__FUNCTION__); //Строим полный список сущностей, которые будут проверены на дату последнего изменения $items[] = to_array($this->getDirItems4CheckChanged($ident)); foreach ($this->RESOURCE_TYPES_CHECK_CHANGE as $type) { $items[] = $this->getResourceDi($ident, $type); } //Включим в список преверяемых сущностей все информационные шаблоны $items[] = $this->getInfoDiList($ident); //Если мы работаем с обложками - проверим и их if ($this->isImagesFactoryEnabled()) { $items[] = $this->getCoverOriginal($ident); } $oldest = null; foreach ($items as $item) { /** @var $di DirItem */ foreach (to_array($item) as $di) { $time = $di->getModificationTime(); if ($time && (!$oldest || $time > $oldest)) { $oldest = $time; $this->LOGGER->info("Resource file [{$di->getRelPath()}] mtime: {$time}, oldest: {$oldest}."); } else { $this->LOGGER->info("Resource file [{$di->getRelPath()}] mtime: {$time}."); } } } $this->PROFILER->stop(); return $this->OLDEST[$ident] = $oldest; }
/** * В конструкторе зарегистрируем все страницы */ protected final function __construct() { $class = get_called_class(); $basic = __CLASS__ == $class; //Логгер $this->LOGGER = PsLogger::inst(__CLASS__); $this->LOGGER->info('USING {} STORAGE: {}', $basic ? 'SDK' : 'CUSTOM', $class); //Стартуем профайлер $this->PROFILER = PsProfiler::inst(__CLASS__); $this->PROFILER->start('Registering Web pages'); //Регистрируем страницы SDK $this->LOGGER->info(); $this->LOGGER->info('PAGES SDK:'); $this->registerSdkPages(); //Если используем не SDK провайдер, вызываем регистратор if (!$basic) { $this->LOGGER->info(); $this->LOGGER->info('PAGES PROJECT:'); $this->registerProjectPages(); } //Проведём инициализацию $this->LOGGER->info(); $this->LOGGER->info('INITIALIZING...'); $this->init(); //Останавливаем профайлер $sec = $this->PROFILER->stop(); //Логируем $this->LOGGER->info(); $this->LOGGER->info('REGISTERING TIME: {} sec', $sec->getTotalTime()); }
public function CreateSprite(CssSprite $sprite) { if ($sprite->exists()) { return; //--- Спрайт существует } $this->LOGGER->info("Waiting to make {$sprite}"); PsLock::lockMethod(__CLASS__, __FUNCTION__); try { if ($sprite->exists()) { $this->LOGGER->info('Sprite was created in another thread, skipping'); } else { $this->PROFILER->start('Sprite creation'); $this->CssSpriteGen->CreateSprite($sprite); $this->LOGGER->info('Sprite was successfully created, path: ' . $sprite->getCssDi()->getAbsPath()); $this->PROFILER->stop(); } } catch (Exception $ex) { PsLock::unlock(); throw $ex; } PsLock::unlock(); }
/** * В конструкторе пробежимся по всем хранилищам и соберём все фолдинги */ protected function __construct() { $this->LOGGER = PsLogger::inst(__CLASS__); $this->PROFILER = PsProfiler::inst(__CLASS__); /* * Инициалилизируем коллекцию */ $this->PROVIDERS = array(); /* * Собираем полный список доступных хранилищ и менеджеров фолдингов в них */ $providerClasses = ConfigIni::getPropCheckType(ConfigIni::GROUP_FOLDINGS, 'providers', array(PsConst::PHP_TYPE_ARRAY, PsConst::PHP_TYPE_NULL)); $providerClasses = to_array($providerClasses); $providerClasses[] = FoldingsProviderSdk::calledClass(); $this->LOGGER->info('Providers: {}', array_to_string($providerClasses)); foreach ($providerClasses as $provider) { if (in_array($provider, $this->PROVIDERS)) { $this->LOGGER->info('[-] {} - {}', $provider, 'is already registered'); continue; //--- } if (!class_exists($provider)) { $this->LOGGER->info('[-] {} - {}', $provider, 'is not included'); continue; //--- } if (!PsUtil::isInstanceOf($provider, FoldingsProviderAbstract::calledClass())) { $this->LOGGER->info('[-] {} - {}', $provider, 'is not instance of ' . FoldingsProviderAbstract::calledClass()); continue; //--- } $this->LOGGER->info('[+] {}', $provider); $this->PROVIDERS[] = $provider; /* * Для каждого хранилища загружаем список входящих в него фолдингов */ $this->PROFILER->start($provider . '::list'); /* @var $folding FoldedResources */ foreach ($provider::listFoldings() as $folding) { $funique = $folding->getUnique(); if (array_key_exists($funique, $this->UNIQUE_2_PROVIDER)) { raise_error(PsStrings::replaceWithBraced('Folding {} is provided by: {}, {}', $funique, $this->UNIQUE_2_PROVIDER[$funique], $provider)); } $this->LOGGER->info(' [>] {}', $funique); $this->UNIQUE_2_PROVIDER[$funique] = $provider; $this->UNIQUE_2_FOLDING[$funique] = $folding; } $this->PROFILER->stop(); } }
/** * Копирует ячейки из картинки-источника в картинку-мозайку. * * @param array $INFO - информация о картинке * @param array $cells - ячейки из БД, которые будут скопированы * @param type $userId - код пользователя, к которому ячейки будут привязаны */ private function copyCells(array $cells, $userId = null) { //Проверим, есть ли сейчас "чистая" картинка, на которую мы будем копировать ячейки if (!$this->diDst()->isImg()) { SimpleImage::inst()->create($this->width, $this->height, self::BG_COLOR)->save($this->diDst())->close(); } if (empty($cells)) { return; //--- } if ($this->LOGGER->isEnabled()) { $this->LOGGER->info('Copy cells of image ' . $this->id . ', user for bind: ' . var_export($userId, true)); $this->LOGGER->info('Not processed cells: ' . print_r($cells, true)); } PsUtil::startUnlimitedMode(); $this->PROFILER->start('Copy cells of img ' . $this->id); //1. Разберёмся с ячейками - привяжем к пользователю те их них, которые никому не принадлежат foreach ($cells as $cell) { $n_part = 1 * $cell['n_part']; $owned = !!$cell['owned']; //Ячейка должна кому-то принадлежать, либо быть привязана к переданному пользователю check_condition($owned || is_numeric($userId), "Ячейка {$this->id}.{$n_part} никому не принадлежит."); if (!$owned) { //Если ячейка уже привязана к пользователю, то не будем лишний раз дёргать базу $this->LOGGER->info('{}. Cell binded to user {}', $n_part, $userId); $this->BEAN->markAsOwned($userId, $this->id, $n_part); } } //2. Копируем ячейки, предварительно объединив их $srcImg = SimpleImage::inst()->load($this->diSrc()); $dstImg = SimpleImage::inst()->load($this->diDst()); $unioned = MosaicImageCellsCompositor::union($cells, $this->cellWidth, $this->cellHeight, false); foreach ($unioned as $cell) { $x1 = $cell[0]; $y1 = $cell[1]; $x2 = $cell[2]; $y2 = $cell[3]; $w = $x2 - $x1; $h = $y2 - $y1; $dstImg->copyFromAnother($srcImg, $x1, $y1, $x1, $y1, $w, $h)->save(); $this->LOGGER->info('Copied rectangle: {}x{}-{}x{}', $x1, $y1, $x2, $y2); } $srcImg->close(); $dstImg->close(); $this->PROFILER->stop(); }
/** * Метод возвращает DirItem элемента, содержащего картинку-представление формулы. * * @param type $formula - текстовая формула * @param type $createIfNotExists - признак, стоит ли пытаться создавать картинку для формулы * @return DirItem */ public function getImgDi($formula, $createIfNotExists = true) { $formula = TexTools::safeFormula($formula); if ($this->CACHE->has($formula)) { return $this->CACHE->get($formula); } $hash = TexTools::formulaHash($formula); $imgDI = $this->DM->getHashedDirItem(null, $hash, $hash, 'gif'); if ($imgDI->isImg()) { $this->CACHE->set($formula, $imgDI); return $imgDI; } if (!$createIfNotExists) { return null; } //Создаём структуру директорий $imgDI->makePath(); $contents = ''; //Запрашиваем графическое представление $this->PROFILER->start($formula); try { //TODO - делать это локально, чтобы не зависить от стороннего сервиса $handle = fopen('http://latex.codecogs.com/gif.latex?' . rawurlencode($formula), 'r'); while (!feof($handle)) { $contents .= fread($handle, 8192); } fclose($handle); $this->PROFILER->stop(); } catch (Exception $ex) { //Останавливаем профайлер без сохранения $this->PROFILER->stop(false); //Делаем дамп ошибки ExceptionHandler::dumpError($ex, "Tex formula convertation requested for:\n{$formula}"); //Попытаемся подчистить за собой, если мы что-то создали $imgDI->remove(); //Пробрасываем эксепшн throw $ex; } //Сохраняем картинку в файл $imgDI->putToFile($contents); //Сохраним текстовое представление $this->DM->getHashedDirItem(null, $hash, $hash, 'gif.tex')->putToFile($formula); $this->CACHE->set($formula, $imgDI); return $imgDI; }
/** * Непосредственное наполнение */ private function doFill($filterName = null) { $this->LOGGER->info("Loading full content of dir [{}] with [{}] filter.", $this->PATH, PsUtil::toString($filterName)); $this->PROFILER->start('doFill'); /* * На данный момент у нас все директории собраны, остаётся только пробежаться по ним * и взять всё необходимое. * При этом нужно выполнить array_values, так как getDirContent возвращает ассоциативный массив, * а файлы в директориях могут повторяться. */ $RESULT = array(); foreach ($this->DIRS as $dirPath) { $items = DirManager::inst($dirPath)->getDirContent(null, $filterName); $RESULT = array_merge($RESULT, array_values($items)); } $this->LOGGER->info('Loading finished, items count: {}. Taken time: {}sec.', count($RESULT), $this->PROFILER->stop()->getTime()); $this->LOGGER->info(''); return $RESULT; }
/** * В конструкторе пробежимся по всем хранилищам и соберём все фолдинги */ protected function __construct() { $this->LOGGER = PsLogger::inst(__CLASS__); $this->PROFILER = PsProfiler::inst(__CLASS__); $this->PROFILER->start('Loading folding entities'); /* * Пробегаемся по всему, настроенному в foldings.ini */ foreach (FoldingsIni::foldingsRel() as $foldedUnique => $dirRelPathes) { $this->FOLDING_2_ENTITY_2_ENTABSPATH[$foldedUnique] = array(); $this->FOLDING_2_ENTITY_2_ENTRELPATH[$foldedUnique] = array(); /* * Загрузим карту сущностей */ foreach (array_unique($dirRelPathes) as $dirRelPath) { $dm = DirManager::inst($dirRelPath); foreach ($dm->getSubDirNames() as $entity) { //Не будем проверять наличие этой сущности, более поздние смогут её переопределить //array_key_exists($entity, $this->FOLDING_2_ENTITY_2_ENTABSPATH[$foldedUnique]) $this->FOLDING_2_ENTITY_2_ENTABSPATH[$foldedUnique][$entity] = $dm->absDirPath($entity); $this->FOLDING_2_ENTITY_2_ENTRELPATH[$foldedUnique][$entity] = $dm->relDirPath($entity); } } ksort($this->FOLDING_2_ENTITY_2_ENTABSPATH[$foldedUnique]); ksort($this->FOLDING_2_ENTITY_2_ENTRELPATH[$foldedUnique]); /* * Построим карты сущностей к типам фолдингов, чтобы мы могли через них выйти на фолдинг */ self::extractFoldedTypeAndSubtype($foldedUnique, $ftype, $fsubtype); /* * Построим карту отношения идентификатора фолдинга к коду ресурса * slib => lib-s */ $this->SOURCE_2_FOLDING[$fsubtype . $ftype] = $foldedUnique; /* * Построим карту отношения идентификатора фолдинга к префиксу класса * SLIB_ => lib-s */ $this->CLASSPREFIX_2_FOLDING[strtoupper($fsubtype . $ftype) . '_'] = $foldedUnique; /* * Построим карту отношения типа фолдинга к массиву подтипов фолдингов * lib => array('s', 'p') * pl = > null */ if (array_key_exists($ftype, $this->TYPE_2_STYPE)) { //Если мы второй раз попали в этот блок для типа фолдинга, то он должен иметь подтип [lib=>array('s')]. check_condition(is_array($this->TYPE_2_STYPE[$ftype]), "Уже зарегистрирован фолдинг с типом [{$ftype}] без подтипов"); $this->TYPE_2_STYPE[$ftype][] = check_condition($fsubtype, "Уже зарегистрирован фолдинг с типом [{$ftype}] и с подтипами"); } else { if ($fsubtype) { //Новый тип фолдинга с подтипом. $this->TYPE_2_STYPE[$ftype] = array($fsubtype); } else { //Новый тип фолдинга без подтипа. $this->TYPE_2_STYPE[$ftype] = null; } } } //Отсортируем по уникальным кодам фолдингов ksort($this->FOLDING_2_ENTITY_2_ENTABSPATH); ksort($this->FOLDING_2_ENTITY_2_ENTRELPATH); ksort($this->TYPE_2_STYPE); //Установим идентификаторы фолдингов $this->FOLDINGS = array_keys($this->FOLDING_2_ENTITY_2_ENTRELPATH); $sec = $this->PROFILER->stop(); if ($this->LOGGER->isEnabled()) { $this->LOGGER->info('FOLDINGS: {}', print_r($this->FOLDINGS, true)); $this->LOGGER->info('FOLDING_2_ENTITY_2_ENTABSPATH: {}', print_r($this->FOLDING_2_ENTITY_2_ENTABSPATH, true)); $this->LOGGER->info('FOLDING_2_ENTITY_2_ENTRELPATH: {}', print_r($this->FOLDING_2_ENTITY_2_ENTRELPATH, true)); $this->LOGGER->info('TYPE_2_STYPE: {}', print_r($this->TYPE_2_STYPE, true)); $this->LOGGER->info('CLASSPREFIX_2_FOLDING: {}', print_r($this->CLASSPREFIX_2_FOLDING, true)); $this->LOGGER->info('SOURCE_2_FOLDING: {}', print_r($this->SOURCE_2_FOLDING, true)); $this->LOGGER->info('BUILDING_TIME: {} sec', $sec->getTotalTime()); } }