Beispiel #1
0
 public function __toString()
 {
     if ($this->_ob_cache !== null) {
         return $this->_ob_cache;
     }
     $path = $this->_path;
     $locale = \Gini\Config::get('system.locale');
     $localeSpecificPath = "@{$locale}/{$path}";
     $engines = \Gini\Config::get('view.engines');
     if (isset($GLOBALS['gini.view_map'][$localeSpecificPath])) {
         $realPath = $GLOBALS['gini.view_map'][$localeSpecificPath];
         $engine = $engines[pathinfo($realPath, PATHINFO_EXTENSION)];
     } elseif (isset($GLOBALS['gini.view_map'][$path])) {
         $realPath = $GLOBALS['gini.view_map'][$path];
         $engine = $engines[pathinfo($realPath, PATHINFO_EXTENSION)];
     } else {
         foreach ($engines as $ext => $engine) {
             $realPath = \Gini\Core::locatePharFile(VIEW_DIR, "{$localeSpecificPath}.{$ext}");
             if (!$realPath) {
                 $realPath = \Gini\Core::locatePharFile(VIEW_DIR, "{$path}.{$ext}");
             }
             if ($realPath) {
                 break;
             }
         }
     }
     if ($engine && $realPath) {
         $class = '\\Gini\\View\\' . $engine;
         $output = \Gini\IoC::construct($class, $realPath, $this->_vars);
     }
     return $this->_ob_cache = (string) $output;
 }
Beispiel #2
0
 public static function possibleCommands($argv)
 {
     // list available cli programs
     $candidates = ['/' => []] + Util::pathAndArgs($argv, true);
     $commands = [];
     $class = null;
     foreach (array_reverse($candidates) as $path => $params) {
         $paths = \Gini\Core::pharFilePaths(CLASS_DIR, rtrim('Gini/Controller/CLI/' . ltrim($path, '/'), '/'));
         foreach ($paths as $p) {
             if (!is_dir($p)) {
                 continue;
             }
             \Gini\File::eachFilesIn($p, function ($file) use(&$commands) {
                 $name = basename(strtolower(explode('/', $file, 2)[0]), '.php');
                 $commands[$name] = $name;
             });
         }
         // enumerate actions in class
         $path = strtr(ltrim($path, '/'), ['-' => '', '_' => '']);
         $basename = basename($path);
         $dirname = dirname($path);
         $class_namespace = '\\Gini\\Controller\\CLI\\';
         if ($dirname != '.') {
             $class_namespace .= strtr($dirname, ['/' => '\\']) . '\\';
         }
         $class = $class_namespace . $basename;
         if (class_exists($class)) {
             break;
         }
         $class = $class_namespace . 'Controller' . $basename;
         if (class_exists($class)) {
             break;
         }
         $class = null;
     }
     if (!$class) {
         $class = '\\Gini\\Controller\\CLI\\App';
         $params = $argv;
     }
     if (class_exists($class)) {
         $rc = new \ReflectionClass($class);
         $methods = $rc->getMethods(\ReflectionMethod::IS_PUBLIC);
         foreach ($methods as $m) {
             if (strncmp('action', $m->name, 6) != 0) {
                 continue;
             }
             if (preg_match_all('`([A-Z]+[a-z\\d]+|.+)`', substr($m->name, 6), $parts)) {
                 $method = strtolower(implode('-', $parts[0]));
                 if ($params[0] === $method) {
                     $commands = [];
                     break;
                 }
                 $commands[] = $method;
             }
         }
     }
     return $commands;
 }
Beispiel #3
0
 public function actionExport($args)
 {
     printf("Exporting ORM structures...\n\n");
     $orm_dirs = \Gini\Core::pharFilePaths(CLASS_DIR, 'Gini/ORM');
     foreach ($orm_dirs as $orm_dir) {
         if (!is_dir($orm_dir)) {
             continue;
         }
         \Gini\File::eachFilesIn($orm_dir, function ($file) use($orm_dir) {
             $oname = strtolower(preg_replace('|.php$|', '', $file));
             if ($oname == 'object') {
                 return;
             }
             $class_name = '\\Gini\\ORM\\' . str_replace('/', '\\', $oname);
             // Check if it is abstract class
             $rc = new \ReflectionClass($class_name);
             if ($rc->isAbstract()) {
                 return;
             }
             printf("   %s\n", $oname);
             $o = \Gini\IoC::construct($class_name);
             $structure = $o->structure();
             // unset system fields
             unset($structure['id']);
             unset($structure['_extra']);
             $i = 1;
             $max = count($structure);
             foreach ($structure as $k => $v) {
                 if ($i == $max) {
                     break;
                 }
                 printf("   ├─ %s (%s)\n", $k, implode(',', array_map(function ($k, $v) {
                     return $v ? "{$k}:{$v}" : $k;
                 }, array_keys($v), $v)));
                 ++$i;
             }
             printf("   └─ %s (%s)\n\n", $k, implode(',', array_map(function ($k, $v) {
                 return $v ? "{$k}:{$v}" : $k;
             }, array_keys($v), $v)));
         });
     }
 }
Beispiel #4
0
 public function actionFormat($argv)
 {
     if (count($argv) < 1) {
         exit("usage: gini i18n format <locales>\n");
     }
     $appname = APP_ID;
     foreach ($argv as $locale) {
         $lodir = I18N_PATH . '/' . $locale . '/LC_MESSAGES';
         \Gini\File::ensureDir($lodir);
         $pofile = $lodir . '/' . $appname . '.po';
         $paths = \Gini\Core::filePaths(RAW_DIR . '/l10n/' . $locale . '.po');
         echo "merge: {$appname}.po\n";
         $cmd = sprintf('msgcat -o %1$s %2$s', escapeshellarg($pofile), implode(' ', array_map('escapeshellarg', $paths)));
         passthru($cmd);
         $mofile = $lodir . '/' . $appname . '.mo';
         echo "compile: {$appname}.po => {$appname}.mo\n";
         $cmd = sprintf('msgfmt -o %s %s', escapeshellarg($mofile), escapeshellarg($pofile));
         passthru($cmd);
     }
 }
Beispiel #5
0
 private static function _getORMPlurals()
 {
     $orm_dirs = \Gini\Core::pharFilePaths(CLASS_DIR, 'Gini/ORM');
     $onames = [];
     foreach ($orm_dirs as $orm_dir) {
         if (!is_dir($orm_dir)) {
             continue;
         }
         \Gini\File::eachFilesIn($orm_dir, function ($file) use($orm_dir, &$onames) {
             $oname = preg_replace('|.php$|', '', $file);
             if ($oname == 'Object') {
                 return;
             }
             $class_name = '\\Gini\\ORM\\' . str_replace('/', '\\', $oname);
             // Check if it is abstract class
             $rc = new \ReflectionClass($class_name);
             if ($rc->isAbstract()) {
                 return;
             }
             $onames[] = strtolower($oname);
         });
     }
     if (count($onames) == 0) {
         return [];
     }
     printf("%s\n", 'Generating ORM plurals cache...');
     if (!class_exists('\\Doctrine\\Common\\Inflector\\Inflector')) {
         echo "    * doctrine/inflector is missing! Perhaps you did't update your composer packages yet.\n\n";
         return [];
     }
     $plurals = [];
     $onames = array_unique($onames);
     foreach ($onames as $oname) {
         $plural = \Doctrine\Common\Inflector\Inflector::pluralize($oname);
         printf("   %s => %s\n", $plural, $oname);
         $plurals[$plural] = $oname;
     }
     echo "\n";
     return $plurals;
 }
Beispiel #6
0
 public function actionInit($args)
 {
     $app = \Gini\Core::moduleInfo(APP_ID);
     $composer_json = ['name' => $app->id, 'description' => $app->description ?: '', 'license' => 'proprietary', 'repositories' => [['type' => 'composer', 'url' => 'http://satis.genee.cn']]];
     $opt = \Gini\Util::getOpt($args, 'n', ['no-packagist']);
     if (isset($opt['n']) || isset($opt['--no-packagist'])) {
         $composer_json['repositories'][] = ['packagist' => false];
         echo "Generating Composer configuration file without Packagist...\n";
     } else {
         echo "Generating Composer configuration file...\n";
     }
     $walked = [];
     $walk = function ($info) use(&$walk, &$walked, &$composer_json) {
         $walked[$info->id] = true;
         foreach ($info->dependencies as $name => $version) {
             if (isset($walked[$name])) {
                 continue;
             }
             $app = \Gini\Core::moduleInfo($name);
             if ($app) {
                 $walk($app);
             }
         }
         $composer_json = \Gini\Util::arrayMergeDeep($info->composer ?: [], $composer_json);
     };
     $walk($app);
     if (isset($composer_json['require']) || isset($composer_json['require-dev'])) {
         if (file_exists(APP_PATH . '/composer.json')) {
             $confirm = strtolower(readline('File exists. Overwrite? [Y/n] '));
             if ($confirm && $confirm != 'y') {
                 echo "   canceled.\n";
                 return;
             }
         }
         file_put_contents(APP_PATH . '/composer.json', J($composer_json, JSON_PRETTY_PRINT));
         echo "   done.\n";
     }
 }
Beispiel #7
0
 public static function fetch($env = null)
 {
     $env = $env ?: APP_PATH . '/.env';
     if (file_exists($env)) {
         $rows = file($env, FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
         foreach ($rows as &$row) {
             if (!$row || $row[0] == '#') {
                 continue;
             }
             putenv($row);
         }
     }
     $items = [];
     $paths = \Gini\Core::pharFilePaths(RAW_DIR, 'config');
     foreach ($paths as $path) {
         self::_load_config_dir($path, $items);
     }
     $env = $_SERVER['GINI_ENV'];
     if ($env) {
         $paths = \Gini\Core::pharFilePaths(RAW_DIR, 'config/@' . $env);
         foreach ($paths as $path) {
             self::_load_config_dir($path, $items);
         }
     }
     return $items;
 }
Beispiel #8
0
 public function actionInstall($argv)
 {
     count($argv) > 0 || APP_ID != 'gini' or die("Usage: gini index install <module> <version>\n\n");
     if (!class_exists('\\Sabre\\DAV\\Client')) {
         self::_loadGiniComposer();
     }
     list($options, $headers) = self::_davOptionsAndHeaders();
     $client = new \Sabre\DAV\Client($options);
     $installedModules = [];
     $installModule = function ($module, $versionRange, $targetDir, $isApp = false) use(&$installModule, &$installedModules, &$client, &$options, &$headers) {
         if (isset($installedModules[$module])) {
             $info = $installedModules[$module];
             $v = new \Gini\Version($info->version);
             // if installed version is incorrect, abort the operation.
             if (!$v->satisfies($versionRange)) {
                 die("Conflict detected on {$module}! Installed: {$v->fullVersion} Expecting: {$versionRange}\n");
             }
         } else {
             // try to see if we've already got it somewhere
             if (isset(\Gini\Core::$MODULE_INFO[$module])) {
                 $info = \Gini\Core::$MODULE_INFO[$module];
                 $v = new \Gini\Version($info->version);
                 if ($v->satisfies($versionRange)) {
                     $matched = $v;
                 }
             }
             // fetch index.json
             echo "Fetching catalog of {$module}...\n";
             while (true) {
                 $response = $client->request('GET', $module . '/index.json', null, $headers);
                 if ($response['statusCode'] == 401 && isset($response['headers']['www-authenticate'])) {
                     // Authentication required
                     // prompt user/password and try again
                     if (!isset($options['userName'])) {
                         list($options, $headers) = self::_davOptionsAndHeaders(true);
                         $client = new \Sabre\DAV\Client($options);
                         continue;
                     }
                     $matched or die("Access denied for fetch catalog of {$module} .\n");
                     $response = null;
                 } elseif ($response['statusCode'] < 200 || $response['statusCode'] > 206) {
                     $matched or die('Error: ' . $response['statusCode'] . "\n");
                     $response = null;
                 }
                 break;
             }
             if ($response) {
                 $indexInfo = (array) json_decode($response['body'], true);
                 // find latest match version
                 foreach ($indexInfo as $version => $foo) {
                     $v = new \Gini\Version($version);
                     if ($v->satisfies($versionRange)) {
                         if ($matched) {
                             if ($matched->compare($v) > 0) {
                                 continue;
                             }
                         }
                         $matched = $v;
                     }
                 }
             }
             if (!$matched) {
                 die("Failed to locate required version!\n");
             }
             if (!$info || $matched->fullVersion != $info->version) {
                 $version = $matched->fullVersion;
                 $info = (object) $indexInfo[$version];
                 $tarPath = "{$module}/{$version}.tgz";
                 echo "Downloading {$module} from {$tarPath}...\n";
                 while (true) {
                     $response = $client->request('GET', $tarPath, null, $headers);
                     if ($response['statusCode'] == 401 && isset($response['headers']['www-authenticate'])) {
                         // Authentication required
                         // prompt user/password and try again
                         if (!isset($options['userName'])) {
                             list($options, $headers) = self::_davOptionsAndHeaders(true);
                             $client = new \Sabre\DAV\Client($options);
                             continue;
                         }
                         die("Access denied for fetch catalog of {$module}.\n");
                     }
                     if ($response['statusCode'] < 200 || $response['statusCode'] > 206) {
                         die('Error: ' . $response['statusCode'] . "\n");
                     }
                     break;
                 }
                 if ($isApp) {
                     $modulePath = $targetDir;
                 } else {
                     $modulePath = "{$targetDir}/modules/{$module}";
                 }
                 if (is_dir($modulePath) && file_exists($modulePath)) {
                     \Gini\File::removeDir($modulePath);
                 }
                 \Gini\File::ensureDir($modulePath);
                 echo "Extracting {$module}...\n";
                 $ph = popen('tar -zx -C ' . escapeshellcmd($modulePath), 'w');
                 if (is_resource($ph)) {
                     fwrite($ph, $response['body']);
                     pclose($ph);
                 }
             } else {
                 $version = $info->version;
                 echo "Found local copy of {$module}/{$version}.\n";
             }
             $installedModules[$module] = $info;
             echo "\n";
         }
         if ($info) {
             foreach ((array) $info->dependencies as $m => $r) {
                 if ($m == 'gini') {
                     continue;
                 }
                 $installModule($m, $r, $targetDir, false);
             }
         }
     };
     if (count($argv) > 0) {
         // e.g. gini install xxx
         $module = $argv[0];
         if (count($argv) > 1) {
             $versionRange = $argv[1];
         } else {
             $versionRange = readline('Please provide a version constraint for the ' . $module . ' requirement:');
         }
         $installModule($module, $versionRange, $_SERVER['PWD'] . "/{$module}", true);
     } else {
         // run: gini install, then you should be in module directory
         if (APP_ID != 'gini') {
             // try to install its dependencies
             $app = \Gini\Core::moduleInfo(APP_ID);
             $installedModules[APP_ID] = $app;
             $installModule(APP_ID, $app->version, APP_PATH, true);
         }
     }
 }
Beispiel #9
0
if (!isset($_SERVER['GINI_MODULE_BASE_PATH'])) {
    $_SERVER['GINI_MODULE_BASE_PATH'] = dirname(SYS_PATH);
}
if (!isset($_SERVER['GINI_APP_PATH'])) {
    $_SERVER['GINI_APP_PATH'] = SYS_PATH;
}
chdir($_SERVER['GINI_APP_PATH']);
// load class map
$class_map_file = $_SERVER['GINI_APP_PATH'] . '/cache/class_map.json';
if (file_exists($class_map_file)) {
    $class_map = @json_decode(@file_get_contents($class_map_file), true);
    if ($class_map) {
        $GLOBALS['gini.class_map'] = $class_map;
    }
}
// load view map
$view_map_file = $_SERVER['GINI_APP_PATH'] . '/cache/view_map.json';
if (file_exists($view_map_file)) {
    $view_map = @json_decode(@file_get_contents($view_map_file), true);
    if ($view_map) {
        $GLOBALS['gini.view_map'] = $view_map;
    }
}
$class_path = SYS_PATH . '/class';
if (file_exists($class_path . '.phar')) {
    require 'phar://' . $class_path . '.phar/Gini/Core.php';
} else {
    require $class_path . '/Gini/Core.php';
}
\Gini\Core::start();
Beispiel #10
0
 public static function setup()
 {
     $host = $_SERVER['HTTP_HOST'];
     $scheme = $_SERVER['HTTP_X_FORWARDED_PROTO'] ?: ($_SERVER['HTTPS'] ? 'https' : 'http');
     $dir = dirname($_SERVER['SCRIPT_NAME']);
     if (substr($dir, -1) != '/') {
         $dir .= '/';
     }
     self::$_base = $scheme . '://' . $host . $dir;
     self::$_rurl = \Gini\Core::moduleInfo(APP_ID)->rurl ?: ['*' => 'assets'];
 }
Beispiel #11
0
 public function actionVersion($argv)
 {
     $info = \Gini\Core::moduleInfo(APP_ID);
     $version = $argv[0];
     if ($version) {
         // set current version
         $v = new \Gini\Version($version);
         $v->compare($info->version) > 0 or die("A newer version (>{$info->version}) is required!\n");
         $info->version = $version;
         \Gini\Core::saveModuleInfo($info);
         // commit it if it is a git repo
         if (is_dir(APP_PATH . '/.git')) {
             $WORK_TREE = escapeshellarg(APP_PATH);
             $GIT_DIR = escapeshellarg(APP_PATH . '/.git');
             $GIT_MSG = escapeshellarg("Bumped version to {$version}");
             $command = "git --git-dir={$GIT_DIR} --work-tree={$WORK_TREE} commit -m {$GIT_MSG} gini.json && git --git-dir={$GIT_DIR} tag {$version}";
             passthru($command);
             return;
         }
     }
     echo "{$info->name} ({$info->id}/{$info->version})\n";
 }
Beispiel #12
0
 public function testPharFilePaths()
 {
     $paths = \Gini\Core::pharFilePaths(CLASS_DIR, 'Gini/Core.php');
     $this->assertTrue(in_array(SYS_PATH . '/class/Gini/Core.php', $paths));
 }
Beispiel #13
0
 public function actionUpgradeId()
 {
     // ORM required class map.
     if (!isset($GLOBALS['gini.class_map'])) {
         echo "You need to run \"gini cache class\" before upgrade ORM id.\n";
         return;
     }
     // enumerate orms
     echo "Updating database structures according ORM definition...\n";
     $orm_dirs = \Gini\Core::pharFilePaths(CLASS_DIR, 'Gini/ORM');
     foreach ($orm_dirs as $orm_dir) {
         if (!is_dir($orm_dir)) {
             continue;
         }
         \Gini\File::eachFilesIn($orm_dir, function ($file) use($orm_dir) {
             $oname = preg_replace('|.php$|', '', $file);
             if ($oname == 'Object') {
                 return;
             }
             $class_name = '\\Gini\\ORM\\' . str_replace('/', '\\', $oname);
             // Check if it is abstract class
             $rc = new \ReflectionClass($class_name);
             if ($rc->isAbstract()) {
                 return;
             }
             $o = \Gini\IoC::construct($class_name);
             // some object might not have database backend
             $db = $o->db();
             if (!$db) {
                 return;
             }
             printf("   %s\n", $oname);
             $structure = $o->structure();
             foreach ($structure as $field => $option) {
                 if (isset($option['object'])) {
                     $db->query('UPDATE :table SET :field=NULL WHERE :field=0', [':table' => $o->tableName(), ':field' => $field . '_id']);
                 }
             }
         });
     }
     echo "   done.\n";
 }
Beispiel #14
0
 public static function fetch($env = null)
 {
     $items = [];
     $paths = \Gini\Core::pharFilePaths(RAW_DIR, 'config');
     foreach ($paths as $path) {
         self::_load_config_dir($path, $items);
     }
     $env = $env ?: $_SERVER['GINI_ENV'] ?: '';
     if ($env) {
         $paths = \Gini\Core::pharFilePaths(RAW_DIR, 'config/@' . $env);
         foreach ($paths as $path) {
             self::_load_config_dir($path, $items);
         }
     }
     return $items;
 }
Beispiel #15
0
 private static function _rurl_mod($url, $type)
 {
     $info = \Gini\Core::moduleInfo(APP_ID);
     $config = (array) \Gini\Config::get('system.rurl_mod');
     if ($type) {
         $query = $config[$type]['query'];
         $query = $query ? strtr($query, ['$(TIMESTAMP)' => time(), '$(VERSION)' => $info->version]) : null;
     }
     return empty($query) ? $url : self::url($url, $query);
 }