diff --git a/CHANGELOG.md b/CHANGELOG.md
index d60a7ab36..fcbd4e51f 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,5 +1,13 @@
+# v1.0.8
+## 01/08/2016
+
+1. [](#new)
+ * Added `rotate`, `flip` and `fixOrientation` image medium methods
+1. [](#bugfix)
+ * Removed IP from Nonce generation. Should be more reliable in a variety of scenarios
+
# v1.0.7
-## 01/XX/2016
+## 01/07/2016
1. [](#new)
* Added `composer create-project` as an additional installation method #585
@@ -11,6 +19,7 @@
* Added global setting for `twig_first` processing (false by default)
* New configuration options for Session settings #553
1. [](#improved)
+ * Switched to SSL for GPM calls
* Use `URI->host()` for session domain
* Add support for `open_basedir` when installing packages via GPM
* Improved `Utils::generateNonceString()` method to handle reverse proxies
@@ -30,6 +39,7 @@
* Fix for markdown attributes on external URLs
* Fixed issue where `data:` page header was acting as `publish_date:`
* Fix for special characters in URL parameters (e.g. /tag:c++) #541
+ * Safety check for an array of nonces to only use the first one
# v1.0.6
## 12/22/2015
diff --git a/composer.json b/composer.json
index 4b5d1efe3..bf9467b7c 100644
--- a/composer.json
+++ b/composer.json
@@ -23,7 +23,10 @@
"donatj/phpuseragentparser": "~0.3",
"pimple/pimple": "~3.0",
"rockettheme/toolbox": "~1.2",
- "maximebf/debugbar": "~1.10"
+ "maximebf/debugbar": "~1.10",
+ "ext-mbstring": "*",
+ "ext-openssl": "*",
+ "ext-curl": "*"
},
"require-dev": {
"codeception/codeception": "^2.1",
diff --git a/composer.lock b/composer.lock
index 2e4ff147c..5252c1f7a 100644
--- a/composer.lock
+++ b/composer.lock
@@ -1076,16 +1076,16 @@
},
{
"name": "twig/twig",
- "version": "v1.23.1",
+ "version": "v1.23.3",
"source": {
"type": "git",
"url": "https://github.com/twigphp/Twig.git",
- "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6"
+ "reference": "ae53fc2c312fdee63773b75cb570304f85388b08"
},
"dist": {
"type": "zip",
- "url": "https://api.github.com/repos/twigphp/Twig/zipball/d9b6333ae8dd2c8e3fd256e127548def0bc614c6",
- "reference": "d9b6333ae8dd2c8e3fd256e127548def0bc614c6",
+ "url": "https://api.github.com/repos/twigphp/Twig/zipball/ae53fc2c312fdee63773b75cb570304f85388b08",
+ "reference": "ae53fc2c312fdee63773b75cb570304f85388b08",
"shasum": ""
},
"require": {
@@ -1133,7 +1133,7 @@
"keywords": [
"templating"
],
- "time": "2015-11-05 12:49:06"
+ "time": "2016-01-11 14:02:19"
}
],
"packages-dev": [
diff --git a/system/blueprints/config/system.yaml b/system/blueprints/config/system.yaml
index 2d7f78b56..ecde4be87 100644
--- a/system/blueprints/config/system.yaml
+++ b/system/blueprints/config/system.yaml
@@ -848,6 +848,17 @@ form:
underline: true
fields:
+ reverse_proxy_setup:
+ type: toggle
+ label: PLUGIN_ADMIN.REVERSE_PROXY
+ highlight: 0
+ help: PLUGIN_ADMIN.REVERSE_PROXY_HELP
+ options:
+ 1: PLUGIN_ADMIN.YES
+ 0: PLUGIN_ADMIN.NO
+ validate:
+ type: bool
+
wrapped_site:
type: toggle
label: PLUGIN_ADMIN.WRAPPED_SITE
diff --git a/system/blueprints/pages/default.yaml b/system/blueprints/pages/default.yaml
index d421bbd62..6eab5d464 100644
--- a/system/blueprints/pages/default.yaml
+++ b/system/blueprints/pages/default.yaml
@@ -139,7 +139,7 @@ form:
type: select
label: PLUGIN_ADMIN.PARENT
classes: fancy
- '@data-options': '\Grav\Common\Page\Pages::parents'
+ '@data-options': '\Grav\Common\Page\Pages::parentsRawRoutes'
'@data-default': '\Grav\Plugin\admin::route'
options:
'/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
diff --git a/system/blueprints/pages/new_folder.yaml b/system/blueprints/pages/new_folder.yaml
new file mode 100644
index 000000000..311d814bd
--- /dev/null
+++ b/system/blueprints/pages/new_folder.yaml
@@ -0,0 +1,35 @@
+rules:
+ slug:
+ pattern: "[a-z][a-z0-9_\-]+"
+ min: 2
+ max: 80
+
+form:
+ validation: loose
+ fields:
+
+ section:
+ type: section
+ title: PLUGIN_ADMIN.ADD_PAGE
+
+ folder:
+ type: text
+ label: PLUGIN_ADMIN.FOLDER_NAME
+ help: PLUGIN_ADMIN.FOLDER_NAME_HELP
+ validate:
+ type: slug
+ required: true
+
+ route:
+ type: select
+ label: PLUGIN_ADMIN.PARENT_PAGE
+ classes: fancy
+ '@data-options': '\Grav\Common\Page\Pages::parents'
+ '@data-default': '\Grav\Plugin\admin::getLastPageRoute'
+ options:
+ '/': PLUGIN_ADMIN.DEFAULT_OPTION_ROOT
+ validate:
+ required: true
+
+ blueprint:
+ type: blueprint
diff --git a/system/config/system.yaml b/system/config/system.yaml
index 4b0bdb486..17a2bf3d4 100644
--- a/system/config/system.yaml
+++ b/system/config/system.yaml
@@ -3,6 +3,7 @@ timezone: '' # Valid values: http://php.net/manua
default_locale: # Default locale (defaults to system)
param_sep: ':' # Parameter separator, use ';' for Apache on windows
wrapped_site: false # For themes/plugins to know if Grav is wrapped by another platform
+reverse_proxy_setup: false # Running in a reverse proxy scenario with different webserver ports than proxy
languages:
supported: [] # List of languages supported. eg: [en, fr, de]
diff --git a/system/defines.php b/system/defines.php
index 929d5d2e4..6127aca1e 100644
--- a/system/defines.php
+++ b/system/defines.php
@@ -2,7 +2,7 @@
// Some standard defines
define('GRAV', true);
-define('GRAV_VERSION', '1.0.6');
+define('GRAV_VERSION', '1.0.8');
define('DS', '/');
define('GRAV_PHP_MIN', '5.5.9');
diff --git a/system/languages/hr.yaml b/system/languages/hr.yaml
index 3dbd80218..098b8f922 100644
--- a/system/languages/hr.yaml
+++ b/system/languages/hr.yaml
@@ -50,3 +50,5 @@ NICETIME:
FORM:
VALIDATION_FAIL: Validacija nije uspjela:
INVALID_INPUT: Unos nije valjan
+MONTHS_OF_THE_YEAR: ['Siječanj', 'Veljača', 'Ožujak', 'Travanj', 'Svibanj', 'Lipanj', 'Srpanj', 'Kolovoz', 'Rujan', 'Listopad', 'Studeni', 'Prosinac']
+DAYS_OF_THE_WEEK: ['ponedjeljak', 'utorak', 'srijeda', 'četvrtak', 'petak', 'subota', 'nedjelja']
diff --git a/system/src/Grav/Common/Config/Setup.php b/system/src/Grav/Common/Config/Setup.php
index b345426c1..8b6b70750 100644
--- a/system/src/Grav/Common/Config/Setup.php
+++ b/system/src/Grav/Common/Config/Setup.php
@@ -158,7 +158,7 @@ class Setup extends Data
}
// Update streams.
- foreach ($files as $path) {
+ foreach (array_reverse($files) as $path) {
$file = CompiledYamlFile::instance($path);
$content = $file->content();
if (!empty($content['schemes'])) {
diff --git a/system/src/Grav/Common/GPM/Remote/Grav.php b/system/src/Grav/Common/GPM/Remote/Grav.php
index 152b8eda7..cbc3179fc 100644
--- a/system/src/Grav/Common/GPM/Remote/Grav.php
+++ b/system/src/Grav/Common/GPM/Remote/Grav.php
@@ -5,7 +5,7 @@ use \Doctrine\Common\Cache\FilesystemCache;
class Grav extends AbstractPackageCollection
{
- protected $repository = 'http://getgrav.org/downloads/grav.json';
+ protected $repository = 'https://getgrav.org/downloads/grav.json';
private $data;
private $version;
diff --git a/system/src/Grav/Common/GPM/Remote/Plugins.php b/system/src/Grav/Common/GPM/Remote/Plugins.php
index df8668491..036fc0c2a 100644
--- a/system/src/Grav/Common/GPM/Remote/Plugins.php
+++ b/system/src/Grav/Common/GPM/Remote/Plugins.php
@@ -12,7 +12,7 @@ class Plugins extends AbstractPackageCollection
*/
protected $type = 'plugins';
- protected $repository = 'http://getgrav.org/downloads/plugins.json';
+ protected $repository = 'https://getgrav.org/downloads/plugins.json';
/**
* Local Plugins Constructor
diff --git a/system/src/Grav/Common/GPM/Remote/Themes.php b/system/src/Grav/Common/GPM/Remote/Themes.php
index 0af055b03..43a5af54d 100644
--- a/system/src/Grav/Common/GPM/Remote/Themes.php
+++ b/system/src/Grav/Common/GPM/Remote/Themes.php
@@ -12,7 +12,7 @@ class Themes extends AbstractPackageCollection
*/
protected $type = 'themes';
- protected $repository = 'http://getgrav.org/downloads/themes.json';
+ protected $repository = 'https://getgrav.org/downloads/themes.json';
/**
* Local Themes Constructor
diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php
index 053b7fa1f..1642211d2 100644
--- a/system/src/Grav/Common/Grav.php
+++ b/system/src/Grav/Common/Grav.php
@@ -58,7 +58,7 @@ class Grav extends Container
$container['grav'] = $container;
$container['debugger'] = new Debugger();
- $container['debugger']->startTimer('_init', 'Initialize');
+ $container['debugger']->startTimer('_services', 'Services');
$container->register(new LoggerServiceProvider);
@@ -173,7 +173,7 @@ class Grav extends Container
$container['inflector'] = new Inflector();
- $container['debugger']->stopTimer('_init');
+ $container['debugger']->stopTimer('_services');
return $container;
}
@@ -183,17 +183,25 @@ class Grav extends Container
/** @var Debugger $debugger */
$debugger = $this['debugger'];
+ // Load site setup and initializing streams.
+ $debugger->startTimer('_setup', 'Site Setup');
+ $this['setup']->init();
+ $this['streams'];
+ $debugger->stopTimer('_setup');
+
// Initialize configuration.
$debugger->startTimer('_config', 'Configuration');
$this['config']->init();
- $this['errors']->resetHandlers();
- $this['uri']->init();
- $this['session']->init();
-
- $debugger->init();
- $this['config']->debug();
$debugger->stopTimer('_config');
+ // Initialize error handlers.
+ $this['errors']->resetHandlers();
+
+ // Initialize debugger.
+ $debugger->init();
+ $debugger->startTimer('init', 'Initialize');
+ $this['config']->debug();
+
// Use output buffering to prevent headers from being sent too early.
ob_start();
if ($this['config']->get('system.cache.gzip')) {
@@ -203,21 +211,23 @@ class Grav extends Container
}
}
- // Initialize the timezone
+ // Initialize the timezone.
if ($this['config']->get('system.timezone')) {
date_default_timezone_set($this['config']->get('system.timezone'));
}
- // Initialize Locale if set and configured
+ // Initialize uri, session.
+ $this['uri']->init();
+ $this['session']->init();
+
+ // Initialize Locale if set and configured.
if ($this['language']->enabled() && $this['config']->get('system.languages.override_locale')) {
setlocale(LC_ALL, $this['language']->getLanguage());
} elseif ($this['config']->get('system.default_locale')) {
setlocale(LC_ALL, $this['config']->get('system.default_locale'));
}
- $debugger->startTimer('streams', 'Streams');
- $this['streams'];
- $debugger->stopTimer('streams');
+ $debugger->stopTimer('init');
$debugger->startTimer('plugins', 'Plugins');
$this['plugins']->init();
diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
index 57bdcd93b..6617ab5a0 100644
--- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
+++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php
@@ -34,6 +34,7 @@ trait ParsedownGravTrait
$this->page = $page;
$this->pages = $grav['pages'];
$this->BlockTypes['{'] [] = "TwigTag";
+ $this->BlockTypes['['] [] = "ShortcodeTag";
$this->base_url = rtrim(self::getGrav()['base_url'] . self::getGrav()['pages']->base(), '/');
$this->pages_dir = self::getGrav()['locator']->findResource('page://');
$this->special_chars = array('>' => 'gt', '<' => 'lt', '"' => 'quot');
@@ -145,6 +146,16 @@ trait ParsedownGravTrait
}
}
+ protected function blockShortcodeTag($Line)
+ {
+ if (preg_match('/^(?:\[)(.*)(?:\])$/', $Line['body'], $matches)) {
+ $Block = array(
+ 'markup' => $Line['body'],
+ );
+ return $Block;
+ }
+ }
+
protected function inlineSpecialCharacter($Excerpt)
{
if ($Excerpt['text'][0] === '&' && ! preg_match('/^?\w+;/', $Excerpt['text'])) {
diff --git a/system/src/Grav/Common/Page/Medium/ImageMedium.php b/system/src/Grav/Common/Page/Medium/ImageMedium.php
index 3db039643..85de365d3 100644
--- a/system/src/Grav/Common/Page/Medium/ImageMedium.php
+++ b/system/src/Grav/Common/Page/Medium/ImageMedium.php
@@ -41,7 +41,8 @@ class ImageMedium extends Medium
public static $magic_actions = [
'resize', 'forceResize', 'cropResize', 'crop', 'zoomCrop',
'negate', 'brightness', 'contrast', 'grayscale', 'emboss',
- 'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive'
+ 'smooth', 'sharp', 'edge', 'colorize', 'sepia', 'enableProgressive',
+ 'rotate', 'flip', 'fixOrientation'
];
/**
diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php
index 4cf61791d..916d99aca 100644
--- a/system/src/Grav/Common/Page/Page.php
+++ b/system/src/Grav/Common/Page/Page.php
@@ -1152,11 +1152,12 @@ class Page
$this->metadata = [];
+ $metadata = [];
// Set the Generator tag
- $this->metadata['generator'] = array('name'=>'generator', 'content'=>'GravCMS');
+ $metadata['generator'] = 'GravCMS';
// Get initial metadata for the page
- $metadata = self::getGrav()['config']->get('site.metadata');
+ $metadata = array_merge($metadata, self::getGrav()['config']->get('site.metadata'));
if (isset($this->header->metadata)) {
// Merge any site.metadata settings in with page metadata
@@ -1173,12 +1174,15 @@ class Page
}
// If it this is a standard meta data type
} else {
- if (in_array($key, $header_tag_http_equivs)) {
- $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES));
- } else {
- $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES));
+ if ($value) {
+ if (in_array($key, $header_tag_http_equivs)) {
+ $this->metadata[$key] = array('http_equiv'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES));
+ } else {
+ $this->metadata[$key] = array('name'=>$key, 'content'=>htmlspecialchars($value, ENT_QUOTES));
+ }
}
}
+
}
}
@@ -1420,6 +1424,7 @@ class Page
if ($var !== null) {
$this->modified = $var;
}
+
return $this->modified;
}
diff --git a/system/src/Grav/Common/Page/Pages.php b/system/src/Grav/Common/Page/Pages.php
index 7193db791..2dd1bbadf 100644
--- a/system/src/Grav/Common/Page/Pages.php
+++ b/system/src/Grav/Common/Page/Pages.php
@@ -398,7 +398,7 @@ class Pages
* @return array
* @throws \RuntimeException
*/
- public function getList(Page $current = null, $level = 0)
+ public function getList(Page $current = null, $level = 0, $rawRoutes = false)
{
if (!$current) {
if ($level) {
@@ -411,11 +411,16 @@ class Pages
$list = array();
if (!$current->root()) {
- $list[$current->route()] = str_repeat(' ', ($level-1)*2) . $current->title();
+ if ($rawRoutes) {
+ $route = $current->rawRoute();
+ } else {
+ $route = $current->route();
+ }
+ $list[$route] = str_repeat(' ', ($level-1)*2) . $current->title();
}
foreach ($current->children() as $next) {
- $list = array_merge($list, $this->getList($next, $level + 1));
+ $list = array_merge($list, $this->getList($next, $level + 1, $rawRoutes));
}
return $list;
@@ -517,18 +522,42 @@ class Pages
}
/**
- * Get available parents.
+ * Get available parents routes
*
* @return array
*/
public static function parents()
+ {
+ $rawRoutes = false;
+ return self::getParents($rawRoutes);
+ }
+
+ /**
+ * Get available parents raw routes.
+ *
+ * @return array
+ */
+ public static function parentsRawRoutes()
+ {
+ $rawRoutes = true;
+ return self::getParents($rawRoutes);
+ }
+
+ /**
+ * Get available parents routes
+ *
+ * @param bool $rawRoutes get the raw route or the normal route
+ *
+ * @return array
+ */
+ private static function getParents($rawRoutes)
{
$grav = Grav::instance();
/** @var Pages $pages */
$pages = $grav['pages'];
- $parents = $pages->getList();
+ $parents = $pages->getList(null, 0, $rawRoutes);
/** @var Admin $admin */
$admin = $grav['admin'];
@@ -544,6 +573,7 @@ class Pages
}
return $parents;
+
}
/**
@@ -790,6 +820,17 @@ class Pages
$page->routable(false);
}
+ // Override the modified time if modular
+ if ($page->template() == 'modular') {
+ foreach ($page->collection() as $child) {
+ $modified = $child->modified();
+
+ if ($modified > $last_modified) {
+ $last_modified = $modified;
+ }
+ }
+ }
+
// Override the modified and ID so that it takes the latest change into account
$page->modified($last_modified);
$page->id($last_modified.md5($page->filePath()));
diff --git a/system/src/Grav/Common/Service/ConfigServiceProvider.php b/system/src/Grav/Common/Service/ConfigServiceProvider.php
index ebb156b1a..79c99ed00 100644
--- a/system/src/Grav/Common/Service/ConfigServiceProvider.php
+++ b/system/src/Grav/Common/Service/ConfigServiceProvider.php
@@ -22,7 +22,7 @@ class ConfigServiceProvider implements ServiceProviderInterface
public function register(Container $container)
{
$container['setup'] = function ($c) {
- return static::setup($c)->init();
+ return static::setup($c);
};
$container['blueprints'] = function ($c) {
diff --git a/system/src/Grav/Common/Twig/Twig.php b/system/src/Grav/Common/Twig/Twig.php
index 0b3be023c..aa3119946 100644
--- a/system/src/Grav/Common/Twig/Twig.php
+++ b/system/src/Grav/Common/Twig/Twig.php
@@ -25,7 +25,7 @@ class Twig
/**
* @var array
*/
- public $twig_vars;
+ public $twig_vars = [];
/**
* @var array
@@ -143,7 +143,7 @@ class Twig
$this->grav->fireEvent('onTwigExtensions');
// Set some standard variables for twig
- $this->twig_vars = array(
+ $this->twig_vars = $this->twig_vars + array(
'config' => $config,
'uri' => $this->grav['uri'],
'base_dir' => rtrim(ROOT_DIR, '/'),
diff --git a/system/src/Grav/Common/Uri.php b/system/src/Grav/Common/Uri.php
index ecac11645..9156d36ab 100644
--- a/system/src/Grav/Common/Uri.php
+++ b/system/src/Grav/Common/Uri.php
@@ -24,8 +24,10 @@ class Uri
protected $params;
protected $path;
protected $paths;
+ protected $port;
protected $query;
protected $root;
+ protected $root_path;
protected $uri;
/**
@@ -117,11 +119,6 @@ class Uri
$base .= $this->name;
$port = $this->port;
- // add the port of needed
- if ($port != '80' && $port != '443') {
- $base .= ":" . $port;
- }
-
return $base;
}
@@ -202,6 +199,11 @@ class Uri
$root_path = $this->buildRootPath();
$this->root = $this->base . $root_path;
$this->url = $this->base . $this->uri;
+
+ $this->port = $port;
+ $this->base = $base;
+ $this->uri = $uri;
+ $this->root_path = $root_path;
}
/**
@@ -214,6 +216,20 @@ class Uri
$config = $grav['config'];
$language = $grav['language'];
+ // resets
+ $this->paths = [];
+ $this->params = [];
+ $this->query = [];
+
+ // add the port to the base for non-standard ports
+ if ($config->get('system.reverse_proxy_setup') == false && $this->port != '80' && $this->port != '443') {
+ $this->base .= ":".$this->port;
+ }
+
+ // Set some defaults
+ $this->root = $this->base . $this->root_path;
+ $this->url = $this->base . $this->uri;
+
// get any params and remove them
$uri = str_replace($this->root, '', $this->url);
@@ -454,6 +470,16 @@ class Uri
return $this->host;
}
+ /**
+ * Return the port number
+ *
+ * @return int
+ */
+ public function port()
+ {
+ return $this->port;
+ }
+
/**
* Gets the environment name
*
diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php
index d8a3b814a..eb88c1937 100644
--- a/system/src/Grav/Common/Utils.php
+++ b/system/src/Grav/Common/Utils.php
@@ -473,6 +473,8 @@ abstract class Utils
/**
* Generates a nonce string to be hashed. Called by self::getNonce()
+ * We removed the IP portion in this version because it causes too many inconsistencies
+ * with reverse proxy setups.
*
* @param string $action
* @param bool $plusOneTick if true, generates the token for the next tick (the next 12 hours)
@@ -481,22 +483,12 @@ abstract class Utils
*/
private static function generateNonceString($action, $plusOneTick = false)
{
- if (!empty($_SERVER['HTTP_CLIENT_IP'])) {
- $ip = $_SERVER['HTTP_CLIENT_IP'];
- } elseif (!empty($_SERVER['HTTP_X_FORWARDED_FOR'])) {
- $ip = $_SERVER['HTTP_X_FORWARDED_FOR'];
- } else {
- $ip = $_SERVER['REMOTE_ADDR'];
- }
-
$username = '';
if (isset(self::getGrav()['user'])) {
$user = self::getGrav()['user'];
$username = $user->username;
}
- $username .= $ip;
-
$token = session_id();
$i = self::nonceTick();
@@ -587,6 +579,11 @@ abstract class Utils
*/
public static function verifyNonce($nonce, $action)
{
+ //Safety check for multiple nonces
+ if (is_array($nonce)) {
+ $nonce = array_shift($nonce);
+ }
+
//Nonce generated 0-12 hours ago
if ($nonce == self::getNonce($action)) {
return true;
diff --git a/system/src/Grav/Console/Gpm/InfoCommand.php b/system/src/Grav/Console/Gpm/InfoCommand.php
index 0ff0850bb..99f8bd2e2 100644
--- a/system/src/Grav/Console/Gpm/InfoCommand.php
+++ b/system/src/Grav/Console/Gpm/InfoCommand.php
@@ -5,6 +5,7 @@ use Grav\Common\GPM\GPM;
use Grav\Console\ConsoleCommand;
use Symfony\Component\Console\Input\InputArgument;
use Symfony\Component\Console\Input\InputOption;
+use Symfony\Component\Console\Question\ConfirmationQuestion;
/**
* Class InfoCommand
@@ -34,6 +35,12 @@ class InfoCommand extends ConsoleCommand
InputOption::VALUE_NONE,
'Force fetching the new data remotely'
)
+ ->addOption(
+ 'all-yes',
+ 'y',
+ InputOption::VALUE_NONE,
+ 'Assumes yes (or best approach) instead of prompting'
+ )
->addArgument(
'package',
InputArgument::REQUIRED,
@@ -107,9 +114,62 @@ class InfoCommand extends ConsoleCommand
}
}
+ $type = rtrim($foundPackage->package_type, 's');
+ $updatable = $this->gpm->{'is' . $type . 'Updatable'}($foundPackage->slug);
+ $installed = $this->gpm->{'is' . $type . 'Installed'}($foundPackage->slug);
+
+ // display current version if installed and different
+ if ($installed && $updatable) {
+ $local = $this->gpm->{'getInstalled'. $type}($foundPackage->slug);
+ $this->output->writeln('');
+ $this->output->writeln("Currently installed version: " . $local->version . "");
+ $this->output->writeln('');
+ }
+
+ // display changelog information
+ $questionHelper = $this->getHelper('question');
+ $skipPrompt = $this->input->getOption('all-yes');
+
+ if (!$skipPrompt) {
+ $question = new ConfirmationQuestion("Would you like to read the changelog? [y|N] ",
+ false);
+ $answer = $questionHelper->ask($this->input, $this->output, $question);
+
+ if ($answer) {
+ $changelog = $foundPackage->changelog;
+
+ $this->output->writeln("");
+ foreach ($changelog as $version => $log) {
+ $title = $version . ' [' . $log['date'] . ']';
+ $content = preg_replace_callback("/\d\.\s\[\]\(#(.*)\)/", function ($match) {
+ return "\n" . ucfirst($match[1]) . ":";
+ }, $log['content']);
+
+ $this->output->writeln(''.$title.'');
+ $this->output->writeln(str_repeat('-', strlen($title)));
+ $this->output->writeln($content);
+ $this->output->writeln("");
+
+ $question = new ConfirmationQuestion("Press [ENTER] to continue or [q] to quit ", true);
+ if (!$questionHelper->ask($this->input, $this->output, $question)) {
+ break;
+ }
+ $this->output->writeln("");
+ }
+ }
+ }
+
+
$this->output->writeln('');
- $this->output->writeln("You can install this package by typing:");
- $this->output->writeln(" " . $this->argv . " install " . $foundPackage->slug . "");
+
+ if ($installed && $updatable) {
+ $this->output->writeln("You can update this package by typing:");
+ $this->output->writeln(" " . $this->argv . " update " . $foundPackage->slug . "");
+ } else {
+ $this->output->writeln("You can install this package by typing:");
+ $this->output->writeln(" " . $this->argv . " install " . $foundPackage->slug . "");
+ }
+
$this->output->writeln('');
}