From 3af85ed14fa8fb9757b4f8562c95b39dbefb78ad Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 8 Jul 2015 20:01:55 -0600 Subject: [PATCH 01/13] added xml, json, css, and js to supported media "file" types --- system/config/media.yaml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/system/config/media.yaml b/system/config/media.yaml index 62dfa75eb..443ec8aeb 100644 --- a/system/config/media.yaml +++ b/system/config/media.yaml @@ -75,6 +75,10 @@ txt: type: file thumb: media/thumb-txt.png mime: text/plain +xml: + type: file + thumb: media/thumb-xml.png + mime: application/xml doc: type: file thumb: media/thumb-doc.png @@ -95,3 +99,16 @@ gz: type: file thumb: media/thumb-gz.png mime: application/gzip +css: + type: file + thumb: media/thumb-css.png + mime: text/css +js: + type: file + thumb: media/thumb-js.png + mime: application/javascript +json: + type: file + thumb: media/thumb-json.png + mime: application/json + From 875885f647af0e3c97c7c7bedbd08af9b592bd38 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 8 Jul 2015 20:03:04 -0600 Subject: [PATCH 02/13] changed pages.types to be an array --- system/config/system.yaml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index fa8b6019c..f78b9f356 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -30,7 +30,7 @@ pages: special_chars: # List of special characters to automatically convert to entities '>': 'gt' '<': 'lt' - types: 'txt|xml|html|json|rss|atom' # Pipe separated list of valid page types + types: [txt,xml,html,json,rss,atom] # list of valid page types expires: 604800 # Page expires time in seconds (604800 seconds = 7 days) last_modified: false # Set the last modified date header based on file modifcation timestamp etag: false # Set the etag header tag From 8a7a9d4a45aff8c092c0ec67552cfe7a46959429 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 8 Jul 2015 20:03:43 -0600 Subject: [PATCH 03/13] added a configurable array for unsupported file types to inline rather than download --- system/config/system.yaml | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/system/config/system.yaml b/system/config/system.yaml index f78b9f356..0e68a3e6f 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -82,11 +82,12 @@ images: media: enable_media_timestamp: false # Enable media timetsamps upload_limit: 0 # Set maximum upload size in bytes (0 is unlimited) + unsupported_inline_types: [] # Array of unsupported media file types to try to display inline session: - enabled: true # Enable Session support - timeout: 1800 # Timeout in seconds - name: grav-site # Name prefix of the session cookie + enabled: true # Enable Session support + timeout: 1800 # Timeout in seconds + name: grav-site # Name prefix of the session cookie security: default_hash: $2y$10$kwsyMVwM8/7j0K/6LHT.g.Fs49xOCTp2b8hh/S5.dPJuJcJB6T.UK From 85add10bef3e47b8baa9ce48ffd113829441d5cd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 8 Jul 2015 20:04:15 -0600 Subject: [PATCH 04/13] better handling of unsupported media types download --- system/src/Grav/Common/Grav.php | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 71810e23e..70163641d 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -437,11 +437,11 @@ class Grav extends Container Utils::download($medium->path(), false); } - // has an extension, try to download it... - if (isset($path_parts['extension'])) { + // unsupported media type, try to download it... + $extension = $uri->extension() ?: $path_parts['extension']; + if ($extension) { $download = true; - // little work-around to ensure .css and .js files are always sent inline not downloaded - if (in_array($path_parts['extension'], ['.css', '.js'])) { + if (in_array(ltrim($extension, '.'), $this['config']->get('system.media.unsupported_inline_types'))) { $download = false; } Utils::download($page->path() . DIRECTORY_SEPARATOR . $uri->basename(), $download); From 3719bac746e685279020e2987258bfb5e426d028 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Wed, 8 Jul 2015 20:05:26 -0600 Subject: [PATCH 05/13] use an array for clarity --- system/src/Grav/Common/Uri.php | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php index c070dfcf2..cf24146dd 100644 --- a/system/src/Grav/Common/Uri.php +++ b/system/src/Grav/Common/Uri.php @@ -120,7 +120,9 @@ class Uri // set the original basename $this->basename = $parts['basename']; - if (preg_match("/\.(".$config->get('system.pages.types').")$/", $parts['basename'])) { + $valid_page_types = implode('|', $config->get('system.pages.types')); + + if (preg_match("/\.(".$valid_page_types.")$/", $parts['basename'])) { $uri = rtrim(str_replace(DIRECTORY_SEPARATOR, DS, $parts['dirname']), DS). '/' .$parts['filename']; $this->extension = $parts['extension']; } From c097907098ad5bc1c2230703009a200f6ac6d9cb Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 09:44:10 -0600 Subject: [PATCH 06/13] safety check --- system/src/Grav/Common/Grav.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 70163641d..c9c4aa221 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -438,7 +438,7 @@ class Grav extends Container } // unsupported media type, try to download it... - $extension = $uri->extension() ?: $path_parts['extension']; + $extension = $uri->extension() ?: isset($path_parts['extension']) ? $path_parts['extension'] : null; if ($extension) { $download = true; if (in_array(ltrim($extension, '.'), $this['config']->get('system.media.unsupported_inline_types'))) { From bb348fff947c0855f299972f8f058791e621ad56 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 11:56:46 -0600 Subject: [PATCH 07/13] fix for translations --- system/src/Grav/Common/Config/Config.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Config/Config.php b/system/src/Grav/Common/Config/Config.php index f1d2d611b..9e749c652 100644 --- a/system/src/Grav/Common/Config/Config.php +++ b/system/src/Grav/Common/Config/Config.php @@ -179,7 +179,7 @@ class Config extends Data $this->loadCompiledConfig($this->configLookup, $this->pluginLookup, 'master'); // process languages if supported - if ($this->get('languages', false)) { + if ($this->get('system.languages', false)) { $this->languagesLookup = $locator->findResources('languages://'); $this->loadCompiledLanguages($this->languagesLookup, $this->pluginLookup, 'master'); } From 14753d499d98d41b38e55a436da8dea41c74e1b9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 14:47:24 -0600 Subject: [PATCH 08/13] Fix for markdown filter error: Issue #115 --- system/src/Grav/Common/TwigExtension.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index 77d06bcfe..448c98af4 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -339,7 +339,7 @@ class TwigExtension extends \Twig_Extension public function markdownFilter($string) { $page = $this->grav['page']; - $defaults = $this->$config->get('system.pages.markdown'); + $defaults = $this->config->get('system.pages.markdown'); // Initialize the preferred variant of Parsedown if ($defaults['extra']) { From b3ba54894ea81e6226eb7442b6b604bee739f04b Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 17:07:52 -0600 Subject: [PATCH 09/13] removed useless call --- system/src/Grav/Common/Page/Page.php | 1 - 1 file changed, 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 8f64059f2..a479c52c5 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -138,7 +138,6 @@ class Page } } $this->published(); - $this->extension(); } /** From e48be33c6c8f50e60105bf5d9ac6b819a3fe35b2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 17:08:29 -0600 Subject: [PATCH 10/13] unified backup command to mimic admin functionality --- system/src/Grav/Console/Cli/BackupCommand.php | 38 +++++++++---------- 1 file changed, 17 insertions(+), 21 deletions(-) diff --git a/system/src/Grav/Console/Cli/BackupCommand.php b/system/src/Grav/Console/Cli/BackupCommand.php index 46590bf39..a597efc7d 100644 --- a/system/src/Grav/Console/Cli/BackupCommand.php +++ b/system/src/Grav/Console/Cli/BackupCommand.php @@ -1,13 +1,15 @@ addArgument( 'destination', InputArgument::OPTIONAL, - 'Where to store the backup' + 'Where to store the backup (/backup is default)' ) ->setDescription("Creates a backup of the Grav instance") ->setHelp('The backup creates a zipped backup. Optionally can be saved in a different destination.'); - $this->source = getcwd(); } @@ -57,19 +49,22 @@ class BackupCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - $this->output = $output; - - $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); - $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); - $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); - $output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta')); + $this->setupConsole($input, $output); $this->progress = new ProgressBar($output); $this->progress->setFormat('Archiving %current% files [%bar%] %elapsed:6s% %memory:6s%'); - $destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : ROOT_DIR; + self::getGrav()['config']->init(); - ZipBackup::backup($destination, [$this, 'output']); + $destination = ($input->getArgument('destination')) ? $input->getArgument('destination') : null; + $log = JsonFile::instance(self::getGrav()['locator']->findResource("log://backup.log", true, true)); + $backup = ZipBackup::backup($destination, [$this, 'output']); + + $log->content([ + 'time' => time(), + 'location' => $backup + ]); + $log->save(); $output->writeln(''); $output->writeln(''); @@ -97,5 +92,6 @@ class BackupCommand extends Command break; } } + } From 07f4cb0892fd01c79239f19d2f4f4b01da059a35 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 17:23:33 -0600 Subject: [PATCH 11/13] updated to latest composer.par --- bin/composer.phar | Bin 1103856 -> 1113024 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/composer.phar b/bin/composer.phar index a08ea4eba3ab936bd19cef6df49d344601a2bce0..4b099f5b829ac253c507a5eff995d7423c7c9b8b 100755 GIT binary patch delta 17861 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 pnvcazF_Fi~{{b~<9Ekt` From b9d6f7592363cf0e31b4d7922e2b281259df743c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 17:23:56 -0600 Subject: [PATCH 12/13] Updated all bin/grav CLI commands to use ConsoleTrait --- system/src/Grav/Console/Cli/CleanCommand.php | 33 ++++------ .../Grav/Console/Cli/ClearCacheCommand.php | 33 +++++----- .../src/Grav/Console/Cli/ComposerCommand.php | 2 + .../src/Grav/Console/Cli/InstallCommand.php | 61 ++++++++----------- .../Grav/Console/Cli/NewProjectCommand.php | 3 + .../src/Grav/Console/Cli/SandboxCommand.php | 25 ++------ 6 files changed, 61 insertions(+), 96 deletions(-) diff --git a/system/src/Grav/Console/Cli/CleanCommand.php b/system/src/Grav/Console/Cli/CleanCommand.php index 5ceaed611..350c9ab54 100644 --- a/system/src/Grav/Console/Cli/CleanCommand.php +++ b/system/src/Grav/Console/Cli/CleanCommand.php @@ -2,6 +2,7 @@ namespace Grav\Console\Cli; use Grav\Common\Filesystem\Folder; +use Grav\Console\ConsoleTrait; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputInterface; @@ -13,6 +14,7 @@ use Symfony\Component\Console\Output\OutputInterface; */ class CleanCommand extends Command { + use ConsoleTrait; /** * @var array @@ -177,27 +179,14 @@ class CleanCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - - - // Create a red output option - $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); - $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); - $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); - $output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta')); - - $this->cleanPaths($output); - - + $this->setupConsole($input, $output); + $this->cleanPaths(); } - // loops over the array of paths and deletes the files/folders - /** - * @param OutputInterface $output - */ - private function cleanPaths(OutputInterface $output) + private function cleanPaths() { - $output->writeln(''); - $output->writeln('DELETING'); + $this->output->writeln(''); + $this->output->writeln('DELETING'); $anything = false; @@ -206,16 +195,16 @@ class CleanCommand extends Command if (is_dir($path) && @Folder::delete($path)) { $anything = true; - $output->writeln('dir: ' . $path); + $this->output->writeln('dir: ' . $path); } elseif (is_file($path) && @unlink($path)) { $anything = true; - $output->writeln('file: ' . $path); + $this->output->writeln('file: ' . $path); } } if (!$anything) { - $output->writeln(''); - $output->writeln('Nothing to clean...'); + $this->output->writeln(''); + $this->output->writeln('Nothing to clean...'); } } diff --git a/system/src/Grav/Console/Cli/ClearCacheCommand.php b/system/src/Grav/Console/Cli/ClearCacheCommand.php index e565671e9..944064839 100644 --- a/system/src/Grav/Console/Cli/ClearCacheCommand.php +++ b/system/src/Grav/Console/Cli/ClearCacheCommand.php @@ -2,6 +2,7 @@ namespace Grav\Console\Cli; use Grav\Common\Cache; +use Grav\Console\ConsoleTrait; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputInterface; @@ -14,6 +15,7 @@ use Symfony\Component\Console\Output\OutputInterface; */ class ClearCacheCommand extends Command { + use ConsoleTrait; /** * @@ -38,40 +40,33 @@ class ClearCacheCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { - // Create a red output option - $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); - $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); - $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); - $output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta')); - - $this->cleanPaths($input, $output); + $this->setupConsole($input, $output); + $this->cleanPaths(); } - // loops over the array of paths and deletes the files/folders /** - * @param InputInterface $input - * @param OutputInterface $output + * loops over the array of paths and deletes the files/folders */ - private function cleanPaths(InputInterface $input, OutputInterface $output) + private function cleanPaths() { - $output->writeln(''); - $output->writeln('Clearing cache'); - $output->writeln(''); + $this->output->writeln(''); + $this->output->writeln('Clearing cache'); + $this->output->writeln(''); - if ($input->getOption('all')) { + if ($this->input->getOption('all')) { $remove = 'all'; - } elseif ($input->getOption('assets-only')) { + } elseif ($this->input->getOption('assets-only')) { $remove = 'assets-only'; - } elseif ($input->getOption('images-only')) { + } elseif ($this->input->getOption('images-only')) { $remove = 'images-only'; - } elseif ($input->getOption('cache-only')) { + } elseif ($this->input->getOption('cache-only')) { $remove = 'cache-only'; } else { $remove = 'standard'; } foreach (Cache::clearCache($remove) as $result) { - $output->writeln($result); + $this->output->writeln($result); } } } diff --git a/system/src/Grav/Console/Cli/ComposerCommand.php b/system/src/Grav/Console/Cli/ComposerCommand.php index 3a28718ac..2688b78c1 100644 --- a/system/src/Grav/Console/Cli/ComposerCommand.php +++ b/system/src/Grav/Console/Cli/ComposerCommand.php @@ -66,6 +66,8 @@ class ComposerCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->setupConsole($input, $output); + $action = 'update'; if ($input->getOption('install')) { diff --git a/system/src/Grav/Console/Cli/InstallCommand.php b/system/src/Grav/Console/Cli/InstallCommand.php index 8aead008f..ef2c2fa71 100644 --- a/system/src/Grav/Console/Cli/InstallCommand.php +++ b/system/src/Grav/Console/Cli/InstallCommand.php @@ -65,6 +65,7 @@ class InstallCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->setupConsole($input, $output); $dependencies_file = '.dependencies'; $local_config_file = exec('eval echo ~/.grav/config'); @@ -74,12 +75,6 @@ class InstallCommand extends Command $this->destination = rtrim($this->destination, DS) . DS; $this->user_path = $this->destination . USER_PATH; - // Create a red output option - $output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); - $output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); - $output->getFormatter()->setStyle('green', new OutputFormatterStyle('green')); - $output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta')); - if (file_exists($local_config_file)) { $this->local_config = Yaml::parse($local_config_file); $output->writeln('Read local config from ' . $local_config_file . ''); @@ -101,9 +96,9 @@ class InstallCommand extends Command $output->writeln("\nInstalling vendor dependencies"); $output->writeln($this->composerUpdate(GRAV_ROOT, 'install')); - $this->gitclone($output); + $this->gitclone(); } else { - $this->symlink($output); + $this->symlink(); } } else { $output->writeln('ERROR invalid YAML in ' . $dependencies_file); @@ -112,45 +107,43 @@ class InstallCommand extends Command } - // loops over the array of paths and deletes the files/folders /** - * @param OutputInterface $output + * Clones from Git */ - private function gitclone(OutputInterface $output) + private function gitclone() { - $output->writeln(''); - $output->writeln('Cloning Bits'); - $output->writeln('============'); - $output->writeln(''); + $this->output->writeln(''); + $this->output->writeln('Cloning Bits'); + $this->output->writeln('============'); + $this->output->writeln(''); foreach ($this->config['git'] as $repo => $data) { $path = $this->destination . DS . $data['path']; if (!file_exists($path)) { exec('cd "' . $this->destination . '" && git clone -b ' . $data['branch'] . ' ' . $data['url'] . ' ' . $data['path']); - $output->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); - $output->writeln(''); + $this->output->writeln('SUCCESS cloned ' . $data['url'] . ' -> ' . $path . ''); + $this->output->writeln(''); } else { - $output->writeln('' . $path . ' already exists, skipping...'); - $output->writeln(''); + $this->output->writeln('' . $path . ' already exists, skipping...'); + $this->output->writeln(''); } } } - // loops over the array of paths and deletes the files/folders /** - * @param OutputInterface $output + * Symlinks */ - private function symlink(OutputInterface $output) + private function symlink() { - $output->writeln(''); - $output->writeln('Symlinking Bits'); - $output->writeln('==============='); - $output->writeln(''); + $this->output->writeln(''); + $this->output->writeln('Symlinking Bits'); + $this->output->writeln('==============='); + $this->output->writeln(''); if (!$this->local_config) { - $output->writeln('No local configuration available, aborting...'); - $output->writeln(''); + $this->output->writeln('No local configuration available, aborting...'); + $this->output->writeln(''); return; } @@ -162,15 +155,15 @@ class InstallCommand extends Command if (file_exists($from)) { if (!file_exists($to)) { symlink($from, $to); - $output->writeln('SUCCESS symlinked ' . $data['src'] . ' -> ' . $data['path'] . ''); - $output->writeln(''); + $this->output->writeln('SUCCESS symlinked ' . $data['src'] . ' -> ' . $data['path'] . ''); + $this->output->writeln(''); } else { - $output->writeln('destination: ' . $to . ' already exists, skipping...'); - $output->writeln(''); + $this->output->writeln('destination: ' . $to . ' already exists, skipping...'); + $this->output->writeln(''); } } else { - $output->writeln('source: ' . $from . ' does not exists, skipping...'); - $output->writeln(''); + $this->output->writeln('source: ' . $from . ' does not exists, skipping...'); + $this->output->writeln(''); } } diff --git a/system/src/Grav/Console/Cli/NewProjectCommand.php b/system/src/Grav/Console/Cli/NewProjectCommand.php index 708b01901..6e193fe25 100644 --- a/system/src/Grav/Console/Cli/NewProjectCommand.php +++ b/system/src/Grav/Console/Cli/NewProjectCommand.php @@ -1,6 +1,7 @@ setupConsole($input, $output); $sandboxCommand = $this->getApplication()->find('sandbox'); $installCommand = $this->getApplication()->find('install'); diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index a5a6ce126..d490655a6 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -2,6 +2,7 @@ namespace Grav\Console\Cli; use Grav\Common\Filesystem\Folder; +use Grav\Console\ConsoleTrait; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputArgument; @@ -15,6 +16,8 @@ use Symfony\Component\Console\Output\OutputInterface; */ class SandboxCommand extends Command { + use ConsoleTrait; + /** * @var array */ @@ -66,22 +69,8 @@ class SandboxCommand extends Command protected $default_file = "---\ntitle: HomePage\n---\n# HomePage\n\nLorem ipsum dolor sit amet, consectetur adipiscing elit. Pellentesque porttitor eu felis sed ornare. Sed a mauris venenatis, pulvinar velit vel, dictum enim. Phasellus ac rutrum velit. Nunc lorem purus, hendrerit sit amet augue aliquet, iaculis ultricies nisl. Suspendisse tincidunt euismod risus, quis feugiat arcu tincidunt eget. Nulla eros mi, commodo vel ipsum vel, aliquet congue odio. Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Pellentesque velit orci, laoreet at adipiscing eu, interdum quis nibh. Nunc a accumsan purus."; - /** - * @var - */ protected $source; - /** - * @var - */ protected $destination; - /** - * @var InputInterface $input - */ - protected $input; - /** - * @var OutputInterface $output - */ - protected $output; /** * @@ -114,14 +103,8 @@ class SandboxCommand extends Command */ protected function execute(InputInterface $input, OutputInterface $output) { + $this->setupConsole($input, $output); $this->destination = $input->getArgument('destination'); - $this->input = $input; - $this->output = $output; - - // Create a red output option - $this->output->getFormatter()->setStyle('red', new OutputFormatterStyle('red')); - $this->output->getFormatter()->setStyle('cyan', new OutputFormatterStyle('cyan')); - $this->output->getFormatter()->setStyle('magenta', new OutputFormatterStyle('magenta')); // Symlink the Core Stuff if ($input->getOption('symlink')) { From 05e00139902a452e0a39132e721d7fb5d9f2fe91 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 9 Jul 2015 17:30:26 -0600 Subject: [PATCH 13/13] version update --- CHANGELOG.md | 13 +++++++++++++ system/defines.php | 2 +- 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3c89cfc8c..41586628a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +# v0.9.31 +## 07/09/2015 + +1. [](#new) + * Added xml, json, css and js to valid media file types +2. [](#improved) + * Better handling of unsupported media type downloads + * Improved `bin/grav backup` command to mimic admin plugin location/name +3. [](#bugfix) + * Critical fix for broken language translations + * Fix for Twig markdown filter error + * Safety check for download extension + # v0.9.30 ## 07/08/2015 diff --git a/system/defines.php b/system/defines.php index ecbf279c5..1f80d03a8 100644 --- a/system/defines.php +++ b/system/defines.php @@ -2,7 +2,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '0.9.30'); +define('GRAV_VERSION', '0.9.31'); define('DS', '/'); // Directories and Paths