Beispiel #1
0
 /**
  * Заменяет TeX-макросы в тексе на те, которые будут заменены на картинки:
  * Block:  $$...$$ -> \[...\]
  * Inline: \{...\} -> \(...\)
  */
 private static function replaceMacrosToImaged($TeX)
 {
     $TeX = str_replace('\\{', '\\(', $TeX);
     $TeX = str_replace('\\}', '\\)', $TeX);
     $TeX = PsStrings::pregReplaceCyclic('/\\$\\$/', $TeX, array('\\[', '\\]'));
     return $TeX;
 }
Beispiel #2
0
 /**
  * @covers PsStrings::replaceMapBracedKeys
  */
 public function testReplaceMapBracedKeys()
 {
     $params['a'] = 1;
     $params['b'] = 2;
     $params['c'] = 3;
     $this->assertEquals(PsStrings::replaceMapBracedKeys('{a}+{b}={c}', $params), '1+2=3');
     $this->assertEquals(PsStrings::replaceMapBracedKeys('{a}', $params), '1');
 }
Beispiel #3
0
 /**
  * Заменяет последовательно {} на аргументы вызова функции
  * @param type $msg - сообщение
  * @param type $param1 - параметр 1
  * @param type $param2 - параметр 2
  * @param type $param3 - параметр 3
  * @return type
  */
 public static function replaceWithBraced($msg = '', $param1 = null, $param2 = null, $param3 = null)
 {
     $params = func_get_args();
     if (count($params) > 1) {
         unset($params[0]);
         $msg = PsStrings::replaceWithParams('{}', $msg, $params);
     }
     return $msg;
 }
Beispiel #4
0
 public function info($msg = '', $param1 = null, $param2 = null, $param3 = null)
 {
     $num = func_num_args();
     if ($num > 1) {
         $params = func_get_args();
         unset($params[0]);
         $msg = PsStrings::replaceWithParams('{}', $msg, $params);
     }
     $this->logger->doWrite($this->id, $msg);
 }
Beispiel #5
0
 protected static final function log($msg, $arg1 = '', $arg2 = '')
 {
     $num = func_num_args();
     if ($num > 1) {
         $params = func_get_args();
         unset($params[0]);
         $msg = PsStrings::replaceWithParams('{}', $msg, $params);
     }
     $class = get_called_class();
     $trace = PsUtil::getClassFirstCall($class);
     $name = $trace['function'];
     echo "\n{$class}::{$name}: " . trim($msg) . "\n";
 }
 /**
  * В конструкторе проинициализируем все параметры соединения
  */
 private function __construct(array $params, $sourceDescr)
 {
     foreach (PsUtil::getClassConsts(__CLASS__, 'PARAM_') as $param) {
         $value = array_get_value(PsCheck::notEmptyString($param), $params);
         if (PsCheck::isNotEmptyString($value)) {
             $this->PARAMS[$param] = $value;
         } else {
             $this->PARAMS[$param] = null;
             //raise_error("Задано пустое значения для параметра $param в источнике $sourceDescr");
         }
     }
     $this->url = PsStrings::replaceWithBraced("{}://{}:{}@{}/{}", $this->scheme(), $this->user(), $this->password(), $this->host(), $this->database());
     $this->toString = PsStrings::replaceWithBraced("{}://{}:{}@{}/{} (source: {})", $this->scheme(), $this->user(), '***', $this->host(), $this->database(), $sourceDescr);
 }
Beispiel #7
0
 public function preCompile($source)
 {
     $source = str_replace('\\(', '{literal}\\(', $source);
     $source = str_replace('\\)', '\\){/literal}', $source);
     $source = str_replace('\\{', '{literal}\\{', $source);
     $source = str_replace('\\}', '\\}{/literal}', $source);
     $source = str_replace('\\[', '{literal}\\[', $source);
     $source = str_replace('\\]', '\\]{/literal}', $source);
     $source = PsStrings::pregReplaceCyclic('/\\$\\$/', $source, array('{literal}$$', '$${/literal}'));
     //Обернём математический текст, например: &alpha; перейдёт в <span class="math_text">&alpha;</span>
     $source = TextFormulesProcessor::replaceMathText($source);
     //Заменим некоторые блоки на вызов методов данного класса
     $source = SmartyReplacesIf::preCompile($source);
     return $source;
 }
Beispiel #8
0
 public static function format($__CLASS__, $__FUNCTION__, array $arguments)
 {
     if (!array_key_exists($__CLASS__, self::$MESSAGES)) {
         /*
          * Защита от зацикливания
          */
         self::$MESSAGES[$__CLASS__] = null;
         /*
          * Определим, где расположен класс с сообщениями
          */
         $classPath = Autoload::inst()->getClassPath($__CLASS__);
         if (!$classPath) {
             return PsUtil::raise('Группа сообщений {} не зарегистрирована', $__CLASS__);
         }
         /*
          * Получим DirItem сообщений для этого класса
          */
         $messagesDi = DirItem::inst(dirname($classPath), $__CLASS__, PsConst::EXT_MSGS);
         if (!$messagesDi->isFile()) {
             return PsUtil::raise('Файл с сообщениями {} не существует', $messagesDi->getName());
         }
         /*
          * Распарсим сообщения из файла
          */
         self::$MESSAGES[$__CLASS__] = $messagesDi->getFileAsProps();
     }
     /*
      * Проверим на зацикливание
      */
     if (self::$MESSAGES[$__CLASS__] === null) {
         PsUtil::raise('Зацикливание при попытке получить сообещние {}::{}', $__CLASS__, $__FUNCTION__);
     }
     /*
      * Проверим на существование самого сообщения
      */
     if (!array_key_exists($__FUNCTION__, self::$MESSAGES[$__CLASS__])) {
         return PsUtil::raise('Сообщение {}::{} не существует', $__CLASS__, $__FUNCTION__);
     }
     /*
      * Заменим макросы {} и вернём сообщение
      */
     return PsStrings::replaceMapBracedKeys(self::$MESSAGES[$__CLASS__][$__FUNCTION__], $arguments);
 }
Beispiel #9
0
function executeProcess(array $argv)
{
    PsConnectionPool::assertDisconnectied();
    /*
     * СОЗДАЁМ SQL
     * 
     * Нам нужны настройки таблиц, которые неоткуда взять, кроме как из базы, поэтому для экспорта данных нужна БД.
     * Все данные из "редактируемых" таблиц также загружаются из этой БД.
     */
    $DB = DirManager::inst(__DIR__ . '/temp');
    $SDK = DirManager::inst(__DIR__ . '/temp/sdk');
    //Почистим файлы для удаления
    dolog('Clearing not .sql/.txt from temp dir');
    /* @var $item DirItem */
    foreach ($DB->getDirContentFull(null, DirItemFilter::FILES) as $item) {
        if (!$item->checkExtension(array(PsConst::EXT_TXT, PsConst::EXT_SQL))) {
            dolog('[-] {}', $item->remove()->getRelPath());
        }
    }
    dolog();
    /*
     * SDK
     */
    //dolog('Processing objects.sql');
    /* @var $DIR DirManager */
    foreach (array(ENTITY_SCOPE_SDK => $SDK, ENTITY_SCOPE_PROJ => $DB) as $scope => $DM) {
        dolog();
        dolog('***************************************************************');
        dolog('>>> Processing scope [{}], dir: [{}]', $scope, $DM->absDirPath());
        $SCHEMA = $DM->getDirItem(null, 'schema.sql');
        if (!$SCHEMA->isFile()) {
            dolog('schema.sql is not exists, skipping');
            continue;
            //---
        }
        $DM_SYSOBJECTS = DirManager::inst($DM->absDirPath(), 'sysobjects');
        /*
         * Очищаем папку, в которой будет содержимое для автосгенерированных файлов
         */
        $DM_AUTO = DirManager::inst($DM_SYSOBJECTS->absDirPath(), 'auto')->clearDir();
        /*
         * Создадим ссылку на файл с данными, выгруженными из таблиц
         */
        $DI_AUTO_DATA = $DM_AUTO->getDirItem(null, 'data.sql');
        /*
         * Сначала сделаем триггеры на таблицы, от которых зависит кеш и к которым привязаны фолдинги.
         */
        LOGBOX_INIT();
        LOGBOX('Making cache and folding table triggers');
        $DM_AUTO_TRIGGERS = $DM_AUTO->getDirItem('triggers')->makePath();
        $DI_AUTO_TRIGGERS_SQL = $DM_AUTO->getDirItem(null, 'triggers', 'sql')->getSqlFileBuilder();
        $triggerPattern = $SDK->getDirItem('sysobjects/patterns', 'ta_iud_pattern.sql')->getFileContents();
        //BUILDIAN AND ADDING TRIGGERS
        foreach (PsTriggersAware::getTriggeredTables($scope) as $table) {
            foreach (PsTriggersAware::getActions() as $action) {
                $actions = PsTriggersAware::getTriggerActions($table, $scope, $action);
                if (empty($actions)) {
                    continue;
                    //---
                }
                $name = 'ta' . strtolower(first_char($action)) . '_' . $table;
                $trigger = str_replace('<%NAME%>', $name, $triggerPattern);
                $trigger = str_replace('<%TABLE%>', $table, $trigger);
                $trigger = str_replace('<%ACTION%>', $action, $trigger);
                $trigger = str_replace('<%CALL%>', implode("\n", $actions), $trigger);
                dolog("+ {$name}");
                foreach ($actions as $_action) {
                    dolog($_action);
                }
                $DI_AUTO_TRIGGERS_SQL->appendFile($DM_AUTO_TRIGGERS->getDirItem(null, $name, 'sql')->putToFile($trigger));
            }
        }
        //Все автоматически сгенерированные триггеры положим в отдельный файл
        $DI_AUTO_TRIGGERS_SQL->save();
        $autoTriggers = DirManager::inst($DM_AUTO_TRIGGERS->getAbsPath())->getDirContent(null, PsConst::EXT_SQL);
        dolog('Triggers made: {}', count($autoTriggers));
        /*
         * objects.sql
         */
        $OBJECTS_SQL = $DM_AUTO->getDirItem(null, 'objects.sql')->getSqlFileBuilder();
        /*
         * Добавляем автосгенерированные триггеры
         */
        LOGBOX('Processing objects.sql');
        if (empty($autoTriggers)) {
            dolog('No auto triggers');
        } else {
            dolog('Adding {} auto triggers', count($autoTriggers));
            $OBJECTS_SQL->appendMlComment('AUTO TRIGGERS SECTION');
            /* @var $triggerDi DirItem */
            foreach ($autoTriggers as $triggerDi) {
                dolog('+ {}', $triggerDi->getName());
                $OBJECTS_SQL->appendFile($triggerDi);
            }
        }
        /*
         * Получаем строки с включениями
         */
        $ALL = $DM_SYSOBJECTS->getDirItem(null, 'all.txt')->getFileLines(false);
        if (empty($ALL)) {
            dolog('No includes');
        } else {
            dolog('Adding {} includes from all.txt', count($ALL));
            $OBJECTS_SQL->appendMlComment('INCLUDES SECTION');
            foreach ($ALL as $include) {
                dolog('+ {}', $include);
                $OBJECTS_SQL->appendFile($DM_SYSOBJECTS->getDirItem($include));
            }
        }
        $OBJECTS_SQL->save();
        /*
         * Создаём скрипты инициализации для схем
         */
        foreach (PsConnectionParams::getDefaultConnectionNames() as $connection) {
            if (PsConnectionParams::has($connection, $scope)) {
                $props = PsConnectionParams::get($connection, $scope);
                $database = $props->database();
                if (empty($database)) {
                    continue;
                    //Не задана БД - пропускаем (для root)
                }
                LOGBOX('Making schema script for {}', $props);
                $SCHEMA_SQL = $DM_AUTO->getDirItem('schemas', $database, 'sql')->makePath()->getSqlFileBuilder();
                //DROP+USE
                $SCHEMA_SQL->clean();
                $SCHEMA_SQL->appendLine("DROP DATABASE IF EXISTS {$database};");
                $SCHEMA_SQL->appendLine("CREATE DATABASE {$database} CHARACTER SET utf8 COLLATE utf8_general_ci;");
                $SCHEMA_SQL->appendLine("USE {$database};");
                if ($scope == ENTITY_SCOPE_PROJ) {
                    dolog('+ SDK PART');
                    //Добавим секцию в лог
                    $SCHEMA_SQL->appendMlComment('>>> SDK');
                    //CREATE CHEMA SCRIPT
                    $SCHEMA_SQL->appendFile($SDK->getDirItem(null, 'schema.sql'));
                    //OBJECTS SCRIPT
                    $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/auto', 'objects.sql'));
                    //Добавим секцию в лог
                    $SCHEMA_SQL->appendMlComment('<<< SDK');
                }
                //CREATE CHEMA SCRIPT
                $SCHEMA_SQL->appendFile($SCHEMA);
                //OBJECTS SCRIPT
                $SCHEMA_SQL->appendFile($OBJECTS_SQL->getDi());
                //CREATE USER
                $grant = "grant all on {}.* to '{}'@'{}' identified by '{}';";
                $SCHEMA_SQL->appendMlComment('Grants');
                $SCHEMA_SQL->appendLine(PsStrings::replaceWithBraced($grant, $database, $props->user(), $props->host(), $props->password()));
                /*
                 * Мы должны создать тестовую схему, чтобы убедиться, что всё хорошо и сконфигурировать db.ini
                 */
                if ($connection == PsConnectionParams::CONN_TEST) {
                    dolog('Making physical schema {}', $props);
                    $rootProps = PsConnectionParams::get(PsConnectionParams::CONN_ROOT);
                    dolog('Root connection props: {}', $rootProps);
                    $rootProps->execureShell($SCHEMA_SQL->getDi());
                    dolog('Connecting to [{}]', $props);
                    PsConnectionPool::configure($props);
                    $tables = PsTable::all();
                    /*
                     * Нам нужно определить новый список таблиц SDK, чтобы по ним 
                     * провести валидацию новых db.ini.
                     * 
                     * Если мы обрабатываем проект, то SDK-шный db.ini уже готов и 
                     * можем положиться на него. Если мы подготавливаем SDK-шный db.ini,
                     * но новый список таблиц возмём из развёрнутой тестовой БД.
                     */
                    $sdkTableNames = $scope == ENTITY_SCOPE_SDK ? array_keys($tables) : DbIni::getSdkTables();
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        //Уберём из всех таблиц - SDK`шные
                        array_remove_keys($tables, $sdkTableNames);
                    }
                    $scopeTableNames = array_keys($tables);
                    sort($scopeTableNames);
                    /*
                     * Составим список таблиц.
                     * Он нам особенно не нужен, но всёже будем его формировать для наглядности - какие таблицы добавились.
                     */
                    $tablesDi = $DM_AUTO->getDirItem(null, 'tables.txt')->putToFile(implode("\n", $scopeTableNames));
                    dolog('Tables: {} saved to {}', print_r($scopeTableNames, true), $tablesDi->getAbsPath());
                    /*
                     * Загружаем полный список таблиц схемы и на основе имеющихся db.ini файлов строим новые, добавляя/удаляя 
                     * таблицы, добавленные/удалённые из схемы.
                     */
                    $dbIniProps = PsDbIniHelper::makeDbIniForSchema($scope, $tables);
                    dolog('db.ini props: {}', print_r($dbIniProps, true));
                    $dbIniErrors = PsDbIniHelper::validateAndSaveDbIniTableProps($scope, $dbIniProps, $sdkTableNames);
                    if ($dbIniErrors) {
                        PsUtil::raise('db.ini errors for {}: {}', $scope, print_r($dbIniErrors, true));
                    }
                    /*
                     * Для проекта выгружаем данные, хранящиеся в файлах
                     */
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        dolog('Exporting tables data from files');
                        $DM_AUTO->getDirItem('data')->makePath();
                        $AUTO_DATA_SQL = $DI_AUTO_DATA->touch()->getSqlFileBuilder();
                        //Пробегаемся по таблицам
                        foreach (DbIni::getTables() as $tableName) {
                            $table = PsTable::inst($tableName);
                            if ($table->isFilesync()) {
                                $fileData = $table->exportFileAsInsertsSql();
                                if ($fileData) {
                                    dolog(' + {}', $tableName);
                                    $AUTO_DATA_SQL->appendFile($DM_AUTO->getDirItem('data', $tableName, 'sql')->putToFile($fileData));
                                } else {
                                    dolog(' - {}', $tableName);
                                }
                            }
                        }
                        $AUTO_DATA_SQL->save();
                        /*
                         * Вставим данные в тестовую схему
                         */
                        dolog('Inserting data to test schema.');
                        $props->execureShell($DI_AUTO_DATA);
                    }
                    /*
                     * Теперь ещё создадим тестовые объекты.
                     * Мы уверены, что для SDK тестовая часть есть всегда.
                     */
                    $TEST_SCHEMA_SQL = $DM_AUTO->getDirItem('test', 'schema', 'sql')->makePath()->getSqlFileBuilder();
                    if ($scope == ENTITY_SCOPE_PROJ) {
                        dolog('+ SDK TEST PART');
                        //Добавим секцию в лог
                        $TEST_SCHEMA_SQL->appendMlComment('>>> SDK');
                        //CREATE CHEMA SCRIPT
                        $TEST_SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/auto/test', 'schema.sql'));
                        //Добавим секцию в лог
                        $TEST_SCHEMA_SQL->appendMlComment('<<< SDK');
                    }
                    $TEST_SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'schema.sql'), false);
                    $TEST_SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'data.sql'), false);
                    $TEST_SCHEMA_SQL->save();
                    /*
                     * На тестовой схеме прогоняем скрипты с тестовыми данными
                     */
                    dolog('Making test schema objects.');
                    $props->execureShell($TEST_SCHEMA_SQL->getDi());
                }
                #end conn== TEST
                /*
                 * Если были сгенерированы данные из файлов - добавляем их
                 */
                if ($DI_AUTO_DATA->isFile() && $DI_AUTO_DATA->getSize() > 0) {
                    dolog('Append data inserts to {}', $SCHEMA_SQL->getDi()->getName());
                    $SCHEMA_SQL->appendFile($DI_AUTO_DATA);
                }
                //SAVE .sql
                $SCHEMA_SQL->save();
            }
        }
    }
    dolog('Database schemas successfully exported');
}
Beispiel #10
0
 /**
  * Основной метод, выполняющий загрузку содержимого тестовой страницы
  */
 private function getContentImpl(RequestArrayAdapter $params, Smarty $smarty)
 {
     //Силовые упражнения
     $exId = $params->int('ex_id');
     if ($exId) {
         //$ex = GymManager::getInstance()->getExercise($exId);
         $tplPath = "gym/exercises/{$exId}.tpl";
         return $smarty->templateExists($tplPath) ? $smarty->fetch($tplPath) : null;
     }
     //Специальные страницы
     $pageType = $params->str('pagetype');
     if ($pageType) {
         $smParams = array();
         switch ($pageType) {
             case 'smarty':
                 foreach (array('blocks', 'functions', 'modifiers') as $type) {
                     $items = DirManager::smarty('plugins/' . $type)->getDirContentFull(null, PsConst::EXT_PHP);
                     /* @var $item DirItem */
                     foreach ($items as $item) {
                         //Название
                         $name = explode('.', $item->getName());
                         $name = $name[1];
                         //Первый комментарий
                         $tokens = token_get_all($item->getFileContents());
                         $comment = array(T_COMMENT, T_DOC_COMMENT);
                         $fileComment = '';
                         foreach ($tokens as $token) {
                             if (in_array($token[0], $comment)) {
                                 $fileComment = trim($token[1]);
                                 break;
                             }
                         }
                         $smParams[$type][] = array('name' => $name, 'comment' => $fileComment);
                     }
                 }
                 break;
             case 'doubleimg':
                 $images = DirManager::images()->getDirContentFull(null, DirItemFilter::IMAGES);
                 $sorted = array();
                 /* @var $img DirItem */
                 foreach ($images as $img) {
                     $ident = $img->getSize() . 'x' . $img->getImageAdapter()->getWidth() . 'x' . $img->getImageAdapter()->getHeight();
                     $sorted[$ident][] = $img;
                 }
                 $result = array();
                 /* @var $img DirItem */
                 foreach ($sorted as $ident => $imgs) {
                     if (count($imgs) > 1) {
                         $result[$ident] = $imgs;
                     }
                 }
                 $smParams = array('images' => $result);
                 break;
             case 'testmethods':
                 $smParams['methods'] = TestManagerCaller::getMethodsList();
                 break;
             case 'imgbysize':
                 $images = DirManager::images()->getDirContentFull(null, DirItemFilter::IMAGES, array('GymExercises'));
                 DirItemSorter::inst()->sort($images, DirItemSorter::BY_SIZE);
                 $smParams = array('images' => $images);
                 break;
             case 'formules':
                 $formules = TexImager::inst()->getAllFormules();
                 $totalSize = 0;
                 /* @var $formula DirItem */
                 foreach ($formules as $formula) {
                     $totalSize += $formula->getSize();
                     $formula->setData('class', 'TeX');
                 }
                 DirItemSorter::inst()->sort($formules, DirItemSorter::BY_SIZE);
                 $smParams = array('formules' => $formules, 'formules_size' => $totalSize);
                 break;
         }
         $content = $smarty->fetch("test/page_{$pageType}.tpl", $smParams);
         if ($pageType) {
             switch ($pageType) {
                 case 'patterns':
                     $out = array();
                     preg_match_all("/===(.*?)===/", $content, $out, PREG_PATTERN_ORDER);
                     $params = array();
                     for ($i = 0; $i < count($out[0]); $i++) {
                         $full = $out[0][$i];
                         $ctt = $out[1][$i];
                         $params[$full] = "<div class=\"demo-head\">{$ctt}</div>";
                     }
                     $content = PsStrings::replaceMap($content, $params);
             }
         }
         return $content;
     }
     //Тестовая страница
     $num = $params->int('num');
     $num = $num ? $num : 1;
     return $smarty->fetch("test/page{$num}.tpl");
 }
Beispiel #11
0
/**
 * Процесс строит скрипты разворачивания БД
 * 
 * @param array $argv
 */
function executeProcess(array $argv)
{
    /*
     * СОЗДАЁМ SQL
     * 
     * Нам нужны настройки таблиц, которые неоткуда взять, кроме как из базы, поэтому для экспорта данных нужна БД.
     */
    $DB = DirManager::inst(__DIR__ . '/temp');
    $SDK = DirManager::inst(__DIR__ . '/temp/ps-sdk');
    //Почистим файлы, которые нам не интересны
    $cleanExt = array(PsConst::EXT_TXT, PsConst::EXT_SQL);
    dolog('Clearing not {} files from temp dir', array_to_string($cleanExt));
    /* @var $item DirItem */
    foreach ($DB->getDirContentFull(null, DirItemFilter::FILES) as $item) {
        if (!$item->checkExtension($cleanExt)) {
            dolog('[-] {}', $item->remove()->getRelPath());
        }
    }
    //Пробежимся по скоупам и выполним обработку
    /* @var $DIR DirManager */
    foreach (array(ENTITY_SCOPE_SDK => $SDK, ENTITY_SCOPE_PROJ => $DB) as $scope => $DM) {
        dolog();
        dolog('***************************** SCOPE [{}] *****************************', $scope);
        dolog('Working directory: [{}]', $DM->absDirPath());
        $SCHEMA = $DM->getDirItem(null, 'schema', PsConst::EXT_SQL);
        if (!$SCHEMA->isFile()) {
            dolog('schema.sql is not exists, skipping');
            continue;
            //---
        }
        //Директория с системными объектами
        $DM_SYSOBJECTS = DirManager::inst($DM->absDirPath(), 'sysobjects');
        //Директория, в которой будет содержимое для автосгенерированных файлов
        $DM_BUILD = DirManager::inst($DM->absDirPath(), 'build')->clearDir();
        //Создадим ссылку на файл с объектами
        $DM_BUILD_ALL_SQL = $DM_BUILD->getDirItem(null, 'all', PsConst::EXT_SQL)->getSqlFileBuilder();
        //Строим objects.sql
        dolog('Processing all.sql');
        /*
         * Получаем строки с включениями в objects.sql
         */
        $ALL_LINES = $DM_SYSOBJECTS->getDirItem(null, 'all', PsConst::EXT_TXT)->getFileLines(false);
        if (empty($ALL_LINES)) {
            dolog('No includes');
        } else {
            dolog('Adding {} includes from all.txt', count($ALL_LINES));
            foreach ($ALL_LINES as $include) {
                dolog('+ {}', $include);
                $DM_BUILD_ALL_SQL->appendFile($DM_SYSOBJECTS->getDirItem($include));
            }
        }
        // << Сохраняем objects.sql
        $DM_BUILD_ALL_SQL->save();
        /*
         * Создаём скрипты инициализации для схем
         */
        dolog('Processing default connection names: {}', array_to_string(array_values(PsConnectionParams::getDefaultConnectionNames())));
        foreach (PsConnectionParams::getDefaultConnectionNames() as $connection) {
            //На момент обработки скоупа мы не должны быть подключены никуда
            PsConnectionPool::assertDisconnectied();
            //Для данного скоупа не задан коннект? Пропускаем...
            if (PsConnectionParams::CONN_ROOT == $connection) {
                dolog('Skip {}', $connection);
                continue;
                //---
            }
            if (!PsConnectionParams::has($connection, $scope)) {
                dolog('No connection properties for {}', $connection);
                continue;
                //---
            }
            //Поработаем с настройками
            $props = PsConnectionParams::get($connection, $scope);
            $database = $props->database();
            if (empty($database)) {
                continue;
                //Не задана БД - пропускаем (для root)
            }
            dolog('Making schema script for {}', $props);
            $SCHEMA_DI = $DM_BUILD->getDirItem('schemas', $database, PsConst::EXT_SQL)->makePath();
            check_condition(!$SCHEMA_DI->isFile(), 'Schema file for database "{}" is already exists. Dublicate database names?', $database);
            $SCHEMA_SQL = $SCHEMA_DI->getSqlFileBuilder();
            //DROP+USE
            $SCHEMA_SQL->clean();
            $SCHEMA_SQL->appendLine("DROP DATABASE IF EXISTS {$database};");
            $SCHEMA_SQL->appendLine("CREATE DATABASE {$database} CHARACTER SET utf8 COLLATE utf8_general_ci;");
            $SCHEMA_SQL->appendLine("USE {$database};");
            //CREATE USER
            $grant = "grant all on {}.* to '{}'@'{}' identified by '{}';";
            $SCHEMA_SQL->appendMlComment('Create user with grants');
            $SCHEMA_SQL->appendLine(PsStrings::replaceWithBraced($grant, $database, $props->user(), $props->host(), $props->password()));
            if ($scope == ENTITY_SCOPE_PROJ) {
                dolog('+ SDK PART');
                //Добавим секцию в лог
                $SCHEMA_SQL->appendMlComment('>>> SDK');
                //CREATE CHEMA SCRIPT
                $SCHEMA_SQL->appendFile($SDK->getDirItem(null, 'schema', PsConst::EXT_SQL));
                //OBJECTS SCRIPT
                $SCHEMA_SQL->appendFile($SDK->getDirItem('build', 'all', PsConst::EXT_SQL));
                //Добавим секцию в лог
                $SCHEMA_SQL->appendMlComment('<<< SDK');
            }
            //CREATE CHEMA SCRIPT
            $SCHEMA_SQL->appendFile($SCHEMA);
            //OBJECTS SCRIPT
            $SCHEMA_SQL->appendFile($DM_BUILD_ALL_SQL->getDi());
            /*
             * Мы должны создать тестовую схему, чтобы убедиться, что всё хорошо и сконфигурировать db.ini
             */
            if ($connection != PsConnectionParams::CONN_TEST) {
                //Всё, сохраняем скрипт, работа закончена
                $SCHEMA_SQL->save();
                continue;
                //---
            }
            /*
             * На тестовой схеме прогоняем скрипт
             */
            dolog('Making physical schema {}', $props);
            $rootProps = PsConnectionParams::get(PsConnectionParams::CONN_ROOT);
            dolog('Root connection props: {}', $rootProps);
            $rootProps->execureShell($SCHEMA_SQL->getDi());
            dolog('Connecting to [{}]', $props);
            PsConnectionPool::configure($props);
            $tables = PsTable::all();
            /*
             * Нам нужно определить новый список таблиц SDK, чтобы по ним 
             * провести валидацию новых db.ini.
             * 
             * Если мы обрабатываем проект, то SDK-шный db.ini уже готов и 
             * можем положиться на него. Если мы подготавливаем SDK-шный db.ini,
             * но новый список таблиц возмём из развёрнутой тестовой БД.
             */
            $sdkTableNames = $scope == ENTITY_SCOPE_SDK ? array_keys($tables) : $SDK->getDirItem('build', 'tables', PsConst::EXT_TXT)->getFileLines();
            if ($scope == ENTITY_SCOPE_PROJ) {
                //Уберём из всех таблиц - SDK`шные
                array_remove_keys($tables, $sdkTableNames);
            }
            $scopeTableNames = array_keys($tables);
            sort($scopeTableNames);
            /*
             * Составим список таблиц.
             * Он нам особенно не нужен, но всёже будем его формировать для наглядности - какие таблицы добавились.
             */
            $TABLES_DI = $DM_BUILD->getDirItem(null, 'tables', PsConst::EXT_TXT)->touch()->putToFile(implode("\n", $scopeTableNames));
            dolog('Tables saved to {}: {}', $TABLES_DI->getRelPath(), print_r($scopeTableNames, true));
            /*
             * Выгрузим данные из таблиц в файл, чтобы убедиться, что всё корректно вставилось.
             */
            if ($scopeTableNames) {
                dolog("Exporting '{}' schema tables data to file", $database);
                $DATA_DI_SQL = $DM_BUILD->getDirItem(null, 'data', PsConst::EXT_SQL)->getSqlFileBuilder();
                $DATA_DI_SQL->clean();
                //Пробегаемся по таблицам
                foreach ($scopeTableNames as $tableName) {
                    $fileData = PsTable::inst($tableName)->exportAsSqlString();
                    if ($fileData) {
                        dolog(' + {} [not empty]', $tableName);
                        $DATA_DI_SQL->appendMlComment('+ table ' . $tableName);
                        $DATA_DI_SQL->appendLine($fileData);
                    } else {
                        dolog(' - {} [empty]', $tableName);
                    }
                }
                $DATA_DI_SQL->save();
            }
            /*
             * Теперь ещё создадим тестовые объекты.
             * Для каждого скоупа свои тестовые данные, так что таблицы можно называть одинаково.
             */
            dolog('Add test part');
            $SCHEMA_SQL->appendMlComment('Test part');
            /*
             if ($scope == ENTITY_SCOPE_PROJ) {
             dolog('+ SDK TEST PART');
            
             //Добавим секцию в лог
             $SCHEMA_SQL->appendMlComment('>>> SDK TEST PART');
            
             //CREATE CHEMA SCRIPT
             $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/test', 'schema', PsConst::EXT_SQL));
            
             //ADD TEST DATA
             $SCHEMA_SQL->appendFile($SDK->getDirItem('sysobjects/test', 'data', PsConst::EXT_SQL));
            
             //Добавим секцию в лог
             $SCHEMA_SQL->appendMlComment('<<< SDK TEST PART');
             }
            */
            $SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'schema', PsConst::EXT_SQL), false);
            $SCHEMA_SQL->appendFile($DM_SYSOBJECTS->getDirItem('test', 'data', PsConst::EXT_SQL), false);
            $SCHEMA_SQL->save();
            #end conn== TEST
            /*
             * Всё, сохраняем финальный скрипт
             */
            //SAVE .sql
            $SCHEMA_SQL->save();
            //Переразвернём тестовую схему с тестовыми таблицами
            dolog("Rebuilding checma '{}'", $database);
            $rootProps->execureShell($SCHEMA_SQL->getDi());
            //Отключимся от схемы
            PsConnectionPool::disconnect();
        }
    }
    dolog('Database schemas successfully exported');
}
Beispiel #12
0
function executeProcess(array $argv)
{
    $CLASS_PATTERN = file_get_contents(file_path(__DIR__, 'class.txt'));
    $METHOD_PATTERN = file_get_contents(file_path(__DIR__, 'method.txt'));
    /*
     * Название тестового файла.
     * Для проверки мы сначала удалим класс для него, если он был, потом проверим, что за класс был сгенерирован.
     */
    $TEST_MESSAGES_FILE = 'ExampleSdkProcessMessages';
    //Убедимся, что тестовый .msgs существует и удалим тестовый .php файл
    $TEST_PHP_DI = DirItem::inst(__DIR__ . '/classes', $TEST_MESSAGES_FILE, PsConst::EXT_PHP)->remove();
    $TEST_MSGS_DI = DirItem::inst(__DIR__ . '/classes', $TEST_MESSAGES_FILE, PsConst::EXT_MSGS);
    check_condition($TEST_MSGS_DI->isFile(), "File {$TEST_MSGS_DI->getAbsPath()} must exists");
    dolog('Loading all files, ended with Messages.msgs');
    //TODO - после нужно получать эту информацию из какого-нибудь места
    $exceptDirs[] = DirManager::autogen()->relDirPath();
    $exceptDirs[] = DirManager::resources()->relDirPath();
    $exceptDirs[] = DirManager::stuff()->relDirPath();
    //$exceptDirs = array();
    $items = DirManager::inst()->getDirContentFull(null, function (DirItem $di) {
        dolog($di->getAbsPath());
        return $di->isFile() && ends_with($di->getName(), 'Messages.msgs');
    }, $exceptDirs);
    dolog('Message files for processing: {}', count($items));
    //Проверим, что был выбран тестовый файл
    check_condition(in_array($TEST_MSGS_DI, $items, true), "Test file [{$TEST_MESSAGES_FILE}] is not included");
    //Удалим его из массива...
    array_remove_value($items, $TEST_MSGS_DI, true);
    //И поместим наверх, чтобы он был обработан первым
    array_unshift($items, $TEST_MSGS_DI);
    /* @var $msgsDi DirItem */
    foreach ($items as $msgsDi) {
        dolog('PROCESSING [{}]', $msgsDi->getAbsPath());
        //Сбросим методы
        $METHODS = array();
        //Извлечём название класса
        $CLASS = $msgsDi->getNameNoExt();
        //DirItem файла с сообщениями php
        $classDi = DirItem::inst($msgsDi->getDirname(), $CLASS, PsConst::EXT_PHP);
        //Получаем сообщения из файла .msgs
        $messages = $msgsDi->getFileAsProps();
        foreach ($messages as $MSG_KEY => $MGG_VALUE) {
            dolog(' >> {}={}', $MSG_KEY, $MGG_VALUE);
            //Получим список всех параметров из макросов ({0}, {1}, {2} и т.д.)
            preg_match_all("/\\{(.+?)\\}/", $MGG_VALUE, $args);
            $args = array_values(array_unique($args[1]));
            sort($args, SORT_NUMERIC);
            $ARGS = array();
            for ($index = 0; $index < count($args); $index++) {
                $arg = $args[$index];
                $lineDescr = PsStrings::replaceWithBraced('[{}] in line [{}={}]', $msgsDi->getRelPath(), $MSG_KEY, $MGG_VALUE);
                check_condition(is_inumeric($arg), "Invalid argument [{$arg}] for {$lineDescr}");
                check_condition($index == $args[$index], "Missing index [{$index}] for {$lineDescr}");
                $ARGS[] = '$p' . $index;
            }
            $ARGS = join(', ', $ARGS);
            //Добавляем метод
            dolog(" A: {}::{} ({})", $CLASS, $MSG_KEY, $ARGS);
            $PARAMS['SUPPORT_CLASS'] = PsMsgs::getClass();
            $PARAMS['MESSAGE'] = $MGG_VALUE;
            $PARAMS['FUNCTION'] = $MSG_KEY;
            $PARAMS['ARGS'] = $ARGS;
            $METHODS[] = PsStrings::replaceMapBracedKeys($METHOD_PATTERN, $PARAMS);
        }
        dolog('Made methods: ({})', count($METHODS));
        if ($METHODS) {
            $PARAMS['FILE'] = $msgsDi->getAbsPath();
            $PARAMS['CLASS'] = $CLASS;
            $PARAMS['DATE'] = date(DF_PS);
            $PARAMS['METHODS'] = "\n" . join("\n\n", $METHODS) . "\n";
            $CLASS_PHP = PsStrings::replaceMapBracedKeys($CLASS_PATTERN, $PARAMS);
            $classDi->putToFile($CLASS_PHP);
        }
        /*
         * Если обрабатываем тестовый файл - проверим его
         */
        //TEST CLASS VALIDATION START >>>
        if ($msgsDi->equals($TEST_MSGS_DI)) {
            dolog('');
            dolog('Validating test class {}', $TEST_MESSAGES_FILE);
            //Проверим, что .php был сгенерирован
            check_condition($TEST_PHP_DI->isFile(), "File {$TEST_PHP_DI->getAbsPath()} was not created!");
            //Проверим, что для каждого сообщения был создан метод
            $methods = PsUtil::newReflectionClass($TEST_MESSAGES_FILE)->getMethods();
            $messages = $TEST_MSGS_DI->getFileAsProps();
            check_condition(count($methods) == count($messages), 'Methods count missmatch, check ' . $TEST_PHP_DI->getAbsPath());
            /* @var $method ReflectionMethod */
            foreach ($methods as $method) {
                check_condition(array_key_exists($method->getName(), $messages), "No method {$TEST_MESSAGES_FILE}::" . $method->getName());
            }
            //Проверим, что возвращают методы тестового сгенерированного класса
            function doTest($className, $methodName, array $params, $expected)
            {
                $method = "{$className}::{$methodName}";
                $actual = call_user_func_array($method, $params);
                dolog("{}({})='{}', Expected='{}'", $method, join(', ', $params), $actual, $expected);
                check_condition($actual == $expected, "{$actual} != {$expected}");
            }
            doTest($TEST_MESSAGES_FILE, 'message1', array(), 'Message 1');
            doTest($TEST_MESSAGES_FILE, 'message2', array('a', 'b', 'c'), 'Parametred a,c,b');
            dolog('Test class is valid!');
        }
        //TEST CLASS VALIDATION END <<<
    }
    //# DirItems validation end
}
Beispiel #13
0
 /**
  * Метод выбрасывает ошибку, заменяя {} последовательно на параметры
  */
 public static function raise($msg, $param1 = null, $param2 = null)
 {
     $params = func_get_args();
     if (count($params) > 1) {
         unset($params[0]);
         $msg = PsStrings::replaceWithParams('{}', $msg, $params);
     }
     raise_error($msg);
 }
Beispiel #14
0
 private function checkCombination(array $char2num)
 {
     $expr = PsStrings::replaceMap($this->EXPR, $char2num);
     $res = PsMathEvaluator::inst()->e($expr);
     if ($res === false) {
         $error = 'Ошибка обработки ребуса: ' . PsMathEvaluator::inst()->lastError();
         $this->LOGGER->info($error);
         raise_error($error);
     }
     if ($res == 0) {
         $combination = PsStrings::replaceMap($this->REBUS, $char2num);
         $this->COMBINATIONS[] = $combination;
         $this->LOGGER->info($combination);
     }
     ++$this->cnt;
 }
Beispiel #15
0
 /**
  * В конструкторе пробежимся по всем хранилищам и соберём все фолдинги
  */
 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();
     }
 }