From 1aeac01284a18618813ac852610c276f8418aa8d Mon Sep 17 00:00:00 2001 From: Alexander Turiak Date: Thu, 5 Feb 2015 12:43:49 +0200 Subject: [PATCH 01/31] Update formatting to have blocks nesting less confusing --- nginx.conf | 33 ++++++++++++++++----------------- 1 file changed, 16 insertions(+), 17 deletions(-) diff --git a/nginx.conf b/nginx.conf index 07295e4da..22f7acd56 100644 --- a/nginx.conf +++ b/nginx.conf @@ -27,26 +27,26 @@ http { } location /user { - rewrite ^/user/accounts/(.*)$ /error redirect; - rewrite ^/user/config/(.*)$ /error redirect; - rewrite ^/user/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; - } + rewrite ^/user/accounts/(.*)$ /error redirect; + rewrite ^/user/config/(.*)$ /error redirect; + rewrite ^/user/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; + } - location /cache { - rewrite ^/cache/(.*) /error redirect; - } + location /cache { + rewrite ^/cache/(.*) /error redirect; + } - location /bin { - rewrite ^/bin/(.*)$ /error redirect; - } + location /bin { + rewrite ^/bin/(.*)$ /error redirect; + } - location /system { - rewrite ^/system/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; - } + location /system { + rewrite ^/system/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; + } - location /vendor { - rewrite ^/vendor/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; - } + location /vendor { + rewrite ^/vendor/(.*)\.(txt|md|html|php|yaml|json|twig|sh|bat)$ /error redirect; + } # Remember to change 127.0.0.1:9000 to the Ip/port # you configured php-cgi.exe to run from @@ -60,7 +60,6 @@ http { include fastcgi_params; } - } } From fb9705809d30993b691719db80c856df46012246 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 5 Feb 2015 15:07:31 -0700 Subject: [PATCH 02/31] HHVM fixes due to issues with traits and static variables #138 --- system/src/Grav/Common/Assets.php | 10 ++-- system/src/Grav/Common/GPM/Local/Plugins.php | 2 +- system/src/Grav/Common/GPM/Local/Themes.php | 2 +- .../src/Grav/Common/GPM/Remote/Collection.php | 2 +- system/src/Grav/Common/GravTrait.php | 3 + .../Common/Markdown/ParsedownGravTrait.php | 8 +-- system/src/Grav/Common/Page/Media.php | 14 ++--- system/src/Grav/Common/Page/Medium.php | 10 ++-- system/src/Grav/Common/Page/Page.php | 58 +++++++++---------- system/src/Grav/Common/User/User.php | 2 +- system/src/Grav/Console/ConsoleTrait.php | 4 +- .../src/Grav/Console/Gpm/UninstallCommand.php | 4 +- 12 files changed, 61 insertions(+), 58 deletions(-) diff --git a/system/src/Grav/Common/Assets.php b/system/src/Grav/Common/Assets.php index b63de9c72..4e940d09e 100644 --- a/system/src/Grav/Common/Assets.php +++ b/system/src/Grav/Common/Assets.php @@ -163,8 +163,8 @@ class Assets public function init() { /** @var Config $config */ - $config = self::$grav['config']; - $base_url = self::$grav['base_url']; + $config = self::getGrav()['config']; + $base_url = self::getGrav()['base_url']; $asset_config = (array)$config->get('system.assets'); $this->config($asset_config); @@ -358,7 +358,7 @@ class Assets } // Sort array by priorities (larger priority first) - if (self::$grav) { + if (self::getGrav()) { usort($this->css, function ($a, $b) { if ($a['priority'] == $b['priority']) { return $b['order'] - $a['order']; @@ -471,7 +471,7 @@ class Assets protected function pipeline($css = true) { /** @var Cache $cache */ - $cache = self::$grav['cache']; + $cache = self::getGrav()['cache']; $key = '?' . $cache->getKey(); if ($css) { @@ -687,7 +687,7 @@ class Assets protected function buildLocalLink($asset) { try { - $asset = self::$grav['locator']->findResource($asset, false); + $asset = self::getGrav()['locator']->findResource($asset, false); } catch (\Exception $e) { } diff --git a/system/src/Grav/Common/GPM/Local/Plugins.php b/system/src/Grav/Common/GPM/Local/Plugins.php index b5193ad86..b52efea93 100644 --- a/system/src/Grav/Common/GPM/Local/Plugins.php +++ b/system/src/Grav/Common/GPM/Local/Plugins.php @@ -17,7 +17,7 @@ class Plugins extends Collection */ public function __construct() { - $grav = self::$grav; + $grav = self::getGrav(); foreach ($grav['plugins']->all() as $name => $data) { $this->items[$name] = new Package($data, $this->type); diff --git a/system/src/Grav/Common/GPM/Local/Themes.php b/system/src/Grav/Common/GPM/Local/Themes.php index 19d68c6a6..673490144 100644 --- a/system/src/Grav/Common/GPM/Local/Themes.php +++ b/system/src/Grav/Common/GPM/Local/Themes.php @@ -6,7 +6,7 @@ class Themes extends Collection private $type = 'themes'; public function __construct() { - $grav = self::$grav; + $grav = self::getGrav(); foreach ($grav['themes']->all() as $name => $data) { $this->items[$name] = new Package($data, $this->type); diff --git a/system/src/Grav/Common/GPM/Remote/Collection.php b/system/src/Grav/Common/GPM/Remote/Collection.php index 58e2e6942..87c97ffae 100644 --- a/system/src/Grav/Common/GPM/Remote/Collection.php +++ b/system/src/Grav/Common/GPM/Remote/Collection.php @@ -31,7 +31,7 @@ class Collection extends Iterator { throw new \RuntimeException("A repository is required for storing the cache"); } - $cache_dir = self::$grav['locator']->findResource('cache://gpm', true, true); + $cache_dir = self::getGrav()['locator']->findResource('cache://gpm', true, true); $this->cache = new FilesystemCache($cache_dir); $this->repository = $repository; diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index b18258323..215b86848 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -13,6 +13,9 @@ trait GravTrait */ public function getGrav() { + if (!self::$grav) { + self::$grav = Grav::instance(); + } return self::$grav; } diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 9ba39e423..9de9efeef 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -29,10 +29,10 @@ trait ParsedownGravTrait protected function init($page) { $this->page = $page; - $this->pages = self::$grav['pages']; + $this->pages = self::getGrav()['pages']; $this->BlockTypes['{'] [] = "TwigTag"; - $this->base_url = rtrim(self::$grav['base_url'] . self::$grav['pages']->base(), '/'); - $this->pages_dir = self::$grav['locator']->findResource('page://'); + $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'); } @@ -159,7 +159,7 @@ trait ParsedownGravTrait } else { // Create the custom lightbox element - + $attributes = $data['a_attributes']; $attributes['href'] = $data['a_href']; diff --git a/system/src/Grav/Common/Page/Media.php b/system/src/Grav/Common/Page/Media.php index afbdeeca4..e6438327a 100644 --- a/system/src/Grav/Common/Page/Media.php +++ b/system/src/Grav/Common/Page/Media.php @@ -55,7 +55,7 @@ class Media extends Getters $medium = $this->get("{$basename}.{$ext}"); if (!$alternative) { - + $medium = $medium ? $medium : $this->createMedium($info->getPathname()); if (!$medium) { @@ -70,7 +70,7 @@ class Media extends Getters } else { $altMedium = $this->createMedium($info->getPathname()); - + if (!$altMedium) { continue; } @@ -86,7 +86,7 @@ class Media extends Getters } $medium = $medium ? $medium : $this->scaleMedium($altMedium, $alternative, 1); - + $medium->addAlternative($this->parseRatio($alternative), $altMedium); } @@ -186,7 +186,7 @@ class Media extends Getters * Create a Medium object from a file * * @param string $file - * + * * @return Medium|null */ protected function createMedium($file) @@ -202,7 +202,7 @@ class Media extends Getters $basename = implode('.', $parts); /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; // Check if medium type has been configured. $params = $config->get("media.".strtolower($ext)); @@ -224,7 +224,7 @@ class Media extends Getters 'modified' => filemtime($file), ); - $locator = self::$grav['locator']; + $locator = self::getGrav()['locator']; $lookup = $locator->findResources('image://'); foreach ($lookup as $lookupPath) { @@ -257,7 +257,7 @@ class Media extends Getters $medium->set('debug', false); $file = $medium->resize($width, $height)->setPrettyName($basename)->url(); - $file = preg_replace('|'. preg_quote(self::$grav['base_url_relative']) .'$|', '', GRAV_ROOT) . $file; + $file = preg_replace('|'. preg_quote(self::getGrav()['base_url_relative']) .'$|', '', GRAV_ROOT) . $file; $medium->set('debug', $debug); diff --git a/system/src/Grav/Common/Page/Medium.php b/system/src/Grav/Common/Page/Medium.php index 56bf1cf0a..224317b79 100644 --- a/system/src/Grav/Common/Page/Medium.php +++ b/system/src/Grav/Common/Page/Medium.php @@ -120,7 +120,7 @@ class Medium extends Data $this->def('mime', 'application/octet-stream'); } - $this->set('debug', self::$grav['config']->get('system.images.debug')); + $this->set('debug', self::getGrav()['config']->get('system.images.debug')); } /** @@ -168,7 +168,7 @@ class Medium extends Data $output = preg_replace('|^' . GRAV_ROOT . '|', '', $this->get('path')) . '/' . $this->get('filename'); } - return self::$grav['base_url'] . $output; + return self::getGrav()['base_url'] . $output; } @@ -332,7 +332,7 @@ class Medium extends Data } } else { // TODO: we need to find out URI in a bit better way. - $this->linkTarget = self::$grav['base_url'] . preg_replace('|^' . GRAV_ROOT . '|', '', $this->get('path')) . '/' . $this->get('filename'); + $this->linkTarget = self::getGrav()['base_url'] . preg_replace('|^' . GRAV_ROOT . '|', '', $this->get('path')) . '/' . $this->get('filename'); } return $this; @@ -422,7 +422,7 @@ class Medium extends Data */ public function image($variable = 'thumb') { - $locator = self::$grav['locator']; + $locator = self::getGrav()['locator']; // TODO: add default file $file = $this->get($variable); @@ -453,7 +453,7 @@ class Medium extends Data $ratio = 1; } - $locator = self::$grav['locator']; + $locator = self::getGrav()['locator']; $overlay = $locator->findResource("system://assets/responsive-overlays/{$ratio}x.png") ?: $locator->findResource('system://assets/responsive-overlays/unknown.png'); $this->image->merge(ImageFile::open($overlay)); } diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 404ce7c42..14281fb2c 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -96,7 +96,7 @@ class Page public function __construct($array = array()) { /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; $this->routable = true; $this->taxonomy = array(); @@ -123,20 +123,20 @@ class Page $this->modularTwig($this->slug[0] == '_'); // Handle publishing dates if no explict published option set - if (self::$grav['config']->get('system.pages.publish_dates') && !isset($this->header->published)) { + if (self::getGrav()['config']->get('system.pages.publish_dates') && !isset($this->header->published)) { // unpublish if required, if not clear cache right before page should be unpublished if ($this->unpublishDate()) { if ($this->unpublishDate() < time()) { $this->published(false); } else { $this->published(); - self::$grav['cache']->setLifeTime($this->unpublishDate()); + self::getGrav()['cache']->setLifeTime($this->unpublishDate()); } } // publish if required, if not clear cache right before page is published if ($this->publishDate() != $this->modified() && $this->publishDate() > time()) { $this->published(false); - self::$grav['cache']->setLifeTime($this->publishDate()); + self::getGrav()['cache']->setLifeTime($this->publishDate()); } } $this->published(); @@ -300,7 +300,7 @@ class Page public function summary($size = null) { /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; $content = $this->content(); // Return summary based on settings in site config file @@ -362,7 +362,7 @@ class Page // Load cached content /** @var Cache $cache */ - $cache = self::$grav['cache']; + $cache = self::getGrav()['cache']; $cache_id = md5('page'.$this->id()); $this->content = $cache->fetch($cache_id); @@ -375,7 +375,7 @@ class Page // if no cached-content run everything if ($this->content == false) { $this->content = $this->raw_content; - self::$grav->fireEvent('onPageContentRaw', new Event(['page' => $this])); + self::getGrav()->fireEvent('onPageContentRaw', new Event(['page' => $this])); if ($twig_first) { if ($process_twig) { @@ -412,7 +412,7 @@ class Page } // Handle summary divider - $delimiter = self::$grav['config']->get('site.summary.delimiter', '==='); + $delimiter = self::getGrav()['config']->get('site.summary.delimiter', '==='); $divider_pos = strpos($this->content, "

{$delimiter}

"); if ($divider_pos !== false) { $this->summary_size = $divider_pos; @@ -430,7 +430,7 @@ class Page protected function processMarkdown() { /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; $defaults = (array) $config->get('system.pages.markdown'); if (isset($this->header()->markdown)) { @@ -463,7 +463,7 @@ class Page */ private function processTwig() { - $twig = self::$grav['twig']; + $twig = self::getGrav()['twig']; $this->content = $twig->processPage($this, $this->content); } @@ -472,10 +472,10 @@ class Page */ private function cachePageContent() { - $cache = self::$grav['cache']; + $cache = self::getGrav()['cache']; $cache_id = md5('page'.$this->id()); - self::$grav->fireEvent('onPageContentProcessed', new Event(['page' => $this])); + self::getGrav()->fireEvent('onPageContentProcessed', new Event(['page' => $this])); $cache->save($cache_id, $this->content); } @@ -650,7 +650,7 @@ class Page public function blueprints() { /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; return $pages->blueprints($this->template()); } @@ -729,7 +729,7 @@ class Page public function media($var = null) { /** @var Cache $cache */ - $cache = self::$grav['cache']; + $cache = self::getGrav()['cache']; if ($var) { $this->media = $var; @@ -958,7 +958,7 @@ class Page // Safety check to ensure we have a header if ($page_header) { // Merge any site.metadata settings in with page metadata - $defaults = (array) self::$grav['config']->get('site.metadata'); + $defaults = (array) self::getGrav()['config']->get('site.metadata'); if (isset($page_header->metadata)) { $page_header->metadata = array_merge($defaults, $page_header->metadata); @@ -1061,10 +1061,10 @@ class Page public function url($include_host = false) { /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; /** @var Uri $uri */ - $uri = self::$grav['uri']; + $uri = self::getGrav()['uri']; $rootUrl = $uri->rootUrl($include_host) . $pages->base(); $url = $rootUrl.'/'.trim($this->route(), '/'); @@ -1263,7 +1263,7 @@ class Page } if (empty($this->max_count)) { /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; $this->max_count = (int) $config->get('system.pages.list.count'); } return $this->max_count; @@ -1338,7 +1338,7 @@ class Page } /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; return $pages->get($this->parent); } @@ -1351,7 +1351,7 @@ class Page public function children() { /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; return $pages->children($this->path()); } @@ -1418,7 +1418,7 @@ class Page public function active() { /** @var Uri $uri */ - $uri = self::$grav['uri']; + $uri = self::getGrav()['uri']; if ($this->url() == $uri->url()) { return true; } @@ -1434,8 +1434,8 @@ class Page public function activeChild() { /** @var Uri $uri */ - $uri = self::$grav['uri']; - $config = self::$grav['config']; + $uri = self::getGrav()['uri']; + $config = self::getGrav()['config']; // Special check when item is home if ($this->home()) { @@ -1489,7 +1489,7 @@ class Page public function find($url, $all = false) { /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; return $pages->dispatch($url, $all); } @@ -1521,9 +1521,9 @@ class Page // TODO: MOVE THIS INTO SOMEWHERE ELSE? /** @var Uri $uri */ - $uri = self::$grav['uri']; + $uri = self::getGrav()['uri']; /** @var Config $config */ - $config = self::$grav['config']; + $config = self::getGrav()['config']; foreach ((array) $config->get('site.taxonomies') as $taxonomy) { if ($uri->param($taxonomy)) { @@ -1559,7 +1559,7 @@ class Page } /** @var Grav $grav */ - $grav = self::$grav['grav']; + $grav = self::getGrav()['grav']; // New Custom event to handle things like pagination. $grav->fireEvent('onCollectionProcessed', new Event(['collection' => $collection])); @@ -1639,7 +1639,7 @@ class Page // @taxonomy: { category: [ blog, featured ], level: 1 } /** @var Taxonomy $taxonomy_map */ - $taxonomy_map = self::$grav['taxonomy']; + $taxonomy_map = self::getGrav()['taxonomy']; if (!empty($parts)) { $params = [implode('.', $parts) => $params]; @@ -1715,7 +1715,7 @@ class Page // Do reordering. if ($reorder && $this->order() != $this->_original->order()) { /** @var Pages $pages */ - $pages = self::$grav['pages']; + $pages = self::getGrav()['pages']; $parent = $this->parent(); diff --git a/system/src/Grav/Common/User/User.php b/system/src/Grav/Common/User/User.php index 8da0896fe..80c0f9a0f 100644 --- a/system/src/Grav/Common/User/User.php +++ b/system/src/Grav/Common/User/User.php @@ -26,7 +26,7 @@ class User extends Data */ public static function load($username) { - $locator = self::$grav['locator']; + $locator = self::getGrav()['locator']; // FIXME: validate directory name $blueprints = new Blueprints('blueprints://user'); diff --git a/system/src/Grav/Console/ConsoleTrait.php b/system/src/Grav/Console/ConsoleTrait.php index 4ad07bc4b..42c65d495 100644 --- a/system/src/Grav/Console/ConsoleTrait.php +++ b/system/src/Grav/Console/ConsoleTrait.php @@ -35,8 +35,8 @@ trait ConsoleTrait */ public function setupConsole(InputInterface $input, OutputInterface $output) { - if (self::$grav) { - self::$grav['config']->set('system.cache.driver', 'default'); + if (self::getGrav()) { + self::getGrav()['config']->set('system.cache.driver', 'default'); } $this->argv = $_SERVER['argv'][0]; diff --git a/system/src/Grav/Console/Gpm/UninstallCommand.php b/system/src/Grav/Console/Gpm/UninstallCommand.php index fdd28a520..085612c4f 100644 --- a/system/src/Grav/Console/Gpm/UninstallCommand.php +++ b/system/src/Grav/Console/Gpm/UninstallCommand.php @@ -140,7 +140,7 @@ class UninstallCommand extends Command */ private function uninstallPackage($package) { - $path = self::$grav['locator']->findResource($package->package_type . '://' . $package->slug); + $path = self::getGrav()['locator']->findResource($package->package_type . '://' . $package->slug); Installer::uninstall($path); $errorCode = Installer::lastErrorCode(); @@ -167,7 +167,7 @@ class UninstallCommand extends Command private function checkDestination($package) { - $path = self::$grav['locator']->findResource($package->package_type . '://' . $package->slug); + $path = self::getGrav()['locator']->findResource($package->package_type . '://' . $package->slug); $questionHelper = $this->getHelper('question'); $skipPrompt = $this->input->getOption('all-yes'); From 50785c24342e1126b678f73969e23ce979b2c9b9 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Thu, 5 Feb 2015 20:59:23 -0700 Subject: [PATCH 03/31] version update --- CHANGELOG.md | 15 +++++++++++++++ system/defines.php | 2 +- 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 67164b01e..a88529ade 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,18 @@ +# v0.9.17 +## 02/05/2015 + +1. [](#new) + * Added **full HHVM support!** Get your speed on with Facebook's crazy fast PHP JIT compiler +2. [](#improved) + * More flexible page summary control + * Support **CamelCase** plugin and theme class names. Replaces dashes and underscores + * Moved summary delimiter into `site.yaml` so it can be configurable + * Various PSR fixes +3. [](#bugfix) + * Fix for `mergeConfig()` not falling back to defaults + * Fix for `addInlineCss()` and `addInlineJs()` Assets not working between Twig tags + * Fix for Markdown adding HTML tags into inline CSS and JS + # v0.9.16 ## 01/30/2015 diff --git a/system/defines.php b/system/defines.php index e55db94b1..562e85140 100644 --- a/system/defines.php +++ b/system/defines.php @@ -2,7 +2,7 @@ // Some standard defines define('GRAV', true); -define('GRAV_VERSION', '0.9.16'); +define('GRAV_VERSION', '0.9.17'); define('DS', '/'); // Directories and Paths From b696e0d7906ab490e4c3727305dd616bb9d952ce Mon Sep 17 00:00:00 2001 From: Gertt Date: Sat, 7 Feb 2015 17:47:58 +0100 Subject: [PATCH 04/31] fix page ids not picking up folder-only pages --- system/src/Grav/Common/Page/Page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index 14281fb2c..ecf18fec5 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1136,7 +1136,7 @@ class Page // Path to the page. $this->path = dirname(dirname($var)); } - return $this->name ? $this->path . '/' . $this->folder . '/' . $this->name : null; + return $this->path . '/' . $this->folder . '/' . ($this->name ? $this->name : ''); } /** From 97b430a88836589e4b6d4cfa5091a3f123682be4 Mon Sep 17 00:00:00 2001 From: Gertt Date: Sat, 7 Feb 2015 17:55:46 +0100 Subject: [PATCH 05/31] Update Page.php --- system/src/Grav/Common/Page/Page.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index ecf18fec5..ceec85e2e 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -1136,7 +1136,7 @@ class Page // Path to the page. $this->path = dirname(dirname($var)); } - return $this->path . '/' . $this->folder . '/' . ($this->name ? $this->name : ''); + return $this->path . '/' . $this->folder . '/' . ($this->name ?: ''); } /** From 1d3559f0db4f9b8892312da07874d1a2ff764fe4 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 7 Feb 2015 12:21:40 -0700 Subject: [PATCH 06/31] Added a new filter to convert relative to absolute URLs --- system/src/Grav/Common/TwigExtension.php | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index 65a546900..a69174e54 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -49,6 +49,7 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFilter('ksort', [$this,'ksortFilter']), new \Twig_SimpleFilter('contains', [$this, 'containsFilter']), new \Twig_SimpleFilter('nicetime', [$this, 'nicetimeFilter']), + new \Twig_SimpleFilter('absoluteUrl', [$this, 'absoluteUrlFilter']) ]; } @@ -316,6 +317,14 @@ class TwigExtension extends \Twig_Extension return "$difference $periods[$j] {$tense}"; } + public function absoluteUrlFilter($string) + { + $url = $this->grav['uri']->base(); + $string = preg_replace('/((?:href|src) *= *[\'"](?!(http|ftp)))/i', "$1$url", $string); + return $string; + + } + /** * Repeat given string x times. * From 07ce9c83ac6fa470210e195a356deffcdc7707dd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 8 Feb 2015 11:42:08 -0700 Subject: [PATCH 07/31] changed getGrav() to static --- system/src/Grav/Common/GravTrait.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Common/GravTrait.php b/system/src/Grav/Common/GravTrait.php index 215b86848..171017363 100644 --- a/system/src/Grav/Common/GravTrait.php +++ b/system/src/Grav/Common/GravTrait.php @@ -11,7 +11,7 @@ trait GravTrait /** * @return Grav */ - public function getGrav() + public static function getGrav() { if (!self::$grav) { self::$grav = Grav::instance(); From d69a0a9b06174d5a35de468c6c59fdc3ccf004c0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 9 Feb 2015 16:35:02 -0700 Subject: [PATCH 08/31] minor naming updates --- system/src/Grav/Common/TwigExtension.php | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index a69174e54..f1b824c99 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -49,7 +49,7 @@ class TwigExtension extends \Twig_Extension new \Twig_SimpleFilter('ksort', [$this,'ksortFilter']), new \Twig_SimpleFilter('contains', [$this, 'containsFilter']), new \Twig_SimpleFilter('nicetime', [$this, 'nicetimeFilter']), - new \Twig_SimpleFilter('absoluteUrl', [$this, 'absoluteUrlFilter']) + new \Twig_SimpleFilter('absolute_url', [$this, 'absoluteUrlFilter']) ]; } @@ -165,8 +165,8 @@ class TwigExtension extends \Twig_Extension * {{ 'send_email'|camelize }} => SendEmail * {{ 'CamelCased'|underscorize }} => camel_cased * {{ 'Something Text'|hyphenize }} => something-text - * {{ 'something text to read'|humanize }} => "Something text to read" - * {{ '181'|monthize}} => 6 + * {{ 'something_text_to_read'|humanize }} => "Something text to read" + * {{ '181'|monthize }} => 6 * {{ '10'|ordinalize }} => 10th * * @param string $action From 5c139e4b3ca8d2c20835e431c1758289ef1fb2e0 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 9 Feb 2015 18:56:12 -0700 Subject: [PATCH 09/31] added a new markdown twig filter --- system/src/Grav/Common/TwigExtension.php | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/TwigExtension.php b/system/src/Grav/Common/TwigExtension.php index f1b824c99..303c7b2b7 100644 --- a/system/src/Grav/Common/TwigExtension.php +++ b/system/src/Grav/Common/TwigExtension.php @@ -1,6 +1,8 @@ grav['page']; + $defaults = $this->grav['config']->get('system.pages.markdown'); + + // Initialize the preferred variant of Parsedown + if ($defaults['extra']) { + $parsedown = new ParsedownExtra($page); + } else { + $parsedown = new Parsedown($page); + } + + $string = $parsedown->text($string); + + return $string; + } + /** * Repeat given string x times. * From d8a29dd6396db04f0de8329eeaf2ab108c698c5e Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 9 Feb 2015 18:56:33 -0700 Subject: [PATCH 10/31] Moved parsedown config into trait --- system/src/Grav/Common/Markdown/ParsedownGravTrait.php | 7 +++++++ system/src/Grav/Common/Page/Page.php | 6 ------ 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php index 9de9efeef..b85a98064 100644 --- a/system/src/Grav/Common/Markdown/ParsedownGravTrait.php +++ b/system/src/Grav/Common/Markdown/ParsedownGravTrait.php @@ -34,6 +34,13 @@ trait ParsedownGravTrait $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'); + + $defaults = self::getGrav()['config']->get('system.pages.markdown'); + + $this->setBreaksEnabled($defaults['auto_line_breaks']); + $this->setUrlsLinked($defaults['auto_url_links']); + $this->setMarkupEscaped($defaults['escape_markup']); + $this->setSpecialChars($defaults['special_chars']); } /** diff --git a/system/src/Grav/Common/Page/Page.php b/system/src/Grav/Common/Page/Page.php index ceec85e2e..4d6c6169c 100644 --- a/system/src/Grav/Common/Page/Page.php +++ b/system/src/Grav/Common/Page/Page.php @@ -449,11 +449,6 @@ class Page $parsedown = new Parsedown($this); } - $parsedown->setBreaksEnabled($defaults['auto_line_breaks']); - $parsedown->setUrlsLinked($defaults['auto_url_links']); - $parsedown->setMarkupEscaped($defaults['escape_markup']); - $parsedown->setSpecialChars($defaults['special_chars']); - $this->content = $parsedown->text($this->content); } @@ -947,7 +942,6 @@ class Page // if not metadata yet, process it. if (null === $this->metadata) { - $header_tag_http_equivs = ['content-type', 'default-style', 'refresh']; $this->metadata = array(); $page_header = $this->header; From 17172f8920794c8002eeacfbbbba6c96ab18387d Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 13 Feb 2015 11:35:04 -0700 Subject: [PATCH 11/31] added a contains() static method --- system/src/Grav/Common/Utils.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index ac4f95f0f..538656a7e 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -28,6 +28,16 @@ abstract class Utils return $needle === '' || substr($haystack, -strlen($needle)) === $needle; } + /** + * @param string $haystack + * @param string $needle + * @return bool + */ + public static function contains($haystack, $needle) + { + return $needle === '' || strpos($haystack, $needle) !== false; + } + /** * Merge two objects into one. * From 2938848df1de9792b883bc276400837ce6944b89 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Fri, 13 Feb 2015 11:35:21 -0700 Subject: [PATCH 12/31] added a twig processTemplate() method --- system/src/Grav/Common/Twig.php | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/system/src/Grav/Common/Twig.php b/system/src/Grav/Common/Twig.php index 0fbdb81fc..e5a7fafbd 100644 --- a/system/src/Grav/Common/Twig.php +++ b/system/src/Grav/Common/Twig.php @@ -219,6 +219,34 @@ class Twig } /** + * Process a Twig template directly by using a template name + * and optional array of variables + * + * @param string $template template to render with + * @param array $vars Optional variables + * @return string + */ + public function processTemplate($template, $vars = array()) + { + // override the twig header vars for local resolution + $this->grav->fireEvent('onTwigTemplateVariables'); + $vars += $this->twig_vars; + + try { + $output = $this->twig->render($template, $vars); + } catch (\Twig_Error_Loader $e) { + throw new \RuntimeException($e->getRawMessage(), 404, $e); + } + + return $output; + + } + + + /** + * Process a Twig template directly by using a Twig string + * and optional array of variables + * * @param string $string string to render. * @param array $vars Optional variables * @return string From b418a7fd1e87a36ee1fe19ade07cd6ae2ec25891 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 14 Feb 2015 10:38:01 -0700 Subject: [PATCH 13/31] added timezone override support --- index.php | 9 +++++---- system/config/system.yaml | 1 + system/src/Grav/Common/Grav.php | 4 ++++ 3 files changed, 10 insertions(+), 4 deletions(-) diff --git a/index.php b/index.php index cf2644f6c..4d125f332 100644 --- a/index.php +++ b/index.php @@ -5,6 +5,7 @@ if (version_compare($ver = PHP_VERSION, $req = '5.4.0', '<')) { exit(sprintf('You are running PHP %s, but Grav needs at least PHP %s to run.', $ver, $req)); } +// Ensure vendor libraries exist $autoload = __DIR__ . '/vendor/autoload.php'; if (!is_file($autoload)) { exit('Please run: bin/grav install'); @@ -15,19 +16,19 @@ use Grav\Common\Grav; // Register the auto-loader. $loader = require_once $autoload; -if (!ini_get('date.timezone')) { - date_default_timezone_set('UTC'); -} +// Set timezone to default, falls back to system if php.ini not set +date_default_timezone_set(@date_default_timezone_get()); +// Get the Grav instance $grav = Grav::instance( array( 'loader' => $loader ) ); +// Process the page try { $grav->process(); - } catch (\Exception $e) { $grav->fireEvent('onFatalException'); throw $e; diff --git a/system/config/system.yaml b/system/config/system.yaml index a3ac7e7a4..9edc14046 100644 --- a/system/config/system.yaml +++ b/system/config/system.yaml @@ -1,4 +1,5 @@ absolute_urls: false # Absolute or relative URLs for `base_url` +timezone: '' # Valid values: http://php.net/manual/en/timezones.php home: alias: '/home' # Default path for home, ie / diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index b9e5ce6af..606047acc 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -172,6 +172,10 @@ class Grav extends Container ob_start('ob_gzhandler'); } + // Initialize the timezone + if ($this['config']->get('system.timezone')) { + date_default_timezone_set($this['config']->get('system.timezone')); + } /** @var Debugger $debugger */ $debugger = $this['debugger']; From 545c76088c5f87c72b65240e65a97aef34d7b3b6 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 14 Feb 2015 13:07:45 -0700 Subject: [PATCH 14/31] move timezone setting to after Config's `init()` method --- system/src/Grav/Common/Grav.php | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/system/src/Grav/Common/Grav.php b/system/src/Grav/Common/Grav.php index 606047acc..37d9cb3b3 100644 --- a/system/src/Grav/Common/Grav.php +++ b/system/src/Grav/Common/Grav.php @@ -172,11 +172,6 @@ class Grav extends Container ob_start('ob_gzhandler'); } - // Initialize the timezone - if ($this['config']->get('system.timezone')) { - date_default_timezone_set($this['config']->get('system.timezone')); - } - /** @var Debugger $debugger */ $debugger = $this['debugger']; @@ -188,6 +183,11 @@ class Grav extends Container $this['config']->debug(); $debugger->stopTimer('_config'); + // Initialize the timezone + if ($this['config']->get('system.timezone')) { + date_default_timezone_set($this['config']->get('system.timezone')); + } + $debugger->startTimer('streams', 'Streams'); $this['streams']; $debugger->stopTimer('streams'); From 1c1f2c268a10f9b55bfd921b3c91dabfccdb64aa Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sat, 14 Feb 2015 22:33:50 -0700 Subject: [PATCH 15/31] beginning of dependency work --- system/src/Grav/Common/GPM/GPM.php | 17 +++- .../src/Grav/Console/Gpm/InstallCommand.php | 91 ++++++++++++++++++- 2 files changed, 105 insertions(+), 3 deletions(-) diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index fd82f3642..26f8999e8 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -347,7 +347,20 @@ class GPM extends Iterator $packages = ['total' => 0, 'not_found' => []]; foreach ($searches as $search) { + $repository = ''; + // if this is an object, get the search data from the key + if (is_object($search)) { + $search = (array) $search; + $key = key($search); + $repository = $search[$key]; + $search = $key; + } + if ($found = $this->findPackage($search)) { + // set override respository if provided + if ($repository) { + $found->override_repository = $repository; + } if (!isset($packages[$found->package_type])) { $packages[$found->package_type] = []; } @@ -355,7 +368,9 @@ class GPM extends Iterator $packages[$found->package_type][$found->slug] = $found; $packages['total']++; } else { - $packages['not_found'][] = $search; + $not_found = new \stdClass(); + $not_found->override_repository = $repository; + $packages['not_found'][$search] = $not_found; } } diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 261a73f4a..f546dd3ec 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -12,6 +12,9 @@ use Symfony\Component\Console\Input\InputInterface; use Symfony\Component\Console\Input\InputOption; use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Question\ConfirmationQuestion; +use Symfony\Component\Console\Question\ChoiceQuestion; +use Symfony\Component\Yaml\Yaml; + /** * Class InstallCommand @@ -42,6 +45,8 @@ class InstallCommand extends Command */ protected $tmp; + protected $local_config; + /** * */ @@ -93,6 +98,11 @@ class InstallCommand extends Command $packages = array_map('strtolower', $this->input->getArgument('package')); $this->data = $this->gpm->findPackages($packages); + $local_config_file = exec('eval echo ~/.grav/config'); + if (file_exists($local_config_file)) { + $this->local_config = Yaml::parse($local_config_file); + } + if ( !Installer::isGravInstance($this->destination) || !Installer::isValidDestination($this->destination, [Installer::EXISTS, Installer::IS_LINK]) @@ -111,7 +121,7 @@ class InstallCommand extends Command if (count($this->data['not_found'])) { $this->output->writeln("These packages were not found on Grav: " . implode(', ', - $this->data['not_found']) . ""); + array_keys($this->data['not_found'])) . ""); } unset($this->data['not_found']); @@ -119,7 +129,48 @@ class InstallCommand extends Command foreach ($this->data as $data) { foreach ($data as $package) { + + //Check for dependencies + if (isset($package->dependencies)) { + $this->output->writeln("Package " . $package->name . " has required dependencies that must be installed first..."); + $this->output->writeln(''); + + $dependency_data = $this->gpm->findPackages($package->dependencies); + + if (!$dependency_data['total']) { + $this->output->writeln("No dependcies found..."); + $this->output->writeln(''); + } else { + unset($dependency_data['total']); + + foreach($dependency_data as $type => $dep_data) { + foreach($dep_data as $name => $dep_package) { + $this->output->writeln("Preparing to install dependency: " . $name . ""); + $this->processPackage($dep_package); + } + + } + +// foreach((array)$package->dependencies as $dependency) { +// if (is_object($dependency)) { +// foreach($dependency as $key=>$val) { +// $dep = $key; +// $install_options[] = 'git'; +// } +// } else { +// // just name for GPM retrieval +// $dep = $dependency; +// } +// +// +// +// +// } + } + } + $version = isset($package->available) ? $package->available : $package->version; + $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); $this->output->write(" |- Downloading package... 0%"); @@ -133,7 +184,8 @@ class InstallCommand extends Command $this->output->writeln(''); } else { $this->output->write(" |- Installing package... "); - $installation = $this->installPackage($package); + //$installation = $this->installPackage($package); + $installation = true; if (!$installation) { $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); @@ -149,6 +201,41 @@ class InstallCommand extends Command $this->clearCache(); } + private function processPackage($package) + { + $install_options = ['gpm']; + + // if no name, not found in GPM + if (!isset($package->name)) { + unset($install_options[0]); + } + // if local config found symlink is a valid option + if (isset($this->local_config)) { + $install_options[] = 'symlink'; + } + // if override set, can install via git + if (isset($package->override_repository)) { + $install_options[] = 'git'; + } + + if (count($install_options) == 0) { + // no valid install options + } elseif (count($install_options) == 1) { + // only one option, use it... + } else { + $helper = $this->getHelper('question'); + $install_list = array_values($install_options); + $default = $install_list[0]; + $question = new ChoiceQuestion( + 'Please select installation method ('.$default.' is default)', array_values($install_list), 0 + ); + $question->setErrorMessage('Method %s is invalid'); + $method = $helper->ask($this->input, $this->output, $question); + $this->output->writeln('You chose: ' . $method); + + } + } + /** * @param $package * From ace8823bd6fe5fa756031eb09c0df479e385bfe7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 13:37:51 -0700 Subject: [PATCH 16/31] Added symlink + git clone installation methods --- system/src/Grav/Common/GPM/GPM.php | 14 ++ .../src/Grav/Console/Gpm/InstallCommand.php | 235 +++++++++++++----- 2 files changed, 185 insertions(+), 64 deletions(-) diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 26f8999e8..3a0c4a886 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -1,7 +1,9 @@ 'user/plugins/%name%', 'themes' => 'user/themes/%name%', 'skeletons' => 'user/']; + /** * Creates a new GPM instance with Local and Remote packages available * @param boolean $refresh Applies to Remote Packages only and forces a refetch of data @@ -368,7 +372,17 @@ class GPM extends Iterator $packages[$found->package_type][$found->slug] = $found; $packages['total']++; } else { + // make a best guess at the type based on the repo URL + if (Utils::contains($repository, '-theme')) { + $type = 'themes'; + } else { + $type = 'plugins'; + } + $not_found = new \stdClass(); + $not_found->name = Inflector::camelize($search); + $not_found->slug = $search; + $not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]); $not_found->override_repository = $repository; $packages['not_found'][$search] = $not_found; } diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index f546dd3ec..89a9d8cd6 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -5,6 +5,8 @@ use Grav\Common\Filesystem\Folder; use Grav\Common\GPM\GPM; use Grav\Common\GPM\Installer; use Grav\Common\GPM\Response; +use Grav\Common\Inflector; +use Grav\Common\Utils; use Grav\Console\ConsoleTrait; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Input\InputArgument; @@ -15,6 +17,7 @@ use Symfony\Component\Console\Question\ConfirmationQuestion; use Symfony\Component\Console\Question\ChoiceQuestion; use Symfony\Component\Yaml\Yaml; +define('GIT_REGEX', '/http[s]?:\/\/(?:.*@)?(github|bitbucket)(?:.org|.com)\/.*\/(.*)/'); /** * Class InstallCommand @@ -47,6 +50,7 @@ class InstallCommand extends Command protected $local_config; + /** * */ @@ -132,49 +136,126 @@ class InstallCommand extends Command //Check for dependencies if (isset($package->dependencies)) { - $this->output->writeln("Package " . $package->name . " has required dependencies that must be installed first..."); + $this->output->writeln("Package " . $package->name . " has ". count($package->dependencies) . " required dependencies that must be installed first..."); $this->output->writeln(''); $dependency_data = $this->gpm->findPackages($package->dependencies); if (!$dependency_data['total']) { - $this->output->writeln("No dependcies found..."); + $this->output->writeln("No dependencies found..."); $this->output->writeln(''); } else { unset($dependency_data['total']); foreach($dependency_data as $type => $dep_data) { foreach($dep_data as $name => $dep_package) { - $this->output->writeln("Preparing to install dependency: " . $name . ""); + $this->processPackage($dep_package); } - } - -// foreach((array)$package->dependencies as $dependency) { -// if (is_object($dependency)) { -// foreach($dependency as $key=>$val) { -// $dep = $key; -// $install_options[] = 'git'; -// } -// } else { -// // just name for GPM retrieval -// $dep = $dependency; -// } -// -// -// -// -// } } } - $version = isset($package->available) ? $package->available : $package->version; + $this->processPackage($package); + } + } - $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); + // clear cache after successful upgrade + $this->clearCache(); + } - $this->output->write(" |- Downloading package... 0%"); - $this->file = $this->downloadPackage($package); + /** + * @param $package + */ + private function processPackage($package) + { + $install_options = ['GPM']; + + // if no name, not found in GPM + if (!isset($package->version)) { + unset($install_options[0]); + } + // if local config found symlink is a valid option + if (isset($this->local_config)) { + $install_options[] = 'Symlink'; + } + // if override set, can install via git + if (isset($package->override_repository)) { + $install_options[] = 'Git'; + } + + // reindex list + $install_options = array_values($install_options); + + if (count($install_options) == 0) { + // no valid install options - error and return + } elseif (count($install_options) == 1) { + // only one option, use it... + $method = $install_options[0]; + } else { + $helper = $this->getHelper('question'); + $question = new ChoiceQuestion( + 'Please select installation method for ' . $package->name . ' ('.$install_options[0].' is default)', array_values($install_options), 0 + ); + $question->setErrorMessage('Method %s is invalid'); + $method = $helper->ask($this->input, $this->output, $question); + } + + $this->output->writeln(''); + + $method_name = 'process'.$method; + + $this->$method_name($package); + } + + /** + * @param $package + * + * @return array + */ + private function getGitRegexMatches($package) + { + if (isset($package->override_repository)) { + $repository = $package->override_repository; + } elseif (isset($package->repository)) { + $repository = $package->repository; + } else { + return false; + } + + preg_match(GIT_REGEX, $repository, $matches); + + return $matches; + } + + /** + * @param $package + */ + private function processSymlink($package) + { + + exec('cd ' . $this->destination); + + $to = $this->destination . DS . $package->install_path; + + $matches = $this->getGitRegexMatches($package); + + $this->output->writeln("Preparing to Symlink " . $package->name . ""); + $this->output->write(" |- Checking source... "); + + foreach ($this->local_config as $path) { + + if (Utils::endsWith($matches[2], '.git')) { + $repo_dir = preg_replace('/\.git$/', '', $matches[2]); + } else { + $repo_dir = $matches[2]; + } + + $from = rtrim($path, '/') . '/' . $repo_dir; + + if (file_exists($from)) { + + $this->output->writeln("ok"); $this->output->write(" |- Checking destination... "); $checks = $this->checkDestination($package); @@ -183,56 +264,80 @@ class InstallCommand extends Command $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); } else { - $this->output->write(" |- Installing package... "); - //$installation = $this->installPackage($package); - $installation = true; - if (!$installation) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); - } else { - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); - } + + symlink($from, $to); + + // extra white spaces to clear out the buffer properly + $this->output->writeln(" |- Symlinking package... ok "); + + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } + return; + } else { + $this->output->writeln("not found!"); } } - - // clear cache after successful upgrade - $this->clearCache(); } - private function processPackage($package) + /** + * @param $package + */ + private function processGit($package) { - $install_options = ['gpm']; + $matches = $this->getGitRegexMatches($package); - // if no name, not found in GPM - if (!isset($package->name)) { - unset($install_options[0]); - } - // if local config found symlink is a valid option - if (isset($this->local_config)) { - $install_options[] = 'symlink'; - } - // if override set, can install via git - if (isset($package->override_repository)) { - $install_options[] = 'git'; - } + $to = $this->destination . DS . $package->install_path; - if (count($install_options) == 0) { - // no valid install options - } elseif (count($install_options) == 1) { - // only one option, use it... + $this->output->writeln("Preparing to Git clone " . $package->name . ""); + + $this->output->write(" |- Checking destination... "); + $checks = $this->checkDestination($package); + + if (!$checks) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); } else { - $helper = $this->getHelper('question'); - $install_list = array_values($install_options); - $default = $install_list[0]; - $question = new ChoiceQuestion( - 'Please select installation method ('.$default.' is default)', array_values($install_list), 0 - ); - $question->setErrorMessage('Method %s is invalid'); - $method = $helper->ask($this->input, $this->output, $question); - $this->output->writeln('You chose: ' . $method); + $cmd = 'cd ' . $this->destination . ' && git clone ' . $matches[0] . ' ' . $package->install_path; + exec($cmd); + // extra white spaces to clear out the buffer properly + $this->output->writeln(" |- Cloning package... ok "); + + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } + } + + /** + * @param $package + */ + private function processGPM($package) + { + $version = isset($package->available) ? $package->available : $package->version; + + $this->output->writeln("Preparing to install " . $package->name . " [v" . $version . "]"); + + $this->output->write(" |- Downloading package... 0%"); + $this->file = $this->downloadPackage($package); + + $this->output->write(" |- Checking destination... "); + $checks = $this->checkDestination($package); + + if (!$checks) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + $this->output->write(" |- Installing package... "); + $installation = $this->installPackage($package); + if (!$installation) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } } } @@ -305,6 +410,8 @@ class InstallCommand extends Command $this->output->writeln(" | '- You decided to not delete the symlink automatically."); return false; + } else { + unlink($this->destination . DS . $package->install_path); } } From bd595ca9f6905f826a6bf74a451885315ebb70a7 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 14:04:50 -0700 Subject: [PATCH 17/31] some corner case fixes --- .../src/Grav/Console/Gpm/InstallCommand.php | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 89a9d8cd6..8ee61bbe7 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -189,6 +189,8 @@ class InstallCommand extends Command if (count($install_options) == 0) { // no valid install options - error and return + $this->output->writeln("not valid installation methods found!"); + return; } elseif (count($install_options) == 1) { // only one option, use it... $method = $install_options[0]; @@ -264,21 +266,26 @@ class InstallCommand extends Command $this->output->writeln(" '- Installation failed or aborted."); $this->output->writeln(''); } else { + if (file_exists($to)) { + $this->output->writeln(" '- Symlink cannot overwrite an existing folder"); + $this->output->writeln(''); + } else { + symlink($from, $to); - symlink($from, $to); + // extra white spaces to clear out the buffer properly + $this->output->writeln(" |- Symlinking package... ok "); - // extra white spaces to clear out the buffer properly - $this->output->writeln(" |- Symlinking package... ok "); + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); } return; - } else { - $this->output->writeln("not found!"); } } + $this->output->writeln("not found!"); + $this->output->writeln(" '- Installation failed or aborted."); } /** From 85fb5bccf3679ec0c6ea534f39c73b9e628ab701 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 14:07:40 -0700 Subject: [PATCH 18/31] text addition --- system/src/Grav/Console/Gpm/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 8ee61bbe7..d0272a1c9 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -267,7 +267,7 @@ class InstallCommand extends Command $this->output->writeln(''); } else { if (file_exists($to)) { - $this->output->writeln(" '- Symlink cannot overwrite an existing folder"); + $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); $this->output->writeln(''); } else { symlink($from, $to); From 9248c5b7096b5d5861d279b1370d400894f14c74 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 14:21:17 -0700 Subject: [PATCH 19/31] added repo URL to output --- system/src/Grav/Console/Gpm/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index d0272a1c9..fd015a0e8 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -297,7 +297,7 @@ class InstallCommand extends Command $to = $this->destination . DS . $package->install_path; - $this->output->writeln("Preparing to Git clone " . $package->name . ""); + $this->output->writeln("Preparing to Git clone " . $package->name . " from " . $matches[0]); $this->output->write(" |- Checking destination... "); $checks = $this->checkDestination($package); From 9959868022d18dba2af2eec2a92b3bfcad0e0c87 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 15:24:07 -0700 Subject: [PATCH 20/31] Don't critically fail, only log when plugin has config but is missing --- system/src/Grav/Common/Plugins.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index dd495963e..c33845fac 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -47,7 +47,8 @@ class Plugins extends Iterator $filePath = $this->grav['locator']('plugins://' . $plugin . DS . $plugin . PLUGIN_EXT); if (!is_file($filePath)) { - throw new \RuntimeException(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); + $this->grav['log']->addWarning(sprintf("Plugin '%s' enabled but not found! Try clearing cache with `bin/grav clear-cache`", $plugin)); + continue; } require_once $filePath; From 300155e82ec962683cddf71122973b06b156be60 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 16:08:24 -0700 Subject: [PATCH 21/31] Added recursive folder copy --- system/src/Grav/Common/Utils.php | 42 +++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Common/Utils.php b/system/src/Grav/Common/Utils.php index 538656a7e..9c973964b 100644 --- a/system/src/Grav/Common/Utils.php +++ b/system/src/Grav/Common/Utils.php @@ -51,7 +51,7 @@ abstract class Utils } /** - * Recurseive remove a directory - DANGEROUS! USE WITH CARE!!!! + * Recursive remove a directory - DANGEROUS! USE WITH CARE!!!! * * @param $dir * @return bool @@ -79,6 +79,46 @@ abstract class Utils return rmdir($dir); } + /** + * Recursive copy of one directory to another + * + * @param $src + * @param $dest + * + * @return bool + */ + public static function rcopy($src, $dest) + { + + // If the src is not a directory do a simple file copy + if (!is_dir($src)) { + copy($src, $dest); + return true; + } + + // If the destination directory does not exist create it + if (!is_dir($dest)) { + if (!mkdir($dest)) { + // If the destination directory could not be created stop processing + return false; + } + } + + // Open the source directory to read in files + $i = new \DirectoryIterator($src); + /** @var \DirectoryIterator $f */ + foreach ($i as $f) { + if ($f->isFile()) { + copy($f->getRealPath(), "$dest/" . $f->getFilename()); + } else { + if (!$f->isDot() && $f->isDir()) { + static::rcopy($f->getRealPath(), "$dest/$f"); + } + } + } + return true; + } + /** * Truncate HTML by text length. * From f8c203c033c7810e5c0429315becb7026a99f67c Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 16:08:53 -0700 Subject: [PATCH 22/31] Set package_type for unknown packages based on best guess --- system/src/Grav/Common/GPM/GPM.php | 1 + 1 file changed, 1 insertion(+) diff --git a/system/src/Grav/Common/GPM/GPM.php b/system/src/Grav/Common/GPM/GPM.php index 3a0c4a886..c33d8cbb5 100644 --- a/system/src/Grav/Common/GPM/GPM.php +++ b/system/src/Grav/Common/GPM/GPM.php @@ -382,6 +382,7 @@ class GPM extends Iterator $not_found = new \stdClass(); $not_found->name = Inflector::camelize($search); $not_found->slug = $search; + $not_found->package_type = $type; $not_found->install_path = str_replace('%name%', $search, $this->install_paths[$type]); $not_found->override_repository = $repository; $packages['not_found'][$search] = $not_found; From 534bb57d3f2b37ce1af745a9dc5db9e3996faefd Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 16:09:16 -0700 Subject: [PATCH 23/31] Use rcopy from Utils class --- .../src/Grav/Console/Cli/SandboxCommand.php | 41 +------------------ 1 file changed, 2 insertions(+), 39 deletions(-) diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 125fe7d0a..2d36ba8c3 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\Common\Utils; use Symfony\Component\Console\Command\Command; use Symfony\Component\Console\Formatter\OutputFormatterStyle; use Symfony\Component\Console\Input\InputArgument; @@ -188,7 +189,7 @@ class SandboxCommand extends Command $to = $this->destination . $target; $this->output->writeln(' ' . $source . ' -> ' . $to); - $this->rcopy($from, $to); + Utils::rcopy($from, $to); } } @@ -326,42 +327,4 @@ class SandboxCommand extends Command exit; } } - - /** - * @param $src - * @param $dest - * - * @return bool - */ - private function rcopy($src, $dest) - { - - // If the src is not a directory do a simple file copy - if (!is_dir($src)) { - copy($src, $dest); - return true; - } - - // If the destination directory does not exist create it - if (!is_dir($dest)) { - if (!mkdir($dest)) { - // If the destination directory could not be created stop processing - return false; - } - } - - // Open the source directory to read in files - $i = new \DirectoryIterator($src); - /** @var \DirectoryIterator $f */ - foreach ($i as $f) { - if ($f->isFile()) { - copy($f->getRealPath(), "$dest/" . $f->getFilename()); - } else { - if (!$f->isDot() && $f->isDir()) { - $this->rcopy($f->getRealPath(), "$dest/$f"); - } - } - } - return true; - } } From 5e22eee1a8080742098976dd5cd2cd41a1083999 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 16:10:00 -0700 Subject: [PATCH 24/31] Look for `_demo` content in packages and prompt to install it --- .../src/Grav/Console/Gpm/InstallCommand.php | 28 ++++++++++++++++++- 1 file changed, 27 insertions(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index fd015a0e8..7c2eb0581 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -206,8 +206,34 @@ class InstallCommand extends Command $this->output->writeln(''); $method_name = 'process'.$method; - $this->$method_name($package); + + $this->installDemoContent($package); + } + + + private function installDemoContent($package) + { + $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; + + if (file_exists($demo_dir)) { + // Demo content exists, prompt to install it. + $this->output->writeln("Attention: ".$package->name . " contains demo content"); + $helper = $this->getHelper('question'); + $question = new ConfirmationQuestion('Do you wish to install this demo content? (DANGER: May merge or overwrite existing user data) [y|N]', false); + + if (!$helper->ask($this->input, $this->output, $question)) { + $this->output->writeln(" '- Skipped! "); + $this->output->writeln(''); + return; + } + + // Confirmation received, copy over the data + $this->output->writeln(" |- Installing demo content... ok "); + Utils::rcopy($demo_dir, $this->destination . DS . 'user'); + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } } /** From e5348ec8f14a07fe192a3d4d535ff8243c046b19 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Sun, 15 Feb 2015 16:16:27 -0700 Subject: [PATCH 25/31] added a space after prompt --- system/src/Grav/Console/Gpm/InstallCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index 7c2eb0581..c59a5e63e 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -220,7 +220,7 @@ class InstallCommand extends Command // Demo content exists, prompt to install it. $this->output->writeln("Attention: ".$package->name . " contains demo content"); $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion('Do you wish to install this demo content? (DANGER: May merge or overwrite existing user data) [y|N]', false); + $question = new ConfirmationQuestion('Do you wish to install this demo content? (DANGER: May merge or overwrite existing user data) [y|N] ', false); if (!$helper->ask($this->input, $this->output, $question)) { $this->output->writeln(" '- Skipped! "); From 26b0b02de25292c03ce05512c38409bde255a8c2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 16 Feb 2015 10:14:14 -0700 Subject: [PATCH 26/31] Fix for issue #140 - plugin/theme install status not working on windows --- system/src/Grav/Common/Plugins.php | 3 ++- system/src/Grav/Common/Themes.php | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Common/Plugins.php b/system/src/Grav/Common/Plugins.php index c33845fac..d0c30c3e3 100644 --- a/system/src/Grav/Common/Plugins.php +++ b/system/src/Grav/Common/Plugins.php @@ -94,7 +94,8 @@ class Plugins extends Iterator public static function all() { $list = array(); - $iterator = new \DirectoryIterator('plugins://'); + $locator = Grav::instance()['locator']; + $iterator = new \DirectoryIterator($locator->findResource('plugins://', false)); /** @var \DirectoryIterator $directory */ foreach ($iterator as $directory) { diff --git a/system/src/Grav/Common/Themes.php b/system/src/Grav/Common/Themes.php index e44472835..4ec394ee9 100644 --- a/system/src/Grav/Common/Themes.php +++ b/system/src/Grav/Common/Themes.php @@ -59,7 +59,8 @@ class Themes extends Iterator public function all() { $list = array(); - $iterator = new \DirectoryIterator('themes://'); + $locator = Grav::instance()['locator']; + $iterator = new \DirectoryIterator($locator->findResource('themes://', false)); /** @var \DirectoryIterator $directory */ foreach ($iterator as $directory) { From 690bb8a8beb976d90042d92d2c8ccf365be90206 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 16 Feb 2015 14:45:21 -0700 Subject: [PATCH 27/31] Fix rcopy reference --- system/src/Grav/Console/Cli/SandboxCommand.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/system/src/Grav/Console/Cli/SandboxCommand.php b/system/src/Grav/Console/Cli/SandboxCommand.php index 2d36ba8c3..4d984d219 100644 --- a/system/src/Grav/Console/Cli/SandboxCommand.php +++ b/system/src/Grav/Console/Cli/SandboxCommand.php @@ -269,7 +269,7 @@ class SandboxCommand extends Command if (count($pages_files) == 0) { $destination = $this->source . '/user/pages'; - $this->rcopy($destination, $pages_dir); + Utils::rcopy($destination, $pages_dir); $this->output->writeln(' ' . $destination . ' -> Created'); } From b8cb788324a72135261cc25c5ba6ff06edcf2ce4 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 16 Feb 2015 14:46:05 -0700 Subject: [PATCH 28/31] Backup pages folder if it exits in demo copy --- .../src/Grav/Console/Gpm/InstallCommand.php | 27 +++++++++++++++++-- 1 file changed, 25 insertions(+), 2 deletions(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index c59a5e63e..a6bb1fd7a 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -215,12 +215,14 @@ class InstallCommand extends Command private function installDemoContent($package) { $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; + $dest_dir = $this->destination . DS . 'user'; + $pages_dir = $dest_dir . DS . 'pages'; if (file_exists($demo_dir)) { // Demo content exists, prompt to install it. $this->output->writeln("Attention: ".$package->name . " contains demo content"); $helper = $this->getHelper('question'); - $question = new ConfirmationQuestion('Do you wish to install this demo content? (DANGER: May merge or overwrite existing user data) [y|N] ', false); + $question = new ConfirmationQuestion('Do you wish to install this demo content? [y|N] ', false); if (!$helper->ask($this->input, $this->output, $question)) { $this->output->writeln(" '- Skipped! "); @@ -228,9 +230,30 @@ class InstallCommand extends Command return; } + // if pages folder exists in demo + if (file_exists($demo_dir . DS . 'pages')) { + $pages_backup = 'pages.' . date('m-d-Y-H-i-s'); + $question = new ConfirmationQuestion('This will backup your current `user/pages` folder to `user/'. $pages_backup. '`, continue? [y|N]', false); + + if (!$helper->ask($this->input, $this->output, $question)) { + $this->output->writeln(" '- Skipped! "); + $this->output->writeln(''); + return; + } + + // backup current pages folder + if (file_exists($dest_dir)) { + if (rename($pages_dir, $dest_dir . DS . $pages_backup)) { + $this->output->writeln(" |- Backing up pages... ok"); + } else { + $this->output->writeln(" |- Backing up pages... failed"); + } + } + } + // Confirmation received, copy over the data $this->output->writeln(" |- Installing demo content... ok "); - Utils::rcopy($demo_dir, $this->destination . DS . 'user'); + Utils::rcopy($demo_dir, $dest_dir); $this->output->writeln(" '- Success! "); $this->output->writeln(''); } From 73a104000a12d1f2faad11b6ad3d0f31450b3750 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 16 Feb 2015 18:28:52 -0700 Subject: [PATCH 29/31] updated bundled composer package --- bin/composer.phar | Bin 1048439 -> 1054749 bytes 1 file changed, 0 insertions(+), 0 deletions(-) diff --git a/bin/composer.phar b/bin/composer.phar index e46677b91013df91437beaa34aabc07d890b1bc8..227468449c3eb06f4a40672667ff496cdd04649d 100755 GIT binary patch delta 10964 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 delta 7189 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 From 04a2f618bdaf7f844f741d98959e07036394397a Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Mon, 16 Feb 2015 18:48:52 -0700 Subject: [PATCH 30/31] now checks for symlink availability before giving that option --- .../src/Grav/Console/Gpm/InstallCommand.php | 91 +++++++++++-------- 1 file changed, 53 insertions(+), 38 deletions(-) diff --git a/system/src/Grav/Console/Gpm/InstallCommand.php b/system/src/Grav/Console/Gpm/InstallCommand.php index a6bb1fd7a..c39087db4 100644 --- a/system/src/Grav/Console/Gpm/InstallCommand.php +++ b/system/src/Grav/Console/Gpm/InstallCommand.php @@ -133,7 +133,6 @@ class InstallCommand extends Command foreach ($this->data as $data) { foreach ($data as $package) { - //Check for dependencies if (isset($package->dependencies)) { $this->output->writeln("Package " . $package->name . " has ". count($package->dependencies) . " required dependencies that must be installed first..."); @@ -176,7 +175,7 @@ class InstallCommand extends Command unset($install_options[0]); } // if local config found symlink is a valid option - if (isset($this->local_config)) { + if (isset($this->local_config) && $this->getSymlinkSource($package)) { $install_options[] = 'Symlink'; } // if override set, can install via git @@ -212,6 +211,9 @@ class InstallCommand extends Command } + /** + * @param $package + */ private function installDemoContent($package) { $demo_dir = $this->destination . DS . $package->install_path . DS . '_demo'; @@ -281,21 +283,14 @@ class InstallCommand extends Command /** * @param $package + * + * @return bool|string */ - private function processSymlink($package) + private function getSymlinkSource($package) { - - exec('cd ' . $this->destination); - - $to = $this->destination . DS . $package->install_path; - $matches = $this->getGitRegexMatches($package); - $this->output->writeln("Preparing to Symlink " . $package->name . ""); - $this->output->write(" |- Checking source... "); - foreach ($this->local_config as $path) { - if (Utils::endsWith($matches[2], '.git')) { $repo_dir = preg_replace('/\.git$/', '', $matches[2]); } else { @@ -305,34 +300,54 @@ class InstallCommand extends Command $from = rtrim($path, '/') . '/' . $repo_dir; if (file_exists($from)) { - - $this->output->writeln("ok"); - - $this->output->write(" |- Checking destination... "); - $checks = $this->checkDestination($package); - - if (!$checks) { - $this->output->writeln(" '- Installation failed or aborted."); - $this->output->writeln(''); - } else { - if (file_exists($to)) { - $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); - $this->output->writeln(''); - } else { - symlink($from, $to); - - // extra white spaces to clear out the buffer properly - $this->output->writeln(" |- Symlinking package... ok "); - - $this->output->writeln(" '- Success! "); - $this->output->writeln(''); - } - - - } - return; + return $from; } } + return false; + } + + /** + * @param $package + */ + private function processSymlink($package) + { + + exec('cd ' . $this->destination); + + $to = $this->destination . DS . $package->install_path; + $from = $this->getSymlinkSource($package); + + $this->output->writeln("Preparing to Symlink " . $package->name . ""); + $this->output->write(" |- Checking source... "); + + if (file_exists($from)) { + $this->output->writeln("ok"); + + $this->output->write(" |- Checking destination... "); + $checks = $this->checkDestination($package); + + if (!$checks) { + $this->output->writeln(" '- Installation failed or aborted."); + $this->output->writeln(''); + } else { + if (file_exists($to)) { + $this->output->writeln(" '- Symlink cannot overwrite an existing package, please remove first"); + $this->output->writeln(''); + } else { + symlink($from, $to); + + // extra white spaces to clear out the buffer properly + $this->output->writeln(" |- Symlinking package... ok "); + + $this->output->writeln(" '- Success! "); + $this->output->writeln(''); + } + + + } + return; + } + $this->output->writeln("not found!"); $this->output->writeln(" '- Installation failed or aborted."); } From 7b32cbe2e1dafa18e4a7ae1a5b23189649e41bd2 Mon Sep 17 00:00:00 2001 From: Andy Miller Date: Tue, 17 Feb 2015 11:22:35 -0700 Subject: [PATCH 31/31] Some performance optimizations for folder/file checking routines --- system/src/Grav/Common/Filesystem/Folder.php | 83 +++++++++++--------- 1 file changed, 46 insertions(+), 37 deletions(-) diff --git a/system/src/Grav/Common/Filesystem/Folder.php b/system/src/Grav/Common/Filesystem/Folder.php index 79eb5ada8..223b3dce8 100644 --- a/system/src/Grav/Common/Filesystem/Folder.php +++ b/system/src/Grav/Common/Filesystem/Folder.php @@ -19,12 +19,13 @@ abstract class Folder { $last_modified = 0; - $directory = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); - $iterator = new \RecursiveIteratorIterator($directory, \RecursiveIteratorIterator::SELF_FIRST); + $dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + $filterItr = new GravRecursiveFolderFilterIterator($dirItr); + $itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST); /** @var \RecursiveDirectoryIterator $file */ - foreach ($iterator as $file) { - $dir_modified = $file->getMTime(); + foreach ($itr as $dir) { + $dir_modified = $dir->getMTime(); if ($dir_modified > $last_modified) { $last_modified = $dir_modified; } @@ -33,6 +34,34 @@ abstract class Folder return $last_modified; } + /** + * Recursively find the last modified time under given path by file. + * + * @param string $path + * @return int + */ + public static function lastModifiedFile($path) + { + $last_modified = 0; + + $dirItr = new \RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS); + $filterItr = new GravRecursiveFileFilterIterator($dirItr); + $itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST); + + /** @var \RecursiveDirectoryIterator $file */ + foreach ($itr as $file) { + if ($file->isDir()) { + continue; + } + $file_modified = $file->getMTime(); + if ($file_modified > $last_modified) { + $last_modified = $file_modified; + } + } + + return $last_modified; + } + /** * Get relative path between target and base path. If path isn't relative, return full path. * @@ -68,30 +97,7 @@ abstract class Folder return $result ?: null; } - /** - * Recursively find the last modified time under given path by file. - * - * @param string $path - * @return int - */ - public static function lastModifiedFile($path) - { - $last_modified = 0; - $dirItr = new \RecursiveDirectoryIterator($path); - $filterItr = new GravRecursiveFilterIterator($dirItr); - $itr = new \RecursiveIteratorIterator($filterItr, \RecursiveIteratorIterator::SELF_FIRST); - - /** @var \RecursiveDirectoryIterator $file */ - foreach ($itr as $file) { - $file_modified = $file->getMTime(); - if ($file_modified > $last_modified) { - $last_modified = $file_modified; - } - } - - return $last_modified; - } /** * Return recursive list of all files and directories under given path. @@ -296,19 +302,22 @@ abstract class Folder } } -class GravRecursiveFilterIterator extends \RecursiveFilterIterator +class GravRecursiveFolderFilterIterator extends \RecursiveFilterIterator { - public static $FILTERS = array( - '..', '.DS_Store' - ); + public function accept() + { + // only accept directories + return $this->current()->isDir(); + } +} + +class GravRecursiveFileFilterIterator extends \RecursiveFilterIterator +{ + public static $FILTERS = ['.DS_Store']; public function accept() { - return !in_array( - $this->current()->getFilename(), - self::$FILTERS, - true - ); + // Ensure any filtered file names are skipped + return !in_array($this->current()->getFilename(), self::$FILTERS, true); } - }