Пример #1
0
 protected function doBuild(\PageContext $ctxt, \PageBuilderContext $builderCtxt, \RequestArrayAdapter $requestParams, \ArrayAdapter $buildParams)
 {
     //1. ЗАГОЛОВОК
     $builderCtxt->setTitle($this->authed ? 'Админка | ' . $this->adminPage->title() : 'xxx');
     //2. JAVASCRIPT
     $builderCtxt->setJsParams($this->authed ? $this->adminPage->getJsParams() : null);
     //3. SMARTY RESOURCES
     if ($this->authed) {
         $builderCtxt->setSmartyParams4Resources($this->adminPage->getSmartyParams4Resources());
         $builderCtxt->setSmartyParam4Resources('IDENT', $this->adminPage->getPageIdent());
         $builderCtxt->setSmartyParam4Resources('TIMELINE_ENABE', true);
     }
     $smartyParams['authed'] = $this->authed;
     $smartyParams['isBasic'] = PsSecurity::isBasic();
     if (!$this->authed) {
         return $smartyParams;
     }
     //Запустим неограниченный по времени режим - мало ли, что мы там будем делать:)
     PsUtil::startUnlimitedMode();
     //Отменим нормализацию страницы
     PsDefines::setNormalizePage(false);
     //Получаем содержимое админской страницы
     $content = ContentHelper::getContent($this->adminPage);
     //Добавляем к ней ресурсы
     $content = APagesResources::inst()->getResourcesLinks($this->adminPage->getPageIdent(), $content);
     $smartyParams['page'] = $this->adminPage;
     $smartyParams['content'] = $content;
     $smartyParams['pagesLayout'] = AdminPagesManager::getInstance()->getLayout();
     return $smartyParams;
 }
Пример #2
0
 public function buildContent()
 {
     //Можно и не устанавливать, т.к. к popup окнам мы не подключаем спрайты
     PsDefines::setReplaceFormulesWithSprites(false);
     $params = array('prinvView' => $this->postCP->getPostPrintVariant());
     return $this->getFoldedEntity()->fetchTpl($params);
 }
Пример #3
0
 /** @return ToDoFile */
 public static function inst()
 {
     if (!isset(self::$todo)) {
         PsDefines::assertProductionOff(__CLASS__);
         self::$todo = new ToDoFile();
     }
     return self::$todo;
 }
/**
 * Управление постом
 */
function smarty_modifier_post_header_controls($post)
{
    $post = $post instanceof PostContentProvider ? $post->getPost() : $post;
    $pp = Handlers::getInstance()->getPostsProcessorByPostType($post->getPostType());
    /*
     * Собираем кнопки управления
     */
    $buttons = array();
    $hintClasses = 'hint--top hint--info hint--rounded';
    //Печать поста
    $attrs = array();
    $title = 'Версия для печати';
    $attrs['href'] = '#print';
    $attrs['title'] = $title;
    $attrs['data'] = array('hint' => $title);
    $attrs['class'] = $hintClasses;
    $content = CssSpritesManager::getDirSprite(CssSpritesManager::DIR_ICO, 'print', true);
    $buttons[] = PsHtml::a($attrs, $content);
    //Оригинальный вид поста
    if (PsDefines::isReplaceFormulesWithImages()) {
        $attrs = array();
        $title = 'Просмотр ' . ps_strtolower($pp->postTitle(null, 2)) . ' без замены формул на картинки';
        $attrs['href'] = '#originalView';
        $attrs['title'] = $title;
        $attrs['data'] = array('hint' => $title);
        $attrs['class'] = $hintClasses;
        $content = CssSpritesManager::getDirSprite(CssSpritesManager::DIR_ICO, 'formula', true);
        $buttons[] = PsHtml::a($attrs, $content);
    }
    //Быстрый просмотр постов (перелистывание)
    $attrs = array();
    $title = 'Предыдущий/следующий ' . ps_strtolower($pp->postTitle(null, 1));
    $attrs['href'] = '#prevNextView';
    $attrs['title'] = $title;
    $attrs['data'] = array('hint' => $title);
    $attrs['class'] = $hintClasses;
    $content = CssSpritesManager::getDirSprite(CssSpritesManager::DIR_ICO, 'prev_next', true);
    $buttons[] = PsHtml::a($attrs, $content);
    //Предыдущий пост
    $prevPost = $pp->getPrevPost($post->getId(), false);
    if ($prevPost) {
        $attrs = array();
        $attrs['data']['hint'] = $pp->postTitle($prevPost);
        $attrs['class'] = $hintClasses;
        $content = CssSpritesManager::getDirSprite(CssSpritesManager::DIR_ICO, 'prev_s', true);
        $buttons[] = $pp->postHref($prevPost, $content, null, $attrs);
    }
    //Следующий пост
    $nextPost = $pp->getNextPost($post->getId(), false);
    if ($nextPost) {
        $attrs = array();
        $attrs['data']['hint'] = $pp->postTitle($nextPost);
        $attrs['class'] = $hintClasses;
        $content = CssSpritesManager::getDirSprite(CssSpritesManager::DIR_ICO, 'next_s', true);
        $buttons[] = $pp->postHref($nextPost, $content, null, $attrs);
    }
    return PsHtml::div(array('class' => PsConstJs::POST_HEAD_CONTROLS), implode(' ', $buttons));
}
Пример #5
0
 private function __construct()
 {
     $this->CAHCE = new SimpleDataCache();
     $this->enabled = PsDefines::isProfilingEnabled();
     $this->dirManager = DirManager::autogen('profilers');
     if ($this->enabled) {
         PsShotdownSdk::registerDestructable($this, PsShotdownSdk::PsProfiler);
     }
 }
Пример #6
0
 protected function processImpl(PostArrayAdapter $adapter, $button)
 {
     PsDefines::assertProductionOff(__CLASS__);
     $text = $adapter->str('text');
     if (!$text) {
         return array('text', 'required');
     }
     $mtime = $adapter->int('mtime');
     ToDoFile::inst()->save($text, $mtime);
     return new AjaxSuccess();
 }
Пример #7
0
 public function buildContent()
 {
     $user = PsUser::inst();
     FORM_RegEditForm::getInstance()->setParam(FORM_PARAM_REG_NAME, $user->getName());
     FORM_RegEditForm::getInstance()->setParam(FORM_PARAM_REG_SEX, $user->getSex());
     FORM_RegEditForm::getInstance()->setParam(FORM_PARAM_REG_ABOUT, $user->getAboutSrc());
     FORM_RegEditForm::getInstance()->setParam(FORM_PARAM_REG_CONTACTS, $user->getContactsSrc());
     FORM_RegEditForm::getInstance()->setParam(FORM_PARAM_REG_MSG, $user->getMsgSrc());
     PsDefines::setReplaceFormulesWithImages(false);
     echo $this->getFoldedEntity()->fetchTpl(array('user' => $user, 'avatars' => $user->getAvatarsList(true)));
 }
Пример #8
0
 public static function testProductivity($callback, $count = 1000)
 {
     PsDefines::assertProductionOff(__CLASS__);
     check_condition(is_callable($callback), 'Передан некорректный callback для тестирования');
     $s = Secundomer::inst();
     for ($index = 0; $index < $count; $index++) {
         $s->start();
         call_user_func($callback);
         $s->stop();
     }
     return $s;
 }
Пример #9
0
 /**
  * Метод регистрации страницы
  * 
  * WebPages::register('xxx.php', 'Консоль администратора', PAGE_ADMIN, self::getIdent(), AuthManager::AUTH_TYPE_NO_MATTER, PAGE_ADMIN);
  * 
  * @param string $path - путь к скрипту, например 'xxx.php'
  * @param string $name - название страницы, например 'Консоль администратора'
  * @param int $code - код страницы PAGE_ADMIN
  * @param int $builderIdent - идентификатор построителя страниц, например 'PB_admin::getIdent()'
  * @param int $authType - тип авторизации, необходимый для доступа к странице, например 'AuthManager::AUTH_TYPE_NO_MATTER'
  * @param int $pageCodeNoAccess - страница, на которую нужно перейти при отсутствии доступа, например 'BASE_PAGE_INDEX'
  * @param bool $allovedInProduction - признак, доступна ли страница в ProductionMode
  */
 protected final function register($path, $name, $code, $builderIdent = null, $authType = AuthManager::AUTH_TYPE_NO_MATTER, $pageCodeNoAccess = null, $allovedInProduction = true)
 {
     if (!$allovedInProduction && PsDefines::isProduction()) {
         return;
         //----
     }
     $path = PsCheck::notEmptyString($path);
     $name = PsCheck::notEmptyString($name);
     $code = PsCheck::int($code);
     if (array_key_exists($code, $this->PAGES)) {
         PsUtil::raise('\'{}\' is already registered. Cannot register WebPage with same code \'{}\'.', $this->PAGES[$code], $code);
     } else {
         $this->PAGES[$code] = new WebPage($path, $name, $code, $authType, $pageCodeNoAccess, $builderIdent);
         $this->LOGGER->info('+{}. {}', pad_left(count($this->PAGES), 2, ' '), $this->PAGES[$code]);
     }
 }
Пример #10
0
 /**
  * Список методов, доступных для вызова
  */
 public static function getMethodsList()
 {
     if (!AuthManager::isAuthorizedAsAdmin() || PsDefines::isProduction()) {
         return array();
     }
     if (!is_array(self::$METHODS)) {
         self::$METHODS = array();
         $methodNames = PsUtil::getClassMethods(TestManager::inst(), true, false, true, true);
         foreach ($methodNames as $name) {
             $method = new ReflectionMethod(TestManager::inst(), $name);
             $params['name'] = $name;
             $params['descr'] = implode("\n", StringUtils::parseMultiLineComments($method->getDocComment()));
             $params['params'] = array();
             /* @var $param ReflectionParameter */
             foreach ($method->getParameters() as $param) {
                 $params['params'][] = array('name' => $param->getName(), 'dflt' => $param->isDefaultValueAvailable() ? var_export($param->getDefaultValue(), true) : null);
             }
             self::$METHODS[$name] = $params;
         }
     }
     return self::$METHODS;
 }
Пример #11
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;
 }
Пример #12
0
 public function buildContent()
 {
     PsDefines::setReplaceFormulesWithImages(false);
     return $this->getFoldedEntity()->fetchTpl($this->params);
 }
Пример #13
0
 private function validateGroup($group)
 {
     /**
      * Если зависимости от сущностей БД ещё не были проверены,
      * то запустим эту проверку и больше о валидности кешей,
      * зависящих от сущностей БД, можно не заботиться.
      * 
      * Эту проверку нужно выполнять в любом случае, так как её запуск может
      * показать изменение сущностей фолдинга или самих фолдингов, работающих
      * с изменёнными таблицами/представлениями.
      */
     DbChangeListener::check();
     $this->TREE->setTypeValidated(self::CHILD_DBENTITY, 'Выполнена проверка изменений в БД');
     /**
      * Если группа не валидируема - пропускаем.
      * Она могла стать валидируемой после проверки по базе.
      */
     if (!$this->TREE->isGroupValidatable($group)) {
         return;
         //---
     }
     $this->LOGGER->info(" > Валидируем группу кешей [{$group}]");
     /*
      * Проверим, можно ли выполнить процесс и, если можно, выполним. 
      * После выполнения о свежести логов можно будет не заботиться.
      */
     $this->LOGGER->info(" ! Пытаемся выполнить внейший процесс");
     if (ExternalProcess::inst()->executeFromClient()) {
         $this->TREE->setTypeValidated(self::CHILD_FOLDING, 'Выполнен внешний процесс от имени клиента');
         return;
         //---
     }
     /*
      * Если мы в продакшене - прекращаем дальнейшие проверки.
      * 
      * Вообще говоря без полной проверки всех фолдингов, от которых зависит данная группа кеша,
      * считать группу провалидированной нельзя. Но если где-либо будет обнаружен изменённый
      * фолдинг, то это приведёт к вызову метода {@link #onFoldingChanged} и кеш всёже будет сброшен.
      */
     $this->LOGGER->info(" ! Проверяем режим продакшн");
     if (PsDefines::isProduction()) {
         $this->TREE->setTypeValidated(self::CHILD_FOLDING, 'Включён режим продакшн');
         return;
         //---
     }
     $foldings = $this->TREE->getChildsForValidate(self::CHILD_FOLDING, $group);
     $this->LOGGER->info(" ! Валидируем фолдинги");
     foreach ($foldings as $fUnique) {
         $this->LOGGER->info(" ! Проверяем на изменение фолдинг [{$fUnique}]");
         if (Handlers::getInstance()->getFoldingByUnique($fUnique)->checkFirstEntityChanged()) {
             //Выполним действия по оповещению об изменении
             $this->onFoldingChanged($fUnique);
             //Не будем проверять вообще все фолдинги, от которых мы зависим - это задача {@see ExternalProcess}.
             return;
             //---
         } else {
             $this->TREE->onChildValidated(self::CHILD_FOLDING, $fUnique);
         }
     }
     $this->LOGGER->info(" < Группа кешей [{$group}] прошла валидацию и не была изменена");
 }
Пример #14
0
 public function get($default = null)
 {
     return PsDefines::get($this->name(), $this->type, $default);
 }
Пример #15
0
 public final function buildPage(array $buildParams = array())
 {
     header('Content-Type: text/html; charset=utf-8');
     ExceptionHandler::registerPretty();
     //Запросим адаптер, чтобы сбросить параметры в сессии
     UnloadArrayAdapter::inst();
     // Подготовим необходимые классы
     $CTXT = PageContext::inst();
     $PAGE = $CTXT->getPage();
     $BUILDER = $this->getPageBuilder($CTXT->getPageType());
     $PROFILER = $BUILDER->getProfiler();
     $RESOURCES = null;
     $TITLE = null;
     $CONTENT = null;
     if ($PROFILER) {
         // Начинаем профилирование
         $PROFILER->start($CTXT->getRequestUrl());
     }
     try {
         //Подготовим объекты, которые будем передавать построителю страницы
         $RQ_PARAMS = RequestArrayAdapter::inst();
         $BUILD_PARAMS = ArrayAdapter::inst($buildParams);
         $BUILDER_CTXT = PageBuilderContext::getInstance();
         //Стартуем контекст
         $BUILDER_CTXT->setContextWithFoldedEntity($BUILDER->getFoldedEntity());
         //Вызываем предварительную обработку страницы
         $BUILDER->preProcessPage($CTXT, $RQ_PARAMS, $BUILD_PARAMS);
         // Оповещаем слушателей
         /* @var $listener PagePreloadListener */
         foreach (Handlers::getInstance()->getPagePreloadListeners() as $listener) {
             $listener->onPagePreload($PAGE);
         }
         //Билдер строит страницу, наполняя контекст. Нам от него нужны будут только данные из контекста
         $PARAMS = $BUILDER->buildPage($CTXT, $BUILDER_CTXT, $RQ_PARAMS, $BUILD_PARAMS);
         //Остановим контекст
         $BUILDER_CTXT->dropContext();
         //Загрузим параметры
         $TITLE = $PARAMS->getTitle();
         $CONTENT = $PARAMS->getContent();
         // Подключаем все необходимые ресурсы
         $RESOURCES = $this->buildResources($PARAMS, $CTXT);
         //Проведём финализацию страницы, чтобы различные менеджеры могли добавить к ней свои данные
         $CONTENT = PageFinaliserFoldings::finalize($this->LOGGER, $CONTENT);
     } catch (Exception $ex) {
         $TITLE = trim($TITLE) . ' (произошла ошибка)';
         $CONTENT = ExceptionHandler::getHtml($ex);
     }
     //Непосредственное построение страницы.
     $PAGE_PARAMS['RESOURCES'] = $RESOURCES;
     $PAGE_PARAMS['TITLE'] = $TITLE;
     $PAGE_PARAMS['CONTENT'] = $CONTENT;
     //ПОДСТАВЛЯЕМ ВСЕ ПАРАМЕТРЫ СТРАНИЦЫ В БАЗОВЫЙ ШАБЛОН
     $PAGE_CONTENT = PSSmarty::template('page/page_pattern.tpl', $PAGE_PARAMS)->fetch();
     $this->LOGGER->infoBox('HTML PAGE', $PAGE_CONTENT);
     //ФИНАЛИЗАЦИЯ СТРАНИЦЫ - ВЫЧИСЛИМ РЕСУРСЫ, КОТОРЫЕ НУЖНО ОТКЛЮЧИТЬ
     $PAGE_CONTENT = PageFinaliserRegExp::finalize($this->LOGGER, $PAGE_CONTENT);
     //НОРМАЛИЗАЦИЯ СТРАНИЦЫ - УДАЛИМ ДВОЙНЫЕ ПРОБЕЛЫ И ПЕРЕНОСЫ
     if (PsDefines::isNormalizePage()) {
         $PAGE_CONTENT = PageNormalizer::finalize($this->LOGGER, $PAGE_CONTENT);
     }
     //ВСТАВИМ ASIS ПАРАМЕТРЫ, ТАК КАК БОЛЕЕ SMARTY ФИЛЬТРЫ ВЫЗЫВАТЬСЯ НЕ БУДУТ
     $PAGE_CONTENT = $this->replaceAsIsValues($PAGE_CONTENT);
     $this->LOGGER->infoBox('PAGE WITH ASIS REPLACED', $PAGE_CONTENT);
     //BOOOM :)
     echo $PAGE_CONTENT;
     if ($PROFILER) {
         // Заканчиваем профилирование
         $PROFILER->stop();
         PageOpenWatcher::updateUserPageWatch($CTXT->getRequestUrl());
     }
 }
Пример #16
0
 /**
  * Признак - авторизованы мы под админом или же работаем в девелопменте.
  * Часто в этом сочитании можно дать возможность выполнять дополнительные действия.
  */
 public static function DEVMODE_OR_ADMIN()
 {
     return !PsDefines::isProduction() || AuthManager::isAuthorizedAsAdmin();
 }
Пример #17
0
 public function doProcess(ArrayAdapter $params)
 {
     PsDefines::assertProductionOff(__CLASS__);
     //Отключим нормализацию страниц, так как мы редактируем HTML
     PsDefines::setNormalizePage(false);
 }
Пример #18
0
 /**
  * Метод выполняет дамп таблицы
  */
 public static function dumpTable($idColumn, $table, array $where = array(), $order = null)
 {
     //Стартуем секундомер
     $secundomer = Secundomer::startedInst("Снятие дампа {$table}");
     //Отключим ограничение по времени
     PsUtil::startUnlimitedMode();
     //Получим экземпляр логгера
     $LOGGER = PsLogger::inst(__CLASS__);
     //Текущий пользователь
     $userId = AuthManager::getUserIdOrNull();
     //Для логов, запросов и все остального
     $table = strtoupper(PsCheck::tableName($table));
     //Макс кол-во записей
     $limit = PsDefines::getTableDumpPortion();
     //Проверим наличие id
     $idColumn = PsCheck::tableColName($idColumn);
     $LOGGER->info('Dumping table {}. Id column: {}, limit: {}. User id: {}.', $table, $idColumn, $limit, $userId);
     //Получаем лок (без ожидания)
     $lockName = "DUMP table {$table}";
     $locked = PsLock::lock($lockName, false);
     $LOGGER->info('Lock name: {}, locked ? {}.', $lockName, var_export($locked, true));
     if (!$locked) {
         return false;
         //Не удалось получить лок
     }
     $zipDi = false;
     try {
         //ЗПРОСЫ:
         //1. Запрос на извлечение колва записей, подлежащих дампированию
         $queryCnt = Query::select("count({$idColumn}) as cnt", $table, $where);
         //2. Запрос на извлечение данных, подлежащих дампированию
         $queryDump = Query::select('*', $table, $where, null, $order, $limit);
         //3. Запрос на извлечение кодов дампируемых записей
         $selectIds = Query::select($idColumn, $table, $where, null, $order, $limit);
         //4. Запрос на удаление дампированных данных
         $queryDel = Query::delete($table, Query::plainParam("{$idColumn} in (select {$idColumn} from (" . $selectIds->build($delParams) . ') t )', $delParams));
         //Выполним запрос для получения кол-ва записей, подлежащих дампу
         $cnt = PsCheck::int(array_get_value('cnt', PSDB::getRec($queryCnt, null, true)));
         $LOGGER->info('Dump recs count allowed: {}.', $cnt);
         if ($cnt < $limit) {
             $LOGGER->info('SKIP dumping table, count allowed ({}) < limit ({})...', $cnt, $limit);
             $LOGGER->info("Query for extract dump records count: {$queryCnt}");
             PsLock::unlock($lockName);
             return false;
         }
         //Время дампа
         $date = PsUtil::fileUniqueTime(false);
         $time = time();
         //Название файлов
         $zipName = $date . ' ' . $table;
         //Элемент, указывающий на zip архив
         $zipDi = DirManager::stuff(null, array(self::DUMPS_TABLE, $table))->getDirItem(null, $zipName, PsConst::EXT_ZIP);
         $LOGGER->info('Dump to: [{}].', $zipDi->getAbsPath());
         if ($zipDi->isFile()) {
             $LOGGER->info('Dump file exists, skip dumping table...');
             PsLock::unlock($lockName);
             return false;
         }
         //Комментарий к таблице
         $commentToken[] = "Date: {$date}";
         $commentToken[] = "Time: {$time}";
         $commentToken[] = "Table: {$table}";
         $commentToken[] = "Manager: {$userId}";
         $commentToken[] = "Recs dumped: {$limit}";
         $commentToken[] = "Total allowed: {$cnt}";
         $commentToken[] = "Query dump cnt:   {$queryCnt}";
         $commentToken[] = "Query dump data:  {$queryDump}";
         $commentToken[] = "Query dump ids:   {$selectIds}";
         $commentToken[] = "Query del dumped: {$queryDel}";
         $comment = implode("\n", $commentToken);
         //Начинаем zip и сохраняем в него данные
         $zip = $zipDi->startZip();
         $zip->addFromString($zipName, serialize(PSDB::getArray($queryDump)));
         $zip->setArchiveComment($comment);
         $zip->close();
         $LOGGER->info('Data successfully dumped, zip comment:');
         $LOGGER->info("[\n{$comment}\n]");
         //Удалим те записи, дамп которых был снят
         $LOGGER->info('Clearing dumped table records...');
         $affected = PSDB::update($queryDel);
         $LOGGER->info('Rows deleted: {}.', $affected);
         $LOGGER->info('Dumping is SUCCESSFULLY finished. Total time: {} sec.', $secundomer->stop()->getAverage());
     } catch (Exception $ex) {
         PsLock::unlock($lockName);
         ExceptionHandler::dumpError($ex);
         $LOGGER->info('Error occured: {}', $ex->getMessage());
         throw $ex;
     }
     return $zipDi;
 }
Пример #19
0
 public function buildContent()
 {
     PsDefines::setReplaceFormulesWithImages(false);
     $navigation = AdminPageNavigation::inst();
     /*
      * Инициализируем необходимые менеджеры
      */
     $TE = TableExporter::inst();
     $RQ = GetArrayAdapter::inst();
     $FORM = FORM_RecEditForm::getInstance();
     $TABLES = PsTable::configured();
     /*
      * Инициализируем параметры, которые нужно будет передать smarty
      */
     $PARAMS['mode'] = null;
     $PARAMS['table'] = null;
     $PARAMS['error'] = null;
     $PARAMS['errors'] = PsDbIniHelper::validateAll();
     /*
      * Обработаем форму
      */
     try {
         if ($FORM->isValid4Process()) {
             $this->processForm($FORM->getData());
         } else {
             if ($FORM->isErrorOccurred()) {
                 $PARAMS['error'] = PsHtml::divErr($FORM->getError());
             }
         }
     } catch (Exception $e) {
         $PARAMS['error'] = ExceptionHandler::getHtml($e);
     }
     /*
      * Обработаем параметры и определим режим работы
      */
     $MODE = $RQ->str('mode', self::MODE_TABLES_LIST);
     /** @var PsTable */
     $TABLE = null;
     // Таблица
     $ROW = null;
     // Редактируемая строка
     switch ($MODE) {
         case self::MODE_ROW_ADD:
             //Если передан фолдинг, то подставим в форму создания его параметры
             $folding = Handlers::getInstance()->getFolding($RQ->str('ftype'), $RQ->str('fsubtype'), false);
             $fident = $RQ->str('fident');
             if ($folding && $folding->getTableName() && $fident) {
                 $TABLE = $TE->getTable($folding);
                 $ROW = $folding->getDbRec4Entity($fident);
                 break;
             }
             $TABLE = PsTable::inst($RQ->str('table'));
             /*
              * Нам не удалось определить внешний вид создаваемой строки, 
              * но если у данной таблицы один фолдинг - возмём вид строки у него.
              */
             $folding = $TABLE->getSingleFolding();
             $ROW = $folding ? $folding->getDbRec4Entity($folding->getNextEntityIdent()) : null;
             break;
         case self::MODE_TABLE_ROWS:
         case self::MODE_TABLE_SQL:
         case self::MODE_TABLE_ARR:
         case self::MODE_ROW_EDIT:
         case self::MODE_ROW_DELETE:
             $TABLE = PsTable::inst($RQ->str('table'));
             switch ($MODE) {
                 case self::MODE_ROW_EDIT:
                 case self::MODE_ROW_DELETE:
                     $ROW = $TABLE->getRow($RQ->int($TABLE->getPk()->getName()));
                     break;
             }
             break;
         case self::MODE_INSERTS:
             //Nothing to do
             break;
         default:
             //Защитимся от некорректного значения параметра 'mode'
             $MODE = self::MODE_TABLES_LIST;
             break;
     }
     $PARAMS['mode'] = $MODE;
     $PARAMS['table'] = $TABLE;
     /*
      * ВЫПОЛНЯЕМ ОБРАБОТКУ
      */
     switch ($MODE) {
         case self::MODE_TABLES_LIST:
             $PARAMS['tables'] = $TABLES;
             $navigation->setCurrent('Список таблиц');
             break;
         case self::MODE_INSERTS:
             $PARAMS['tables'] = $TABLES;
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->setCurrent('Вставка данных');
             break;
         case self::MODE_TABLE_ROWS:
             $PARAMS['rows'] = $TABLE->getRows();
             $PARAMS['addurl'] = self::urlRecAdd($TABLE);
             $PARAMS['modified'] = $TABLE->getModifiedRows();
         case self::MODE_TABLE_SQL:
         case self::MODE_TABLE_ARR:
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->setCurrent($TABLE->getName());
             break;
         default:
             switch ($MODE) {
                 /*
                  * Помимо действий над записью, мы ещё раздиляем действия над фолдингами 
                  * (если они есть для таблицы). Поэтому мы установм: 
                  * FormAction - для типа редактирования записи
                  * FormButton - для типа работы с фолдингом
                  */
                 case self::MODE_ROW_ADD:
                     $FORM->setFormAction(PS_ACTION_CREATE);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_CREATE);
                     if ($TABLE->hasFoldings()) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_CREATEF);
                     }
                     $navigation->setCurrent('Создание записи');
                     break;
                 case self::MODE_ROW_EDIT:
                     $FORM->setFormAction(PS_ACTION_EDIT);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_EDIT);
                     if ($TABLE->hasFoldings() && !$TABLE->hasFoldingEntity4DbRec($ROW, true)) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_EDITF);
                     }
                     $navigation->setCurrent('Редактирование записи');
                     break;
                 case self::MODE_ROW_DELETE:
                     $FORM->setFormAction(PS_ACTION_DELETE);
                     $FORM->setButtons(FORM_RecEditForm::BUTTON_DELETE);
                     if ($TABLE->hasFoldingEntity4DbRec($ROW, true)) {
                         $FORM->addButton(FORM_RecEditForm::BUTTON_DELETEF);
                     }
                     $navigation->setCurrent('Удаление записи');
                     break;
                 default:
                     raise_error("Неизвестный режим: [{$MODE}]");
             }
             $FORM->setHidden('table', $TABLE->getName());
             $FORM->setSmartyParam('table', $TABLE);
             $FORM->setSmartyParam('rec', $ROW);
             $navigation->addPath(self::urlTables(), 'Список таблиц');
             $navigation->addPath(self::urlTableRows($TABLE), $TABLE->getName());
             break;
     }
     echo $this->getFoldedEntity()->fetchTpl($PARAMS);
 }
Пример #20
0
 /**
  * Метод получает на вход url ресурса и пытается его обфусцировать, если это возможно.
  *      
  * @return: путь к ресурсу, который должнет быть подключен, или null, если ресурс подключать не нужно
  */
 private function tryReplaceResource($url)
 {
     if (!starts_with($url, DIR_SEPARATOR)) {
         //Это внешний ресурс: http:// и т.д. - подключаем.
         return $url;
     }
     $di = DirItem::inst($url);
     if (!$di->isFile() || $di->getSize() <= 0) {
         return null;
     }
     if (!PsDefines::isProduction()) {
         //Не будем пытаться обфусцировать в девелопменте
         //return $url;
     }
     if (!ends_with($url, '.js')) {
         //Мы не можем обфусцировать .css файлы, так как они используют относительные пути к ресурсам.
         return $url;
     }
     return $url;
     $url = $di->getRelPath();
     if (!starts_with($url, $this->OBFUSCATABLE)) {
         //Не стоит обфусцировать не наши .js файлы, так как они могут внутри использовать ссылки на рядом лежащие ресурсы
         return $url;
     }
     $type = 'js';
     $obfuscatedDi = DirManager::autogen("resources/{$type}")->getDirItem(null, md5($url), $type);
     $mtyme = $obfuscatedDi->getModificationTime();
     if (!$mtyme || $mtyme < $di->getModificationTime()) {
         $obfuscatedDi->writeToFile(StringUtils::normalizeResourceFile($type, $di->getFileContents()), true);
     }
     return $obfuscatedDi->getRelPath();
 }
Пример #21
0
 protected function __construct()
 {
     //Разрешаем работать с классом только администратору
     AuthManager::checkAdminAccess();
     //Мы должны находиться не в продакшене
     PsDefines::assertProductionOff(__CLASS__);
     $this->LOGGER = PsLogger::inst(__CLASS__);
     $this->BEAN = TESTBean::inst();
 }
Пример #22
0
 /**
  * В процессе закрытия данного класса мы напишем полный список изменённых сущностей
  */
 public function onDestruct()
 {
     foreach (array('ACTION_FOLDING_' => 'Фолдинги', 'ACTION_ENTITY_' => 'Сущности') as $CONST_PREFIX => $name) {
         $this->LOGGER->infoBox($name);
         foreach (PsUtil::getClassConsts($this, $CONST_PREFIX) as $action) {
             $idents = array_get_value($action, $this->ACTIONS, array());
             $count = count($idents);
             $this->LOGGER->info();
             $this->LOGGER->info($action . ':');
             if ($count > 0) {
                 for ($i = 0; $i < $count; $i++) {
                     $this->LOGGER->info("\t" . (1 + $i) . '. ' . $idents[$i][0] . ($idents[$i][1] ? ' [' . $idents[$i][1] . ']' : ''));
                 }
             } else {
                 $this->LOGGER->info("\t -- Нет --");
             }
         }
     }
     /**
      * Распечатаем карту зависимости сущностей фолдинга.
      * Операция настолько тяжёлая, что в режиме ajax также будем избегать её выполнение.
      */
     if (PsDefines::isDevmode() && !PageContext::inst()->isAjax()) {
         $this->LOGGER->infoBox('Карта зависимости сущностей фолдингов:');
         foreach ($this->getDependsOnMap() as $who => $fromWhoArr) {
             $this->LOGGER->info("\t{$who}:");
             foreach ($fromWhoArr as $fromWho) {
                 $this->LOGGER->info("\t\t{$fromWho}");
             }
         }
     }
 }
Пример #23
0
 /**
  * Вызывается после компиляции макета (построения php-файла).
  * Может быть переопределён в наследнике.
  * 
  * @param string $source - "сырой" код шаблона
  * @param Smarty_Internal_Template $template
  */
 protected function outputImpl($source, Smarty_Internal_Template $template)
 {
     if (PsDefines::isReplaceFormulesWithImages()) {
         return TexImager::inst()->replaceInText($source);
     }
     return $source;
 }
Пример #24
0
 public function buildContent()
 {
     $navigation = AdminPageNavigation::inst();
     $RQ = RequestArrayAdapter::inst();
     /** @var FoldedEntity */
     $entity = FoldedStorageInsts::getFoldedEntityByUnique($RQ->str('entity'), false);
     /** @var FoldedResources */
     $folding = $entity ? $entity->getFolding() : FoldedStorageInsts::byUnique($RQ->str('folding'), false);
     $mode = $RQ->str('mode', self::MODE_FOLDINGS_LIST);
     $PARAMS['mode'] = $mode;
     $PARAMS['error'] = null;
     $PARAMS['entity'] = $entity;
     $PARAMS['folding'] = $folding;
     $PARAMS['foldings'] = FoldedStorageInsts::listFoldings();
     $ftype = $folding ? $folding->getFoldingType() : '';
     $fsubtype = $folding ? $folding->getFoldingSubType() : '';
     $fident = $entity ? $entity->getIdent() : '';
     $flist = $RQ->str('list');
     $ftplpath = $RQ->str('tplpath');
     //РЕДИРЕКТ
     if ($mode != self::MODE_FOLDINGS_LIST && !$folding) {
         PsUtil::redirectTo(self::urlFoldingsList());
     }
     //ВЫПОЛНЕНИЕ
     switch ($mode) {
         //СПИСОК ВСЕХ ФОЛДИНГОВ
         case self::MODE_FOLDINGS_LIST:
             $navigation->setCurrent('Список фолдингов');
             break;
             //СПИСОК СУЩНОСТЕЙ ДАННОГО ФОЛДИНГА
         //СПИСОК СУЩНОСТЕЙ ДАННОГО ФОЛДИНГА
         case self::MODE_FOLDING_CONTENT:
             $newIdent = $folding->getNextEntityIdent();
             //Форма создания
             $FORM = FORM_AdminFoldingCreateForm::getInstance();
             $FORM->setHidden('folding', $folding->getUnique());
             $FORM->setParam(FORM_AdminFoldingCreateForm::PARAM_NEW_FOLDING_IDENT, $newIdent);
             $FORM->setSmartyParam('folding', $folding);
             /* @var $TABLE PsTable */
             $FORM->setSmartyParam('rec', $folding->getDbRec4Entity($newIdent));
             //Форма загрузки
             $FORM = FORM_AdminFoldingUploadForm::getInstance();
             $FORM->setHidden('folding', $folding->getUnique());
             $navigation->addPath(self::urlFoldingsList(), 'Список фолдингов');
             $navigation->setCurrent($folding->getEntityName());
             break;
         case self::MODE_FOLDING_LIST_EDIT:
             $PARAMS['list'] = $flist;
             //TODO - выкинуто
             //$PARAMS['listIdents'] = $folding->getPossibleListIdents($flist);
             $navigation->addPath(self::urlFoldingsList(), 'Список фолдингов');
             $navigation->addPath(self::urlFoldingEntitys($folding), $folding->getEntityName());
             $navigation->setCurrent('Редактирование списка ' . $flist);
             break;
         case self::MODE_FOLDING_TPLS_LIST:
             $PARAMS['tplsList'] = $folding->getAllInfoTpls($fident);
             $navigation->addPath(self::urlFoldingsList(), 'Список фолдингов');
             $navigation->addPath(self::urlFoldingEntitys($folding), $folding->getEntityName());
             $navigation->addPath(self::urlFoldingEdit($entity), $fident);
             $navigation->setCurrent('Информационные шаблоны');
             break;
         case self::MODE_FOLDING_TPL_EDIT:
             $PARAMS['tplsList'] = $folding->getAllInfoTpls($fident);
             $tpl = $folding->getInfoTpl($entity->getIdent(), $ftplpath);
             $PARAMS['tpl'] = $tpl;
             //Отфетчим содержимое, извлеча из запроса те параметры, которые начинаются на sm_
             $PARAMS['content'] = $tpl->fetchNoCache($RQ->getByKeyPrefix('sm_', true));
             $FORM = FORM_AdminFoldingInfoTplEditForm::getInstance();
             $FORM->setHidden('fentity', $entity->getUnique());
             $FORM->setHidden('ftpl', $tpl->getInfoRelPath());
             $FORM->setSmartyParam('tpl', $tpl->getDirItem()->getFileContents());
             $navigation->addPath(self::urlFoldingsList(), 'Список фолдингов');
             $navigation->addPath(self::urlFoldingEntitys($folding), $folding->getEntityName());
             $navigation->addPath(self::urlFoldingEdit($entity), $fident);
             $navigation->addPath(self::urlFoldingInfoTplsList($entity), 'Информационные шаблоны');
             $navigation->setCurrent($tpl->getInfoRelPath());
             break;
         case self::MODE_FOLDING_EDIT:
             //Ссылка для скачивания спрайтов
             $download['class'] = 'download';
             $download['data'] = array('ftype' => $ftype, 'fsubtype' => $fsubtype, 'fident' => $fident);
             $PARAMS['download'] = PsHtml::a($download, '[Скачать]');
             $spriteImg = $folding->getSprite($fident);
             $spriteImg = $spriteImg && $spriteImg->getImgDi()->isImg() ? $spriteImg->getImgDi() : null;
             $PARAMS['sprite'] = $spriteImg ? PsHtml::a(array('href' => $spriteImg->getRelPath()), '[Спрайт]', true) : null;
             //Информационные шаблоны
             $PARAMS['patterns'] = '';
             if (count($folding->getInfoDiList($fident))) {
                 $patterns['href'] = self::urlFoldingInfoTplsList($entity);
                 $PARAMS['patterns'] = PsHtml::a($patterns, '[Инфо шаблоны]');
             }
             $PARAMS['info'] = '';
             try {
                 $prew = $folding->getFoldedEntityPreview($fident);
                 if (is_array($prew)) {
                     $PARAMS['info'] = array_get_value('info', $prew);
                     $PARAMS['content'] = array_get_value('content', $prew);
                 } else {
                     $PARAMS['content'] = $prew;
                 }
             } catch (Exception $e) {
                 $PARAMS['content'] = ExceptionHandler::getHtml($e);
             }
             /*
              * Подготовим форму редактирования фолдинга
              */
             $FORM = FORM_AdminFoldingEditForm::getInstance();
             /* hiddens */
             $FORM->setHidden('ftype', $ftype);
             $FORM->setHidden('fsubtype', $fsubtype);
             $FORM->setHidden('fident', $fident);
             $rtypes = $folding->getAllowedResourceTypes();
             /* fields */
             foreach ($rtypes as $rtype) {
                 $FORM->setParam($rtype, $folding->getResourceDi($fident, $rtype)->getFileContents(false));
             }
             /* smarty */
             $FORM->setSmartyParam('types', $rtypes);
             $FORM->setSmartyParam('covers', $folding->isImagesFactoryEnabled());
             /* table */
             $TABLE = null;
             $DBROW = null;
             if ($folding->getTableName()) {
                 $TABLE = TableExporter::inst()->getTable($folding->getTableName());
                 //TODO - выкинуто
                 //$DBROW = $TABLE->getFoldingDbRec($folding, $fident);
             }
             $FORM->setSmartyParam('table', $TABLE);
             $FORM->setSmartyParam('row', $DBROW);
             if (!$DBROW) {
                 $FORM->removeButton(FORM_AdminFoldingEditForm::BUTTON_DELETE_ALL);
             }
             /*
              * Навигация
              */
             $navigation->addPath(self::urlFoldingsList(), 'Список фолдингов');
             $navigation->addPath(self::urlFoldingEntitys($folding), $folding->getEntityName());
             $navigation->setCurrent($fident);
             break;
     }
     PsDefines::setReplaceFormulesWithImages(false);
     echo $this->getFoldedEntity()->fetchTpl($PARAMS);
 }
Пример #25
0
 /**
  * Функция для регистрации страниц
  * 
  * @param type $path
  * @param type $name
  * @param type $code
  * @param AbstractPageBuilder $builderIdent
  * @param type $authType
  * @param type $basePageCode
  * @param type $pageCodeNoAccess
  * @param type $allovedInProduction
  * @return type
  */
 public static final function register($path, $name, $code, $builderIdent, $authType, $basePageCode = null, $pageCodeNoAccess = null, $allovedInProduction = true)
 {
     self::$allowedScripts[] = $path;
     if (!$allovedInProduction && PsDefines::isProduction()) {
         return;
         //----
     }
     check_condition(self::$storeState === 1, 'Страница не может быть заретистирована, хранилище находится в состоянии [' . self::$storeState . ']');
     check_condition(is_string($path) && !isEmpty($path), "Некорректный путь для страницы [{$path}]");
     check_condition(is_integer($code), "Некорректный код для страницы [{$code}]");
     $pathBase = get_file_name($path);
     check_condition(!array_key_exists($pathBase, self::$page2pathBase) && !array_key_exists($code, self::$page2code), "Страница [{$name} ({$code})] не может быть зарегистрирована дважды");
     $page = new WebPage($path, $name, $code, $authType, $basePageCode, $pageCodeNoAccess, $builderIdent);
     self::$page2code[$code] = $page;
     self::$page2pathBase[$pathBase] = $page;
 }
Пример #26
0
 public function buildContent()
 {
     PsDefines::setReplaceFormulesWithImages(false);
     echo $this->postCP->getPostPopupVariant();
 }
Пример #27
0
 protected function doProcess(PageContext $ctxt, RequestArrayAdapter $requestParams, ArrayAdapter $buildParams)
 {
     PsDefines::assertProductionOff(__CLASS__);
     PsUtil::startUnlimitedMode();
 }
Пример #28
0
 public function get()
 {
     return PsDefines::get($this->name(), $this->ctxt, $this->phpType, $this->default);
 }
Пример #29
0
 protected function __construct()
 {
     PsDefines::assertProductionOff(__CLASS__);
     parent::__construct();
 }
Пример #30
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}].");
 }