Exemple #1
0
 /**
  * Метод разбирает файл с ребусами, который выглядит как:
  * 
  * ребус 1
  * ответ 1.1
  * ответ 1.2
  * 
  * ребус 2
  * ответ 2.1
  * ответ 2.2
  * 
  * @return type
  */
 private function parseAnswersFile(DirItem $di)
 {
     $result = array();
     $lines = explode("\n", trim($di->getFileContents(false)));
     $current = null;
     foreach ($lines as $line) {
         $line = trim($line);
         if ($line && !$current) {
             //Начинается новый ребус
             $current = $line;
             $result[$current] = array();
         } else {
             if ($line && $current) {
                 //Ответ на ребус
                 $result[$current][] = $line;
             } else {
                 if (!$line && $current) {
                     //Пробел, закончили ребус
                     $current = null;
                 }
             }
         }
     }
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info('Rebuses of {}:', $di->getRelPath());
         $this->LOGGER->info(print_r($result, true));
         $this->LOGGER->info();
     }
     return $result;
 }
Exemple #2
0
 /**
  * Функция производит финализацию страницы, показываемой пользователю, добавляя к ней элемент с содержащимися в нём ссылками.
  */
 public function appendLibItemsToPageContent($CONTENT)
 {
     $matches = array();
     $data = PsConstJs::BUBBLE_LOADER_FOLDING_DATA;
     $pattern = "/data-{$data}=\"(.+?)\"/si";
     preg_match_all($pattern, $CONTENT, $matches);
     $matches = array_unique(array_get_value(1, $matches, array()));
     $items = array();
     foreach ($matches as $unique) {
         $entity = Handlers::getInstance()->getFoldedEntityByUnique($unique, false);
         if ($entity && $entity->getFolding()->isItByType(LibResources::LIB_FOLDING_TYPE)) {
             $items[$entity->getUnique()] = $entity->getFolding()->getBubble($entity->getIdent());
         }
     }
     $has = count($items) > 0;
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info();
         $this->LOGGER->info('Библиотечные элементы, добавленные на страницу:');
         if ($has) {
             foreach ($items as $unique => $lib) {
                 $this->LOGGER->info("\t{$unique}");
             }
         } else {
             $this->LOGGER->info("\t-- Нет --");
         }
     }
     return $CONTENT . ($has ? PsHtml::div(array('id' => PsConstJs::BUBBLE_LOADER_FOLDING_STORE_ID), implode('', $items)) : '');
 }
 protected function __construct()
 {
     $this->CACHE = new SimpleDataCache();
     $this->LOGGER = PsLogger::inst(__CLASS__);
     if ($this->LOGGER->isEnabled()) {
         PsShotdownSdk::registerDestructable($this, PsShotdownSdk::FoldedResourcesManager);
     }
 }
 /**
  * Метод регистрации экземпляров фолдингов
  * 
  * @param FoldedResources $inst - экземпляр
  */
 protected final function register(FoldedResources $inst)
 {
     $unique = $inst->getUnique();
     if (array_key_exists($unique, $this->FOLDINGS)) {
         PsUtil::raise('Folding \'{}\' is already registered. Cannot register \'{}\' with same unique.', $this->FOLDINGS[$unique], $inst);
     } else {
         $this->FOLDINGS[$unique] = $inst;
         if ($this->LOGGER->isEnabled()) {
             $this->LOGGER->info('+{}. {}, count: {}.', pad_left(count($this->FOLDINGS), 3, ' '), $inst, FoldedStorage::getEntitiesCount($unique));
         }
     }
 }
Exemple #5
0
 /**
  * Метод выполняет фактическую замену TEX тега на его представление в виде картинки или спрайта.
  * 
  * @param str $original \[v_{\text{cp}}=\frac{\Delta S}{\Delta t}\]
  * @param str $formula    v_{\text{cp}}=\frac{\Delta S}{\Delta t}
  * @param str $type     block or inline
  */
 public function _replaceInTextImpl($original, $formula, $isBlock)
 {
     $type = $isBlock ? 'block' : 'inline';
     $replace = '';
     if ($formula) {
         /*
          * Проверяем, разрешена ли замена формул на спрайты и есть ли сейчас контекст.
          * Если всё выполнено, то это вовсе не означает, что необходимый спрайт подключен и есть 
          * спрайт для данной формулы.
          */
         if (PsDefines::isReplaceFormulesWithSprites() && FoldedContextWatcher::getInstance()->getSpritableContext()) {
             $replace = CssSpritesManager::getFormulaSprite(FoldedContextWatcher::getInstance()->getSpritableContext()->getSpritable(), $formula, array('TeX', $type));
         }
         /*
          * Если спрайта не нашлось, то заменяем на картинку.
          */
         if (!$replace) {
             $imgDi = $this->getImgDi($formula);
             $imgPath = $imgDi ? $imgDi->getRelPath() : null;
             if ($imgPath) {
                 $replace = PsHtml::img(array('src' => $imgPath, 'class' => "TeX {$type}", 'alt' => ''));
             } else {
                 $replace = $original;
             }
         }
     }
     /*
      * Логирование
      */
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info(++$this->replaced . ". Replacing {$type} TeX");
         $this->LOGGER->info("FULL:   {$original}");
         $this->LOGGER->info("CONTENT:  {$formula}");
         $this->LOGGER->info("SAVED:    {$formula}");
         $this->LOGGER->info("REPLACED: {$replace}");
         $this->LOGGER->info("\n");
     }
     return $replace;
 }
Exemple #6
0
 /**
  * Копирует ячейки из картинки-источника в картинку-мозайку.
  * 
  * @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();
 }
Exemple #7
0
 /**
 * Распечатывает текущее состояние дерева зависимости в лог.
 * При этом в дереве отмечаются всегда только полностью проверенные сущности.
 * Если, например, группа зависит от таблиц БД, которые были провалидированы, но при этом
 * сама группа отмечена, как валидная, то мы увидим подобную картину:
 * 
  +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();
 }
 /**
  * В конструкторе пробежимся по всем хранилищам и соберём все фолдинги
  */
 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());
     }
 }
 private function uploadFileImpl(DirItem $source, FILEAdapter $file = null, $userId = null, array $params = array())
 {
     $userId = $this->checkUserId($userId);
     $this->LOGGER->info("Processing file upload for user [{$userId}], source {$source}.");
     $aa = ArrayAdapter::inst($params);
     $uploaded = $file ? $source : null;
     $originalName = $file ? $file->getOriginalName() : $source->getName();
     $dbMsg = null;
     try {
         $this->LOGGER->info('Calling onBeforeSave...');
         $dbMsg = $this->onBeforeSave($source, $userId, $aa);
         $this->LOGGER->info("\tDone!");
     } catch (Exception $ex) {
         $this->LOGGER->info('Error occurred in onBeforeSave method: ' . $ex->getMessage());
         $this->LOGGER->info('Source file will be deleted ? {}.', var_export(!!$uploaded, true));
         if ($uploaded) {
             $uploaded->remove();
         }
         throw $ex;
     }
     if ($uploaded) {
         //Это уже и так загруженный файл
         $this->LOGGER->info('Source file is uploaded file');
     } else {
         $this->LOGGER->info('Move source file to uploads dir');
         $uploaded = $this->makeTmpDirItem();
         $source->copyTo($uploaded);
     }
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info("\tUploaded file: {$uploaded}");
         $this->LOGGER->info("\tOriginal name: [{$originalName}]");
         $this->LOGGER->info("\tMime: [{$uploaded->getMime()}]");
         $this->LOGGER->info("\tParams: " . array_to_string($params, false));
     }
     $uploadId = null;
     if ($this->isStoreToDb()) {
         $this->LOGGER->info("Saving upload file into database. DbMsg: '{$dbMsg}'.");
         try {
             $uploadId = UploadsBean::inst()->saveFileUpload($this->DBTYPE, $uploaded->getAbsPath(), $originalName, $uploaded->getMime(), $userId, $dbMsg);
             //Почистим кеш, вдруг мы запрашивали информацию по данному файлу
             $this->CACHE->remove($uploadId);
             $this->LOGGER->info("\tFile successfully saved, uploadId = {$uploadId}.");
         } catch (Exception $ex) {
             $this->LOGGER->info('Error occured while saving file to DB: ' . $ex->getMessage());
             $this->LOGGER->info('Deleting upload file...');
             $uploaded->remove();
             $uploaded = null;
             throw $ex;
         }
         $uploaded->setData('id', $uploadId);
     }
     try {
         $this->LOGGER->info('Calling onAfterSave...');
         $this->onAfterSave($uploaded, $userId, $aa);
         $this->LOGGER->info("\tDone!");
     } catch (Exception $ex) {
         $this->LOGGER->info('Error occured in onAfterSave method: ' . $ex->getMessage());
         if (is_inumeric($uploadId)) {
             $this->LOGGER->info('Deleting db record...');
             UploadsBean::inst()->clearFileUpload($uploadId);
             $uploadId = null;
         }
         $this->LOGGER->info('Deleting upload file...');
         $uploaded->remove();
         $uploaded = null;
         throw $ex;
     }
     /*
      * Если класс работает автономно и не работает с базой, то файл нужно удалить.
      */
     if ($this->isAutonomous() && !$this->isStoreToDb()) {
         $this->LOGGER->info('Class is auto clean, deleting uploaded file...');
         $uploaded->remove();
         $uploaded = null;
     }
     $this->LOGGER->info('');
     return $uploaded;
 }
Exemple #10
0
 public function fetchTplImpl($ident, $smParams = null, $returnType = self::FETCH_RETURN_CONTENT, $addResources = false, $cacheId = null)
 {
     $this->assertHasAccess($ident);
     $logMsg = null;
     if ($this->LOGGER->isEnabled()) {
         $rqNum = ++self::$FETCH_REQUEST_CNT;
         $logMsg = "#{$rqNum} Smarty params count: " . count(to_array($smParams)) . ", type: {$returnType}, resources: " . var_export($addResources, true) . ", " . ($cacheId ? "cache id: [{$cacheId}]" : 'nocache');
         $this->LOGGER->info("Tpl fetching requested for entity [{$ident}]. {$logMsg}");
         FoldedResourcesManager::onEntityAction(FoldedResourcesManager::ACTION_ENTITY_FETCH_REQUESTD, $this, $ident, $logMsg);
     }
     $entity = $this->getFoldedEntity($ident);
     //Сразу установим зависимость от текущей сущности
     FoldedContextWatcher::getInstance()->setDependsOnEntity($entity);
     $CTXT = $this->getFoldedContext();
     $PCLASS = $CTXT->tplFetchParamsClass();
     $PCLASS_BASE = FoldedTplFetchPrams::getClassName();
     check_condition(PsUtil::isInstanceOf($PCLASS, $PCLASS_BASE), "Класс [{$PCLASS}] для хранения данных контекста {$CTXT} должен быть подклассом {$PCLASS_BASE}");
     //Если мы не возвращаем содержимое, то в любом случае ресурсы добавлять не к чему
     $addResources = $addResources && !in_array($returnType, array(self::FETCH_RETURN_PARAMS, self::FETCH_RETURN_PARAMS_OB));
     $keysRequired = PsUtil::getClassConsts($PCLASS, 'PARAM_');
     $keysRequiredParams = array_diff($keysRequired, array(FoldedTplFetchPrams::PARAM_CONTENT));
     $PARAMS = null;
     $PARAMS_KEY = null;
     $CONTENT = null;
     $CONTENT_KEY = null;
     $RETURN_KEY = null;
     if ($cacheId) {
         $cacheId = ensure_wrapped_with($cacheId, '[', ']') . '[' . PsDefines::getReplaceFormulesType() . ']';
         $RETURN_KEY = $cacheId . '-' . $returnType;
         if (array_key_exists($ident, $this->FETCH_RETURNS)) {
             if (array_key_exists($RETURN_KEY, $this->FETCH_RETURNS[$ident])) {
                 return $this->FETCH_RETURNS[$ident][$RETURN_KEY];
             }
         } else {
             $this->FETCH_RETURNS[$ident] = array();
         }
         $PARAMS_KEY = empty($keysRequiredParams) ? null : $cacheId . '-params';
         $CONTENT_KEY = $cacheId . '-content';
         switch ($returnType) {
             case self::FETCH_RETURN_FULL:
             case self::FETCH_RETURN_FULL_OB:
                 $CONTENT = $this->getFromFoldedCache($ident, $CONTENT_KEY);
                 $PARAMS = $PARAMS_KEY ? $this->getFromFoldedCache($ident, $PARAMS_KEY, $keysRequiredParams) : array();
                 if ($CONTENT && is_array($PARAMS)) {
                     $CONTENT = $addResources ? $this->getResourcesLinks($ident, $CONTENT) : $CONTENT;
                     $PARAMS[FoldedTplFetchPrams::PARAM_CONTENT] = $CONTENT;
                     switch ($returnType) {
                         case self::FETCH_RETURN_FULL:
                             return $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $PARAMS;
                         case self::FETCH_RETURN_FULL_OB:
                             return $this->FETCH_RETURNS[$ident][$RETURN_KEY] = new $PCLASS($PARAMS);
                         default:
                             raise_error("Unprocessed fetch return type [{$returnType}].");
                     }
                 }
                 break;
             case self::FETCH_RETURN_CONTENT:
                 $CONTENT = $this->getFromFoldedCache($ident, $CONTENT_KEY);
                 if ($CONTENT) {
                     $CONTENT = $addResources ? $this->getResourcesLinks($ident, $CONTENT) : $CONTENT;
                     return $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $CONTENT;
                 }
                 break;
             case self::FETCH_RETURN_PARAMS:
             case self::FETCH_RETURN_PARAMS_OB:
                 $PARAMS = $PARAMS_KEY ? $this->getFromFoldedCache($ident, $PARAMS_KEY, $keysRequiredParams) : array();
                 if (is_array($PARAMS)) {
                     switch ($returnType) {
                         case self::FETCH_RETURN_PARAMS:
                             return $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $PARAMS;
                         case self::FETCH_RETURN_PARAMS_OB:
                             return $this->FETCH_RETURNS[$ident][$RETURN_KEY] = new $PCLASS($PARAMS);
                         default:
                             raise_error("Unprocessed fetch return type [{$returnType}].");
                     }
                 }
                 break;
         }
     }
     $settedNow = false;
     if (!$entity->equalTo(FoldedContextWatcher::getInstance()->getFoldedEntity())) {
         $CTXT->setContextWithFoldedEntity($entity);
         $settedNow = true;
     }
     try {
         $CONTENT = $this->getTpl($ident, $smParams)->fetch();
         $entityNow = FoldedContextWatcher::getInstance()->getFoldedEntity();
         check_condition($entity->equalTo($entityNow), "After tpl fetching folded entity [{$entity}] chenged to [{$entityNow}]");
         $PARAMS_FULL = $CTXT->finalizeTplContent($CONTENT);
         check_condition(is_array($PARAMS_FULL), "After [{$entity}] tpl finalisation not array is returned");
         $keysReturned = array_keys($PARAMS_FULL);
         if (count(array_diff($keysReturned, $keysRequired)) || count(array_diff($keysRequired, $keysReturned))) {
             raise_error("After [{$entity}] tpl finalisation required keys: " . array_to_string($keysRequired) . '], returned keys: [' . array_to_string($keysReturned) . ']');
         }
         if ($this->LOGGER->isEnabled()) {
             $this->LOGGER->info("Tpl fetching actually done for entity [{$ident}]. {$logMsg}");
             FoldedResourcesManager::onEntityAction(FoldedResourcesManager::ACTION_ENTITY_FETCH_DONE, $this, $ident, $logMsg);
         }
     } catch (Exception $e) {
         /*
          * Произошла ошибка!
          * 
          * Если мы устанавливали контенст и он не поменялся после завершения фетчинга (если поменялся, это ошибка), то нужно его обязательно завершить.
          * Если контекст был установлен во внешнем блоке, то этот блок должен позаботиться о сбросе контекста.
          * 
          * Далее от нас требуется только пробросить ошибку наверх.
          */
         if ($settedNow && $entity->equalTo(FoldedContextWatcher::getInstance()->getFoldedEntity())) {
             $CTXT->dropContext();
         }
         throw $e;
     }
     $CONTENT = $PARAMS_FULL[FoldedTplFetchPrams::PARAM_CONTENT];
     $PARAMS = $PARAMS_FULL;
     unset($PARAMS[FoldedTplFetchPrams::PARAM_CONTENT]);
     if ($PARAMS_KEY) {
         $this->saveToFoldedCache($PARAMS, $ident, $PARAMS_KEY);
     }
     if ($CONTENT_KEY) {
         $this->saveToFoldedCache($CONTENT, $ident, $CONTENT_KEY);
     }
     if ($settedNow) {
         $CTXT->dropContext();
     }
     if ($addResources) {
         $CONTENT = $this->getResourcesLinks($ident, $CONTENT);
         $PARAMS_FULL[FoldedTplFetchPrams::PARAM_CONTENT] = $CONTENT;
     }
     switch ($returnType) {
         case self::FETCH_RETURN_FULL:
             return $RETURN_KEY ? $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $PARAMS_FULL : $PARAMS_FULL;
         case self::FETCH_RETURN_FULL_OB:
             return $RETURN_KEY ? $this->FETCH_RETURNS[$ident][$RETURN_KEY] = new $PCLASS($PARAMS_FULL) : new $PCLASS($PARAMS_FULL);
         case self::FETCH_RETURN_CONTENT:
             return $RETURN_KEY ? $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $CONTENT : $CONTENT;
         case self::FETCH_RETURN_PARAMS:
             return $RETURN_KEY ? $this->FETCH_RETURNS[$ident][$RETURN_KEY] = $PARAMS : $PARAMS;
         case self::FETCH_RETURN_PARAMS_OB:
             return $RETURN_KEY ? $this->FETCH_RETURNS[$ident][$RETURN_KEY] = new $PCLASS($PARAMS) : new $PCLASS($PARAMS);
     }
     raise_error("Unknown fetch return type [{$returnType}].");
 }
 /**
  * Метод, выполняющий всё вычисление и всю обработку
  */
 private function doProcess($cells)
 {
     PsProfiler::inst(__CLASS__)->start('Unioning cells');
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->infoBox('Unioning ' . count($cells) . ' cells, user check: ' . var_export($this->checkUser, true));
         $this->LOGGER->info();
         $this->LOGGER->info('Before sorting and indexing:');
         $this->LOGGER->info(print_r($cells, true));
     }
     //Расположим ячейки от левого верхнего угла до правого нижнего (как при письме)
     usort($cells, function ($c1, $c2) {
         if ($c1['y_cell'] == $c2['y_cell']) {
             return $c1['x_cell'] > $c2['x_cell'] ? 1 : -1;
         }
         return $c1['y_cell'] > $c2['y_cell'] ? 1 : -1;
     });
     $this->cells = array();
     //Проиндексируем массив
     foreach ($cells as $cell) {
         $cell['x_cell'] = 1 * $cell['x_cell'];
         $cell['y_cell'] = 1 * $cell['y_cell'];
         $cell['id_user'] = 1 * $cell['id_user'];
         $this->cells[$cell['x_cell'] . 'x' . $cell['y_cell']] = $cell;
     }
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info();
         $this->LOGGER->info('After sorting and indexing:');
         $this->LOGGER->info(print_r($this->cells, true));
         $this->LOGGER->info();
     }
     //Пробегаем по всем ячейкам, объединяя их и исключая те ячейки, с которыми мы объединились
     $unioned = 0;
     foreach ($this->cells as $ident => $cell) {
         if (!array_key_exists($ident, $this->cells)) {
             //Видимо уже удаили ячейку из списка ячеек
             continue;
         }
         $x = $cell['x_cell'];
         $y = $cell['y_cell'];
         $id_user = $cell['id_user'];
         $dx = $this->getRightCellsCnt($x, $y, $id_user);
         if ($dx > 0) {
             //Объединяемся с ячейками справа
             $x1 = ($x - 1) * $this->w;
             $y1 = ($y - 1) * $this->h;
             $x2 = ($x + $dx) * $this->w;
             $y2 = $y * $this->h;
             for ($delta = 1; $delta <= $dx; $delta++) {
                 $cident = $x + $delta . 'x' . $y;
                 if ($this->LOGGER->isEnabled()) {
                     $cid_user = array_get_value_in(array($cident, 'id_user'), $this->cells);
                     $this->LOGGER->info(++$unioned . ". [{$ident}]({$id_user}) + [{$cident}]({$cid_user})");
                 }
                 unset($this->cells[$cident]);
             }
             $this->result[] = array($x1, $y1, $x2, $y2, $id_user);
             continue;
         }
         $dy = $this->getBottomCellsCnt($x, $y, $id_user);
         if ($dy > 0) {
             //Объединяемся с ячейками снизу
             $x1 = ($x - 1) * $this->w;
             $y1 = ($y - 1) * $this->h;
             $x2 = $x * $this->w;
             $y2 = ($y + $dy) * $this->h;
             for ($delta = 1; $delta <= $dy; $delta++) {
                 $cident = $x . 'x' . ($y + $delta);
                 if ($this->LOGGER->isEnabled()) {
                     $cid_user = array_get_value_in(array($cident, 'id_user'), $this->cells);
                     $this->LOGGER->info(++$unioned . ". [{$ident}]({$id_user}) + [{$cident}]({$cid_user})");
                 }
                 unset($this->cells[$cident]);
             }
             $this->result[] = array($x1, $y1, $x2, $y2, $id_user);
             continue;
         }
         //Не с кем объединяться, берём только эту ячейку
         $x1 = ($x - 1) * $this->w;
         $y1 = ($y - 1) * $this->h;
         $x2 = $x * $this->w;
         $y2 = $y * $this->h;
         $this->result[] = array($x1, $y1, $x2, $y2, $id_user);
     }
     $secundomer = PsProfiler::inst(__CLASS__)->stop();
     if ($this->LOGGER->isEnabled()) {
         $this->LOGGER->info();
         $this->LOGGER->info('Unioned cells:');
         $this->LOGGER->info(print_r($this->result, true));
         $this->LOGGER->info('Compression: {}%', round(count($this->result) / count($cells) * 100));
         if ($secundomer) {
             $this->LOGGER->info('Done in ' . $secundomer->getAverage() . ' seconds');
         }
     }
 }
Exemple #12
0
 protected function doAudit($action, $userId = null, $data = null, $saveToSession = false, $parentAction = null, $auditIfNoParent = true, $clearParent = true)
 {
     try {
         $action = $this->validateAction($action);
         $parentAction = $this->validateAction($parentAction, true);
         $actionSessionKey = $this->sessionCode($action);
         $parentActionSessionKey = $parentAction ? $this->sessionCode($parentAction) : null;
         $parentId = $parentActionSessionKey ? SessionArrayHelper::getInt($parentActionSessionKey) : null;
         $hasParentIdInSession = is_integer($parentId);
         $userId = AuthManager::validateUserIdOrNull($userId);
         $userIdAuthed = AuthManager::getUserIdOrNull();
         if ($this->LOGGER->isEnabled()) {
             $this->LOGGER->info();
             $this->LOGGER->info("<Запись #{}>", ++$this->NUM);
             $this->LOGGER->info('Действие: {}', $this->decodeAction($action));
             $this->LOGGER->info('Пользователь: {}', is_inumeric($userId) ? $userId : 'НЕТ');
             $this->LOGGER->info('Авторизованный пользователь: {}', is_inumeric($userIdAuthed) ? $userIdAuthed : 'НЕТ');
             $this->LOGGER->info('Данные: {}', $data === null ? 'НЕТ' : print_r($data, true));
             $this->LOGGER->info('Сохранять в сессию: {}', $saveToSession ? 'ДА' : 'НЕТ');
             $this->LOGGER->info('Родительское действие: {}', $this->decodeAction($parentAction));
             if ($parentAction) {
                 $this->LOGGER->info('Родительское действие есть в сессии: {}', $hasParentIdInSession ? "ДА ({$parentActionSessionKey}={$parentId})" : 'НЕТ');
                 if ($hasParentIdInSession) {
                     $this->LOGGER->info('Очищать родительское действие в сессии: {}', $clearParent ? 'ДА' : 'НЕТ');
                 } else {
                     $this->LOGGER->info('Производить аудит при отсутствии родит. действия: {}', $auditIfNoParent ? 'ДА' : 'НЕТ');
                 }
             }
         }
         if (!$hasParentIdInSession && !$auditIfNoParent) {
             $this->LOGGER->info('АУДИТ НЕ ПРОИЗВЕДЁН!');
             return;
             //--- Нужен предок, но его нет
         }
         $encoded = 0;
         if (is_array($data)) {
             if (count($data) == 0) {
                 $data = null;
             } else {
                 $data = self::encodeData($data);
                 $encoded = 1;
             }
         }
         check_condition($data === null || is_string($data) || is_numeric($data), 'Illegal audit data type: ' . gettype($data) . ' for ' . $this);
         $recId = UtilsBean::inst()->saveAudit($parentId, $userId, $userIdAuthed, $this->PROCESS_CODE, $action, $data, $encoded);
         if ($this->LOGGER->isEnabled()) {
             if ($data !== null) {
                 $this->LOGGER->info('Данные кодированы: {}', $encoded ? "ДА ({$data})" : 'НЕТ');
             }
             $this->LOGGER->info('Информация сохранена в базу, id={}', $recId);
         }
         if ($saveToSession) {
             SessionArrayHelper::setInt($actionSessionKey, $recId);
             $this->LOGGER->info("Данные о действии сохранены в сессию ({$actionSessionKey}={$recId})");
         }
         if ($hasParentIdInSession && $clearParent) {
             SessionArrayHelper::reset($parentActionSessionKey);
             $this->LOGGER->info('Данные о родительском действии удалены из сессии');
         }
         $this->LOGGER->info('АУДИТ ПРОИЗВЕДЁН.');
     } catch (Exception $ex) {
         //Не удалось записть аудит, но работа должна быть продолжена!
         ExceptionHandler::dumpError($ex);
     }
 }