public static function create($zipName, $paths, $reSkip = null) { if (!self::isAvailable()) { throw new ZipException(); } if (!is_writable(dirname($zipName))) { throw new RuntimeException(t('Невозможно создать %name: папка защищена от записи.', array('%name' => $zipName))); } if (file_exists($zipName)) { unlink($zipName); } $z = new ZipArchive(); if (true !== ($res = $z->open($zipName, ZIPARCHIVE::CREATE))) { throw new RuntimeException(t('Не удалось создать архив %name.', array('%name' => $zipName))); } foreach ((array) $paths as $path) { if (is_dir($path)) { $files = os::listFiles($path); } else { $files = os::find($path); } foreach ($files as $file) { if (null === $reSkip or !preg_match($reSkip, $file)) { $z->addFile($file); } } } $z->close(); }
public static function rpc_rebuild(Context $ctx) { // Обновление БД. foreach (os::find('lib/modules/*/*.yml') as $fileName) { $schema = Spyc::YAMLLoad($fileName); Logger::log('applying ' . $fileName, 'module'); if (!empty($schema['tables'])) { foreach ($schema['tables'] as $tableName => $tableInfo) { TableInfo::check($tableName, $tableInfo); } } } $ctx->registry->rebuild(); $ctx->registry->broadcast('ru.molinos.cms.install', array($ctx)); }
/** * Вытаскивает таблицу маршрутизации из .ini файла, если не находит — возвращает пустой массив. */ private function load_ini(Context $ctx) { $raw = array(); foreach ($ctx->config->get('routes', array()) as $k => $v) { $raw['GET/' . $k] = $v; } foreach (os::find('lib', 'modules', '*', 'route.ini') as $iniFile) { foreach (ini::read($iniFile) as $k => $v) { if (is_array($v)) { $raw[$k] = $v; $raw[$k]['static'] = true; } elseif ('dynamic' == $k and false !== strpos($v, '::')) { list($class, $method) = explode('::', $v); if (method_exists($class, $method)) { try { if (is_array($tmp = call_user_func(array($class, $method), $ctx))) { foreach ($tmp as $k => $v) { $raw[$k] = $v; } } } catch (Exception $e) { Logger::log(get_class($e) . ' in ' . $v . '()'); } } } } } // Опрос динамических маршрутов. foreach ((array) $ctx->registry->poll('ru.molinos.cms.route.poll') as $tmp) { if (!empty($tmp['result'])) { foreach ($tmp['result'] as $k => $v) { $raw[$k] = $v; } } } return $raw; }
/** * Сканирует классы, обновляет файлы module.ini */ public function rebuildMeta() { foreach (os::find('lib', 'modules', '*', 'module.ini') as $iniFileName) { $moduleName = basename(dirname($iniFileName)); if (!empty($argv[1]) and $argv[1] != $moduleName) { continue; } $ini = ini::read($iniFileName); $path = dirname($iniFileName); if (file_exists($routeFileName = os::path($path, 'route.ini'))) { $routes = ini::read($routeFileName); } else { $routes = array(); } // Удаляем временные маршруты, считанные из комментариев в прошлый раз. foreach ($routes as $k => $v) { if (is_array($v) and !empty($v['volatile'])) { unset($routes[$k]); } } foreach ($ini as $k => $v) { if (is_array($v)) { unset($ini[$k]); } } foreach (os::find($path, '*.php') as $fileName) { $baseName = basename($fileName); if (0 === strpos($baseName, 'test')) { continue; } elseif ('.test.php' == substr($baseName, -9)) { continue; } $source = strtolower(file_get_contents($fileName)); if (preg_match('@^\\s*(?:abstract\\s+)?class\\s+([a-z0-9_]+)(\\s+extends\\s+([^\\s]+))*(\\s+implements\\s+([^\\n\\r]+))*@m', $source, $m)) { $className = $m[1]; $ini['classes'][$m[1]] = $baseName; if (preg_match_all('#(?:@mcms_message\\s+)([a-z0-9.]+)(?:[^{]*public\\s+static\\s+function\\s+)([^(]+)#s', $source, $m)) { foreach ($m[1] as $idx => $message) { $method = $m[2][$idx]; $ini['messages'][$message][] = $className . '::' . $method; } } if (preg_match_all('#(?:@route\\s+)([a-z0-9./-]+)(?:[^{]*public\\s+static\\s+function\\s+)([^(]+)#s', $source, $m)) { foreach ($m[1] as $idx => $route) { $parts = explode('//', $route); $parts[0] = strtoupper($parts[0]); $routes[implode('//', $parts)] = array('call' => $className . '::' . $m[2][$idx], 'volatile' => true); } } } elseif (preg_match('@^\\s*interface\\s+([a-z0-9_]+)@m', $source, $m)) { $ini['classes'][$m[1]] = $baseName; } } $ini['changelog'] = 'http://molinos-cms.googlecode.com/svn/dist/' . MCMS_RELEASE . '/changelogs/' . $moduleName . '.txt'; if (!empty($ini['classes'])) { ksort($ini['classes']); } if (!empty($routes)) { ksort($routes); ini::write($routeFileName, $routes); } elseif (file_exists($routeFileName)) { unlink($routeFileName); } ini::write($iniFileName, $ini); } }
<?php /** * Скрипт для обновления файлов module.ini * * Не требует никаких параметров. Анализирует все PHP файлы, * добавляет информацию о них в module.ini соответствующего * модуля. Попутно сканирует информацию об обработчиках сообщений, * указанную в комментариях с префиксом @mcms_message. */ require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'client.inc'; Context::last()->registry->rebuildMeta(); $masks = array('.reg*.php', 'cache.*'); foreach ($masks as $mask) { foreach (os::find('sites', '*', $mask) as $path) { if (file_exists($path)) { unlink($path); printf(" - %s\n", $path); } } } die("OK\n");
/** * Проверяет, возможна ли работа с FTP. * Возвращает список доступных файлов. */ private static function getFtpFiles(Context $ctx) { if (!($ftp = $ctx->config->get('modules/files/ftp'))) { return false; } if (!is_dir($ftp = os::path(MCMS_SITE_FOLDER, $ftp))) { return false; } if (!($files = os::find(os::path($ftp, '*')))) { return false; } return $files; }
update_changelog(os::path('tools', 'svn', MCMS_RELEASE, 'changelog.txt'), null, 'rel-8.12..master'); if (!is_dir($dirName = os::path('tools', 'svn', MCMS_RELEASE, 'changelogs'))) { if (!mkdir($dirName, 0750, true)) { throw new Exception('could not create ' . $dirName); } } foreach (os::find('lib', 'modules', '*') as $tmp) { update_changelog(os::path($dirName, basename($tmp) . '.txt'), $tmp); } os::exec('git clean -fd'); printf("Creating %s\n", $zipName = 'molinos-cms-' . MCMS_VERSION . '.zip'); zip::create($zipName, array('.htaccess.dist', '*.php', 'doc', os::path('lib', 'modules', 'admin'), os::path('lib', 'modules', 'api'), os::path('lib', 'modules', 'auth'), os::path('lib', 'modules', 'authbasic'), os::path('lib', 'modules', 'base'), os::path('lib', 'modules', 'compressor'), os::path('lib', 'modules', 'core'), os::path('lib', 'modules', 'cron'), os::path('lib', 'modules', 'files'), os::path('lib', 'modules', 'indexer'), os::path('lib', 'modules', 'install'), os::path('lib', 'modules', 'markdown'), os::path('lib', 'modules', 'mimemail'), os::path('lib', 'modules', 'modman'), os::path('lib', 'modules', 'nodeapi'), os::path('lib', 'modules', 'pdo'), os::path('lib', 'modules', 'routeadmin'), os::path('lib', 'modules', 'schema'), os::path('lib', 'modules', 'xslt'), os::path('tools', '*.php'), os::path('sites', 'default')), '@~$@'); printf("Rebuilding modules.\n"); $b = new Builder(os::path('tools', 'svn', MCMS_RELEASE, 'modules.ini')); $b->run(); foreach (os::find('tmp', 'modules', '*.zip') as $zipName) { $name = basename($zipName); if (preg_match('@^(.*)-(.*)\\.zip$@', $name, $m)) { $info = "{$m[1]} v{$m[2]}"; } else { $info = $name; } printf("Uploading %s\n", $zipName); if (os::exec('googlecode_upload.py', array('-s', $info, '-p', 'molinos-cms', '-l', 'Deprecated,Type-Module,R' . MCMS_RELEASE, $zipName))) { printf(" error\n"); } } printf("Sending changes to Subversion.\n"); chdir('tools/svn'); if (!os::exec('svn', array('commit', '-m', 'Automatic upload by tools/release.php'), $status)) { if ($rev = trim(array_pop(explode(' ', trim(implode('', $status)))), '.')) {
require dirname(__FILE__) . DIRECTORY_SEPARATOR . 'client.inc'; $paths = array(); foreach (os::find('lib/modules/*') as $moduleName) { $fileName = os::path('wiki', 'mod_' . basename($moduleName)) . '.wiki'; $paths[] = $fileName; } foreach (os::find('lib/modules/*/route.ini') as $routeName) { $ini = ini::read($routeName); foreach (array_keys($ini) as $path) { if (2 == count($parts = explode('//', $path, 2))) { if (0 === strpos($parts[1], 'api/')) { $paths[] = os::path('wiki', str_replace('.', '_', str_replace('/', '_', $parts[1])) . '.wiki'); } } } } foreach (os::find('lib/modules/*/module.ini') as $fileName) { $ini = ini::read($fileName); if (!empty($ini['messages']) and is_array($ini['messages'])) { foreach (array_keys($ini['messages']) as $messageName) { $paths[] = $k = os::path('wiki', preg_replace('/[^a-z]+/', '_', $messageName) . '.wiki'); } } } sort($paths); foreach (array_unique($paths) as $path) { if (!file_exists($path)) { printf("+ %s\n", $path); touch($path); } }
/** * Возвращает файлы для админки. */ private static function getAdminFiles(Context $ctx, $compressed = true) { if (!$compressed) { list($scripts, $styles) = self::getGlobal($ctx); foreach (os::find('lib', 'modules', '*', 'scripts', 'admin', '*.js') as $fileName) { $scripts[] = $fileName; } foreach (os::find('lib', 'modules', '*', 'styles', 'admin', '*.css') as $fileName) { $styles[] = $fileName; } } else { $scripts = $styles = array(); $prefix = $ctx->config->getPath('main/tmpdir') . DIRECTORY_SEPARATOR . 'admin.'; if (file_exists($js = $prefix . 'js')) { $scripts[] = $js; } if (file_exists($css = $prefix . 'css')) { $styles[] = $css; } if (empty($scripts) or empty($styles)) { list($scripts, $styles) = self::getAdminFiles($ctx, false); if (empty($scripts)) { touch($js); } else { os::write($js, self::join($scripts, ';')); } $scripts = array($js); if (empty($styles)) { touch($css); } else { os::write($css, self::join($styles)); } $styles = array($css); } } return array($scripts, $styles); }