/** * Процесс выполняет периодические задачи cron * * @param array $argv */ function executeProcess(array $argv) { $SYNC_DIR = 'd:/Zona Downloads/Архив пранкоты/'; $lists = DirManager::inst(__DIR__)->getDirContent('m3u', PsConst::EXT_M3U); $filesCopied = DirItem::inst(__DIR__, 'all_copied', 'list')->remove()->touch(); $filesSkipped = DirItem::inst(__DIR__, 'all_skipped', 'list')->remove()->touch(); $destDir = DirManager::inst(__DIR__, 'dest')->clearDir()->makePath(); /* @var $list DirItem */ foreach ($lists as $name => $list) { $name = mb_convert_encoding($name, 'UTF-8', 'cp1251'); dolog("+ {$name}"); foreach ($list->getFileLines() as $newFile) { $newFile = mb_convert_encoding($newFile, 'UTF-8', 'UTF-8'); if (starts_with($newFile, '#')) { dolog(" - {$newFile}"); continue; //--- } $absPath = next_level_dir($SYNC_DIR, $newFile); $absPath = iconv('UTF-8', 'cp1251', $absPath); $isFile = is_file($absPath); dolog(" + {$newFile} ? {}", var_export($isFile, true)); if (!$isFile) { $filesSkipped->writeLineToFile($absPath); continue; //--- } $fileName = iconv('UTF-8', 'cp1251', basename($newFile)); copy($absPath, $destDir->absFilePath(null, $fileName)); $filesCopied->writeLineToFile($absPath); } //print_r($list->getFileLines()); } }
private function generateImpl() { $images = DirManager::inst('ps-addon/crop')->getDirContent('oboi', DirItemFilter::FILES); for ($i = 0; $i < rand(2000, 3000); $i++) { $img = $images[array_rand($images)]; echo PsHtml::img(array('src' => PsImgEditor::resize($img, '60x60', null))); } }
/** * Процесс строит скрипты для вставки ячеек в БД * * @param array $argv */ function executeProcess(array $argv) { $DM = DirManager::inst(array(__DIR__, 'output')); $customNum = $argv[1]; dolog('Processing mosaic demo, custom num={}', $customNum); /* @var $dir DirItem */ foreach ($DM->getDirContent(null, DirItemFilter::DIRS) as $dir) { if (is_inumeric($customNum) && $customNum != $dir->getName()) { continue; //---- } $imgDM = DirManager::inst($dir->getAbsPath()); $imgDI = end($imgDM->getDirContent(null, DirItemFilter::IMAGES)); $map = $imgDM->getDirItem(null, 'map', 'txt')->getFileAsProps(); $demoDM = DirManager::inst($imgDM->absDirPath(), 'demo'); $demoDM->clearDir(); dolog("Building map for: [{}].", $imgDI->getRelPath()); //CELLS BINDING $dim = $imgDM->getDirItem(null, 'settings', 'txt')->getFileAsProps(); $dim = $dim['dim']; $dim = explode('x', $dim); $cw = 1 * $dim[0]; $ch = 1 * $dim[1]; $sourceImg = SimpleImage::inst()->load($imgDI); $w = $sourceImg->getWidth(); $h = $sourceImg->getHeight(); $destImg = SimpleImage::inst()->create($w, $h, MosaicImage::BG_COLOR); dolog("Img size: [{$w} x {$h}]."); check_condition($w > 0 && !($w % $cw), 'Bad width'); check_condition($h > 0 && !($h % $ch), 'Bad height'); $totalCells = count($map); $lengtn = strlen("{$totalCells}"); //dolog("Cells cnt: [$xcells x $ycells], total: $totalCells."); //СТРОИМ КАРТИНКИ $secundomer = Secundomer::startedInst(); //$encoder = new PsGifEncoder(); for ($cellCnt = 0; $cellCnt <= $totalCells; $cellCnt++) { $name = pad_zero_left($cellCnt, $lengtn); $copyTo = $demoDM->absFilePath(null, $name, 'jpg'); if ($cellCnt > 0) { $cellParams = $map[$cellCnt]; $cellParams = explode('x', $cellParams); $xCell = $cellParams[0]; $yCell = $cellParams[1]; $x = ($xCell - 1) * $cw; $y = ($yCell - 1) * $ch; $destImg->copyFromAnother($sourceImg, $x, $y, $x, $y, $cw, $ch); } $destImg->save($copyTo); dolog("[{$totalCells}] {$copyTo}"); } //$encoder->saveToFile($demoDM->absFilePath(null, 'animation')); $secundomer->stop(); dolog('Execution time: ' . $secundomer->getTotalTime()); } }
/** * Возвращает названия всех классов в директории */ public static function getDirClassNames($__DIR__, $subDir, $parent) { $classes = array(); foreach (DirManager::inst($__DIR__)->getDirContent($subDir, PsConst::EXT_PHP, DirManager::DC_NAMES_NO_EXT) as $name) { if (PsUtil::isInstanceOf($name, $parent)) { $classes[] = $name; } } return $classes; }
/** * Получает ссылку на файл с конфигом .ini */ private static function getIniDi($scope) { switch ($scope) { case ENTITY_SCOPE_SDK: return DirManager::inst(PS_DIR_INCLUDES)->getDirItem(DirManager::DIR_CONFIG, self::getConfigName()); case ENTITY_SCOPE_PROJ: return DirManager::inst(PS_DIR_ADDON)->getDirItem(DirManager::DIR_CONFIG, self::getConfigName()); } PsUtil::raise('Invalid scope [{}] for method {}::{}', $scope, __CLASS__, __FUNCTION__); }
/** * Метод для очистки кучи перед выполнением тестов */ public static function cleanScrap($absPath = null) { $dm = DirManager::inst($absPath ? $absPath : DirManagerTestHelper::scrapAbsPath()); /* @var $di DirItem */ foreach ($dm->getDirContent() as $name => $di) { if ($di->isDir()) { self::cleanScrap($di->getAbsPath()); } if (array_key_exists($name, self::$SCRAP)) { continue; //--- } $di->remove(); } }
/** * Метод регистрирует директорию, как доступную для поиска и подключения классов * * @param type $dirName - название директории (одна из констант DIR_ данного класса) */ public function registerBaseDir($path, $required = true) { //Получим DirManager, соответствующий нашей директории $dm = DirManager::inst($path); //Проверим - может уже подключили? if (array_key_exists($dm->relDirPath(), $this->DIRS)) { return; //--- } $dirAbsPath = $dm->absDirPath(); //Проверим, является ли путь - директорией if (!$dm->isDir()) { check_condition(!$required, "Invalid class path dir given: [{$dirAbsPath}]"); return; //--- } //Отлогируем $this->LOGGER->infoBox("CLASS PATH DIR [{$dirAbsPath}] REGISTERED"); //Сохраним ссылку на директорию $this->DIRS[$dm->relDirPath()] = new AutoloadDir($dm); }
/** * Конвертирует картинки в .png * * @param array $argv */ function executeProcess(array $argv) { $SRC_DIR = 'source'; $OUT_DIR = 'output'; $dm = DirManager::inst(__DIR__); //Создадим $SRC_DIR $dm->makePath($SRC_DIR); //Перенесём все картинки из корня в $SRC_DIR $items = $dm->getDirContent(null, DirItemFilter::IMAGES); /* @var $img DirItem */ foreach ($items as $img) { $img->copyTo($dm->absFilePath($SRC_DIR, $img->getName()))->remove(); } //Очистим $OUT_DIR $dm->clearDir($OUT_DIR)->makePath($OUT_DIR); //Список картинок $items = $dm->getDirContent($SRC_DIR, DirItemFilter::IMAGES); /* @var $img DirItem */ foreach ($items as $img) { SimpleImage::inst()->load($img)->resizeSmart(36, 36)->save($dm->absFilePath($OUT_DIR, $img->getNameNoExt(), 'png'), IMAGETYPE_PNG)->close(); } }
public function saveCommentsFormules2Zip() { $formules = $this->getAllComments(); if (empty($formules)) { return null; //--- } $zipDi = DirManager::inst('admin/stuff', 'zip')->getDirItem(null, 'posts-comments', 'zip')->remove(); $zip = $zipDi->startZip(); $totalSize = 0; /** @var $imgDi DirItem */ foreach ($formules as $imgDi) { $imgDi->setData('class', 'TeX'); $totalSize += $imgDi->getSize(); $name = $imgDi->getName(); $path = 'formules/f' . $name[0] . '/f' . $name[1] . '/f' . $name[2] . '/'; $zip->addFile($imgDi->getAbsPath(), $imgDi->getRelPath()); $zip->addFile($imgDi->getAbsPath() . '.tex', $imgDi->getRelPath() . '.tex'); } $zip->close(); return array('zip' => $zipDi, 'formules' => $formules, 'imagesSize' => $totalSize); }
<?php /* * Выполняет обработку. */ require_once '../ToolsResources.php'; $CALLED_FILE = __FILE__; $SRC_DIR = 'source'; $OUT_DIR = 'output'; $dm = DirManager::inst(__DIR__); //Создадим $SRC_DIR $dm->makePath($SRC_DIR); //Перенесём все картинки из корня в $SRC_DIR $items = $dm->getDirContent(null, DirItemFilter::IMAGES); foreach ($items as $img) { copy($img->getAbsPath(), $dm->absFilePath($SRC_DIR, $img->getName())); $img->remove(); } //Удалим из $SRC_DIR всё, кроме *.bat и *.php $items = $dm->getDirContent(null, DirItemFilter::FILES); foreach ($items as $file) { if (!$file->checkExtension(array('bat', 'php'))) { $file->remove(); } } //Очистим $OUT_DIR $items = $dm->getDirContent($OUT_DIR, DirItemFilter::IMAGES); foreach ($items as $img) { $img->remove(); } $items = $dm->getDirContent($SRC_DIR, DirItemFilter::IMAGES);
/** * Процесс строит скрипты разворачивания БД * * @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'); }
/** * DirManager директории, в которой находится основная функциональность для работы с фолдингами * @return DirManager */ public function getFoldedDir() { return DirManager::inst(__DIR__); }
private function __construct() { $this->CLASS = get_called_class(); $this->CACHE = new SimpleDataCache(); $this->DBTYPE = $this->isStoreToDb() ? $this->CLASS : null; $this->DIR_MANAGER = DirManager::inst(array(ConfigIni::uploadsDirRel(), $this->CLASS)); $this->LOGGER = PsLogger::inst($this->CLASS); $this->LOGGER->info('Instance created. Work with db ? {}. Is autonomous ? {}.', var_export($this->isStoreToDb(), true), var_export($this->isAutonomous(), true)); $this->LOGGER->info('Upload dir: [{}].', $this->DIR_MANAGER->relDirPath()); $this->LOGGER->info(); }
/** * Процесс строит скрипты для вставки ячеек в БД * * @param array $argv */ function executeProcess(array $argv) { $DM = DirManager::inst(__DIR__); //Перенесём картинки в директорию со всеми картинками /* @var $img DirItem */ foreach ($DM->getDirContent(null, DirItemFilter::IMAGES) as $img) { $img->copyTo($DM->absFilePath('source', $img->getName())); $img->remove(); } //Очистим директорию с выходными файлами $DM->clearDir('output'); $DM->makePath('output'); //Пробегаемся по картинкам, разбиваем их на ячейки и строим sql для вставки /* @var $img DirItem */ foreach ($DM->getDirContent('source', DirItemFilter::IMAGES) as $img) { $id = $img->getNameNoExt(); //Обрабатываем только картинки с целыми кодами if (is_inumeric($id)) { dolog("Processing img [{$img->getRelPath()}]."); $id = 1 * $id; } else { dolog("Skip img [{$img->getRelPath()}], name is not numeric."); continue; //--- } //Начало обработки $outDm = DirManager::inst(array(__DIR__, 'output'), $id); //Скопируем картинку $img->copyTo($outDm->absFilePath(null, $img->getName())); //Вычислим размеры ячейки $cw = 10; $ch = 10; $dim = $DM->getDirItem('source', $id, 'txt')->getFileAsProps(false); $dim = $dim['dim']; if ($dim) { $dim = explode('x', $dim); $cw = 1 * $dim[0]; $ch = 1 * $dim[1]; } //Скопируем свойства, с которыми она создавалась $outDm->getDirItem(null, 'settings', 'txt')->putToFile('dim=' . $cw . 'x' . $ch); dolog("Cell dimensions: [{$cw} x {$ch}]."); //Размеры картинки получим у самой картинки $w = $img->getImageAdapter()->getWidth(); $h = $img->getImageAdapter()->getHeight(); dolog("Img size: [{$w} x {$h}]."); check_condition($w > 0 && !($w % $cw), 'Bad width'); check_condition($h > 0 && !($h % $ch), 'Bad height'); $xcells = $w / $cw; $ycells = $h / $ch; $totalCells = $xcells * $ycells; dolog("Cells cnt: [{$xcells} x {$ycells}], total: {$totalCells}."); $generator = new MosaicCellsGenerator($totalCells); $secundomer = Secundomer::startedInst(); $sqlDI = $outDm->getDirItem(null, 'fill', 'sql'); $mapDI = $outDm->getDirItem(null, 'map', 'txt'); $sqlImg = "delete from ps_img_mosaic_parts where id_img={$id};"; $sqlDI->writeLineToFile($sqlImg); $sqlImg = "delete from ps_img_mosaic_answers where id_img={$id};"; $sqlDI->writeLineToFile($sqlImg); $sqlImg = "delete from ps_img_mosaic where id_img={$id};"; $sqlDI->writeLineToFile($sqlImg); $sqlImg = "insert into ps_img_mosaic (id_img, w, h, cx, cy, cw, ch) values ({$id}, {$w}, {$h}, {$xcells}, {$ycells}, {$cw}, {$ch});"; $sqlDI->writeLineToFile($sqlImg); for ($cellCnt = 1; $cellCnt <= $totalCells; $cellCnt++) { $cellNum = $generator->getCellNum(); $xCell = $cellNum % $xcells; $xCell = $xCell == 0 ? $xcells : $xCell; $yCell = ($cellNum - $xCell) / $xcells + 1; $sqlCell = "insert into ps_img_mosaic_parts (id_img, n_part, x_cell, y_cell) values ({$id}, {$cellCnt}, {$xCell}, {$yCell});"; $sqlDI->writeLineToFile($sqlCell); $mapDI->writeLineToFile($cellCnt . '=' . $xCell . 'x' . $yCell); } $secundomer->stop(); dolog('Execution time: ' . $secundomer->getTotalTime()); } }
/** * Имплементация тестирования получения содержимого поддиректорий */ private function doTestGetDirContentFull($deepLevel, $filterType, $exceptDirs = array(), $forceEnableDirs = array()) { $dm = DirManager::inst(DirManagerTestHelper::dirsAbsPath()); $dm->cd(DirManagerTestHelper::SCRAP); //Найденные элементы кучи, отфильтрованные по текстовому фильтру (фильтр/расширение) $itemsFound = $dm->getDirContentFull(null, $filterType, $exceptDirs, $forceEnableDirs); //Найденные элементы кучи, отфильтрованные при помощи функции обратного вызова $itemsFoundCallback = $dm->getDirContentFull(null, function (DirItem $di) use($filterType) { return DirItemFilter::filter($filterType, $di); }, $exceptDirs, $forceEnableDirs); $this->assertEquals($itemsFound, $itemsFoundCallback); $itemsFiltered = DirManagerTestHelper::SCRAP_FILTER($filterType); //Проверим, что для фильтра есть проверка $this->assertTrue(count($itemsFound) > 0, 'No items filtered for: ' . $filterType); //Проверим, что было извлечено кол-во элементов по кол-ву вложения кучи $this->assertTrue(count($itemsFound) == count($itemsFiltered) * $deepLevel, "filterType={$filterType}, deepLevel={$deepLevel}"); //Пробежимся по мапу и проверим, что все элементы действительно фильтруются //Параллельно разобъём элементы в группы по названиям $GROUPS = array(); /* @var $item DirItem */ foreach ($itemsFound as $item) { $this->assertTrue(DirItemFilter::filter($filterType, $item)); $this->assertTrue(DirItemFilter::filter(function (DirItem $di) use($filterType) { return DirItemFilter::filter($filterType, $di); }, $item)); //Будем сразу складывать в ассоциативный массив, чтобы потом не думать о проверке уникальности $GROUPS[$item->getName()][$item->getDirname()] = 1; } //Проверим вложенность подпапок. Достаточно проверить, что они не пересекаются foreach ($GROUPS as $pathes) { $this->assertTrue(count($pathes) == $deepLevel); } }
*/ LOGBOX('Set consts'); $props = DirItem::inst(__DIR__, 'consts.txt')->getFileAsProps(); dolog(print_r($props, true)); PsGlobals::inst()->updateProps($props); /* * УДАЛИМ ТЕСТОВЫЕ ДИРЕКТОРИИ */ LOGBOX('Remove test dirs'); $dirs = DirManager::inst()->getDirContentFull(null, DirItemFilter::DIRS); $testDirNames = array('temp', 'orig', '4use', 'tests', 'testcase'); $testDirStartsWith = array('!'); /* @var $dir DirItem */ foreach ($dirs as $dir) { if (in_array($dir->getName(), $testDirNames) || starts_with($dir->getName(), $testDirStartsWith)) { $path = $dir->getAbsPath(); dolog('Removing: ' . $path); DirManager::inst($path)->clearDir(null, true); } } /* * УДАЛИМ АРХИВЫ */ LOGBOX('Remove archivs'); $archivs = DirManager::inst()->getDirContentFull(null, DirItemFilter::ARCHIVES); /* @var $dir DirItem */ foreach ($archivs as $arc) { dolog('Removing: ' . $arc->getAbsPath()); $arc->remove(); } dolog("\nFile actions successfully finished\n");
/** @return DirManager */ public function getResourcesDm($ident, $subDir = null) { return DirManager::inst(FoldedStorage::getEntityChild($this->UNIQUE, $ident, $subDir)); }
public function getSpriteImages() { return DirManager::inst()->getDirContent($this->relPath, DirItemFilter::IMAGES); }
/** * В конструкторе пробежимся по всем хранилищам и соберём все фолдинги */ 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()); } }
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'); }
/** * Непосредственное наполнение */ private function doFill($filterName = null) { $this->LOGGER->info("Loading full content of dir [{}] with [{}] filter.", $this->PATH, PsUtil::toString($filterName)); $this->PROFILER->start('doFill'); /* * На данный момент у нас все директории собраны, остаётся только пробежаться по ним * и взять всё необходимое. * При этом нужно выполнить array_values, так как getDirContent возвращает ассоциативный массив, * а файлы в директориях могут повторяться. */ $RESULT = array(); foreach ($this->DIRS as $dirPath) { $items = DirManager::inst($dirPath)->getDirContent(null, $filterName); $RESULT = array_merge($RESULT, array_values($items)); } $this->LOGGER->info('Loading finished, items count: {}. Taken time: {}sec.', count($RESULT), $this->PROFILER->stop()->getTime()); $this->LOGGER->info(''); return $RESULT; }
} $DM->clearDir('output'); $DM->makePath('output'); $images = $DM->getDirContent('source', DirItemFilter::IMAGES); /** @var DirItem */ foreach ($images as $img) { $id = $img->getNameNoExt(); if (is_numeric($id)) { dolog("Processing img [{$img->getAbsPath()}]."); $id = 1 * $id; } else { dolog("Scip img [{$img->getAbsPath()}], name is not numeric."); continue; } //Начало обработки $outDm = DirManager::inst(array(__DIR__, 'output'), $id); //Скопируем картинку $img->copyTo($outDm->absFilePath(null, $img->getName())); $cw = 10; $ch = 10; $dim = $DM->getDirItem('source', $id, 'txt')->getFileAsProps(false); $dim = $dim['dim']; if ($dim) { $dim = explode('x', $dim); $cw = 1 * $dim[0]; $ch = 1 * $dim[1]; } //Скопируем свойства, с которыми она создавалась $outDm->getDirItem(null, 'settings', 'txt')->writeToFile('dim=' . $cw . 'x' . $ch); dolog("Cell dimensions: [{$cw} x {$ch}]."); $w = $img->getImageAdapter()->getWidth();
/** * Метод создаёт новый фолдинг */ public function makeNewFolding(ArrayAdapter $adapter) { $ifaces = $adapter->arr('ifaces'); $rtypes = $adapter->arr('rtypes'); $type = lowertrim($adapter->str('FoldingType')); $subtype = lowertrim($adapter->str('FoldingSubType')); $group = $adapter->str('FoldingGroup'); $classPrefix = $adapter->str('FoldingClassPrefix'); check_condition($type, 'Не передан тип фолдинга'); check_condition($group, 'Не передана группа для фолдинга'); check_condition($classPrefix, 'Не передан префикс для классов фолдинга'); //TODO - определять директорию для воздания менеджера фолдингов. die('Folding dir is not deffined.'); $classesDi = DirItem::inst(array('sdk/kit', 'folded'), $group); check_condition(!$classesDi->isDir(), "Директория {$classesDi} уже существует"); check_condition(!$classesDi->isFile(), "Элемент {$classesDi} не может быть файлом"); $rtypes = array_intersect(array_keys(PsUtil::getClassConsts('FoldedResources', 'RTYPE_')), $rtypes); $rtypesArr = trim(implode(', self::', $rtypes)); $rtypesArr = $rtypesArr ? "self::{$rtypesArr}" : ''; $hasPhp = in_array('RTYPE_PHP', $rtypes); $classesDm = DirManager::inst($classesDi->getRelPath())->makePath(); $resourcesPatternDmTo = DirManager::resources(array('folded', $group, FoldedResources::PATTERN_NAME)); check_condition(!$resourcesPatternDmTo->isDir(), "Целевая директория {$resourcesPatternDmTo} существует"); $resourcesPatternDmFrom = DirManager::resources(array('folded', FoldedResources::PATTERN_NAME)); check_condition($resourcesPatternDmFrom->isDir(), "Некорректна директория-источник {$resourcesPatternDmFrom}"); $interfaces = array(); foreach ($this->getFoldedInterfaces($ifaces) as $name => $ifaceClass) { $ctt = $ifaceClass->getClassBody(); if ($ctt) { $interfaces[] = "/****************\n\t * {$name}\n\t ****************/\n" . $ctt; } } $smParams = $adapter->getData(); $smParams['rtypes'] = $rtypesArr; $smParams['funique'] = FoldedResources::unique($type, $subtype); $smParams['BaseClass'] = 'Base' . $classPrefix; $smParams['ManagerClass'] = $classPrefix . 'Manager'; $smParams['ResourcesClass'] = $classPrefix . 'Resources'; $smParams['implements'] = $ifaces ? 'implements ' . implode(', ', $ifaces) . ' ' : ''; $smParams['interfaces'] = $interfaces ? implode("\n\n\t", $interfaces) : ''; try { //КЛАССЫ //Resources $tpl = PSSmarty::template(DirItem::inst(array(__DIR__, 'tpls'), 'resources.tpl'), $smParams); $di = $classesDm->getDirItem(null, $smParams['ResourcesClass'], 'php'); $di->writeToFile(trim($tpl->fetch()), true); //Manager $tpl = PSSmarty::template(DirItem::inst(array(__DIR__, 'tpls'), 'manager.tpl'), $smParams); $di = $classesDm->getDirItem(null, $smParams['ManagerClass'], 'php'); $di->writeToFile(trim($tpl->fetch()), true); if ($hasPhp) { //BaseClass $tpl = PSSmarty::template(DirItem::inst(array(__DIR__, 'tpls'), 'baseclass.tpl'), $smParams); $di = $classesDm->getDirItem(null, $smParams['BaseClass'], 'php'); $di->writeToFile(trim($tpl->fetch()), true); } //ШАБЛОН ДЛЯ СУЩНОСТЕЙ $resourcesPatternDmTo->makePath(); foreach ($rtypes as $rtype) { $ext = FoldedResources::resourceTypeToExt(PsUtil::newReflectionClass('FoldedResources')->getConstant($rtype)); $diTo = $resourcesPatternDmTo->getDirItem(null, FoldedResources::PATTERN_NAME, $ext); $diFrom = $resourcesPatternDmFrom->getDirItem(null, FoldedResources::PATTERN_NAME, $ext); if ($ext == PsConst::EXT_PHP) { $diTo->writeToFile(str_replace('eclassnamebase', $smParams['BaseClass'], $diFrom->getFileContents())); continue; } $diFrom->copyTo($diTo); } } catch (Exception $ex) { $classesDm->clearDir(null, true); $resourcesPatternDmTo->clearDir(null, true); throw $ex; } }
require_once '../ToolsResources.php'; require_once 'MosaicCellsGenerator.php'; $CALLED_FILE = __FILE__; $DM = DirManager::inst(array(__DIR__, 'output')); $dirs = $DM->getDirContent(null, DirItemFilter::DIRS); $customNum = getCmdParam(1); /** @var DirItem */ foreach ($dirs as $dir) { if (is_numeric($customNum) && $customNum != $dir->getName()) { continue; } $imgDM = DirManager::inst($dir->getAbsPath()); $imgDI = end($imgDM->getDirContent(null, DirItemFilter::IMAGES)); $map = $imgDM->getDirItem(null, 'map', 'txt')->getFileAsProps(); $demoDM = DirManager::inst($imgDM->absDirPath(), 'demo'); $demoDM->clearDir(); $imgAbs = $imgDI->getAbsPath(); dolog("Building map for: [{$imgAbs}]."); //CELLS BINDING $dim = $imgDM->getDirItem(null, 'settings', 'txt')->getFileAsProps(); $dim = $dim['dim']; $dim = explode('x', $dim); $cw = 1 * $dim[0]; $ch = 1 * $dim[1]; $sourceImg = SimpleImage::inst()->load($imgAbs); $w = $sourceImg->getWidth(); $h = $sourceImg->getHeight(); $destImg = SimpleImage::inst()->create($w, $h, MosaicImage::BG_COLOR); dolog("Img size: [{$w} x {$h}]."); check_condition($w > 0 && !($w % $cw), 'Bad width');
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 }
/** * Метод возвращает экземпляр класса, подключающего библиотеки. * Для переопределения этого класса, на уровне проектного config.ini * должен быть задан другой класс, отвечающий за подключение библиотек. * * Это позволит: * 1. Использовать стандартизованный метод подключения внешних библиотек * 2. Переопределить подключение библиотек из SDK */ public static final function inst() { if (isset(self::$inst)) { return self::$inst; //---- } /* * Получим название класса, отвечающего за подключение библиотек */ $class = ConfigIni::libsIncluder(); /* * Подготовим директории */ $SDK_LIB_DIR = DirManager::inst(PS_DIR_INCLUDES, DirManager::DIR_LIB)->absDirPath(); $PROJ_LIB_DIR = DirManager::inst(PS_DIR_ADDON, DirManager::DIR_LIB)->absDirPath(); /* * Класс подключения библиотек совпадает с базовым */ if (__CLASS__ == $class) { self::$inst = new PsLibs(); self::$inst->SDK_LIB_DIR = $SDK_LIB_DIR; self::$inst->LOGGER = PsLogger::inst($class); self::$inst->LOGGER->info('Libs includer SDK: [{}]', __FILE__); self::$inst->LOGGER->info('Libs directory SDK: [{}]', $SDK_LIB_DIR); return self::$inst; //--- } /* * Нам передан класс, который отличается от SDK */ $classPath = Autoload::inst()->getClassPath($class); if (!PsCheck::isNotEmptyString($classPath)) { return PsUtil::raise('Не удалось найти класс загрузчика библиотек [{}]', $class); } /* * Указанный класс должен быть наследником данного */ if (!PsUtil::isInstanceOf($class, __CLASS__)) { return PsUtil::raise('Указанный загрузчик библиотек [{}] не является наследником класса [{}]', $class, __CLASS__); } self::$inst = new $class(); self::$inst->SDK_LIB_DIR = $SDK_LIB_DIR; self::$inst->PROJ_LIB_DIR = $PROJ_LIB_DIR; self::$inst->LOGGER = PsLogger::inst($class); self::$inst->LOGGER->info('Libs includer CUSTOM: [{}]', $classPath); self::$inst->LOGGER->info('Libs directory SDK: [{}]', $SDK_LIB_DIR); self::$inst->LOGGER->info('Libs directory CUSTOM: [{}]', $PROJ_LIB_DIR); return self::$inst; //--- }