From ecfac4183ab31c2637c18e2967f2a8531b12004e Mon Sep 17 00:00:00 2001 From: Nikolaos Dimopoulos Date: Sun, 23 Sep 2018 10:15:08 -0400 Subject: [PATCH 1/3] Fixed robots.txt --- public/robots.txt | 11 +---------- 1 file changed, 1 insertion(+), 10 deletions(-) diff --git a/public/robots.txt b/public/robots.txt index c943d4e..2c5663e 100644 --- a/public/robots.txt +++ b/public/robots.txt @@ -1,14 +1,5 @@ User-agent: * Allow: / -Disallow: /*/*/_sources/*.txt -Disallow: /*/*/_sources/api/*.txt -Disallow: /*/*/_sources/reference/*.txt -Disallow: /report.html - User-agent: Yandex -Disallow: /*/*/_sources/*.txt -Disallow: /*/*/_sources/api/*.txt -Disallow: /*/*/_sources/reference/*.txt -Disallow: /report.html -Host: docs.phalconphp.com +Host: docs.zephir-lang.com From 201bc1ad31d381996eb5366c50593c059838d3d4 Mon Sep 17 00:00:00 2001 From: Nikolaos Dimopoulos Date: Tue, 27 Nov 2018 13:07:08 -0500 Subject: [PATCH 2/3] Refactored config; Added safeguards for languages/versions; Allow all languages --- VERSIONS | 3 +- app/config/app.php | 61 ---------- app/config/config.php | 114 +++++++++++++++++++ app/config/error.php | 21 ---- app/config/highlight.php | 30 ----- app/config/providers.php | 36 ------ app/config/routes.php | 43 ------- app/controllers/BaseController.php | 12 +- app/controllers/DocsController.php | 12 +- app/library/Bootstrap.php | 4 +- app/library/Config/Factory.php | 132 ---------------------- app/providers/Config/ServiceProvider.php | 5 +- app/tasks/GetLanguagesTask.php | 37 +++--- boxfile.yml | 6 +- storage/{languages => crowdin}/.gitignore | 0 15 files changed, 162 insertions(+), 354 deletions(-) delete mode 100644 app/config/app.php create mode 100644 app/config/config.php delete mode 100644 app/config/error.php delete mode 100644 app/config/highlight.php delete mode 100644 app/config/providers.php delete mode 100644 app/config/routes.php delete mode 100644 app/library/Config/Factory.php rename storage/{languages => crowdin}/.gitignore (100%) diff --git a/VERSIONS b/VERSIONS index 688abaa..384fdb0 100644 --- a/VERSIONS +++ b/VERSIONS @@ -1 +1,2 @@ -0.10 \ No newline at end of file +0.10 +0.11 \ No newline at end of file diff --git a/app/config/app.php b/app/config/app.php deleted file mode 100644 index dd7dc09..0000000 --- a/app/config/app.php +++ /dev/null @@ -1,61 +0,0 @@ - $version, - 'versions' => $versions, - 'languages' => $languages, - 'timezone' => env('APP_TIMEZONE', 'UTC'), - 'debug' => env('APP_DEBUG'), - 'env' => env('APP_ENV'), - 'url' => env('APP_URL'), - 'name' => env('APP_NAME'), - 'project' => env('APP_PROJECT'), - 'description' => env('APP_DESCRIPTION'), - 'descriptionLong' => env('APP_DESCRIPTION_LONG', 'Official Zephir Documentation'), - 'keywords' => env('APP_KEYWORDS'), - 'repo' => env('APP_REPO'), - 'docs' => env('APP_DOCS'), - 'baseUri' => env('APP_BASE_URI'), - 'staticUrl' => env('APP_STATIC_URL'), - 'lang' => env('APP_LANG'), - 'supportEmail' => env('APP_SUPPORT_EMAIL'), - 'googleAnalytics' => env('GOOGLE_ANALYTICS'), - 'algoliaSearchKey' => env('ALGOLIA_SEARCH_KEY'), -]; diff --git a/app/config/config.php b/app/config/config.php new file mode 100644 index 0000000..a43322b --- /dev/null +++ b/app/config/config.php @@ -0,0 +1,114 @@ + [ + 'version' => $version, + 'versions' => $versions, + 'languages' => $languages, + 'timezone' => env('APP_TIMEZONE', 'UTC'), + 'debug' => env('APP_DEBUG'), + 'env' => env('APP_ENV'), + 'url' => env('APP_URL'), + 'name' => env('APP_NAME'), + 'project' => env('APP_PROJECT'), + 'description' => env('APP_DESCRIPTION'), + 'descriptionLong' => env('APP_DESCRIPTION_LONG', 'Official Zephir Documentation'), + 'keywords' => env('APP_KEYWORDS'), + 'repo' => env('APP_REPO'), + 'docs' => env('APP_DOCS'), + 'baseUri' => env('APP_BASE_URI'), + 'staticUrl' => env('APP_STATIC_URL'), + 'lang' => env('APP_LANG'), + 'supportEmail' => env('APP_SUPPORT_EMAIL'), + 'googleAnalytics' => env('GOOGLE_ANALYTICS'), + 'algoliaSearchKey' => env('ALGOLIA_SEARCH_KEY'), + ], + 'error' => [ + 'controller' => 'error', + 'action' => 'show500', + ], + 'highlight' => [ + 'version' => '9.11.0', + 'js' => [ + 'cpp', + 'css', + 'json', + 'php', + 'shell', + 'twig', + 'yaml', + 'zephir', + ], + ], + 'providers' => [ + // Application Service Providers + Docs\Providers\Config\ServiceProvider::class, + Docs\Providers\FileSystem\ServiceProvider::class, + Docs\Providers\UrlResolver\ServiceProvider::class, + Docs\Providers\Routing\ServiceProvider::class, + Docs\Providers\Logger\ServiceProvider::class, + Docs\Providers\ViewCache\ServiceProvider::class, + Docs\Providers\VoltTemplate\ServiceProvider::class, + Docs\Providers\View\ServiceProvider::class, + Docs\Providers\CacheData\ServiceProvider::class, + Docs\Providers\Markdown\ServiceProvider::class, + Docs\Providers\Assets\ServiceProvider::class, + Docs\Providers\Dispatcher\ServiceProvider::class, + Docs\Providers\Tags\ServiceProvider::class, + ], + 'routes' => [ + DocsController::class => [ + 'methods' => [ + 'get' => [ + '/' => 'redirectAction', + '/{l}' => 'mainAction', + '/{l}/{v}' => 'mainAction', + '/{l}/{v}/{p}' => 'mainAction', + ], + + // This is exactly the same execution as GET, but the Response has no body + 'head' => [ + '/' => 'redirectAction', + '/{l}' => 'mainAction', + '/{l}/{v}' => 'mainAction', + '/{l}/{v}/{p}' => 'mainAction', + ], + ], + ], + ], +]; diff --git a/app/config/error.php b/app/config/error.php deleted file mode 100644 index 57129ee..0000000 --- a/app/config/error.php +++ /dev/null @@ -1,21 +0,0 @@ - 'error', - 'action' => 'show500', -]; diff --git a/app/config/highlight.php b/app/config/highlight.php deleted file mode 100644 index b243f51..0000000 --- a/app/config/highlight.php +++ /dev/null @@ -1,30 +0,0 @@ - '9.11.0', - 'js' => [ - 'cpp', - 'css', - 'json', - 'php', - 'shell', - 'twig', - 'yaml', - 'zephir', - ], -]; diff --git a/app/config/providers.php b/app/config/providers.php deleted file mode 100644 index 1683bcb..0000000 --- a/app/config/providers.php +++ /dev/null @@ -1,36 +0,0 @@ - [ - 'methods' => [ - 'get' => [ - '/' => 'redirectAction', - '/{l:[a-z]{2}}' => 'mainAction', - '/{l:[a-z]{2}}/{v}' => 'mainAction', - '/{l:[a-z]{2}}/{v}/{p}' => 'mainAction', - '/{l:[a-z]{2}}/{v}/api/{p}' => 'mainAction', - '/sitemap.xml' => 'sitemapAction', - '/search' => 'searchAction', - ], - - // This is exactly the same execution as GET, but the Response has no body - 'head' => [ - '/' => 'redirectAction', - '/{l:[a-z]{2}}' => 'mainAction', - '/{l:[a-z]{2}}/{v}' => 'mainAction', - '/{l:[a-z]{2}}/{v}/{p}' => 'mainAction', - '/{l:[a-z]{2}}/{v}/api/{p}' => 'mainAction', - ], - ], - ], -]; diff --git a/app/controllers/BaseController.php b/app/controllers/BaseController.php index ce55ba2..bf5c19b 100644 --- a/app/controllers/BaseController.php +++ b/app/controllers/BaseController.php @@ -17,6 +17,7 @@ namespace Docs\Controllers; +use function array_search; use Phalcon\Cache\BackendInterface; use Phalcon\Config; use Phalcon\Mvc\Controller as PhController; @@ -25,6 +26,7 @@ use function Docs\Functions\config; use function Docs\Functions\environment; use function file_exists; +use function var_dump; /** * Docs\Controllers\BaseController @@ -256,11 +258,12 @@ protected function getMenu($language, $version, $fileName): string */ protected function getVersion(string $stub = '', string $version = ''): string { - if (empty($version) || strtolower($version) === 'latest') { + $versions = config('app.versions')->toArray(); + if (empty($version) || + strtolower($version) === 'latest' || + false === array_search($version, $versions) + ) { $version = config('app.version', '9999'); - } else { - $version = filter_var($version, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION); - $version = $version ?? config('app.version', '9999'); } return "{$stub}{$version}"; @@ -276,7 +279,6 @@ protected function getVersion(string $stub = '', string $version = ''): string protected function getLanguage(string $language): string { $languages = $this->config->path('app.languages', []); - if (!isset($languages[$language])) { return 'en'; } diff --git a/app/controllers/DocsController.php b/app/controllers/DocsController.php index da9c4fa..ac40f5a 100644 --- a/app/controllers/DocsController.php +++ b/app/controllers/DocsController.php @@ -2,6 +2,7 @@ namespace Docs\Controllers; +use Docs\Cli\Tasks\GetLanguagesTask; use Docs\Exception\HttpException; use Phalcon\Http\ResponseInterface; use Phalcon\Text; @@ -25,17 +26,18 @@ class DocsController extends BaseController */ public function mainAction(string $language = null, string $version = null, string $page = ''): ResponseInterface { - if (empty($language)) { + $checkedLanguage = $this->getLanguage($language); + if ($checkedLanguage !== $language) { return $this->response->redirect(base_url($this->getVersion('/en/'))); } - $language = $this->getLanguage($language); - - if (true === empty($version) || 'latest' === $version) { + $checkVersion = $this->getVersion('', $version); + if ($checkVersion !== $version) { $suffix = ''; if (true !== empty($page)) { $suffix = '/' . $page; } + return $this->response->redirect( base_url( $this->getVersion('/' . $language . '/') . $suffix @@ -43,8 +45,6 @@ public function mainAction(string $language = null, string $version = null, stri ); } - $version = $this->getVersion('', $version); - $renderFile = 'index/article'; if (empty($page)) { $page = 'welcome'; diff --git a/app/library/Bootstrap.php b/app/library/Bootstrap.php index 01a16ca..60d4713 100644 --- a/app/library/Bootstrap.php +++ b/app/library/Bootstrap.php @@ -85,8 +85,8 @@ public function __construct($mode = 'normal') $this->createInternalApplication(); $this->container->setShared('app', $this->app); - /** @noinspection PhpIncludeInspection */ - $providers = require config_path('providers.php'); + $config = require config_path('config.php'); + $providers = $config['providers']; if (is_array($providers)) { $this->initializeServiceProviders($providers); } diff --git a/app/library/Config/Factory.php b/app/library/Config/Factory.php deleted file mode 100644 index 9ae450d..0000000 --- a/app/library/Config/Factory.php +++ /dev/null @@ -1,132 +0,0 @@ -get('filesystem', [$path]); - - $files = array_filter($filesystem->listContents(), function ($metadata) { - return isset($metadata['type']) && - $metadata['type'] == 'file' && - isset($metadata['extension']) && - $metadata['extension'] == 'php'; - }); - - return self::load($files); - } - - /** - * Load all configuration. - * - * @param array $files - * - * @return Config - */ - protected static function load(array $files) - { - $config = new Config(); - $merge = self::merge(); - - /** @var Filesystem $filesystem */ - $filesystem = Di::getDefault()->get('filesystem', [cache_path('config')]); - - if ($filesystem->has('cached.php') && !environment('development')) { - $merge($config, cache_path('config/cached.php')); - - return $config; - } - - foreach ($files as $file) { - $merge($config, config_path($file['path']), $file['filename']); - } - - if (environment('production') && !$filesystem->has('cached.php')) { - self::dump($filesystem, 'cached.php', $config->toArray()); - } - - return $config; - } - - protected static function merge() - { - return function (Config &$config, $path, $node = null) { - /** @noinspection PhpIncludeInspection */ - $toMerge = include($path); - - if (is_array($toMerge)) { - $toMerge = new Config($toMerge); - } - - if ($toMerge instanceof Config) { - if (!$node) { - return $config->merge($toMerge); - } - - if (!$config->offsetExists($node) || !$config->{$node} instanceof Config) { - $config->offsetSet($node, new Config()); - } - - return $config->get($node)->merge($toMerge); - } - - return null; - }; - } - - protected static function dump(Filesystem $filesystem, $path, array $data) - { - $header = <<put($path, $contents, $data); - } -} diff --git a/app/providers/Config/ServiceProvider.php b/app/providers/Config/ServiceProvider.php index 43bec9b..0ee8680 100644 --- a/app/providers/Config/ServiceProvider.php +++ b/app/providers/Config/ServiceProvider.php @@ -17,7 +17,7 @@ namespace Docs\Providers\Config; -use Docs\Config\Factory; +use Phalcon\Config; use Phalcon\Di\ServiceProviderInterface; use Phalcon\DiInterface; use function Docs\Functions\config_path; @@ -39,7 +39,8 @@ public function register(DiInterface $container) $container->setShared( 'config', function () { - return Factory::create(config_path()); + $config = require config_path('config.php'); + return new Config($config); } ); } diff --git a/app/tasks/GetLanguagesTask.php b/app/tasks/GetLanguagesTask.php index ace60a3..b807289 100644 --- a/app/tasks/GetLanguagesTask.php +++ b/app/tasks/GetLanguagesTask.php @@ -17,13 +17,14 @@ namespace Docs\Cli\Tasks; +use Phalcon\CLI\Task; +use function asort; use function Docs\Functions\app_path; use function Docs\Functions\env; use function file_put_contents; use function json_decode; -use Phalcon\CLI\Task; -use const PHP_EOL; use function sprintf; +use const PHP_EOL; /** * GetLanguagesTask @@ -36,7 +37,7 @@ class GetLanguagesTask extends Task public function mainAction() { echo 'Getting Languages from Crowdin...' . PHP_EOL; - $template = 'https://api.crowdin.com/api/project/zephir-documentation/status?key=%s&json'; + $template = 'https://api.crowdin.com/api/project/zephir-documentation/info?key=%s&json'; $url = sprintf($template, env('CROWDIN_API_KEY'), ''); $handle = curl_init(); @@ -45,7 +46,7 @@ public function mainAction() curl_setopt($handle, CURLOPT_POST, true); curl_setopt($handle, CURLOPT_POSTFIELDS, ['json' => 1]); - $fileName = app_path('/storage/languages/languages.json'); + $fileName = app_path('/storage/crowdin/crowdin.json'); $results = curl_exec($handle); $errorNumber = curl_errno($handle); $errorDescription = curl_error($handle); @@ -56,18 +57,28 @@ public function mainAction() echo $errorDescription . PHP_EOL; } - $languages = [ - 'en' => 'English', - ]; - $data = json_decode($results, true); - foreach ($data as $item) { - $code = $item['code']; - $text = $item['name']; - $languages[$code] = $text; + $crowdin = json_decode($results, true); + $languages = []; + foreach ($crowdin['languages'] as $language) { + $languages[$language['code']] = $language['name']; + } + + $versions = []; + foreach ($crowdin['files'] as $file) { + if ('branch' === $file['node_type']) { + $versions[] = $file['name']; + } } asort($languages); - file_put_contents($fileName, json_encode($languages)); + arsort($versions); + + $data = [ + 'languages' => $languages, + 'versions' => $versions, + ]; + + file_put_contents($fileName, json_encode($data)); echo 'Updated languages.' . PHP_EOL; } diff --git a/boxfile.yml b/boxfile.yml index 75c0c5a..19adfb6 100644 --- a/boxfile.yml +++ b/boxfile.yml @@ -31,7 +31,6 @@ run.config: - dom - json - mbstring - - phalcon - simplexml - tokenizer - xml @@ -43,6 +42,9 @@ run.config: - xdebug rm: - opcache + extra_packages: + - php71-phalcon-3.3.2 extra_steps: - - echo "alias phalcon=\'phalcon.php\'" >> /data/var/home/gonano/.bashrc + - echo 'extension=phalcon.so' >> "/data/etc/php/dev_php.ini" + - echo 'extension=phalcon.so' >> "/data/etc/php/prod_php.ini" - cp /app/storage/setup/xdebug.ini /data/etc/php.dev.d/xdebug.ini diff --git a/storage/languages/.gitignore b/storage/crowdin/.gitignore similarity index 100% rename from storage/languages/.gitignore rename to storage/crowdin/.gitignore From 9d8c85dc9d1d14b8bf95a42ee98204bae8b68fb3 Mon Sep 17 00:00:00 2001 From: Nikolaos Dimopoulos Date: Tue, 27 Nov 2018 17:43:32 -0500 Subject: [PATCH 3/3] Work on the languages --- app/tasks/GetLanguagesTask.php | 81 ++++++++++++++++++++++------- app/views/inc/header-languages.volt | 16 +++--- 2 files changed, 71 insertions(+), 26 deletions(-) diff --git a/app/tasks/GetLanguagesTask.php b/app/tasks/GetLanguagesTask.php index b807289..80ad56e 100644 --- a/app/tasks/GetLanguagesTask.php +++ b/app/tasks/GetLanguagesTask.php @@ -17,12 +17,15 @@ namespace Docs\Cli\Tasks; +use function array_multisort; use Phalcon\CLI\Task; use function asort; use function Docs\Functions\app_path; use function Docs\Functions\env; use function file_put_contents; use function json_decode; +use const SORT_ASC; +use const SORT_STRING; use function sprintf; use const PHP_EOL; @@ -36,32 +39,48 @@ class GetLanguagesTask extends Task */ public function mainAction() { + echo 'Getting Supported Languages from Crowdin...' . PHP_EOL; + $url = 'https://api.crowdin.com/api/supported-languages?json'; + $data = $this->makeCurl($url); + + $languageMap = []; + $supported = json_decode($data['results'], true); + foreach ($supported as $language) { + $languageMap[$language['crowdin_code']] = $language['locale']; + } + echo 'Getting Languages from Crowdin...' . PHP_EOL; $template = 'https://api.crowdin.com/api/project/zephir-documentation/info?key=%s&json'; $url = sprintf($template, env('CROWDIN_API_KEY'), ''); + $data = $this->makeCurl($url); + $fileName = app_path('/storage/crowdin/crowdin.json'); + $results = $data['results']; - $handle = curl_init(); - curl_setopt($handle, CURLOPT_URL, $url); - curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); - curl_setopt($handle, CURLOPT_POST, true); - curl_setopt($handle, CURLOPT_POSTFIELDS, ['json' => 1]); - - $fileName = app_path('/storage/crowdin/crowdin.json'); - $results = curl_exec($handle); - $errorNumber = curl_errno($handle); - $errorDescription = curl_error($handle); - curl_close($handle); - - if ($errorNumber > 0) { + if ($data['errorNumber'] > 0) { $results = '[]'; - echo $errorDescription . PHP_EOL; + echo $data['errorDescription'] . PHP_EOL; } $crowdin = json_decode($results, true); - $languages = []; + $languages = [ + 'en' => [ + 'name' => 'English', + 'code' => 'en', + ] + ]; foreach ($crowdin['languages'] as $language) { - $languages[$language['code']] = $language['name']; + $code = $languageMap[$language['code']] ?? 'en'; + + $languages[$code] = [ + 'name' => $language['name'], + 'code' => $language['code'], + ]; } + array_multisort(array_column($languages, 'name'), SORT_ASC, $languages); + + /** + * Now create the final array + */ $versions = []; foreach ($crowdin['files'] as $file) { @@ -69,17 +88,43 @@ public function mainAction() $versions[] = $file['name']; } } - - asort($languages); arsort($versions); $data = [ 'languages' => $languages, 'versions' => $versions, + 'map' => $languageMap, ]; file_put_contents($fileName, json_encode($data)); echo 'Updated languages.' . PHP_EOL; } + + /** + * Sends a CURL request + * + * @param string $url + * + * @return array + */ + private function makeCurl(string $url): array + { + $handle = curl_init(); + curl_setopt($handle, CURLOPT_URL, $url); + curl_setopt($handle, CURLOPT_RETURNTRANSFER, true); + curl_setopt($handle, CURLOPT_POST, true); + curl_setopt($handle, CURLOPT_POSTFIELDS, ['json' => 1]); + + $results = curl_exec($handle); + $errorNumber = curl_errno($handle); + $errorDescription = curl_error($handle); + curl_close($handle); + + return [ + 'results' => $results, + 'errorNumber' => $errorNumber, + 'errorDescription' => $errorDescription, + ]; + } } diff --git a/app/views/inc/header-languages.volt b/app/views/inc/header-languages.volt index 7c23733..159dee5 100644 --- a/app/views/inc/header-languages.volt +++ b/app/views/inc/header-languages.volt @@ -3,6 +3,7 @@ {% else %} {% set suffix = '' %} {% endif %} + {% set languages = config.path('app.languages', []) %}