From 13e44649708829023695f57c5606d200c5f5b97f Mon Sep 17 00:00:00 2001 From: Simon Dann Date: Fri, 23 Feb 2018 10:49:29 +0000 Subject: [PATCH] Various 2.0 Amends (#304) * :truck: added two new steps for #297 in new folder as per #282 * :truck: drafting things out * :fire: disabling 1.* tests for refactoring * :truck: tinkering * :truck: filling in ProjectFile methods from File * Refactoring to use ProjectFile * Updating dependencies as per #270, this breaks everything... * (#270) Update for working with 7.0 * Store uid in meta array so File object can be duplicated correctly * (#284) Refactoring project to use ProjectFile * (#300) Use Plates v4, this restricts us from launching 2.0 until v4 is stable * (#284) Refactored out File entity usage for ProjectFile * (#270) Refactored test for 7.0 - passing * (#270) Enabling a handfull of tests - passing * (#300) Refactored most Plates Extensions * (#282) Refactored LoadSourceFileTree * (#300) Refactored to use Plates v4 * Apply fixes from StyleCI (#301) Unit tests allowed to fail * (#270) lock file was generated on 7.2, needs removing so 7.0 unit tests "pass" --- .travis.yml | 3 +- composer.json | 11 +- composer.lock | 833 +++++++++++------- phpunit.xml | 4 +- src/Entities/CachedFile.php | 22 +- src/Entities/ContentType.php | 44 +- src/Entities/Filesystem/FileAction.php | 12 +- src/Entities/Filesystem/FileWriter.php | 3 +- .../Filesystem/FilesystemInterface.php | 8 +- src/Entities/Generators/FileGenerator.php | 19 +- .../Generators/PaginationGenerator.php | 17 +- .../Generators/TaxonomyArchiveGenerator.php | 3 +- src/Entities/Pagination.php | 4 +- src/Entities/Permalink.php | 11 +- src/Entities/Project.php | 14 +- src/Entities/ProjectFile.php | 456 ++++++++++ src/Entities/ProjectFileInterface.php | 6 + src/Entities/Renderers/DefaultRenderer.php | 15 +- src/Entities/Renderers/HTMLRenderer.php | 39 +- src/Entities/Renderers/MarkdownRenderer.php | 27 +- src/Entities/Renderers/PlatesRenderer.php | 31 +- src/Entities/Renderers/RendererInterface.php | 10 +- src/Entities/Taxonomy.php | 4 +- src/Entities/ViewFile.php | 6 +- src/Entities/ViewFileTrait.php | 12 +- src/Modules/Api/Json.php | 7 +- src/Modules/Config/DefaultConfig.php | 4 +- src/Modules/Content/Compile.php | 15 +- src/Modules/Content/LoadSourceFiles.php | 8 +- .../ContentTypes/ParseContentTypes.php | 13 +- .../Generators/ContentGeneratorFactory.php | 4 +- src/Modules/Plates/Extensions/Environment.php | 54 ++ .../Plates/Extensions/Helpers.php | 6 +- .../Plates/Extensions/RenderProjectFile.php | 54 ++ src/Modules/Plates/Extensions/Site.php | 58 ++ src/Modules/Plates/Extensions/Url.php | 57 ++ .../Renderers/ContentRendererFactory.php | 14 +- src/Plates/Engine.php | 10 +- src/Plates/Extensions/Environment.php | 34 - src/Plates/Extensions/Site.php | 40 - src/Plates/Extensions/Url.php | 34 - src/Plates/Template.php | 13 +- src/Providers/PlatesServiceProvider.php | 34 +- src/Steps/LexicalAnalysis.php | 30 + .../LoadContentGenerators.php | 9 +- .../LoadContentRenderers.php | 8 +- .../LoadContentTypes.php | 6 +- src/Steps/LoadSourceFileTree.php | 230 +++++ src/{Modules/Content => Steps}/ReadCache.php | 3 +- src/Steps/RenderPlates.php | 57 ++ src/Steps/SyntaxAnalysis.php | 301 +++++++ tests/CommandTestBase.php | 2 +- tests/Feature/PermalinkTest.php | 12 +- .../Feature/TaxonomyArchiveGeneratorTest.php | 5 +- tests/TestCase.php | 25 +- tests/Traits/MockFile.php | 13 +- tests/Traits/MockViewFile.php | 17 +- ...eTest.php => ArrayContainerMergeNTest.php} | 2 +- tests/Unit/CacheTest.php | 2 +- ...llectionsTest.php => CollectionsNTest.php} | 2 +- ...st.php => CommandLineApplicationNTest.php} | 2 +- tests/Unit/ContentGraphNTest.php | 75 ++ ...ntentTypeTest.php => ContentTypeNTest.php} | 6 +- .../{EntitiesTest.php => EntitiesNTest.php} | 2 +- tests/Unit/{FileTest.php => FileNTest.php} | 6 +- ...ontMatterTest.php => FrontMatterNTest.php} | 10 +- .../{HelpersTest.php => HelpersNTest.php} | 2 +- tests/Unit/PaginationTest.php | 15 +- ...lerTest.php => StopwatchProfilerNTest.php} | 2 +- .../{TaxonomyTest.php => TaxonomyNTest.php} | 9 +- tests/assets/build_test_41/check/about.html | 1 + tests/assets/build_test_41/check/index.html | 1 + tests/assets/build_test_41/src/config.php | 7 + .../_blog/2016-03-10-test-blog-entry.md | 7 + .../_blog/2016-03-11-test-blog-entry-two.md | 7 + .../src/source/_templates/default.phtml | 19 + .../src/source/_views/blog.phtml | 16 + .../assets/build_test_41/src/source/about.md | 4 + .../build_test_41/src/source/assets/js/app.js | 1 + .../src/source/assets/js/something_else/a.js | 1 + .../src/source/assets/js/something_else/b.js | 1 + .../ignored_folder/should_be_ignored.md | 1 + .../assets/build_test_41/src/source/index.php | 1 + 83 files changed, 2303 insertions(+), 690 deletions(-) create mode 100644 src/Entities/ProjectFile.php create mode 100644 src/Modules/Plates/Extensions/Environment.php rename src/{ => Modules}/Plates/Extensions/Helpers.php (88%) create mode 100644 src/Modules/Plates/Extensions/RenderProjectFile.php create mode 100644 src/Modules/Plates/Extensions/Site.php create mode 100644 src/Modules/Plates/Extensions/Url.php delete mode 100644 src/Plates/Extensions/Environment.php delete mode 100644 src/Plates/Extensions/Site.php delete mode 100644 src/Plates/Extensions/Url.php create mode 100644 src/Steps/LexicalAnalysis.php rename src/{Modules/Generators => Steps}/LoadContentGenerators.php (84%) rename src/{Modules/Renderers => Steps}/LoadContentRenderers.php (84%) rename src/{Modules/ContentTypes => Steps}/LoadContentTypes.php (91%) create mode 100644 src/Steps/LoadSourceFileTree.php rename src/{Modules/Content => Steps}/ReadCache.php (95%) create mode 100644 src/Steps/RenderPlates.php create mode 100644 src/Steps/SyntaxAnalysis.php rename tests/Unit/{ArrayContainerMergeTest.php => ArrayContainerMergeNTest.php} (99%) rename tests/Unit/{CollectionsTest.php => CollectionsNTest.php} (98%) rename tests/Unit/{CommandLineApplicationTest.php => CommandLineApplicationNTest.php} (89%) create mode 100644 tests/Unit/ContentGraphNTest.php rename tests/Unit/{ContentTypeTest.php => ContentTypeNTest.php} (90%) rename tests/Unit/{EntitiesTest.php => EntitiesNTest.php} (99%) rename tests/Unit/{FileTest.php => FileNTest.php} (56%) rename tests/Unit/{FrontMatterTest.php => FrontMatterNTest.php} (84%) rename tests/Unit/{HelpersTest.php => HelpersNTest.php} (98%) rename tests/Unit/{StopwatchProfilerTest.php => StopwatchProfilerNTest.php} (97%) rename tests/Unit/{TaxonomyTest.php => TaxonomyNTest.php} (97%) create mode 100644 tests/assets/build_test_41/check/about.html create mode 100644 tests/assets/build_test_41/check/index.html create mode 100644 tests/assets/build_test_41/src/config.php create mode 100644 tests/assets/build_test_41/src/source/_blog/2016-03-10-test-blog-entry.md create mode 100644 tests/assets/build_test_41/src/source/_blog/2016-03-11-test-blog-entry-two.md create mode 100644 tests/assets/build_test_41/src/source/_templates/default.phtml create mode 100644 tests/assets/build_test_41/src/source/_views/blog.phtml create mode 100644 tests/assets/build_test_41/src/source/about.md create mode 100644 tests/assets/build_test_41/src/source/assets/js/app.js create mode 100644 tests/assets/build_test_41/src/source/assets/js/something_else/a.js create mode 100644 tests/assets/build_test_41/src/source/assets/js/something_else/b.js create mode 100644 tests/assets/build_test_41/src/source/ignored_folder/should_be_ignored.md create mode 100644 tests/assets/build_test_41/src/source/index.php diff --git a/.travis.yml b/.travis.yml index d8ed5f2..c90872e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -4,9 +4,9 @@ sudo: false matrix: include: - - php: 5.6 - php: 7.0 - php: 7.1 + - php: 7.2 env: WITH_COVERAGE=true - php: nightly allow_failures: @@ -24,6 +24,7 @@ before_install: - travis_retry composer self-update install: + - rm composer.lock - travis_retry composer install --no-interaction --prefer-dist --no-suggest; script: diff --git a/composer.json b/composer.json index a93cf34..c9c5412 100644 --- a/composer.json +++ b/composer.json @@ -7,6 +7,10 @@ "site", "generator" ], + "support": { + "issues": "https://github.com/tapestry-cloud/tapestry/issues", + "source": "https://github.com/tapestry-cloud/tapestry" + }, "license": "MIT", "authors": [ { @@ -28,25 +32,26 @@ } }, "require": { - "php": ">=5.6.0", + "php": ">=7.0.0", "symfony/console": "^3.4", "symfony/filesystem": "^3.4", "symfony/finder" : "^3.4", "symfony/yaml": "^3.4", "symfony/process": "^3.4", "league/container": "^2.4", - "league/plates": "^3.3", + "league/plates": "^4", "league/event": "^2.1", "nesbot/carbon": "^1", "composer/semver": "^1.4", "michelf/php-markdown": "^1.7" }, "require-dev": { - "phpunit/phpunit": "^5" + "phpunit/phpunit": "6.*|7.*" }, "bin": [ "bin/tapestry.php" ], + "minimum-stability" : "dev", "scripts": { "box": [ "composer install --no-dev --prefer-dist", diff --git a/composer.lock b/composer.lock index 8297fdf..490ccec 100644 --- a/composer.lock +++ b/composer.lock @@ -4,20 +4,20 @@ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "This file is @generated automatically" ], - "content-hash": "39658cc0978003cdb7dd516c9c9019eb", + "content-hash": "971787be1597da0c1a180ab2bee1045c", "packages": [ { "name": "composer/semver", - "version": "1.4.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/composer/semver.git", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573" + "reference": "2b303e43d14d15cc90c8e8db4a1cdb6259f1a5c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/semver/zipball/c7cb9a2095a074d131b65a8a0cd294479d785573", - "reference": "c7cb9a2095a074d131b65a8a0cd294479d785573", + "url": "https://api.github.com/repos/composer/semver/zipball/2b303e43d14d15cc90c8e8db4a1cdb6259f1a5c5", + "reference": "2b303e43d14d15cc90c8e8db4a1cdb6259f1a5c5", "shasum": "" }, "require": { @@ -66,7 +66,7 @@ "validation", "versioning" ], - "time": "2016-08-30T16:08:34+00:00" + "time": "2017-11-06T09:05:54+00:00" }, { "name": "container-interop/container-interop", @@ -101,16 +101,16 @@ }, { "name": "league/container", - "version": "2.4.1", + "version": "2.x-dev", "source": { "type": "git", "url": "https://github.com/thephpleague/container.git", - "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0" + "reference": "e541429f0932f240d0e5a183fcd4b9b9939dde5a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/container/zipball/43f35abd03a12977a60ffd7095efd6a7808488c0", - "reference": "43f35abd03a12977a60ffd7095efd6a7808488c0", + "url": "https://api.github.com/repos/thephpleague/container/zipball/e541429f0932f240d0e5a183fcd4b9b9939dde5a", + "reference": "e541429f0932f240d0e5a183fcd4b9b9939dde5a", "shasum": "" }, "require": { @@ -162,20 +162,20 @@ "provider", "service" ], - "time": "2017-05-10T09:20:27+00:00" + "time": "2017-05-10T09:36:53+00:00" }, { "name": "league/event", - "version": "2.1.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/thephpleague/event.git", - "reference": "e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd" + "reference": "0bfa3954c93a7b596168b4fd32d0e6631fd175e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/event/zipball/e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd", - "reference": "e4bfc88dbcb60c8d8a2939a71f9813e141bbe4cd", + "url": "https://api.github.com/repos/thephpleague/event/zipball/0bfa3954c93a7b596168b4fd32d0e6631fd175e2", + "reference": "0bfa3954c93a7b596168b4fd32d0e6631fd175e2", "shasum": "" }, "require": { @@ -183,7 +183,7 @@ }, "require-dev": { "henrikbjorn/phpspec-code-coverage": "~1.0.1", - "phpspec/phpspec": "~2.0.0" + "phpspec/phpspec": "^2.2" }, "type": "library", "extra": { @@ -212,40 +212,52 @@ "event", "listener" ], - "time": "2015-05-21T12:24:47+00:00" + "time": "2016-07-23T09:33:29+00:00" }, { "name": "league/plates", - "version": "3.3.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/thephpleague/plates.git", - "reference": "b1684b6f127714497a0ef927ce42c0b44b45a8af" + "reference": "f53f4c1fa4bf307d0f3858a348172ff4faf7669a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/thephpleague/plates/zipball/b1684b6f127714497a0ef927ce42c0b44b45a8af", - "reference": "b1684b6f127714497a0ef927ce42c0b44b45a8af", + "url": "https://api.github.com/repos/thephpleague/plates/zipball/f53f4c1fa4bf307d0f3858a348172ff4faf7669a", + "reference": "f53f4c1fa4bf307d0f3858a348172ff4faf7669a", "shasum": "" }, "require": { - "php": "^5.3 | ^7.0" + "php": "^7.0" }, "require-dev": { - "mikey179/vfsstream": "^1.4", - "phpunit/phpunit": "~4.0", + "eloquent/phony-peridot": "^2.0", + "peridot-php/leo": "^1.6", + "peridot-php/peridot": "^1.19", + "peridot-php/peridot-code-coverage-reporters": "^3.0", "squizlabs/php_codesniffer": "~1.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "4.0-dev" } }, "autoload": { "psr-4": { "League\\Plates\\": "src" - } + }, + "files": [ + "src/Template/match.php", + "src/Extension/Data/data.php", + "src/Extension/Path/path.php", + "src/Extension/RenderContext/func.php", + "src/Extension/RenderContext/render-context.php", + "src/Extension/LayoutSections/layout-sections.php", + "src/Extension/Folders/folders.php", + "src/Util/util.php" + ] }, "notification-url": "https://packagist.org/downloads/", "license": [ @@ -256,6 +268,11 @@ "name": "Jonathan Reinink", "email": "jonathan@reinink.ca", "role": "Developer" + }, + { + "name": "RJ Garcia", + "email": "rj@bighead.net", + "role": "Developer" } ], "description": "Plates, the native PHP template system that's fast, easy to use and easy to extend.", @@ -267,34 +284,29 @@ "templating", "views" ], - "time": "2016-12-28T00:14:17+00:00" + "time": "2018-01-31T07:20:23+00:00" }, { "name": "michelf/php-markdown", - "version": "1.7.0", + "version": "1.8.0", "source": { "type": "git", "url": "https://github.com/michelf/php-markdown.git", - "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220" + "reference": "01ab082b355bf188d907b9929cd99b2923053495" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/michelf/php-markdown/zipball/1f51cc520948f66cd2af8cbc45a5ee175e774220", - "reference": "1f51cc520948f66cd2af8cbc45a5ee175e774220", + "url": "https://api.github.com/repos/michelf/php-markdown/zipball/01ab082b355bf188d907b9929cd99b2923053495", + "reference": "01ab082b355bf188d907b9929cd99b2923053495", "shasum": "" }, "require": { "php": ">=5.3.0" }, "type": "library", - "extra": { - "branch-alias": { - "dev-lib": "1.4.x-dev" - } - }, "autoload": { - "psr-0": { - "Michelf": "" + "psr-4": { + "Michelf\\": "Michelf/" } }, "notification-url": "https://packagist.org/downloads/", @@ -318,25 +330,25 @@ "keywords": [ "markdown" ], - "time": "2016-10-29T18:58:20+00:00" + "time": "2018-01-15T00:49:33+00:00" }, { "name": "nesbot/carbon", - "version": "1.22.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc" + "reference": "604c1ddef58dfc5eda97ae83c00b8e0027b72fec" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc", - "reference": "7cdf42c0b1cc763ab7e4c33c47a24e27c66bfccc", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/604c1ddef58dfc5eda97ae83c00b8e0027b72fec", + "reference": "604c1ddef58dfc5eda97ae83c00b8e0027b72fec", "shasum": "" }, "require": { "php": ">=5.3.0", - "symfony/translation": "~2.6 || ~3.0" + "symfony/translation": "~2.6 || ~3.0 || ~4.0" }, "require-dev": { "friendsofphp/php-cs-fixer": "~2", @@ -371,20 +383,20 @@ "datetime", "time" ], - "time": "2017-01-16T07:55:07+00:00" + "time": "2018-02-22T10:18:22+00:00" }, { "name": "psr/container", - "version": "1.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/php-fig/container.git", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f" + "reference": "2cc4a01788191489dc7459446ba832fa79a216a7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/php-fig/container/zipball/b7ce3b176482dbbc1245ebf52b181af44c2cf55f", - "reference": "b7ce3b176482dbbc1245ebf52b181af44c2cf55f", + "url": "https://api.github.com/repos/php-fig/container/zipball/2cc4a01788191489dc7459446ba832fa79a216a7", + "reference": "2cc4a01788191489dc7459446ba832fa79a216a7", "shasum": "" }, "require": { @@ -420,11 +432,11 @@ "container-interop", "psr" ], - "time": "2017-02-14T16:28:37+00:00" + "time": "2017-06-28T15:35:32+00:00" }, { "name": "psr/log", - "version": "1.0.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/php-fig/log.git", @@ -471,16 +483,16 @@ }, { "name": "symfony/console", - "version": "v3.4.2", + "version": "3.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e" + "reference": "996fd519af74ddfaa7733ea358acbca5d7d43f34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/9f21adfb92a9315b73ae2ed43138988ee4913d4e", - "reference": "9f21adfb92a9315b73ae2ed43138988ee4913d4e", + "url": "https://api.github.com/repos/symfony/console/zipball/996fd519af74ddfaa7733ea358acbca5d7d43f34", + "reference": "996fd519af74ddfaa7733ea358acbca5d7d43f34", "shasum": "" }, "require": { @@ -536,36 +548,36 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-02-09T14:10:47+00:00" }, { "name": "symfony/debug", - "version": "v3.4.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "543deab3ffff94402440b326fc94153bae2dfa7a" + "reference": "af2d12fa3962eee6c7d2301058df1e8cf6eb273c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/543deab3ffff94402440b326fc94153bae2dfa7a", - "reference": "543deab3ffff94402440b326fc94153bae2dfa7a", + "url": "https://api.github.com/repos/symfony/debug/zipball/af2d12fa3962eee6c7d2301058df1e8cf6eb273c", + "reference": "af2d12fa3962eee6c7d2301058df1e8cf6eb273c", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": "^7.1.3", "psr/log": "~1.0" }, "conflict": { - "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2" + "symfony/http-kernel": "<3.4" }, "require-dev": { - "symfony/http-kernel": "~2.8|~3.0|~4.0" + "symfony/http-kernel": "~3.4|~4.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -592,20 +604,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2017-12-12T08:27:14+00:00" + "time": "2018-02-04T13:22:04+00:00" }, { "name": "symfony/filesystem", - "version": "v3.4.2", + "version": "3.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "25b135bea251829e3db6a77d773643408b575ed4" + "reference": "e078773ad6354af38169faf31c21df0f18ace03d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/25b135bea251829e3db6a77d773643408b575ed4", - "reference": "25b135bea251829e3db6a77d773643408b575ed4", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/e078773ad6354af38169faf31c21df0f18ace03d", + "reference": "e078773ad6354af38169faf31c21df0f18ace03d", "shasum": "" }, "require": { @@ -641,20 +653,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-01-03T07:37:34+00:00" }, { "name": "symfony/finder", - "version": "v3.4.2", + "version": "3.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a" + "reference": "6a615613745cef820d807443f32076bb9f5d0a38" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/dac8d7db537bac7ad8143eb11360a8c2231f251a", - "reference": "dac8d7db537bac7ad8143eb11360a8c2231f251a", + "url": "https://api.github.com/repos/symfony/finder/zipball/6a615613745cef820d807443f32076bb9f5d0a38", + "reference": "6a615613745cef820d807443f32076bb9f5d0a38", "shasum": "" }, "require": { @@ -690,20 +702,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2017-11-05T16:10:10+00:00" + "time": "2018-02-11T17:15:12+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.6.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296" + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", - "reference": "2ec8b39c38cb16674bbf3fea2b6ce5bf117e1296", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/78be803ce01e55d3491c1397cf1c64beb9c1b63b", + "reference": "78be803ce01e55d3491c1397cf1c64beb9c1b63b", "shasum": "" }, "require": { @@ -715,7 +727,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.6-dev" + "dev-master": "1.7-dev" } }, "autoload": { @@ -749,20 +761,20 @@ "portable", "shim" ], - "time": "2017-10-11T12:05:26+00:00" + "time": "2018-01-30T19:27:44+00:00" }, { "name": "symfony/process", - "version": "v3.4.2", + "version": "3.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098" + "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/bb3ef65d493a6d57297cad6c560ee04e2a8f5098", - "reference": "bb3ef65d493a6d57297cad6c560ee04e2a8f5098", + "url": "https://api.github.com/repos/symfony/process/zipball/cc4aea21f619116aaf1c58016a944e4821c8e8af", + "reference": "cc4aea21f619116aaf1c58016a944e4821c8e8af", "shasum": "" }, "require": { @@ -798,37 +810,37 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2017-12-14T19:40:10+00:00" + "time": "2018-02-12T17:55:00+00:00" }, { "name": "symfony/translation", - "version": "v3.4.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "4c5d5582baf2829751a5207659329c1f52eedeb6" + "reference": "db7a511c2bd8110a57c3b00364d724668cfa3c83" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/4c5d5582baf2829751a5207659329c1f52eedeb6", - "reference": "4c5d5582baf2829751a5207659329c1f52eedeb6", + "url": "https://api.github.com/repos/symfony/translation/zipball/db7a511c2bd8110a57c3b00364d724668cfa3c83", + "reference": "db7a511c2bd8110a57c3b00364d724668cfa3c83", "shasum": "" }, "require": { - "php": "^5.5.9|>=7.0.8", + "php": "^7.1.3", "symfony/polyfill-mbstring": "~1.0" }, "conflict": { - "symfony/config": "<2.8", + "symfony/config": "<3.4", "symfony/dependency-injection": "<3.4", "symfony/yaml": "<3.4" }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.8|~3.0|~4.0", + "symfony/config": "~3.4|~4.0", "symfony/dependency-injection": "~3.4|~4.0", "symfony/finder": "~2.8|~3.0|~4.0", - "symfony/intl": "^2.8.18|^3.2.5|~4.0", + "symfony/intl": "~3.4|~4.0", "symfony/yaml": "~3.4|~4.0" }, "suggest": { @@ -839,7 +851,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.4-dev" + "dev-master": "4.1-dev" } }, "autoload": { @@ -866,20 +878,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2017-12-12T08:27:14+00:00" + "time": "2018-02-19T12:10:10+00:00" }, { "name": "symfony/yaml", - "version": "v3.4.2", + "version": "3.4.x-dev", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "afe0cd38486505c9703707707d91450cfc1bd536" + "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/afe0cd38486505c9703707707d91450cfc1bd536", - "reference": "afe0cd38486505c9703707707d91450cfc1bd536", + "url": "https://api.github.com/repos/symfony/yaml/zipball/6af42631dcf89e9c616242c900d6c52bd53bd1bb", + "reference": "6af42631dcf89e9c616242c900d6c52bd53bd1bb", "shasum": "" }, "require": { @@ -924,38 +936,37 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2017-12-11T20:38:23+00:00" + "time": "2018-02-16T09:50:28+00:00" } ], "packages-dev": [ { "name": "doctrine/instantiator", - "version": "1.0.5", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/doctrine/instantiator.git", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d" + "reference": "dcbbb92ee8534a4244559f3b0e5702dd30b43f47" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/instantiator/zipball/8e884e78f9f0eb1329e445619e04456e64d8051d", - "reference": "8e884e78f9f0eb1329e445619e04456e64d8051d", + "url": "https://api.github.com/repos/doctrine/instantiator/zipball/dcbbb92ee8534a4244559f3b0e5702dd30b43f47", + "reference": "dcbbb92ee8534a4244559f3b0e5702dd30b43f47", "shasum": "" }, "require": { - "php": ">=5.3,<8.0-DEV" + "php": "^7.1" }, "require-dev": { - "athletic/athletic": "~0.1.8", + "doctrine/coding-standard": "~2.1.0", "ext-pdo": "*", "ext-phar": "*", - "phpunit/phpunit": "~4.0", - "squizlabs/php_codesniffer": "~2.0" + "phpunit/phpunit": "^6.5.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "1.2.x-dev" } }, "autoload": { @@ -980,31 +991,36 @@ "constructor", "instantiate" ], - "time": "2015-06-14T21:17:01+00:00" + "time": "2018-01-29T06:31:30+00:00" }, { "name": "myclabs/deep-copy", - "version": "1.7.0", + "version": "1.x-dev", "source": { "type": "git", "url": "https://github.com/myclabs/DeepCopy.git", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e" + "reference": "9f807201f6e6a8b7ab3582d815511d1807c9c202" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", - "reference": "3b8a3a99ba1f6a3952ac2747d989303cbd6b7a3e", + "url": "https://api.github.com/repos/myclabs/DeepCopy/zipball/9f807201f6e6a8b7ab3582d815511d1807c9c202", + "reference": "9f807201f6e6a8b7ab3582d815511d1807c9c202", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.1" }, "require-dev": { "doctrine/collections": "^1.0", "doctrine/common": "^2.6", - "phpunit/phpunit": "^4.1" + "phpunit/phpunit": "^6.4" }, "type": "library", + "extra": { + "branch-alias": { + "dev-1.x": "1.x-dev" + } + }, "autoload": { "psr-4": { "DeepCopy\\": "src/DeepCopy/" @@ -1025,32 +1041,134 @@ "object", "object graph" ], - "time": "2017-10-19T19:58:43+00:00" + "time": "2017-12-18T00:20:24+00:00" }, { - "name": "phpdocumentor/reflection-common", + "name": "phar-io/manifest", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/phar-io/manifest.git", + "reference": "014feadb268809af7c8e2f7ccd396b8494901f58" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/manifest/zipball/014feadb268809af7c8e2f7ccd396b8494901f58", + "reference": "014feadb268809af7c8e2f7ccd396b8494901f58", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-phar": "*", + "phar-io/version": "^1.0.1", + "php": "^5.6 || ^7.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0.x-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Component for reading phar.io manifest information from a PHP Archive (PHAR)", + "time": "2017-04-07T07:07:10+00:00" + }, + { + "name": "phar-io/version", "version": "1.0.1", + "source": { + "type": "git", + "url": "https://github.com/phar-io/version.git", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/phar-io/version/zipball/a70c0ced4be299a63d32fa96d9281d03e94041df", + "reference": "a70c0ced4be299a63d32fa96d9281d03e94041df", + "shasum": "" + }, + "require": { + "php": "^5.6 || ^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + }, + { + "name": "Sebastian Heuer", + "email": "sebastian@phpeople.de", + "role": "Developer" + }, + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de", + "role": "Developer" + } + ], + "description": "Library for handling version information and constraints", + "time": "2017-03-05T17:38:23+00:00" + }, + { + "name": "phpdocumentor/reflection-common", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6" + "reference": "81339187a96c6fdb70cd876b129891f8ca501508" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", - "reference": "21bdeb5f65d7ebf9f43b1b25d404f87deab5bfb6", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/81339187a96c6fdb70cd876b129891f8ca501508", + "reference": "81339187a96c6fdb70cd876b129891f8ca501508", "shasum": "" }, "require": { - "php": ">=5.5" + "php": ">=7.1" }, "require-dev": { - "phpunit/phpunit": "^4.6" + "phpunit/phpunit": "^6" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "2.x-dev" } }, "autoload": { @@ -1079,38 +1197,40 @@ "reflection", "static analysis" ], - "time": "2017-09-11T18:02:19+00:00" + "time": "2018-02-14T18:58:54+00:00" }, { "name": "phpdocumentor/reflection-docblock", - "version": "3.3.2", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2" + "reference": "182609736818dc750d42470c0be2a5ed74bad3bd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/bf329f6c1aadea3299f08ee804682b7c45b326a2", - "reference": "bf329f6c1aadea3299f08ee804682b7c45b326a2", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/182609736818dc750d42470c0be2a5ed74bad3bd", + "reference": "182609736818dc750d42470c0be2a5ed74bad3bd", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0", - "phpdocumentor/reflection-common": "^1.0.0", - "phpdocumentor/type-resolver": "^0.4.0", - "webmozart/assert": "^1.0" + "php": ">=7.1", + "phpdocumentor/type-resolver": "^0", + "webmozart/assert": "^1" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^4.4" + "doctrine/instantiator": "^1", + "mockery/mockery": "^1" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "4.x-dev" + } + }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1124,41 +1244,39 @@ } ], "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "time": "2017-11-10T14:09:06+00:00" + "time": "2018-02-14T19:00:58+00:00" }, { "name": "phpdocumentor/type-resolver", - "version": "0.4.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7" + "reference": "69bf1b199584f2004365a150c2e6cfbe852b6d66" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/9c977708995954784726e25d0cd1dddf4e65b0f7", - "reference": "9c977708995954784726e25d0cd1dddf4e65b0f7", + "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/69bf1b199584f2004365a150c2e6cfbe852b6d66", + "reference": "69bf1b199584f2004365a150c2e6cfbe852b6d66", "shasum": "" }, "require": { - "php": "^5.5 || ^7.0", - "phpdocumentor/reflection-common": "^1.0" + "php": ">=7.1", + "phpdocumentor/reflection-common": "^2" }, "require-dev": { - "mockery/mockery": "^0.9.4", - "phpunit/phpunit": "^5.2||^4.8.24" + "mockery/mockery": "^1.0", + "phpunit/phpunit": "^6.5" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0.x-dev" + "dev-master": "0.x-dev" } }, "autoload": { "psr-4": { - "phpDocumentor\\Reflection\\": [ - "src/" - ] + "phpDocumentor\\Reflection\\": "src" } }, "notification-url": "https://packagist.org/downloads/", @@ -1171,20 +1289,20 @@ "email": "me@mikevanriel.com" } ], - "time": "2017-07-14T14:27:02+00:00" + "time": "2018-02-14T18:59:20+00:00" }, { "name": "phpspec/prophecy", - "version": "1.7.3", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf" + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", - "reference": "e4ed002c67da8eceb0eb8ddb8b3847bb53c5c2bf", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/dfd6be44111a7c41c2e884a336cc4f461b3b2401", + "reference": "dfd6be44111a7c41c2e884a336cc4f461b3b2401", "shasum": "" }, "require": { @@ -1196,7 +1314,7 @@ }, "require-dev": { "phpspec/phpspec": "^2.5|^3.2", - "phpunit/phpunit": "^4.8.35 || ^5.7" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.5" }, "type": "library", "extra": { @@ -1234,44 +1352,44 @@ "spy", "stub" ], - "time": "2017-11-24T13:59:53+00:00" + "time": "2018-02-19T10:16:54+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "4.0.8", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d" + "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/ef7b2f56815df854e66ceaee8ebe9393ae36a40d", - "reference": "ef7b2f56815df854e66ceaee8ebe9393ae36a40d", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/f8ca4b604baf23dab89d87773c28cc07405189ba", + "reference": "f8ca4b604baf23dab89d87773c28cc07405189ba", "shasum": "" }, "require": { "ext-dom": "*", "ext-xmlwriter": "*", - "php": "^5.6 || ^7.0", - "phpunit/php-file-iterator": "^1.3", - "phpunit/php-text-template": "^1.2", - "phpunit/php-token-stream": "^1.4.2 || ^2.0", - "sebastian/code-unit-reverse-lookup": "^1.0", - "sebastian/environment": "^1.3.2 || ^2.0", - "sebastian/version": "^1.0 || ^2.0" + "php": "^7.1", + "phpunit/php-file-iterator": "^1.4.2", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-token-stream": "^3.0", + "sebastian/code-unit-reverse-lookup": "^1.0.1", + "sebastian/environment": "^3.0", + "sebastian/version": "^2.0.1", + "theseer/tokenizer": "^1.1" }, "require-dev": { - "ext-xdebug": "^2.1.4", - "phpunit/phpunit": "^5.7" + "phpunit/phpunit": "^7.0" }, "suggest": { - "ext-xdebug": "^2.5.1" + "ext-xdebug": "^2.6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "6.0-dev" } }, "autoload": { @@ -1286,7 +1404,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1297,11 +1415,11 @@ "testing", "xunit" ], - "time": "2017-04-02T07:44:40+00:00" + "time": "2018-02-02T07:01:41+00:00" }, { "name": "phpunit/php-file-iterator", - "version": "1.4.5", + "version": "1.4.x-dev", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-file-iterator.git", @@ -1389,28 +1507,28 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.9", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", - "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/8b8454ea6958c3dee38453d3bd571e023108c91f", + "reference": "8b8454ea6958c3dee38453d3bd571e023108c91f", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1425,7 +1543,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1434,33 +1552,33 @@ "keywords": [ "timer" ], - "time": "2017-02-26T11:10:40+00:00" + "time": "2018-02-01T13:07:23+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.12", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16" + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/1ce90ba27c42e4e44e6d8458241466380b51fa16", - "reference": "1ce90ba27c42e4e44e6d8458241466380b51fa16", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/21ad88bbba7c3d93530d93994e0a33cd45f02ace", + "reference": "21ad88bbba7c3d93530d93994e0a33cd45f02ace", "shasum": "" }, "require": { "ext-tokenizer": "*", - "php": ">=5.3.3" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^7.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1483,20 +1601,20 @@ "keywords": [ "tokenizer" ], - "time": "2017-12-04T08:55:13+00:00" + "time": "2018-02-01T13:16:43+00:00" }, { "name": "phpunit/phpunit", - "version": "5.7.26", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd" + "reference": "d6767fef9bd6f1ae69d9e7f5128c00f5f23b3d1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd", - "reference": "7fbc25c13309de0c4c9bb48b7361f1eca34c7fbd", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d6767fef9bd6f1ae69d9e7f5128c00f5f23b3d1c", + "reference": "d6767fef9bd6f1ae69d9e7f5128c00f5f23b3d1c", "shasum": "" }, "require": { @@ -1505,33 +1623,31 @@ "ext-libxml": "*", "ext-mbstring": "*", "ext-xml": "*", - "myclabs/deep-copy": "~1.3", - "php": "^5.6 || ^7.0", - "phpspec/prophecy": "^1.6.2", - "phpunit/php-code-coverage": "^4.0.4", - "phpunit/php-file-iterator": "~1.4", - "phpunit/php-text-template": "~1.2", - "phpunit/php-timer": "^1.0.6", - "phpunit/phpunit-mock-objects": "^3.2", - "sebastian/comparator": "^1.2.4", - "sebastian/diff": "^1.4.3", - "sebastian/environment": "^1.3.4 || ^2.0", - "sebastian/exporter": "~2.0", - "sebastian/global-state": "^1.1", - "sebastian/object-enumerator": "~2.0", - "sebastian/resource-operations": "~1.0", - "sebastian/version": "~1.0.3|~2.0", - "symfony/yaml": "~2.1|~3.0|~4.0" - }, - "conflict": { - "phpdocumentor/reflection-docblock": "3.0.2" + "myclabs/deep-copy": "^1.6.1", + "phar-io/manifest": "^1.0.1", + "phar-io/version": "^1.0", + "php": "^7.1", + "phpspec/prophecy": "^1.7", + "phpunit/php-code-coverage": "^6.0", + "phpunit/php-file-iterator": "^1.4.3", + "phpunit/php-text-template": "^1.2.1", + "phpunit/php-timer": "^2.0", + "phpunit/phpunit-mock-objects": "^6.1", + "sebastian/comparator": "^2.1", + "sebastian/diff": "^3.0", + "sebastian/environment": "^3.1", + "sebastian/exporter": "^3.1", + "sebastian/global-state": "^2.0", + "sebastian/object-enumerator": "^3.0.3", + "sebastian/resource-operations": "^1.0", + "sebastian/version": "^2.0.1" }, "require-dev": { "ext-pdo": "*" }, "suggest": { "ext-xdebug": "*", - "phpunit/php-invoker": "~1.1" + "phpunit/php-invoker": "^2.0" }, "bin": [ "phpunit" @@ -1539,7 +1655,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "5.7.x-dev" + "dev-master": "7.1-dev" } }, "autoload": { @@ -1565,33 +1681,30 @@ "testing", "xunit" ], - "time": "2017-12-17T06:14:38+00:00" + "time": "2018-02-21T14:21:08+00:00" }, { "name": "phpunit/phpunit-mock-objects", - "version": "3.4.4", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118" + "reference": "f18297be46ffe21e82b2b1801fa437e8809ab8c9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/a23b761686d50a560cc56233b9ecf49597cc9118", - "reference": "a23b761686d50a560cc56233b9ecf49597cc9118", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/f18297be46ffe21e82b2b1801fa437e8809ab8c9", + "reference": "f18297be46ffe21e82b2b1801fa437e8809ab8c9", "shasum": "" }, "require": { - "doctrine/instantiator": "^1.0.2", - "php": "^5.6 || ^7.0", - "phpunit/php-text-template": "^1.2", - "sebastian/exporter": "^1.2 || ^2.0" - }, - "conflict": { - "phpunit/phpunit": "<5.4.0" + "doctrine/instantiator": "^1.0.5", + "php": "^7.1", + "phpunit/php-text-template": "^1.2.1", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "^5.4" + "phpunit/phpunit": "^7.0" }, "suggest": { "ext-soap": "*" @@ -1599,7 +1712,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.2.x-dev" + "dev-master": "6.1-dev" } }, "autoload": { @@ -1614,7 +1727,7 @@ "authors": [ { "name": "Sebastian Bergmann", - "email": "sb@sebastian-bergmann.de", + "email": "sebastian@phpunit.de", "role": "lead" } ], @@ -1624,20 +1737,20 @@ "mock", "xunit" ], - "time": "2017-06-30T09:13:00+00:00" + "time": "2018-02-21T12:41:00+00:00" }, { "name": "sebastian/code-unit-reverse-lookup", - "version": "1.0.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/code-unit-reverse-lookup.git", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18" + "reference": "3488be0a7b346cd6e5361510ed07e88f9bea2e88" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", - "reference": "4419fcdb5eabb9caa61a27c7a1db532a6b55dd18", + "url": "https://api.github.com/repos/sebastianbergmann/code-unit-reverse-lookup/zipball/3488be0a7b346cd6e5361510ed07e88f9bea2e88", + "reference": "3488be0a7b346cd6e5361510ed07e88f9bea2e88", "shasum": "" }, "require": { @@ -1669,34 +1782,34 @@ ], "description": "Looks up which function or method a line of code belongs to", "homepage": "https://github.com/sebastianbergmann/code-unit-reverse-lookup/", - "time": "2017-03-04T06:30:41+00:00" + "time": "2017-03-04T10:23:55+00:00" }, { "name": "sebastian/comparator", - "version": "1.2.4", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", - "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/34369daee48eafb2651bea869b4b15d75ccc35f9", + "reference": "34369daee48eafb2651bea869b4b15d75ccc35f9", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/diff": "~1.2", - "sebastian/exporter": "~1.2 || ~2.0" + "php": "^7.0", + "sebastian/diff": "^2.0 || ^3.0", + "sebastian/exporter": "^3.1" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.2.x-dev" + "dev-master": "2.1.x-dev" } }, "autoload": { @@ -1727,38 +1840,39 @@ } ], "description": "Provides the functionality to compare PHP values for equality", - "homepage": "http://www.github.com/sebastianbergmann/comparator", + "homepage": "https://github.com/sebastianbergmann/comparator", "keywords": [ "comparator", "compare", "equality" ], - "time": "2017-01-29T09:50:25+00:00" + "time": "2018-02-01T13:46:46+00:00" }, { "name": "sebastian/diff", - "version": "1.4.3", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" + "reference": "ebf0c4e8996ad83136861660593aa6b3b1bb24cf" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", - "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/ebf0c4e8996ad83136861660593aa6b3b1bb24cf", + "reference": "ebf0c4e8996ad83136861660593aa6b3b1bb24cf", "shasum": "" }, "require": { - "php": "^5.3.3 || ^7.0" + "php": "^7.1" }, "require-dev": { - "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" + "phpunit/phpunit": "^7.0", + "symfony/process": "^2 || ^3.3 || ^4" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "1.4-dev" + "dev-master": "3.0-dev" } }, "autoload": { @@ -1783,34 +1897,37 @@ "description": "Diff implementation", "homepage": "https://github.com/sebastianbergmann/diff", "keywords": [ - "diff" + "diff", + "udiff", + "unidiff", + "unified diff" ], - "time": "2017-05-22T07:24:03+00:00" + "time": "2018-02-02T07:14:03+00:00" }, { "name": "sebastian/environment", - "version": "2.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/environment.git", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac" + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/5795ffe5dc5b02460c3e34222fee8cbe245d8fac", - "reference": "5795ffe5dc5b02460c3e34222fee8cbe245d8fac", + "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/cd0871b3975fb7fc44d11314fd1ee20925fce4f5", + "reference": "cd0871b3975fb7fc44d11314fd1ee20925fce4f5", "shasum": "" }, "require": { - "php": "^5.6 || ^7.0" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "^5.0" + "phpunit/phpunit": "^6.1" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1835,34 +1952,34 @@ "environment", "hhvm" ], - "time": "2016-11-26T07:53:53+00:00" + "time": "2017-07-01T08:51:00+00:00" }, { "name": "sebastian/exporter", - "version": "2.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/exporter.git", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4" + "reference": "573f8b71a29cc8afa5f8285d1aee4b4d52717637" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", - "reference": "ce474bdd1a34744d7ac5d6aad3a46d48d9bac4c4", + "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/573f8b71a29cc8afa5f8285d1aee4b4d52717637", + "reference": "573f8b71a29cc8afa5f8285d1aee4b4d52717637", "shasum": "" }, "require": { - "php": ">=5.3.3", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/recursion-context": "^3.0" }, "require-dev": { "ext-mbstring": "*", - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.1.x-dev" } }, "autoload": { @@ -1902,27 +2019,27 @@ "export", "exporter" ], - "time": "2016-11-19T08:54:04+00:00" + "time": "2017-11-16T09:48:09+00:00" }, { "name": "sebastian/global-state", - "version": "1.1.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/global-state.git", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4" + "reference": "a27e666314b2df0ab686c2abdee43ffbda48ac10" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4", - "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4", + "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/a27e666314b2df0ab686c2abdee43ffbda48ac10", + "reference": "a27e666314b2df0ab686c2abdee43ffbda48ac10", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.2" + "phpunit/phpunit": "^6.0" }, "suggest": { "ext-uopz": "*" @@ -1930,7 +2047,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.0-dev" + "dev-master": "2.0-dev" } }, "autoload": { @@ -1953,33 +2070,34 @@ "keywords": [ "global state" ], - "time": "2015-10-12T03:26:01+00:00" + "time": "2017-11-16T09:49:42+00:00" }, { "name": "sebastian/object-enumerator", - "version": "2.0.1", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/object-enumerator.git", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7" + "reference": "a496797f3bd6821bfe2acb594e0901dfb00572dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/1311872ac850040a79c3c058bea3e22d0f09cbb7", - "reference": "1311872ac850040a79c3c058bea3e22d0f09cbb7", + "url": "https://api.github.com/repos/sebastianbergmann/object-enumerator/zipball/a496797f3bd6821bfe2acb594e0901dfb00572dd", + "reference": "a496797f3bd6821bfe2acb594e0901dfb00572dd", "shasum": "" }, "require": { - "php": ">=5.6", - "sebastian/recursion-context": "~2.0" + "php": "^7.0", + "sebastian/object-reflector": "^1.1.1", + "sebastian/recursion-context": "^3.0" }, "require-dev": { - "phpunit/phpunit": "~5" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -1999,32 +2117,77 @@ ], "description": "Traverses array structures and object graphs to enumerate all referenced objects", "homepage": "https://github.com/sebastianbergmann/object-enumerator/", - "time": "2017-02-18T15:18:39+00:00" + "time": "2017-11-16T09:50:04+00:00" + }, + { + "name": "sebastian/object-reflector", + "version": "dev-master", + "source": { + "type": "git", + "url": "https://github.com/sebastianbergmann/object-reflector.git", + "reference": "ff755086ff55902772e3fae5dd5f29bcbae68285" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/sebastianbergmann/object-reflector/zipball/ff755086ff55902772e3fae5dd5f29bcbae68285", + "reference": "ff755086ff55902772e3fae5dd5f29bcbae68285", + "shasum": "" + }, + "require": { + "php": "^7.0" + }, + "require-dev": { + "phpunit/phpunit": "^6.0" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.1-dev" + } + }, + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Sebastian Bergmann", + "email": "sebastian@phpunit.de" + } + ], + "description": "Allows reflection of object attributes, including inherited and non-public ones", + "homepage": "https://github.com/sebastianbergmann/object-reflector/", + "time": "2018-01-07T16:00:13+00:00" }, { "name": "sebastian/recursion-context", - "version": "2.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a" + "reference": "0f7f5eb7697036c570aff6812a8efe60c417725e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/2c3ba150cbec723aa057506e73a8d33bdb286c9a", - "reference": "2c3ba150cbec723aa057506e73a8d33bdb286c9a", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/0f7f5eb7697036c570aff6812a8efe60c417725e", + "reference": "0f7f5eb7697036c570aff6812a8efe60c417725e", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.4" + "phpunit/phpunit": "^6.0" }, "type": "library", "extra": { "branch-alias": { - "dev-master": "2.0.x-dev" + "dev-master": "3.0.x-dev" } }, "autoload": { @@ -2052,20 +2215,20 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2016-11-19T07:33:16+00:00" + "time": "2017-11-16T10:04:08+00:00" }, { "name": "sebastian/resource-operations", - "version": "1.0.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/resource-operations.git", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52" + "reference": "fadc83f7c41fb2924e542635fea47ae546816ece" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", - "reference": "ce990bb21759f94aeafd30209e8cfcdfa8bc3f52", + "url": "https://api.github.com/repos/sebastianbergmann/resource-operations/zipball/fadc83f7c41fb2924e542635fea47ae546816ece", + "reference": "fadc83f7c41fb2924e542635fea47ae546816ece", "shasum": "" }, "require": { @@ -2094,7 +2257,7 @@ ], "description": "Provides a list of PHP built-in functions that operate on resources", "homepage": "https://www.github.com/sebastianbergmann/resource-operations", - "time": "2015-07-28T20:34:47+00:00" + "time": "2016-10-03T07:43:09+00:00" }, { "name": "sebastian/version", @@ -2139,18 +2302,58 @@ "homepage": "https://github.com/sebastianbergmann/version", "time": "2016-10-03T07:35:21+00:00" }, + { + "name": "theseer/tokenizer", + "version": "1.1.0", + "source": { + "type": "git", + "url": "https://github.com/theseer/tokenizer.git", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/theseer/tokenizer/zipball/cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "reference": "cb2f008f3f05af2893a87208fe6a6c4985483f8b", + "shasum": "" + }, + "require": { + "ext-dom": "*", + "ext-tokenizer": "*", + "ext-xmlwriter": "*", + "php": "^7.0" + }, + "type": "library", + "autoload": { + "classmap": [ + "src/" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "BSD-3-Clause" + ], + "authors": [ + { + "name": "Arne Blankerts", + "email": "arne@blankerts.de", + "role": "Developer" + } + ], + "description": "A small library for converting tokenized PHP source code into XML and potentially other formats", + "time": "2017-04-07T12:08:54+00:00" + }, { "name": "webmozart/assert", - "version": "1.2.0", + "version": "dev-master", "source": { "type": "git", "url": "https://github.com/webmozart/assert.git", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f" + "reference": "0df1908962e7a3071564e857d86874dad1ef204a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/webmozart/assert/zipball/2db61e59ff05fe5126d152bd0655c9ea113e550f", - "reference": "2db61e59ff05fe5126d152bd0655c9ea113e550f", + "url": "https://api.github.com/repos/webmozart/assert/zipball/0df1908962e7a3071564e857d86874dad1ef204a", + "reference": "0df1908962e7a3071564e857d86874dad1ef204a", "shasum": "" }, "require": { @@ -2187,16 +2390,16 @@ "check", "validate" ], - "time": "2016-11-23T20:04:58+00:00" + "time": "2018-01-29T19:49:41+00:00" } ], "aliases": [], - "minimum-stability": "stable", + "minimum-stability": "dev", "stability-flags": [], "prefer-stable": false, "prefer-lowest": false, "platform": { - "php": ">=5.6.0" + "php": ">=7.0.0" }, "platform-dev": [] } diff --git a/phpunit.xml b/phpunit.xml index 4b8fe2a..a867465 100644 --- a/phpunit.xml +++ b/phpunit.xml @@ -10,10 +10,10 @@ stopOnFailure="false"> - ./tests/Feature + ./tests/Feature - ./tests/Unit + ./tests/Unit diff --git a/src/Entities/CachedFile.php b/src/Entities/CachedFile.php index 3baacba..5716436 100644 --- a/src/Entities/CachedFile.php +++ b/src/Entities/CachedFile.php @@ -5,14 +5,14 @@ class CachedFile { /** - * File unique identifier. + * ProjectFile unique identifier. * * @var string */ private $uid; /** - * File invalidation hash. + * ProjectFile invalidation hash. * * @var string */ @@ -31,11 +31,12 @@ class CachedFile /** * CachedFile constructor. * - * @param File $file + * @param ProjectFile $file * @param array $layouts * @param string $sourceDirectory + * @throws \Exception */ - public function __construct(File $file, array $layouts = [], $sourceDirectory = '') + public function __construct(ProjectFile $file, array $layouts = [], $sourceDirectory = '') { $this->layouts = $layouts; $this->sourceDirectory = $sourceDirectory; @@ -46,11 +47,11 @@ public function __construct(File $file, array $layouts = [], $sourceDirectory = /** * Check to see if the current cache entry is still valid. * - * @param File $file + * @param ProjectFile $file * @return bool * @throws \Exception */ - public function check(File $file) + public function check(ProjectFile $file) { if ($file->getUid() !== $this->uid) { throw new \Exception('This CachedFile is not for uid ['.$file->getUid().']'); @@ -60,12 +61,13 @@ public function check(File $file) } /** - * Calculates the invalidation hash for the given File. + * Calculates the invalidation hash for the given ProjectFile. * - * @param File $file + * @param ProjectFile $file * @return string + * @throws \Exception */ - private function hashFile(File $file) + private function hashFile(ProjectFile $file) { $arr = []; @@ -80,7 +82,7 @@ private function hashFile(File $file) } } - array_push($arr, $file->getLastModified()); + array_push($arr, $file->getMTime()); return sha1(implode('.', $arr)); } diff --git a/src/Entities/ContentType.php b/src/Entities/ContentType.php index aa0e318..d284e26 100644 --- a/src/Entities/ContentType.php +++ b/src/Entities/ContentType.php @@ -53,7 +53,7 @@ class ContentType private $taxonomies = []; /** - * Collection of Entities\File that this ContentType has collected. + * Collection of Entities\ProjectFile that this ContentType has collected. * * @var FlatCollection */ @@ -78,7 +78,7 @@ public function __construct($name, array $settings) $this->name = $name; $this->path = (isset($settings['path']) ? $settings['path'] : ('_'.$this->name)); - $this->template = (isset($settings['template']) ? $settings['template'] : $this->name); + $this->template = (isset($settings['template']) ? $settings['template'] : '_templates'.DIRECTORY_SEPARATOR.$this->name); $this->permalink = (isset($settings['permalink']) ? $settings['permalink'] : ($this->name.'/{slug}.{ext}')); $this->enabled = (isset($settings['enabled']) ? boolval($settings['enabled']) : false); @@ -112,9 +112,15 @@ public function isEnabled() return boolval($this->enabled); } - public function addFile(File $file) + /** + * Add a ProjectFile to the ContentType. + * + * @param ProjectFile $file + * @throws \Exception + */ + public function addFile(ProjectFile $file) { - $file->setData(['contentType' => $this->name]); + $file->setData('contentType', $this->name); $this->itemsOrderCache = null; $this->items->set($file->getUid(), $file->getData('date')->getTimestamp()); @@ -124,12 +130,18 @@ public function addFile(File $file) $taxonomy->addFile($file, $classification); } } else { - $file->setData([$taxonomy->getName() => []]); + $file->setData($taxonomy->getName(), []); } } } - public function hasFile(File $file) + /** + * Check if this ContentType contains ProjectFile. + * + * @param ProjectFile $file + * @return bool + */ + public function hasFile(ProjectFile $file) { return $this->items->has($file->getUid()); } @@ -165,7 +177,7 @@ public function getPermalink() * * @param string $order * - * @return array + * @return ProjectFile[] */ public function getFileList($order = 'desc') { @@ -194,6 +206,7 @@ public function getFileList($order = 'desc') * Mutate project files that are contained within this ContentType. * * @param Project $project + * @throws \Exception */ public function mutateProjectFiles(Project $project) { @@ -201,30 +214,29 @@ public function mutateProjectFiles(Project $project) $contentRenderers = $project->get('content_renderers'); foreach (array_keys($this->getFileList()) as $fileKey) { - /** @var File $file */ + /** @var ProjectFile $file */ if (! $file = $project->get('files.'.$fileKey)) { continue; } - $file->setData(['content_type' => $this->name]); + $file->setData('content_type', $this->name); if ($this->permalink !== '*') { - $file->setPermalink(new Permalink($this->permalink)); + $file->setData('permalink', $this->permalink); } // If we are not a default Content Type $templatePath = $project->sourceDirectory.DIRECTORY_SEPARATOR.'_views'.DIRECTORY_SEPARATOR.$this->template.'.phtml'; if ($this->template !== 'default' && file_exists($templatePath)) { - $fileRenderer = $contentRenderers->get($file->getExt()); - $file->setData(['content' => $fileRenderer->render($file)]); - $file->setFileInfo(new SplFileInfo($templatePath, '_views', '_views'.DIRECTORY_SEPARATOR.$this->template.'.phtml')); - + $fileRenderer = $contentRenderers->get($file->getExtension()); + $file->setData('content', $fileRenderer->render($file)); + $file = new ProjectFile(new SplFileInfo($templatePath, '_views', '_views'.DIRECTORY_SEPARATOR.$this->template.'.phtml'), $file->getData(), false); if ($fileRenderer->supportsFrontMatter()) { $frontMatter = new FrontMatter($file->getFileContent()); $file->setData(array_merge_recursive($file->getData(), $frontMatter->getData())); - $file->setContent($frontMatter->getContent()); + $file->loadContent($frontMatter->getContent()); } else { - $file->setContent($file->getFileContent()); + $file->loadContent($file->getFileContent()); } if ($file->hasData('generator')) { diff --git a/src/Entities/Filesystem/FileAction.php b/src/Entities/Filesystem/FileAction.php index 2774b76..db19070 100644 --- a/src/Entities/Filesystem/FileAction.php +++ b/src/Entities/Filesystem/FileAction.php @@ -2,14 +2,14 @@ namespace Tapestry\Entities\Filesystem; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Console\Output\OutputInterface; abstract class FileAction implements FilesystemInterface { /** - * @var File + * @var ProjectFile */ protected $file; @@ -21,19 +21,19 @@ abstract class FileAction implements FilesystemInterface /** * FilesystemInterface constructor. * - * @param File $file + * @param ProjectFile $file * @param string $destinationPath */ - public function __construct(File $file, $destinationPath) + public function __construct(ProjectFile $file, $destinationPath) { $this->file = $file; $this->destinationPath = $destinationPath; } /** - * @return File + * @return ProjectFile */ - public function getFile() + public function getFile() : ProjectFile { return $this->file; } diff --git a/src/Entities/Filesystem/FileWriter.php b/src/Entities/Filesystem/FileWriter.php index 3ec4dc8..fa31315 100644 --- a/src/Entities/Filesystem/FileWriter.php +++ b/src/Entities/Filesystem/FileWriter.php @@ -8,10 +8,11 @@ class FileWriter extends FileAction implements FilesystemInterface { /** - * @param Filesystem $filesystem + * @param Filesystem $filesystem * @param OutputInterface $output * * @return void + * @throws \Exception */ public function __invoke(Filesystem $filesystem, OutputInterface $output) { diff --git a/src/Entities/Filesystem/FilesystemInterface.php b/src/Entities/Filesystem/FilesystemInterface.php index f037fb9..db7604b 100644 --- a/src/Entities/Filesystem/FilesystemInterface.php +++ b/src/Entities/Filesystem/FilesystemInterface.php @@ -2,7 +2,7 @@ namespace Tapestry\Entities\Filesystem; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Console\Output\OutputInterface; @@ -11,13 +11,13 @@ interface FilesystemInterface /** * FilesystemInterface constructor. * - * @param File $file + * @param ProjectFile $file * @param string $destinationPath */ - public function __construct(File $file, $destinationPath); + public function __construct(ProjectFile $file, $destinationPath); /** - * @return File + * @return ProjectFile */ public function getFile(); diff --git a/src/Entities/Generators/FileGenerator.php b/src/Entities/Generators/FileGenerator.php index f8de52c..82c99e7 100644 --- a/src/Entities/Generators/FileGenerator.php +++ b/src/Entities/Generators/FileGenerator.php @@ -2,29 +2,29 @@ namespace Tapestry\Entities\Generators; -use Tapestry\Entities\File; use Tapestry\Entities\Project; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\ProjectFileInterface; use Tapestry\Entities\ProjectFileGeneratorInterface; class FileGenerator implements ProjectFileInterface, ProjectFileGeneratorInterface { /** - * @var File + * @var ProjectFile */ protected $file; /** - * @var array|File[] + * @var array|ProjectFile[] */ private $generatedFiles = []; /** * FileGenerator constructor. * - * @param File $file + * @param ProjectFile $file */ - public function __construct(File $file) + public function __construct(ProjectFile $file) { $this->file = $file; } @@ -37,8 +37,8 @@ public function __construct(File $file) public function generate(Project $project) { if ($generators = $this->file->getData('generator')) { - // Kick off the generation with the first generator. Because File generators can either mutate the current File - // or generate an array of File's we then continue the generation with a while loop until all generators have been + // Kick off the generation with the first generator. Because ProjectFile generators can either mutate the current ProjectFile + // or generate an array of ProjectFile's we then continue the generation with a while loop until all generators have been // run resulting in a flat array. $first = reset($generators); $this->mergeGenerated($project->getContentGenerator($first, $this->file)->generate($project)); @@ -71,7 +71,7 @@ public function __call($name, $arguments) * * @return bool */ - private function canGenerate() + private function canGenerate() : bool { foreach ($this->generatedFiles as $file) { if ($uses = $file->getData('generator')) { @@ -87,7 +87,8 @@ private function canGenerate() /** * Merge the generated files into our local generatedFiles list. * - * @param File|File[] $generated + * @param ProjectFile|ProjectFile[] $generated + * @return void */ private function mergeGenerated($generated) { diff --git a/src/Entities/Generators/PaginationGenerator.php b/src/Entities/Generators/PaginationGenerator.php index 9256044..12ca983 100644 --- a/src/Entities/Generators/PaginationGenerator.php +++ b/src/Entities/Generators/PaginationGenerator.php @@ -2,10 +2,10 @@ namespace Tapestry\Entities\Generators; -use Tapestry\Entities\File; use Tapestry\Entities\Project; use Tapestry\Entities\Permalink; use Tapestry\Entities\Pagination; +use Tapestry\Entities\ProjectFile; class PaginationGenerator extends FileGenerator { @@ -13,6 +13,7 @@ class PaginationGenerator extends FileGenerator * @param Project $project * * @return \Tapestry\Entities\ProjectFileInterface|\Tapestry\Entities\ProjectFileInterface[] + * @throws \Exception */ public function generate(Project $project) { @@ -67,13 +68,11 @@ public function generate(Project $project) foreach (array_chunk($paginationItems, $configuration['perPage'], true) as $pageItems) { $pageFile = clone $newFile; $currentPage++; - $pageFile->setData(['pagination' => new Pagination($project, $pageItems, $totalPages, ($currentPage))]); + $pageFile->setData('pagination', new Pagination($project, $pageItems, $totalPages, ($currentPage))); if ($currentPage > 1) { $pageFile->setUid($pageFile->getUid().'_page_'.$currentPage); - - $permalink = $pageFile->getPermalink(); - $template = $permalink->getTemplate(); + $template = $pageFile->getData('permalink', ''); if (strpos($template, '.')) { $parts = explode('.', $template); @@ -95,7 +94,7 @@ public function generate(Project $project) $template = implode('/', $parts); } - $pageFile->setPermalink(new Permalink($template)); + $pageFile->setData('permalink', $template); } array_push($generatedFiles, $pageFile); @@ -106,13 +105,13 @@ public function generate(Project $project) if ($totalGenerated > 1) { /** * @var int - * @var File $generatedFile + * @var ProjectFile $generatedFile */ foreach ($generatedFiles as $key => &$generatedFile) { /* * @var Pagination - * @var null|File $previous - * @var null|File $next + * @var null|ProjectFile $previous + * @var null|ProjectFile $next */ $pagination = $generatedFile->getData('pagination'); diff --git a/src/Entities/Generators/TaxonomyArchiveGenerator.php b/src/Entities/Generators/TaxonomyArchiveGenerator.php index b816b1b..553b5c5 100644 --- a/src/Entities/Generators/TaxonomyArchiveGenerator.php +++ b/src/Entities/Generators/TaxonomyArchiveGenerator.php @@ -13,7 +13,8 @@ class TaxonomyArchiveGenerator extends FileGenerator implements ProjectFileGener * Taxonomy name with the Files passed to them. * * @param Project $project - * @return array|\Tapestry\Entities\File + * @return array|\Tapestry\Entities\ProjectFile + * @throws \Exception */ public function generate(Project $project) { diff --git a/src/Entities/Pagination.php b/src/Entities/Pagination.php index 607b401..aaacc8c 100644 --- a/src/Entities/Pagination.php +++ b/src/Entities/Pagination.php @@ -77,7 +77,7 @@ public function getItems() } array_walk_recursive($this->items, function (&$file, $fileKey) { - /** @var File $compiledFile */ + /** @var ProjectFile $compiledFile */ if (! $compiledFile = $this->project->get('compiled.'.$fileKey)) { $file = null; } else { @@ -139,7 +139,7 @@ public function isLast() } /** - * @param array|File[] $pages + * @param array|ProjectFile[] $pages */ public function setPages(array $pages = []) { diff --git a/src/Entities/Permalink.php b/src/Entities/Permalink.php index 04fe85f..cfda91d 100644 --- a/src/Entities/Permalink.php +++ b/src/Entities/Permalink.php @@ -40,18 +40,19 @@ public function getTemplate() /** * Returns a compiled permalink path in string form. * - * @param File $file + * @param ProjectFile $file * @param bool $pretty * * @return mixed|string + * @throws \Exception */ - public function getCompiled(File $file, $pretty = true) + public function getCompiled(ProjectFile $file, bool $pretty = true) { $output = $this->template; - $output = str_replace('{ext}', $file->getExt(), $output); - $output = str_replace('{filename}', $this->sluggify($file->getFilename()), $output); + $output = str_replace('{ext}', $file->getExtension(), $output); + $output = str_replace('{filename}', $this->sluggify($file->getBasename('.'.$file->getExtension(false))), $output); - $filePath = str_replace('\\', '/', $file->getPath()); + $filePath = str_replace('\\', '/', $file->getRelativePath()); if (substr($filePath, 0, 1) === '/') { $filePath = substr($filePath, 1); } diff --git a/src/Entities/Project.php b/src/Entities/Project.php index 22c52bd..63fd418 100644 --- a/src/Entities/Project.php +++ b/src/Entities/Project.php @@ -51,7 +51,7 @@ public function __construct($cwd, $dist, $environment) } /** - * @param ProjectFileInterface|File|FileGenerator $file + * @param ProjectFileInterface|ProjectFile|FileGenerator $file */ public function addFile(ProjectFileInterface $file) { @@ -61,7 +61,7 @@ public function addFile(ProjectFileInterface $file) /** * @param string $key * - * @return ProjectFileInterface|File|FileGenerator + * @return ProjectFileInterface|ProjectFile|FileGenerator */ public function getFile($key) { @@ -69,7 +69,7 @@ public function getFile($key) } /** - * @param ProjectFileInterface|File|FileGenerator $file + * @param ProjectFileInterface|ProjectFile|FileGenerator $file */ public function removeFile(ProjectFileInterface $file) { @@ -77,8 +77,8 @@ public function removeFile(ProjectFileInterface $file) } /** - * @param ProjectFileInterface|File|FileGenerator $oldFile - * @param ProjectFileInterface|File|FileGenerator $newFile + * @param ProjectFileInterface|ProjectFile|FileGenerator $oldFile + * @param ProjectFileInterface|ProjectFile|FileGenerator $newFile */ public function replaceFile(ProjectFileInterface $oldFile, ProjectFileInterface $newFile) { @@ -88,11 +88,11 @@ public function replaceFile(ProjectFileInterface $oldFile, ProjectFileInterface /** * @param string $name - * @param File $file + * @param ProjectFile $file * * @return ProjectFileGeneratorInterface */ - public function getContentGenerator($name, File $file) + public function getContentGenerator($name, ProjectFile $file) { return $this->get('content_generators')->get($name, $file); } diff --git a/src/Entities/ProjectFile.php b/src/Entities/ProjectFile.php new file mode 100644 index 0000000..ac5dfd6 --- /dev/null +++ b/src/Entities/ProjectFile.php @@ -0,0 +1,456 @@ +getPathname(), $file->getRelativePath(), $file->getRelativePathname()); + if ($autoBoot === true) { + $this->boot($data); + } + } + + /** + * Boot the file. + * + * @param array $data + * @throws \Exception + * + * @return void + */ + public function boot(array $data = []) + { + $this->meta = []; + $this->permalink = new Permalink(); + + $defaultData = array_merge([ + 'date' => DateTime::createFromFormat('U', $this->getMTime()), + 'pretty_permalink' => true, + ], $data); + + preg_match('/^(\d{4}-\d{2}-\d{2})-(.*)/', $this->getBasename('.'.$this->getExtension()), + $matches); + if (count($matches) === 3) { + $defaultData['date'] = new DateTime($matches[1]); + $defaultData['draft'] = false; + $defaultData['slug'] = $matches[2]; + $defaultData['title'] = ucfirst(str_replace('-', ' ', $defaultData['slug'])); + } + + $this->setDataFromArray($defaultData); + + $this->setUid((! empty($this->getRelativePathname())) ? $this->getRelativePathname() : $this->getPathname()); + } + + /** + * Get this files uid. + * + * @return string + */ + public function getUid() + { + return $this->meta['uid']; + } + + /** + * Set this files uid. + * + * @param string$uid + * + * @return void + */ + public function setUid($uid) + { + $uid = str_replace('.', '_', $uid); + $uid = str_replace(['/', '\\'], '_', $uid); + $this->meta['uid'] = $uid; + } + + /** + * Set this files data (via frontmatter or other source). + * + * @param array|string $key + * @param null|mixed $value + * @throws \Exception + * + * @return void + */ + public function setData($key, $value = null) + { + if (is_array($key) && is_null($value)) { + $this->setDataFromArray($key); + + return; + } + + if ($key === 'date' && ! $value instanceof DateTime) { + $date = new DateTime(); + if (! $unix = strtotime($value)) { + if (! $unix = strtotime('@'.$value)) { + throw new \Exception('The date ['.$value.'] is in a format not supported by Tapestry.'); + } + } + $value = $date->createFromFormat('U', $unix); + } + + if ($key === 'permalink') { + $this->permalink->setTemplate($value); + } + + $this->meta[$key] = $value; + } + + /** + * Set this files data from array source. + * + * @param array $data + * @throws \Exception + * + * @return void + */ + public function setDataFromArray(array $data) + { + foreach ($data as $key => $value) { + $this->setData($key, $value); + } + } + + /** + * Return this files data (set via frontmatter if any is found). + * + * @param null $key + * @param null $default + * + * @return array|mixed|null + */ + public function getData($key = null, $default = null) + { + if (is_null($key)) { + return $this->meta; + } + if (! $this->hasData($key)) { + return $default; + } + + return $this->meta[$key]; + } + + /** + * Return true if this file has data set for $key. + * + * @param $key + * + * @return bool + */ + public function hasData($key) + { + return isset($this->meta[$key]); + } + + /** + * Get the content of the file that this object relates to. + * + * @throws \Exception + * + * @return string + */ + public function getFileContent() + { + $content = file_get_contents($this->getPathname()); + if ($content !== false) { + return $content; + } + + throw new \Exception('Unable to read file ['.$this->getPathname().']'); + } + + /** + * Set the files content, this should be excluding any frontmatter. + * + * @param $content + */ + public function loadContent($content) + { + $this->content = $content; + } + + /** + * Returns the file content, this will be excluding any frontmatter. + * + * @throws \Exception + * + * @return string + */ + public function getContent() + { + if (! $this->isLoaded()) { + throw new \Exception('The file ['.$this->getRelativePathname().'] has not been loaded.'); + } + + return $this->content; + } + + /** + * Pretty Permalinks are disabled on all files that have their + * permalink structure configured via front matter. + * + * @return mixed|string + * @throws \Exception + */ + public function getCompiledPermalink() + { + $pretty = $this->getData('pretty_permalink', true); + if ($this->hasData('permalink')) { + $pretty = false; + } + + return $this->permalink->getCompiled($this, $pretty); + } + + /** + * @param string $key + * @param $value + */ + public function setOverloaded(string $key, $value) + { + $this->overloaded[$key] = $value; + } + + /** + * Allows the overloading of the SplFileInfo filename property. + * + * @param bool $overload + * @return mixed|string + */ + public function getFilename(bool $overload = true) + { + if ($overload === true && isset($this->overloaded['filename'])) { + return $this->overloaded['filename']; + } + + return parent::getFilename(); + } + + /** + * Allows the overloading of the SplFileInfo extension property. + * + * @param bool $overload + * @return mixed|string + */ + public function getExtension(bool $overload = true) + { + if ($overload === true && isset($this->overloaded['ext'])) { + return $this->overloaded['ext']; + } + + return parent::getExtension(); + } + + /** + * A file can be considered loaded once its content property has been set, that way you know any frontmatter has + * also been injected into the File objects data property. + * + * @return bool + */ + public function isLoaded() + { + return $this->content !== false; + } + + /** + * Set by the Compile class when it passes this File through a Renderer. + * + * @param $value + */ + public function setRendered(bool $value = true) + { + $this->rendered = $value; + } + + /** + * Has this File been passed through a Renderer? + * + * @return bool + */ + public function isRendered() + { + return $this->rendered; + } + + /** + * @return bool + */ + public function isToCopy() : bool + { + return $this->copy; + } + + /** + * @param bool $copy + * + * @return void + */ + public function setToCopy(bool $copy) + { + $this->copy = $copy; + } + + /** + * @return bool + */ + public function isBlocked() : bool + { + return $this->blocked; + } + + /** + * @param bool $blocked + */ + public function setBlocked(bool $blocked = true) + { + $this->blocked = $blocked; + } + + /** + * @return bool + */ + public function isIgnored(): bool + { + return $this->ignored; + } + + /** + * @param bool $ignored + */ + public function setIgnored(bool $ignored = true) + { + $this->ignored = $ignored; + } + + ///////////////////////////////////////////// + // Deprecated Methods + ///////////////////////////////////////////// + + /** + * @deprecated + * @throws \Exception + */ + public function setFilename() + { + throw new \Exception('Deprecated Function [setFilename] used.'); + } + + /** + * @deprecated + * @throws \Exception + */ + public function getExt() + { + throw new \Exception('Deprecated Function [getExt] used.'); + } + + /** + * @deprecated + * @throws \Exception + */ + public function setExt() + { + throw new \Exception('Deprecated Function [setExt] used.'); + } + + /** + * @deprecated + * @throws \Exception + */ + public function getLastModified() + { + throw new \Exception('Deprecated Function [getLastModified] used.'); + } + + /** + * @deprecated + * @throws \Exception + */ + public function setLastModified() + { + throw new \Exception('Deprecated Function [setLastModified] used.'); + } +} diff --git a/src/Entities/ProjectFileInterface.php b/src/Entities/ProjectFileInterface.php index 2005d07..6904967 100644 --- a/src/Entities/ProjectFileInterface.php +++ b/src/Entities/ProjectFileInterface.php @@ -2,6 +2,12 @@ namespace Tapestry\Entities; +/** + * Interface ProjectFileInterface. + * + * This Interface exists to allow the FileGenerator class to wrap a ProjectFile and pass + * method calls via the magic __call method. + */ interface ProjectFileInterface { } diff --git a/src/Entities/Renderers/DefaultRenderer.php b/src/Entities/Renderers/DefaultRenderer.php index 87e7b41..161f63d 100644 --- a/src/Entities/Renderers/DefaultRenderer.php +++ b/src/Entities/Renderers/DefaultRenderer.php @@ -2,12 +2,12 @@ namespace Tapestry\Entities\Renderers; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; class DefaultRenderer implements RendererInterface { /** - * @var array File extensions that this renderer supports + * @var array ProjectFile extensions that this renderer supports */ private $extensions = ['*']; @@ -46,11 +46,11 @@ public function canRender($extension) /** * Render the input file content and return the output. * - * @param File $file + * @param ProjectFile $file * * @return string */ - public function render(File $file) + public function render(ProjectFile $file) { return ''; } @@ -76,13 +76,14 @@ public function supportsFrontMatter() } /** - * The default action is to set a File for copying and therefore + * The default action is to set a ProjectFile for copying and therefore * disable its pretty permalink output. * - * @param File $file + * @param ProjectFile $file * @return void + * @throws \Exception */ - public function mutateFile(File &$file) + public function mutateFile(ProjectFile &$file) { $file->setToCopy(true); $file->setData([ diff --git a/src/Entities/Renderers/HTMLRenderer.php b/src/Entities/Renderers/HTMLRenderer.php index c9278db..7492168 100644 --- a/src/Entities/Renderers/HTMLRenderer.php +++ b/src/Entities/Renderers/HTMLRenderer.php @@ -2,10 +2,14 @@ namespace Tapestry\Entities\Renderers; -use Tapestry\Entities\File; use Tapestry\Entities\Project; -use Symfony\Component\Finder\SplFileInfo; +use Tapestry\Entities\ProjectFile; +/** + * Class HTMLRenderer. + * + * Mutate HTML input file into a PHTML output file for intermediate compiling. + */ class HTMLRenderer implements RendererInterface { /** @@ -63,11 +67,12 @@ public function canRender($extension) /** * Render the input file content and return the output. * - * @param File $file + * @param ProjectFile $file * * @return string + * @throws \Exception */ - public function render(File $file) + public function render(ProjectFile $file) { return $file->getContent(); } @@ -79,7 +84,7 @@ public function render(File $file) */ public function getDestinationExtension($ext) { - return 'html'; + return 'phtml'; } /** @@ -93,29 +98,15 @@ public function supportsFrontMatter() } /** - * @param File $file + * @param ProjectFile $file * * @return void + * @throws \Exception */ - public function mutateFile(File &$file) + public function mutateFile(ProjectFile &$file) { - // - // If the HTML file has a template then we should pass it on to the plates renderer - // - if ($template = $file->getData('template')) { - $templateRelativePath = '_templates'.DIRECTORY_SEPARATOR.$template.'.phtml'; - $templatePath = $this->project->sourceDirectory.DIRECTORY_SEPARATOR.$templateRelativePath; - if (file_exists($templatePath)) { - $fileName = $file->getFilename(); - $filePath = $file->getPath(); - - $file->setRendered(false); - $file->setData(['content' => $file->getContent()]); - $file->setFileInfo(new SplFileInfo($templatePath, '_templates', $templateRelativePath)); - $file->setContent($file->getFileContent()); - $file->setFilename($fileName); - $file->setPath($filePath); - } + if ($layout = $file->getData('layout')) { + $file->loadContent('layout("'.$layout.'", $projectFile->getData()) ?>'.$file->getContent()); } } } diff --git a/src/Entities/Renderers/MarkdownRenderer.php b/src/Entities/Renderers/MarkdownRenderer.php index 0889bdb..c5c03b6 100644 --- a/src/Entities/Renderers/MarkdownRenderer.php +++ b/src/Entities/Renderers/MarkdownRenderer.php @@ -3,12 +3,17 @@ namespace Tapestry\Entities\Renderers; use Michelf\MarkdownExtra; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; +/** + * Class MarkdownRenderer. + * + * Mutate MD input file into a PHTML output file for intermediate compiling. + */ class MarkdownRenderer implements RendererInterface { /** - * @var array File extensions that this renderer supports + * @var array ProjectFile extensions that this renderer supports */ private $extensions = ['md', 'markdown']; @@ -62,11 +67,12 @@ public function canRender($extension) /** * Render the input file content and return the output. * - * @param File $file + * @param ProjectFile $file * * @return string + * @throws \Exception */ - public function render(File $file) + public function render(ProjectFile $file) { return $this->markdown->transform($file->getContent()); } @@ -78,7 +84,7 @@ public function render(File $file) */ public function getDestinationExtension($ext) { - return 'html'; + return 'phtml'; } /** @@ -92,16 +98,15 @@ public function supportsFrontMatter() } /** - * @param File $file + * @param ProjectFile $file * * @return void + * @throws \Exception */ - public function mutateFile(File &$file) + public function mutateFile(ProjectFile &$file) { - // If markdown file has a layout associated with it, we need to ensure it gets rendered within that - if ($file->hasData('layout')) { - $file->setExt('phtml'); // Templates are managed by the phtml renderer - $file->setRendered(false); // Set rendered to false so that within Compile.php's Execute Renderers loop it gets re-rendered + if ($layout = $file->getData('layout')) { + $file->loadContent('layout("'.$layout.'", $projectFile->getData()) ?>'.$file->getContent()); } } } diff --git a/src/Entities/Renderers/PlatesRenderer.php b/src/Entities/Renderers/PlatesRenderer.php index 2da0ceb..7125c2c 100644 --- a/src/Entities/Renderers/PlatesRenderer.php +++ b/src/Entities/Renderers/PlatesRenderer.php @@ -2,10 +2,15 @@ namespace Tapestry\Entities\Renderers; -use Tapestry\Entities\File; -use Tapestry\Plates\Engine; +use League\Plates\Engine; use Tapestry\Entities\Project; +use Tapestry\Entities\ProjectFile; +/** + * Class PlatesRenderer. + * + * Pass through phtml files for intermediate compiling. + */ class PlatesRenderer implements RendererInterface { /** @@ -33,7 +38,7 @@ public function __construct(Engine $parser, Project $project) { $this->parser = $parser; $this->project = $project; - $this->parser->setProject($project); + //$this->parser->setProject($project); //@todo determine if this is nessessary with v4 } /** @@ -71,13 +76,14 @@ public function canRender($extension) /** * Render the input file content and return the output. * - * @param File $file + * @param ProjectFile $file * * @return string + * @throws \Exception */ - public function render(File $file) + public function render(ProjectFile $file) { - return $this->parser->renderFile($file); + return $file->getContent(); } /** @@ -87,7 +93,7 @@ public function render(File $file) */ public function getDestinationExtension($ext) { - return 'html'; + return 'phtml'; } /** @@ -101,12 +107,17 @@ public function supportsFrontMatter() } /** - * @param File $file + * @param ProjectFile $file * * @return void + * @throws \Exception */ - public function mutateFile(File &$file) + public function mutateFile(ProjectFile &$file) { - // ... + if (! str_contains($file->getContent(), '$v->layout')) { + if ($layout = $file->getData('layout')) { + $file->loadContent('layout("'.$layout.'", $projectFile->getData()) ?>'.$file->getContent()); + } + } } } diff --git a/src/Entities/Renderers/RendererInterface.php b/src/Entities/Renderers/RendererInterface.php index 2a7cac1..4106f8e 100644 --- a/src/Entities/Renderers/RendererInterface.php +++ b/src/Entities/Renderers/RendererInterface.php @@ -2,7 +2,7 @@ namespace Tapestry\Entities\Renderers; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; /** * Interface RendererInterface. @@ -39,11 +39,11 @@ public function canRender($extension); /** * Render the input file content and return the output. * - * @param File $file + * @param ProjectFile $file * * @return string */ - public function render(File $file); + public function render(ProjectFile $file); /** * Returns the extension that the rendered output conforms to. @@ -63,9 +63,9 @@ public function supportsFrontMatter(); * A Renderer can mutate an input file so that the Compile class pushes it through to another renderer, this is used * by the HTMLRenderer to pass through a html file that has a template to the PlatesRenderer. * - * @param File $file + * @param ProjectFile $file * * @return void */ - public function mutateFile(File &$file); + public function mutateFile(ProjectFile &$file); } diff --git a/src/Entities/Taxonomy.php b/src/Entities/Taxonomy.php index 6b3c4c0..4011244 100644 --- a/src/Entities/Taxonomy.php +++ b/src/Entities/Taxonomy.php @@ -42,10 +42,10 @@ public function getName() } /** - * @param File $file + * @param ProjectFile $file * @param $classification */ - public function addFile(File $file, $classification) + public function addFile(ProjectFile $file, $classification) { $classification = str_slug($classification); if (! $this->items->has($classification)) { diff --git a/src/Entities/ViewFile.php b/src/Entities/ViewFile.php index 8868259..4807e27 100644 --- a/src/Entities/ViewFile.php +++ b/src/Entities/ViewFile.php @@ -5,7 +5,7 @@ /** * Class ViewFile. * - * A wrapper surrounding a File object for the purpose of providing view helper + * A wrapper surrounding a ProjectFile object for the purpose of providing view helper * methods that are friendly to the end user. */ class ViewFile @@ -23,7 +23,7 @@ class ViewFile private $fileUid; /** - * @var File + * @var ProjectFile */ private $file; @@ -40,7 +40,7 @@ public function __construct(Project $project, $fileUid) } /** - * @return File + * @return ProjectFile */ public function getFile() { diff --git a/src/Entities/ViewFileTrait.php b/src/Entities/ViewFileTrait.php index e09384e..461ae6d 100644 --- a/src/Entities/ViewFileTrait.php +++ b/src/Entities/ViewFileTrait.php @@ -7,18 +7,18 @@ * * This trait contains methods that are shared between the ViewFile class and Tapestry\Plates\Extensions\Helpers * - * @see Tapestry\Plates\Extensions\Helpers - * @see Tapestry\Entities\ViewFile + * @see \Tapestry\Plates\Extensions\Helpers + * @see \Tapestry\Entities\ViewFile */ trait ViewFileTrait { /** - * @return File + * @return ProjectFile */ abstract public function getFile(); /** - * Returns data from attached File or $default if not found. + * Returns data from attached ProjectFile or $default if not found. * * @param $key * @param null $default @@ -33,6 +33,7 @@ public function getData($key, $default = null) * Returns the Files compiled permalink. * * @return mixed|string + * @throws \Exception */ public function getPermalink() { @@ -43,6 +44,7 @@ public function getPermalink() * Returns the Files compiled permalink as a absolute url. * * @return string + * @throws \Exception */ public function getUrl() { @@ -145,7 +147,7 @@ public function hasPreviousNext() } /** - * Returns true if the File has draft front matter set to true. + * Returns true if the ProjectFile has draft front matter set to true. * * @return bool */ diff --git a/src/Modules/Api/Json.php b/src/Modules/Api/Json.php index 810ae7b..9b3c42a 100644 --- a/src/Modules/Api/Json.php +++ b/src/Modules/Api/Json.php @@ -3,10 +3,10 @@ namespace Tapestry\Modules\Api; use Tapestry\Step; -use Tapestry\Entities\File; use Tapestry\Entities\Project; use Tapestry\Entities\Taxonomy; use Tapestry\Entities\ContentType; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Filesystem\Filesystem; use Symfony\Component\Console\Output\OutputInterface; use Tapestry\Modules\ContentTypes\ContentTypeFactory; @@ -38,6 +38,7 @@ public function __construct(Filesystem $filesystem) * @param OutputInterface $output * * @return bool + * @throws \Exception */ public function __invoke(Project $project, OutputInterface $output) { @@ -55,7 +56,7 @@ public function __invoke(Project $project, OutputInterface $output) /** * @var string - * @var File $file + * @var ProjectFile $file */ foreach ($project->get('files') as $id => $file) { $json['files'][$id] = [ @@ -63,7 +64,7 @@ public function __invoke(Project $project, OutputInterface $output) 'ext' => $file->getExt(), 'data' => $file->getData(), 'content' => $file->getFileContent(), - 'modified' => $file->getLastModified(), + 'modified' => $file->getMTime(), 'path' => $file->getPath(), ]; } diff --git a/src/Modules/Config/DefaultConfig.php b/src/Modules/Config/DefaultConfig.php index cbd72f6..dd11387 100644 --- a/src/Modules/Config/DefaultConfig.php +++ b/src/Modules/Config/DefaultConfig.php @@ -28,8 +28,8 @@ 'content_types' => [ 'blog' => [ 'path' => '_blog', - 'template' => 'blog', - 'permalink' => 'blog/{year}/{slug}.html', + 'template' => '_views/blog', + 'permalink' => 'blog/{year}/{slug}.{ext}', 'enabled' => true, 'taxonomies' => [ 'tags', diff --git a/src/Modules/Content/Compile.php b/src/Modules/Content/Compile.php index f6ae507..0caf1ea 100644 --- a/src/Modules/Content/Compile.php +++ b/src/Modules/Content/Compile.php @@ -4,12 +4,12 @@ use Tapestry\Step; use Tapestry\Tapestry; -use Tapestry\Entities\File; use Tapestry\Entities\Cache; use Tapestry\Entities\Project; use Tapestry\Entities\ViewFile; use Tapestry\Entities\CachedFile; use Tapestry\Entities\ContentType; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\ProjectFileInterface; use Symfony\Component\Filesystem\Filesystem; use Tapestry\Entities\Filesystem\FileCopier; @@ -29,7 +29,7 @@ class Compile implements Step private $filesystem; /** - * @var array|File[] + * @var array|ProjectFile[] */ private $files = []; /** @@ -138,7 +138,7 @@ private function iterateProjectContentTypes(ContentTypeFactory $contentTypes, Pr // Foreach ContentType look up their Files and run the particular Renderer on their $content before updating // the Project File. foreach (array_keys($contentType->getFileList()) as $fileKey) { - /** @var File $file */ + /** @var ProjectFile $file */ if (! $file = $project->get('files.'.$fileKey)) { continue; } @@ -158,10 +158,11 @@ private function iterateProjectContentTypes(ContentTypeFactory $contentTypes, Pr * Where a file has a use statement, we now need to collect the associated use data and inject it. * * @param Project $project + * @throws \Exception */ private function collectProjectFilesUseData(Project $project) { - /** @var File $file */ + /** @var ProjectFile $file */ foreach ($project['compiled'] as $file) { if (! $uses = $file->getData('use')) { continue; @@ -172,7 +173,7 @@ private function collectProjectFilesUseData(Project $project) } array_walk_recursive($items, function (&$file, $fileKey) use ($project) { - /** @var File $compiledFile */ + /** @var ProjectFile $compiledFile */ if (! $compiledFile = $project->get('compiled.'.$fileKey)) { $file = null; } else { @@ -192,7 +193,7 @@ private function collectProjectFilesUseData(Project $project) private function checkForPermalinkClashes(Project $project, OutputInterface $output) { - /** @var File $file */ + /** @var ProjectFile $file */ foreach ($project['compiled'] as $file) { if (isset($this->permalinkTable[sha1($file->getCompiledPermalink())])) { $output->writeln('[!] The permalink ['.$file->getCompiledPermalink().'] is already in use!'); @@ -271,7 +272,7 @@ private function mutateFilesToFilesystemInterfaces(Project $project, Cache $cach } /** - * @param ProjectFileInterface|ProjectFileInterface[]|File|File[] $files + * @param ProjectFileInterface|ProjectFileInterface[]|ProjectFile|ProjectFile[] $files */ private function add($files) { diff --git a/src/Modules/Content/LoadSourceFiles.php b/src/Modules/Content/LoadSourceFiles.php index 0455007..ac6648b 100644 --- a/src/Modules/Content/LoadSourceFiles.php +++ b/src/Modules/Content/LoadSourceFiles.php @@ -4,8 +4,8 @@ use Tapestry\Step; use Tapestry\Tapestry; -use Tapestry\Entities\File; use Tapestry\Entities\Project; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Finder\Finder; use Tapestry\Entities\Configuration; use Symfony\Component\Console\Output\OutputInterface; @@ -98,7 +98,7 @@ public function __invoke(Project $project, OutputInterface $output) $this->excluded->excludeFromFinder($finder); foreach ($finder->files() as $file) { - $file = new File($file, [ + $file = new ProjectFile($file, [ 'pretty_permalink' => $this->prettyPermalink, ]); $renderer = $contentRenderers->get($file->getFileInfo()->getExtension()); @@ -149,11 +149,11 @@ public function __invoke(Project $project, OutputInterface $output) /** * If the file is a draft, but auto publish is enabled and the files date is in the past then it should be published. - * @param File $file + * @param ProjectFile $file * @version 1.0.9 * @return bool */ - private function canAutoPublish(File $file) + private function canAutoPublish(ProjectFile $file) { if ($this->autoPublish === false) { return false; diff --git a/src/Modules/ContentTypes/ParseContentTypes.php b/src/Modules/ContentTypes/ParseContentTypes.php index ab54ee8..d805541 100644 --- a/src/Modules/ContentTypes/ParseContentTypes.php +++ b/src/Modules/ContentTypes/ParseContentTypes.php @@ -3,9 +3,9 @@ namespace Tapestry\Modules\ContentTypes; use Tapestry\Step; -use Tapestry\Entities\File; use Tapestry\Entities\Project; use Tapestry\Entities\ContentType; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\Generators\FileGenerator; use Symfony\Component\Console\Output\OutputInterface; @@ -14,10 +14,11 @@ class ParseContentTypes implements Step /** * Process the Project at current. * - * @param Project $project + * @param Project $project * @param OutputInterface $output * * @return bool + * @throws \Exception */ public function __invoke(Project $project, OutputInterface $output) { @@ -31,7 +32,7 @@ public function __invoke(Project $project, OutputInterface $output) // is to be used for pagination and taxonomy output where pages are generated that do not exist in the source path. // - /** @var File $file */ + /** @var ProjectFile $file */ foreach ($project['files']->all() as $file) { if (! $uses = $file->getData('use')) { continue; @@ -49,19 +50,19 @@ public function __invoke(Project $project, OutputInterface $output) continue; } - $file->setData([$use.'_items' => $contentType->getTaxonomy($useTaxonomy)->getFileList()]); + $file->setData($use.'_items', $contentType->getTaxonomy($useTaxonomy)->getFileList()); // If the file doesn't have a generator set then we need to define one if (! $file->hasData('generator')) { // do we _need_ to add a generator here? - $file->setData(['generator' => ['TaxonomyIndexGenerator']]); + $file->setData('generator', ['TaxonomyIndexGenerator']); } } else { /** @var ContentType $contentType */ if (! $contentType = $project['content_types.'.$use]) { continue; } - $file->setData([$use.'_items' => $contentType->getFileList()]); + $file->setData($use.'_items', $contentType->getFileList()); } } diff --git a/src/Modules/Generators/ContentGeneratorFactory.php b/src/Modules/Generators/ContentGeneratorFactory.php index b8b4083..b5c2be1 100644 --- a/src/Modules/Generators/ContentGeneratorFactory.php +++ b/src/Modules/Generators/ContentGeneratorFactory.php @@ -2,7 +2,7 @@ namespace Tapestry\Modules\Generators; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; class ContentGeneratorFactory { @@ -24,7 +24,7 @@ public function add($class) $this->items[$reflection->getShortName()] = $class; } - public function get($name, File $file) + public function get($name, ProjectFile $file) { return new $this->items[$name]($file); } diff --git a/src/Modules/Plates/Extensions/Environment.php b/src/Modules/Plates/Extensions/Environment.php new file mode 100644 index 0000000..03f7ab2 --- /dev/null +++ b/src/Modules/Plates/Extensions/Environment.php @@ -0,0 +1,54 @@ +environment = $project->environment; + } + + /** + * Register the `getEnvironment` helper with Plates. + * + * @param Engine $engine + */ + public function register(Engine $engine) + { + $engine->addMethods(['getEnvironment' => [$this, 'getEnvironment']]); + } + + /** + * Returns the current environment. + * + * @return string + */ + public function getEnvironment() : string + { + return $this->environment; + } +} diff --git a/src/Plates/Extensions/Helpers.php b/src/Modules/Plates/Extensions/Helpers.php similarity index 88% rename from src/Plates/Extensions/Helpers.php rename to src/Modules/Plates/Extensions/Helpers.php index 59d8716..ce63c1e 100644 --- a/src/Plates/Extensions/Helpers.php +++ b/src/Modules/Plates/Extensions/Helpers.php @@ -1,9 +1,9 @@ addMethods([ + 'renderProjectFile' => function (Engine $plates, ProjectFile $file) { + $c = $plates->getContainer(); + + $rt = new \League\Plates\RenderTemplate\FileSystemRenderTemplate([ + [ + \League\Plates\Template\matchExtensions($c->get('config')['php_extensions']), + new \League\Plates\RenderTemplate\PhpRenderTemplate($c->get('renderTemplate.bind')), + ], + [ + \League\Plates\Template\matchExtensions($c->get('config')['image_extensions']), + \League\Plates\RenderTemplate\MapContentRenderTemplate::base64Encode(new \League\Plates\RenderTemplate\StaticFileRenderTemplate()), + ], + [ + \League\Plates\Template\matchStub(true), + new \League\Plates\RenderTemplate\StaticFileRenderTemplate(), + ], + ]); + if ($c->get('config')['validate_paths']) { + $rt = new \League\Plates\RenderTemplate\ValidatePathRenderTemplate($rt, $c->get('fileExists')); + } + $rt = array_reduce($c->get('renderTemplate.factories'), function ($rt, $create) { + return $create($rt); + }, $rt); + $rt = new \League\Plates\RenderTemplate\ComposeRenderTemplate($rt, $c->get('compose')); + + return $rt; + }, + ]); + } +} diff --git a/src/Modules/Plates/Extensions/Site.php b/src/Modules/Plates/Extensions/Site.php new file mode 100644 index 0000000..942bed2 --- /dev/null +++ b/src/Modules/Plates/Extensions/Site.php @@ -0,0 +1,58 @@ +configuration = $configuration; + } + + /** + * Register the `site` helper with Plates. + * + * @param Engine $engine + */ + public function register(Engine $engine) + { + $engine->addMethods(['site' => [$this, 'site']]); + } + + /** + * Return site config by `$key` or return `$default` if not found. + * + * @param string $key + * @param mixed|null $default + * @return mixed|null + */ + public function site(string $key, $default = null) + { + $key = 'site.'.$key; + if ($value = $this->configuration->get($key, $default)) { + return $value; + } + + return $default; + } +} diff --git a/src/Modules/Plates/Extensions/Url.php b/src/Modules/Plates/Extensions/Url.php new file mode 100644 index 0000000..311c10d --- /dev/null +++ b/src/Modules/Plates/Extensions/Url.php @@ -0,0 +1,57 @@ + 'http://www.example.com/abc/123' + */ +class Url implements Extension +{ + /** + * @var \Tapestry\Entities\Url + */ + private $url; + + /** + * Url constructor. + * + * @param \Tapestry\Entities\Url $url + */ + public function __construct(\Tapestry\Entities\Url $url) + { + $this->url = $url; + } + + /** + * Register the `url` helper with Plates. + * + * @param Engine $engine + */ + public function register(Engine $engine) + { + $engine->addMethods(['url' => [$this, 'url']]); + } + + /** + * Returns the input `$uri` parsed through the `Url` class. + * + * @see \Tapestry\Entities\Url + * @param string $uri + * @return string + */ + public function url(string $uri = '') : string + { + return $this->url->parse($uri); + } +} diff --git a/src/Modules/Renderers/ContentRendererFactory.php b/src/Modules/Renderers/ContentRendererFactory.php index 69dabb2..6b15b2b 100644 --- a/src/Modules/Renderers/ContentRendererFactory.php +++ b/src/Modules/Renderers/ContentRendererFactory.php @@ -3,7 +3,7 @@ namespace Tapestry\Modules\Renderers; use Exception; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\Renderers\RendererInterface; class ContentRendererFactory @@ -26,6 +26,7 @@ class ContentRendererFactory * ContentRendererFactory constructor. * * @param array|RendererInterface[] $items + * @throws Exception */ public function __construct(array $items = []) { @@ -102,16 +103,17 @@ public function get($ext) /** * Identify which Renderer to be used and then execute it upon the file in question. * - * @param File $file + * @param ProjectFile $file + * @throws Exception */ - public function renderFile(File &$file) + public function renderFile(ProjectFile &$file) { if ($file->isRendered()) { return; } - $fileRenderer = $this->get($file->getExt()); - $file->setContent($fileRenderer->render($file)); - $file->setExt($fileRenderer->getDestinationExtension($file->getExt())); + $fileRenderer = $this->get($file->getExtension()); + $file->loadContent($fileRenderer->render($file)); + $file->setOverloaded('ext', $fileRenderer->getDestinationExtension($file->getExtension())); $file->setRendered(true); $fileRenderer->mutateFile($file); } diff --git a/src/Plates/Engine.php b/src/Plates/Engine.php index 4b5476b..0be189f 100644 --- a/src/Plates/Engine.php +++ b/src/Plates/Engine.php @@ -2,11 +2,15 @@ namespace Tapestry\Plates; -use Tapestry\Entities\File; use Tapestry\Entities\Project; +use Tapestry\Entities\ProjectFile; use League\Plates\Engine as LeagueEngine; use Tapestry\Entities\Collections\FlatCollection; +/** + * Class Engine. + * @deprecated + */ class Engine extends LeagueEngine { /** @@ -40,11 +44,11 @@ public function make($name) /** * Create a new template and render it. * - * @param File $file + * @param ProjectFile $file * * @return string */ - public function renderFile(File $file) + public function renderFile(ProjectFile $file) { return $this->make( $file->getFileInfo()->getRelativePath(). diff --git a/src/Plates/Extensions/Environment.php b/src/Plates/Extensions/Environment.php deleted file mode 100644 index 2bcd361..0000000 --- a/src/Plates/Extensions/Environment.php +++ /dev/null @@ -1,34 +0,0 @@ -environment = $project->environment; - } - - public function register(Engine $engine) - { - $engine->registerFunction('getEnvironment', [$this, 'getEnvironment']); - } - - public function getEnvironment() - { - return $this->environment; - } -} diff --git a/src/Plates/Extensions/Site.php b/src/Plates/Extensions/Site.php deleted file mode 100644 index 3dd68ae..0000000 --- a/src/Plates/Extensions/Site.php +++ /dev/null @@ -1,40 +0,0 @@ -configuration = $configuration; - } - - public function register(Engine $engine) - { - $engine->registerFunction('site', [$this, 'site']); - } - - public function site($key, $default = null) - { - $key = 'site.'.$key; - if ($value = $this->configuration->get($key, $default)) { - return $value; - } - - return $default; - } -} diff --git a/src/Plates/Extensions/Url.php b/src/Plates/Extensions/Url.php deleted file mode 100644 index 688ec86..0000000 --- a/src/Plates/Extensions/Url.php +++ /dev/null @@ -1,34 +0,0 @@ -url = $url; - } - - public function register(Engine $engine) - { - $engine->registerFunction('url', [$this, 'url']); - } - - public function url($uri = '') - { - return $this->url->parse($uri); - } -} diff --git a/src/Plates/Template.php b/src/Plates/Template.php index df24bcd..78f4b58 100644 --- a/src/Plates/Template.php +++ b/src/Plates/Template.php @@ -5,11 +5,12 @@ use Exception; use Throwable; use LogicException; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use League\Plates\Template\Template as PlatesTemplate; /** * Class Template. + * @deprecated */ class Template extends PlatesTemplate { @@ -20,7 +21,7 @@ class Template extends PlatesTemplate protected $engine; /** - * @var File|null + * @var ProjectFile|null */ private $file = null; @@ -61,21 +62,21 @@ public function getFile() return $this->file; } - public function setFile(File $file) + public function setFile(ProjectFile $file) { $this->file = $file; } /** - * Render the File. + * Render the ProjectFile. * - * @param File $file + * @param ProjectFile $file * @param array $data * @return string * @throws Exception * @throws Throwable */ - public function renderFile(File $file, array $data = []) + public function renderFile(ProjectFile $file, array $data = []) { $this->data($data); unset($data); diff --git a/src/Providers/PlatesServiceProvider.php b/src/Providers/PlatesServiceProvider.php index 2acb3b5..123a032 100644 --- a/src/Providers/PlatesServiceProvider.php +++ b/src/Providers/PlatesServiceProvider.php @@ -2,12 +2,12 @@ namespace Tapestry\Providers; -use Tapestry\Plates\Engine; +use League\Plates\Engine; use Tapestry\Entities\Project; -use Tapestry\Plates\Extensions\Url; -use Tapestry\Plates\Extensions\Site; -use Tapestry\Plates\Extensions\Helpers; -use Tapestry\Plates\Extensions\Environment; +use Tapestry\Modules\Plates\Extensions\Url; +use Tapestry\Modules\Plates\Extensions\Site; +use Tapestry\Modules\Plates\Extensions\Environment; +use Tapestry\Modules\Plates\Extensions\RenderProjectFile; use League\Container\ServiceProvider\AbstractServiceProvider; class PlatesServiceProvider extends AbstractServiceProvider @@ -25,6 +25,9 @@ class PlatesServiceProvider extends AbstractServiceProvider * from the ContainerAwareTrait. * * @return void + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface + * @throws \Exception */ public function register() { @@ -33,12 +36,21 @@ public function register() /** @var Project $project */ $project = $container->get(Project::class); - $container->share(Engine::class, function () use ($project, $container) { - $engine = new Engine($project->sourceDirectory, 'phtml'); - $engine->loadExtension($container->get(Site::class)); - $engine->loadExtension($container->get(Url::class)); - $engine->loadExtension($container->get(Helpers::class)); - $engine->loadExtension($container->get(Environment::class)); + $intermediatePath = $project->currentWorkingDirectory.DIRECTORY_SEPARATOR.'.compileTmp'; + + if (! file_exists($intermediatePath)) { + if (! mkdir($intermediatePath)) { + throw new \Exception('Could not create folder at ['.$intermediatePath.']'); + } + } + + $container->share(Engine::class, function () use ($project, $container, $intermediatePath) { + $engine = Engine::create([$intermediatePath, $project->sourceDirectory], 'phtml'); + //$engine->register($container->get(Site::class)); + //$engine->register($container->get(Url::class)); + $engine->register($container->get(RenderProjectFile::class)); + //$engine->register($container->get(Helpers::class)); // @todo rewrite this for v4 + //$engine->register($container->get(Environment::class)); return $engine; }); diff --git a/src/Steps/LexicalAnalysis.php b/src/Steps/LexicalAnalysis.php new file mode 100644 index 0000000..84ecfd0 --- /dev/null +++ b/src/Steps/LexicalAnalysis.php @@ -0,0 +1,30 @@ + index.phtml -> BlogPosts (paginated 3 per page) -> post-1.md + // -> post-2.md + // -> post-3.md + // + return true; + } +} diff --git a/src/Modules/Generators/LoadContentGenerators.php b/src/Steps/LoadContentGenerators.php similarity index 84% rename from src/Modules/Generators/LoadContentGenerators.php rename to src/Steps/LoadContentGenerators.php index f816ccf..c8e4aaf 100644 --- a/src/Modules/Generators/LoadContentGenerators.php +++ b/src/Steps/LoadContentGenerators.php @@ -1,12 +1,13 @@ configuration = $configuration; diff --git a/src/Modules/Renderers/LoadContentRenderers.php b/src/Steps/LoadContentRenderers.php similarity index 84% rename from src/Modules/Renderers/LoadContentRenderers.php rename to src/Steps/LoadContentRenderers.php index 330a3fc..40b9295 100644 --- a/src/Modules/Renderers/LoadContentRenderers.php +++ b/src/Steps/LoadContentRenderers.php @@ -1,12 +1,13 @@ tapestry = $tapestry; + $this->now = new \DateTime(); + $this->ignoredPaths = array_merge($configuration->get('ignore'), ['_views', '_templates']); + $this->prettyPermalink = boolval($configuration->get('pretty_permalink', true)); + $this->publishDrafts = boolval($configuration->get('publish_drafts', false)); + $this->autoPublish = (isset($tapestry['cmd_options']['auto-publish']) ? boolval($tapestry['cmd_options']['auto-publish']) : false); + } + + /** + * Process the Project at current. + * + * @param Project $project + * @param OutputInterface $output + * + * @return bool + * @throws \Exception + */ + public function __invoke(Project $project, OutputInterface $output) + { + if (! file_exists($project->sourceDirectory)) { + $output->writeln('[!] The project source path could not be opened at ['.$project->sourceDirectory.']'); + + return false; + } + + /** @var Cache $cache */ + $cache = $project->get('cache'); + + // Table containing all files found and their last update time. + if (! $hashTable = $cache->getItem('fileHashTable')) { + $hashTable = []; + } + + /** @var ContentTypeFactory $contentTypes */ + $contentTypes = $project->get('content_types'); + + foreach ($contentTypes->all() as $contentType) { + $path = $contentType->getPath(); + if ($path !== '*' && ! isset($this->dontIgnorePaths[$contentType->getPath()])) { + $this->dontIgnorePaths[] = $contentType->getPath(); + } + } + unset($contentType); + + /** @var ContentRendererFactory $contentRenderers */ + $contentRenderers = $project->get('content_renderers'); + + $finder = new Finder(); + $finder->files() + ->followLinks() + ->in($project->sourceDirectory) + ->ignoreDotFiles(true); + + foreach ($finder->files() as $file) { + $file = new ProjectFile($file, ['pretty_permalink' => $this->prettyPermalink]); + if (isset($hashTable[$file->getUid()]) && $hashTable[$file->getUid()] == $file->getMTime()) { + $file->isBlocked(); + } else { + $hashTable[$file->getUid()] = $file->getMTime(); + } + + if ($this->shouldIgnore($file)) { + $file->setIgnored(); + } + + $renderer = $contentRenderers->get($file->getFileInfo()->getExtension()); + + if ($renderer->supportsFrontMatter()) { + $frontMatter = new FrontMatter($file->getFileContent()); + $file->setData($frontMatter->getData()); + $file->loadContent($frontMatter->getContent()); + } + + // Publish Drafts / Scheduled Posts + if ($this->publishDrafts === false) { + // If file is a draft and cant auto publish then it remains a draft + if ( + boolval($file->getData('draft', false)) === true && + $this->canAutoPublish($file) === false + ) { + continue; + } + + // If file is not a draft, but the date is in the future then it is scheduled + if ($file->getData('date', new \DateTime()) > $this->now) { + continue; + } + } + + if (! $contentType = $contentTypes->find($file->getRelativePath())) { + $contentType = $contentTypes->get('*'); + } else { + $contentType = $contentTypes->get($contentType); + } + + // Identify if $file belongs to default renderer and therefore should be copied (for issue #255) + if ($renderer->getName() === 'DefaultRenderer') { + $renderer->mutateFile($file); + } + + $contentType->addFile($file); + $project->addFile($file); + $output->writeln('[+] File ['.$file->getRelativePathname().'] bucketed into content type ['.$contentType->getName().']'); + } + + $cache->setItem('fileHashTable', $hashTable); + + return true; + } + + /** + * If the file is a draft, but auto publish is enabled and the files date is in the past then it should be published. + * + * @param ProjectFile $file + * @version 1.0.9 + * @return bool + */ + private function canAutoPublish(ProjectFile $file) + { + if ($this->autoPublish === false) { + return false; + } + + if ($file->getData('date', new \DateTime()) <= $this->now) { + return true; + } + + return false; + } + + /** + * Files found in '_views', '_templates' should have their ignored flag set true. + * This is so they are available for SyntaxAnalysis but not parsed and output to dist + * because that would make no sense... + * + * @param ProjectFile $file + * @return bool + */ + private function shouldIgnore(ProjectFile $file): bool + { + $relativePath = $file->getRelativePath(); + + foreach ($this->dontIgnorePaths as $dontIgnorePath) { + if (str_contains($relativePath, $dontIgnorePath)) { + return false; + } + } + + foreach ($this->ignoredPaths as $ignoredPath) { + if (str_contains($relativePath, $ignoredPath)) { + return true; + } + } + + // Paths containing underscores are ignored by default. + foreach (explode('/', str_replace('\\', '/', $relativePath)) as $pathItem) { + if (substr($pathItem, 0, 1) === '_') { + return true; + } + } + + return false; + } +} diff --git a/src/Modules/Content/ReadCache.php b/src/Steps/ReadCache.php similarity index 95% rename from src/Modules/Content/ReadCache.php rename to src/Steps/ReadCache.php index a1b0013..1214cb3 100644 --- a/src/Modules/Content/ReadCache.php +++ b/src/Steps/ReadCache.php @@ -1,6 +1,6 @@ plates = $plates; + } + + /** + * @param Project $project + * @param OutputInterface $output + * + * @return bool + */ + public function __invoke(Project $project, OutputInterface $output) + { + /** @var FlatCollection $files */ + $files = $project['files']; + + foreach ($project->get('plates_cache') as $id => $path) { + if (substr($path, 0, 1) === '/') { + $path = substr($path, 1); + } + + $p = explode('.', $path); + array_pop($p); + + $path = implode('/', $p); + + /** @var ProjectFile $file */ + $file = $files->get($id); + + $html = $this->plates->render($path, ['projectFile' => $file]); + } + + return true; + } +} diff --git a/src/Steps/SyntaxAnalysis.php b/src/Steps/SyntaxAnalysis.php new file mode 100644 index 0000000..f093cc6 --- /dev/null +++ b/src/Steps/SyntaxAnalysis.php @@ -0,0 +1,301 @@ +plates = $plates; + } + + /** + * Process the Project at current. + * + * @param Project $project + * @param OutputInterface $output + * + * @return bool + * @throws \Exception + */ + public function __invoke(Project $project, OutputInterface $output) + { + // + // Identify all source files and build the initial symbol table + // + + /** @var ContentTypeFactory $contentTypes */ + $contentTypes = $project->get('content_types'); + + /** @var ContentRendererFactory $contentRenderers */ + $contentRenderers = $project->get('content_renderers'); + + /** @var Cache $cache */ + $cache = $project->get('cache'); + + // + // For V4 of plates, this Analysis should build a .tmp folder containing the source files converted into + // .phtml files. Once complete each phtml file in the .tmp folder can be output to dist as html. + // + // We are essentially compiling from md, html, etc into phtml files and then passing those through Plates. + // + // The syntax tree will allow us to see which source files have changed and which phtml intermediate files + // those changes affect, so that for each build execution we only have to pass those affected intermediate + // files through Plates. + // + // @todo analyse files with changes and only write intermediate files that have changes + // + + $this->iterateProjectContentTypes($contentTypes, $project, $output); + $this->collectProjectFilesUseData($project); + + if (! $this->checkForFileGeneratorError($output)) { + return false; + } + + if (! $this->checkForPermalinkClashes($project, $output)) { + return false; + } + + $this->writeIntermediateFiles($project, $contentRenderers); + + return true; + } + + /** + * @param Project $project + * @param ContentRendererFactory $contentRenderers + * @throws \Exception + */ + private function writeIntermediateFiles(Project $project, ContentRendererFactory $contentRenderers) + { + $filesystem = new Filesystem(); + $platesCache = $project['plates_cache'] ?? []; + $intermediatePath = $project->currentWorkingDirectory.DIRECTORY_SEPARATOR.'.compileTmp'; + + while (! $this->allFilesRendered()) { + foreach ($this->files as $file) { + if ($file->isRendered()) { + continue; + } + $contentRenderers->renderFile($file); + if (! $file->isToCopy()) { + $permalink = $file->getCompiledPermalink(); + $platesFilePath = $intermediatePath.$permalink; + $filesystem->dumpFile($platesFilePath, $file->getContent()); + + $platesCache[$file->getUid()] = $permalink; + + if ($layout = $file->getData('layout')) { + $filesystem->copy($project->sourceDirectory.DIRECTORY_SEPARATOR.$layout.'.phtml', $intermediatePath.DIRECTORY_SEPARATOR.$layout.'.phtml'); + } + } + $file->setRendered(); + } + } + + $project['plates_cache'] = $platesCache; + } + + /** + * Iterate over the file list of all content types and add the files they contain to the local compiled file list + * also at this point run any generators that the file may be linked to. + * + * @param ContentTypeFactory $contentTypes + * @param Project $project + * @param OutputInterface $output + * @throws \Exception + */ + private function iterateProjectContentTypes(ContentTypeFactory $contentTypes, Project $project, OutputInterface $output) + { + foreach ($contentTypes->all() as $contentType) { + $output->writeln('[+] Compiling content within ['.$contentType->getName().']'); + + // Foreach ContentType look up their Files and run the particular Renderer on their $content before updating + // the Project File. + foreach (array_keys($contentType->getFileList()) as $fileKey) { + /** @var ProjectFile $file */ + if (! $file = $project->get('files.'.$fileKey)) { + continue; + } + + if ($file->isIgnored()) { + continue; + } + + if (! $file->hasData('layout')) { + $file->setData('layout', $contentType->getTemplate()); + } + + // Pre-compile via use of File Generators + if ($file instanceof FileGenerator) { //@todo check if this is ever true + $this->add($file->generate($project)); + } else { + $this->add($file); + } + $project->set('compiled', $this->files); + } + } + + $project->set('compiled', $this->files); + } + + /** + * @param Project $project + * @param OutputInterface $output + * @return bool + * @throws \Exception + */ + private function checkForPermalinkClashes(Project $project, OutputInterface $output) : bool + { + /** @var ProjectFile $file */ + foreach ($project['compiled'] as $file) { + if (isset($this->permalinkTable[sha1($file->getCompiledPermalink())])) { + $output->writeln('[!] The permalink ['.$file->getCompiledPermalink().'] is already in use!'); + + return false; + } + $this->permalinkTable[sha1($file->getCompiledPermalink())] = [ + 'uid' => $file->getUid(), + 'permalink' => $file->getCompiledPermalink(), + ]; + } + + return true; + } + + /** + * @param OutputInterface $output + * @return bool + */ + private function checkForFileGeneratorError(OutputInterface $output) : bool + { + if (! $this->allFilesGenerated()) { + foreach ($this->files as &$file) { + if ($uses = $file->getData('generator')) { + if (count($uses) > 0) { + $output->writeln('[!] File ['.$file->getUid().'] has not completed generating'); + } + } + } + unset($file); + + return false; + } + + return true; + } + + /** + * Where a file has a use statement, we now need to collect the associated use data and inject it. + * + * @param Project $project + * @throws \Exception + */ + private function collectProjectFilesUseData(Project $project) + { + /** @var ProjectFile $file */ + foreach ($project['compiled'] as $file) { + if (! $uses = $file->getData('use')) { + continue; + } + foreach ($uses as $use) { + if (! $items = $file->getData($use.'_items')) { + continue; + } + + array_walk_recursive($items, function (&$file, $fileKey) use ($project) { + /** @var ProjectFile $compiledFile */ + if (! $compiledFile = $project->get('compiled.'.$fileKey)) { + $file = null; + } else { + $file = new ViewFile($project, $compiledFile->getUid()); + } + }); + + // Filter out deleted pages, such as drafts + $items = array_filter($items, function ($value) { + return ! is_null($value); + }); + + $file->setData([$use.'_items' => $items]); + } + } + } + + /** + * @param ProjectFileInterface|ProjectFileInterface[]|ProjectFile|ProjectFile[] $files + */ + private function add($files) + { + if (is_array($files)) { + foreach ($files as $file) { + $this->files[$file->getUid()] = $file; + } + } else { + $this->files[$files->getUid()] = $files; + } + } + + /** + * Returns true once all the compiled files have been rendered. + * + * @return bool + */ + private function allFilesRendered() :bool + { + foreach ($this->files as $file) { + if (! $file->isRendered()) { + return false; + } + } + + return true; + } + + private function allFilesGenerated() : bool + { + foreach ($this->files as $file) { + if ($uses = $file->getData('generator')) { + if (count($uses) > 0) { + return false; + } + } + } + + return true; + } +} diff --git a/tests/CommandTestBase.php b/tests/CommandTestBase.php index d3ecaa7..e7d7a51 100644 --- a/tests/CommandTestBase.php +++ b/tests/CommandTestBase.php @@ -8,7 +8,7 @@ require_once __DIR__ . '/../src/bootstrap.php'; -abstract class CommandTestBase extends \PHPUnit_Framework_TestCase +abstract class CommandTestBase extends \PHPUnit\Framework\TestCase { /** * @var null|Application diff --git a/tests/Feature/PermalinkTest.php b/tests/Feature/PermalinkTest.php index 07ee99b..1d77d53 100644 --- a/tests/Feature/PermalinkTest.php +++ b/tests/Feature/PermalinkTest.php @@ -3,7 +3,7 @@ namespace Tapestry\Tests\Feature; use Symfony\Component\Finder\SplFileInfo; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\Permalink; use Tapestry\Modules\Content\FrontMatter; use Tapestry\Tests\TestCase; @@ -11,26 +11,26 @@ class PermalinkTest extends TestCase { /** - * @param File $file + * @param ProjectFile $file * @return Permalink * @throws \Exception */ - private function setupPermalinks(File $file) + private function setupPermalinks(ProjectFile $file) { return $file->getCompiledPermalink(); } /** * @param string $filePath - * @return File + * @return ProjectFile * @throws \Exception */ private function setupFile($filePath) { - $file = new File(new SplFileInfo($filePath, '', '')); + $file = new ProjectFile(new SplFileInfo($filePath, '', '')); $frontMatter = new FrontMatter($file->getFileContent()); $file->setData($frontMatter->getData()); - $file->setContent($frontMatter->getContent()); + $file->loadContent($frontMatter->getContent()); return $file; } diff --git a/tests/Feature/TaxonomyArchiveGeneratorTest.php b/tests/Feature/TaxonomyArchiveGeneratorTest.php index b176b49..c98bb93 100644 --- a/tests/Feature/TaxonomyArchiveGeneratorTest.php +++ b/tests/Feature/TaxonomyArchiveGeneratorTest.php @@ -2,12 +2,11 @@ namespace Tapestry\Tests\Feature; -use Tapestry\Tests\CommandTestBase; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Console\Input\ArrayInput; use Symfony\Component\Console\Output\NullOutput; use Tapestry\Console\DefaultInputDefinition; use Tapestry\Entities\Collections\FlatCollection; -use Tapestry\Entities\File; use Tapestry\Entities\Filesystem\FileWriter; use Tapestry\Entities\Project; use Tapestry\Generator; @@ -48,7 +47,7 @@ public function testGenerator() $miscCategory = $compiledFiles['blog_categories_category_phtml_misc']; $miscCategoryFile = $miscCategory->getFile(); - $this->assertInstanceOf(File::class, $miscCategoryFile); + $this->assertInstanceOf(ProjectFile::class, $miscCategoryFile); $this->assertTrue($miscCategoryFile->hasData('blog_categories_items')); $this->assertTrue($miscCategoryFile->hasData('blog_categories')); diff --git a/tests/TestCase.php b/tests/TestCase.php index a499d83..ae6db56 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -11,7 +11,7 @@ use Tapestry\Console\Input; use Tapestry\Tapestry; -class TestCase extends \PHPUnit_Framework_TestCase { +class TestCase extends \PHPUnit\Framework\TestCase { /** * The unique tmp test directory for this test case, set on each test setup. @@ -65,7 +65,7 @@ protected function tearDown() * @param bool $overwrite * @return void */ - protected function copy($origin, $destination, $overwrite = false) + protected function copy(string $origin, string $destination, bool $overwrite = false) { (new Filesystem())->copy($origin, $destination, $overwrite); } @@ -77,7 +77,7 @@ protected function copy($origin, $destination, $overwrite = false) * @param string $destination * @return void */ - protected function mirror($origin, $destination) + protected function mirror(string $origin, string $destination) { (new Filesystem())->mirror($origin, $destination); } @@ -87,7 +87,7 @@ protected function mirror($origin, $destination) * * @param string $source */ - protected function loadToTmp($source) + protected function loadToTmp(string $source) { $this->mirror($source, $this->tmpDirectory); } @@ -98,7 +98,8 @@ protected function loadToTmp($source) * @param null|string $path * @return string */ - protected function tmpPath($path = null) { + protected function tmpPath(string $path = null) : string + { if (is_null($path)) { return $this->tmpDirectory; } @@ -116,7 +117,8 @@ protected function tmpPath($path = null) { * @param null|string $path * @return string */ - protected function assetPath($path = null) { + protected function assetPath(string $path = null) : string + { if (is_null($path)) { return realpath(__DIR__ . '/assets'); } @@ -136,7 +138,7 @@ protected function assetPath($path = null) { * @param array $options * @return ApplicationTester */ - protected function runCommand($command, $argv = '', array $options = []) + protected function runCommand(string $command, string $argv = '', array $options = []) : ApplicationTester { $arguments = ['command' => $command]; $argv = (strlen($argv) > 0) ? explode(' ', $argv) : []; @@ -183,13 +185,8 @@ protected function runCommand($command, $argv = '', array $options = []) * * @since Method available since Release 3.2.14 */ - public static function assertFileEquals( - $expected, - $actual, - $message = '', - $canonicalize = false, - $ignoreCase = false - ) { + public static function assertFileEquals(string $expected, string $actual, string $message = '', bool $canonicalize = false, bool $ignoreCase = false): void + { self::assertFileExists($expected, $message); self::assertFileExists($actual, $message); self::assertEquals( diff --git a/tests/Traits/MockFile.php b/tests/Traits/MockFile.php index a93da4a..4fb700b 100644 --- a/tests/Traits/MockFile.php +++ b/tests/Traits/MockFile.php @@ -3,7 +3,7 @@ namespace Tapestry\Tests\Traits; use Symfony\Component\Finder\SplFileInfo; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Tapestry\Modules\Content\FrontMatter; trait MockFile { @@ -17,7 +17,7 @@ trait MockFile { * * @return String */ - protected function getRelativePath($base, $path) { + protected function getRelativePath(string $base, string $path) { // On windows strip drive letter $base = preg_replace('/^[A-Z]:/i', '', $base); $path = preg_replace('/^[A-Z]:/i', '', $path); @@ -39,15 +39,16 @@ protected function getRelativePath($base, $path) { * @param $filePath * @param string $base * - * @return File + * @return ProjectFile + * @throws \Exception */ - protected function mockFile($filePath, $base = __DIR__ . '/..') + protected function mockFile(string $filePath, string $base = __DIR__ . '/..') : ProjectFile { $base = realpath($base); - $file = new File(new SplFileInfo($filePath, $this->getRelativePath($base, $filePath), $this->getRelativePath($base, $filePath))); + $file = new ProjectFile(new SplFileInfo($filePath, $this->getRelativePath($base, $filePath), $this->getRelativePath($base, $filePath))); $frontMatter = new FrontMatter($file->getFileContent()); $file->setData($frontMatter->getData()); - $file->setContent($frontMatter->getContent()); + $file->loadContent($frontMatter->getContent()); $file->getUid(); // Force the file to generate its uid return $file; } diff --git a/tests/Traits/MockViewFile.php b/tests/Traits/MockViewFile.php index cba8d43..494ff12 100644 --- a/tests/Traits/MockViewFile.php +++ b/tests/Traits/MockViewFile.php @@ -4,8 +4,8 @@ use Symfony\Component\Finder\SplFileInfo; use Tapestry\Entities\Configuration; -use Tapestry\Entities\File; use Tapestry\Entities\Project; +use Tapestry\Entities\ProjectFile; use Tapestry\Entities\ViewFile; use Tapestry\Modules\Content\FrontMatter; use Tapestry\Modules\Renderers\ContentRendererFactory; @@ -13,12 +13,21 @@ trait MockViewFile { - protected function mockViewFile(Tapestry $tapestry, $viewPath, $render = false) + /** + * @param Tapestry $tapestry + * @param $viewPath + * @param bool $render + * @return ViewFile + * @throws \Exception + * @throws \Psr\Container\ContainerExceptionInterface + * @throws \Psr\Container\NotFoundExceptionInterface + */ + protected function mockViewFile(Tapestry $tapestry, string $viewPath, bool $render = false) : ViewFile { - $file = new File(new SplFileInfo($viewPath, '', '')); + $file = new ProjectFile(new SplFileInfo($viewPath, '', '')); $frontMatter = new FrontMatter($file->getFileContent()); $file->setData($frontMatter->getData()); - $file->setContent($frontMatter->getContent()); + $file->loadContent($frontMatter->getContent()); /** @var Project $project */ $project = $tapestry->getContainer()->get(Project::class); diff --git a/tests/Unit/ArrayContainerMergeTest.php b/tests/Unit/ArrayContainerMergeNTest.php similarity index 99% rename from tests/Unit/ArrayContainerMergeTest.php rename to tests/Unit/ArrayContainerMergeNTest.php index c4a1a4f..c821505 100644 --- a/tests/Unit/ArrayContainerMergeTest.php +++ b/tests/Unit/ArrayContainerMergeNTest.php @@ -6,7 +6,7 @@ use Tapestry\Tests\Mocks\MockArrayAccessByKeyClass; use Tapestry\Tests\TestCase; -class ArrayContainerMergeTest extends TestCase +class ArrayContainerMergeNTest extends TestCase { public function testArrayContainerClassBaseFunctionality() { diff --git a/tests/Unit/CacheTest.php b/tests/Unit/CacheTest.php index 95e04e7..58b2986 100644 --- a/tests/Unit/CacheTest.php +++ b/tests/Unit/CacheTest.php @@ -8,7 +8,7 @@ use Tapestry\Entities\CacheStore; use Tapestry\Entities\Project; use Tapestry\Exceptions\InvalidVersionException; -use Tapestry\Modules\Content\ReadCache; +use Tapestry\Steps\ReadCache; use Tapestry\Tapestry; use Tapestry\Tests\TestCase; diff --git a/tests/Unit/CollectionsTest.php b/tests/Unit/CollectionsNTest.php similarity index 98% rename from tests/Unit/CollectionsTest.php rename to tests/Unit/CollectionsNTest.php index f591d01..9e7e296 100644 --- a/tests/Unit/CollectionsTest.php +++ b/tests/Unit/CollectionsNTest.php @@ -6,7 +6,7 @@ use Tapestry\Entities\Collections\FlatCollection; use Tapestry\Tests\TestCase; -class CollectionsTest extends TestCase +class CollectionsNTest extends TestCase { public function testFlatCollection() { diff --git a/tests/Unit/CommandLineApplicationTest.php b/tests/Unit/CommandLineApplicationNTest.php similarity index 89% rename from tests/Unit/CommandLineApplicationTest.php rename to tests/Unit/CommandLineApplicationNTest.php index 7eb1f0a..c332b22 100644 --- a/tests/Unit/CommandLineApplicationTest.php +++ b/tests/Unit/CommandLineApplicationNTest.php @@ -6,7 +6,7 @@ use Tapestry\Tapestry; use Tapestry\Tests\TestCase; -class CommandLineApplicationTest extends TestCase +class CommandLineApplicationNTest extends TestCase { public function testApplicationVersion() { diff --git a/tests/Unit/ContentGraphNTest.php b/tests/Unit/ContentGraphNTest.php new file mode 100644 index 0000000..cbe5496 --- /dev/null +++ b/tests/Unit/ContentGraphNTest.php @@ -0,0 +1,75 @@ +loadToTmp($this->assetPath('build_test_7/src')); + $this->loadToTmp($this->assetPath('build_test_41/src')); + $tapestry = $this->mockTapestry($this->tmpDirectory); + + /** @var Project $project */ + $project = $tapestry->getContainer()->get(Project::class); + + $generator = new Generator([ + ReadCache::class, + LoadContentTypes::class, + LoadContentRenderers::class, + LoadContentGenerators::class, + LoadSourceFileTree::class, + ParseContentTypes::class, + + SyntaxAnalysis::class, + //LexicalAnalysis::class, + RenderPlates::class + ], $tapestry); + $generator->generate($project, new NullOutput()); + + //touch($this->tmpDirectory . '/source/something.html'); + + //$generator->generate($project, new NullOutput()); + + // + // For refactoring issues #300, #297, #284, #282, #270: + // + // Tapestry now parses all files in the source folder and builds an hash table containing them all + // and their last change date. + // + // Test that the following happens: + // + // [ ] All files in source folder are loaded + // [ ] All files in source folder are bucketed correctly + // + // Because ignored files are still "parsed" during the LoadSourceFileTree step it also needs to be checked that + // they have an ignored flag set. This ensures that template files don't then get copied from source to dist. + // + // [ ] Ignored files are ignored + // + + $f = 0; + } +} \ No newline at end of file diff --git a/tests/Unit/ContentTypeTest.php b/tests/Unit/ContentTypeNTest.php similarity index 90% rename from tests/Unit/ContentTypeTest.php rename to tests/Unit/ContentTypeNTest.php index 686afc9..facc80e 100644 --- a/tests/Unit/ContentTypeTest.php +++ b/tests/Unit/ContentTypeNTest.php @@ -4,11 +4,11 @@ use Symfony\Component\Finder\SplFileInfo; use Tapestry\Entities\ContentType; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Tapestry\Modules\ContentTypes\ContentTypeFactory; use Tapestry\Tests\TestCase; -class ContentTypeTest extends TestCase +class ContentTypeNTest extends TestCase { /** @@ -18,7 +18,7 @@ class ContentTypeTest extends TestCase public function testAddFileMutatesFileDataWithContentTypeName() { $contentType = new ContentType('Test', ['enabled' => true]); - $file = new File(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); + $file = new ProjectFile(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); $this->assertFalse($file->hasData('contentType')); $contentType->addFile($file); $this->assertTrue($file->hasData('contentType')); diff --git a/tests/Unit/EntitiesTest.php b/tests/Unit/EntitiesNTest.php similarity index 99% rename from tests/Unit/EntitiesTest.php rename to tests/Unit/EntitiesNTest.php index 3e1b0f5..b106aac 100644 --- a/tests/Unit/EntitiesTest.php +++ b/tests/Unit/EntitiesNTest.php @@ -6,7 +6,7 @@ use Tapestry\Entities\Url; use Tapestry\Tests\TestCase; -class EntitiesTest extends TestCase +class EntitiesNTest extends TestCase { public function testUrlEntity() { diff --git a/tests/Unit/FileTest.php b/tests/Unit/FileNTest.php similarity index 56% rename from tests/Unit/FileTest.php rename to tests/Unit/FileNTest.php index d7deaa1..7bb0966 100644 --- a/tests/Unit/FileTest.php +++ b/tests/Unit/FileNTest.php @@ -3,14 +3,14 @@ namespace Tapestry\Tests\Unit; use Symfony\Component\Finder\SplFileInfo; -use Tapestry\Entities\File; +use Tapestry\Entities\ProjectFile; use Tapestry\Tests\TestCase; -class FileTest extends TestCase +class FileNTest extends TestCase { function testFileGetUid() { - $file = new File(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); + $file = new ProjectFile(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); $this->assertNotEmpty($file->getUid()); } } diff --git a/tests/Unit/FrontMatterTest.php b/tests/Unit/FrontMatterNTest.php similarity index 84% rename from tests/Unit/FrontMatterTest.php rename to tests/Unit/FrontMatterNTest.php index 7936833..d23a6e1 100644 --- a/tests/Unit/FrontMatterTest.php +++ b/tests/Unit/FrontMatterNTest.php @@ -2,12 +2,12 @@ namespace Tapestry\Tests\Unit; -use Tapestry\Tests\CommandTestBase; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Finder\SplFileInfo; -use Tapestry\Entities\File; use Tapestry\Modules\Content\FrontMatter; +use Tapestry\Tests\TestCase; -class FrontMatterTest extends CommandTestBase +class FrontMatterNTest extends TestCase { /** * Written for issue #148 @@ -15,7 +15,7 @@ class FrontMatterTest extends CommandTestBase */ function testFrontMatterParsedWhenBodyEmpty() { - $file = new File(new SplFileInfo(__DIR__ . '/../Mocks/TestFileNoBody.md', '', '')); + $file = new ProjectFile(new SplFileInfo(__DIR__ . '/../Mocks/TestFileNoBody.md', '', '')); $frontMatter = new FrontMatter($file->getFileContent()); $this->assertSame('', $frontMatter->getContent()); $this->assertSame([ @@ -27,7 +27,7 @@ function testFrontMatterParsedWhenBodyEmpty() function testFrontMatterAndBodyParsedCorrectly() { - $file = new File(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); + $file = new ProjectFile(new SplFileInfo(__DIR__ . '/../Mocks/TestFile.md', '', '')); $frontMatter = new FrontMatter($file->getFileContent()); $this->assertSame('This is a test file...', $frontMatter->getContent()); $this->assertSame([ diff --git a/tests/Unit/HelpersTest.php b/tests/Unit/HelpersNTest.php similarity index 98% rename from tests/Unit/HelpersTest.php rename to tests/Unit/HelpersNTest.php index 25480e4..615da05 100644 --- a/tests/Unit/HelpersTest.php +++ b/tests/Unit/HelpersNTest.php @@ -6,7 +6,7 @@ use Tapestry\Tests\TestCase; use Tapestry\Tests\Traits\MockTapestry; -class HelpersTest extends TestCase +class HelpersNTest extends TestCase { use MockTapestry; diff --git a/tests/Unit/PaginationTest.php b/tests/Unit/PaginationTest.php index 75b27ec..90afbf1 100644 --- a/tests/Unit/PaginationTest.php +++ b/tests/Unit/PaginationTest.php @@ -2,9 +2,8 @@ namespace Tapestry\Tests\Unit; -use Tapestry\Tests\CommandTestBase; +use Tapestry\Entities\ProjectFile; use Symfony\Component\Finder\SplFileInfo; -use Tapestry\Entities\File; use Tapestry\Entities\Generators\PaginationGenerator; use Tapestry\Entities\Pagination; use Tapestry\Entities\Project; @@ -16,10 +15,10 @@ class PaginationTest extends TestCase private function setupPagination(Project $project, $filePath) { - $file = new File(new SplFileInfo($filePath, '', '')); + $file = new ProjectFile(new SplFileInfo($filePath, '', '')); $frontMatter = new FrontMatter($file->getFileContent()); $file->setData($frontMatter->getData()); - $file->setContent($frontMatter->getContent()); + $file->loadContent($frontMatter->getContent()); $this->assertEquals(['PaginationGenerator'], $file->getData('generator')); @@ -31,7 +30,7 @@ private function setupPagination(Project $project, $filePath) $p->setUid('item-' . $i); $project->set('compiled.item-' . $i, $p); } - $file->setData(['test_items' => $testItems]); + $file->setData('test_items', $testItems); return new PaginationGenerator($file); } @@ -45,8 +44,8 @@ public function testPaginationCoreFunctionality() $this->assertEquals(17, count($generatedFiles)); /** - * @var File $firstPage - * @var File $lastPage + * @var ProjectFile $firstPage + * @var ProjectFile $lastPage */ $firstPage = array_shift($generatedFiles); $lastPage = array_pop($generatedFiles); @@ -80,7 +79,7 @@ public function testPaginationSkipFunctionality() $generatedFiles = $generator->generate($project); $this->assertTrue(is_array($generatedFiles)); - /** @var File $firstPage */ + /** @var ProjectFile $firstPage */ $firstPage = $generatedFiles[0]; /** @var Pagination $pagination */ diff --git a/tests/Unit/StopwatchProfilerTest.php b/tests/Unit/StopwatchProfilerNTest.php similarity index 97% rename from tests/Unit/StopwatchProfilerTest.php rename to tests/Unit/StopwatchProfilerNTest.php index 209314c..a5b408a 100644 --- a/tests/Unit/StopwatchProfilerTest.php +++ b/tests/Unit/StopwatchProfilerNTest.php @@ -5,7 +5,7 @@ use Tapestry\Profiler; use Tapestry\Tests\TestCase; -class StopwatchProfilerTest extends TestCase +class StopwatchProfilerNTest extends TestCase { public function testProfiler() { diff --git a/tests/Unit/TaxonomyTest.php b/tests/Unit/TaxonomyNTest.php similarity index 97% rename from tests/Unit/TaxonomyTest.php rename to tests/Unit/TaxonomyNTest.php index 0051978..1ef25fa 100644 --- a/tests/Unit/TaxonomyTest.php +++ b/tests/Unit/TaxonomyNTest.php @@ -2,13 +2,12 @@ namespace Tapestry\Tests\Unit; -use Tapestry\Tests\CommandTestBase; -use PHPUnit_Framework_Constraint_IsEqual; +use PHPUnit\Framework\Constraint\IsEqual; use Tapestry\Entities\Taxonomy; use Tapestry\Tests\TestCase; use Tapestry\Tests\Traits\MockFile; -class TaxonomyTest extends TestCase +class TaxonomyNTest extends TestCase { use MockFile; @@ -156,7 +155,7 @@ public function testTaxonomyClassOrder() private function isOr($test, $checkA, $checkB) { - $constraintA = new PHPUnit_Framework_Constraint_IsEqual( + $constraintA = new IsEqual( $checkA, 0.0, 10, @@ -168,7 +167,7 @@ private function isOr($test, $checkA, $checkB) { return true; } - $constraintB = new PHPUnit_Framework_Constraint_IsEqual( + $constraintB = new IsEqual( $checkB, 0.0, 10, diff --git a/tests/assets/build_test_41/check/about.html b/tests/assets/build_test_41/check/about.html new file mode 100644 index 0000000..efe5048 --- /dev/null +++ b/tests/assets/build_test_41/check/about.html @@ -0,0 +1 @@ +

Hello world!

\ No newline at end of file diff --git a/tests/assets/build_test_41/check/index.html b/tests/assets/build_test_41/check/index.html new file mode 100644 index 0000000..7a5ebc1 --- /dev/null +++ b/tests/assets/build_test_41/check/index.html @@ -0,0 +1 @@ +

Hello world

\ No newline at end of file diff --git a/tests/assets/build_test_41/src/config.php b/tests/assets/build_test_41/src/config.php new file mode 100644 index 0000000..a972e37 --- /dev/null +++ b/tests/assets/build_test_41/src/config.php @@ -0,0 +1,7 @@ + [ + 'ignored_folder', + ], +]; diff --git a/tests/assets/build_test_41/src/source/_blog/2016-03-10-test-blog-entry.md b/tests/assets/build_test_41/src/source/_blog/2016-03-10-test-blog-entry.md new file mode 100644 index 0000000..afaaaae --- /dev/null +++ b/tests/assets/build_test_41/src/source/_blog/2016-03-10-test-blog-entry.md @@ -0,0 +1,7 @@ +--- +title: This is a test blog entry +--- + +# This is a test posting + +Test, Test, Test... \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/_blog/2016-03-11-test-blog-entry-two.md b/tests/assets/build_test_41/src/source/_blog/2016-03-11-test-blog-entry-two.md new file mode 100644 index 0000000..fcde37d --- /dev/null +++ b/tests/assets/build_test_41/src/source/_blog/2016-03-11-test-blog-entry-two.md @@ -0,0 +1,7 @@ +--- +title: This is another test blog entry +--- + +# This is a test posting + +Something goes here... \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/_templates/default.phtml b/tests/assets/build_test_41/src/source/_templates/default.phtml new file mode 100644 index 0000000..c19eb77 --- /dev/null +++ b/tests/assets/build_test_41/src/source/_templates/default.phtml @@ -0,0 +1,19 @@ + + + + + + <?= (isset($title) ? $title : '') ?> + + + + + +

Tapestry Scaffold

+
Congratulations you have successfully scaffolded your first tapestry site.
+ + \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/_views/blog.phtml b/tests/assets/build_test_41/src/source/_views/blog.phtml new file mode 100644 index 0000000..4993913 --- /dev/null +++ b/tests/assets/build_test_41/src/source/_views/blog.phtml @@ -0,0 +1,16 @@ + + + + + + <?= (isset($title) ? $title : '') ?> + + + + + + \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/about.md b/tests/assets/build_test_41/src/source/about.md new file mode 100644 index 0000000..3045422 --- /dev/null +++ b/tests/assets/build_test_41/src/source/about.md @@ -0,0 +1,4 @@ +--- +key: value +--- +# Hello world! \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/assets/js/app.js b/tests/assets/build_test_41/src/source/assets/js/app.js new file mode 100644 index 0000000..0e3e8f1 --- /dev/null +++ b/tests/assets/build_test_41/src/source/assets/js/app.js @@ -0,0 +1 @@ +var n = 42; \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/assets/js/something_else/a.js b/tests/assets/build_test_41/src/source/assets/js/something_else/a.js new file mode 100644 index 0000000..a2f899a --- /dev/null +++ b/tests/assets/build_test_41/src/source/assets/js/something_else/a.js @@ -0,0 +1 @@ +var a = 42; \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/assets/js/something_else/b.js b/tests/assets/build_test_41/src/source/assets/js/something_else/b.js new file mode 100644 index 0000000..430db3c --- /dev/null +++ b/tests/assets/build_test_41/src/source/assets/js/something_else/b.js @@ -0,0 +1 @@ +var b = 42; \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/ignored_folder/should_be_ignored.md b/tests/assets/build_test_41/src/source/ignored_folder/should_be_ignored.md new file mode 100644 index 0000000..8318c86 --- /dev/null +++ b/tests/assets/build_test_41/src/source/ignored_folder/should_be_ignored.md @@ -0,0 +1 @@ +Test \ No newline at end of file diff --git a/tests/assets/build_test_41/src/source/index.php b/tests/assets/build_test_41/src/source/index.php new file mode 100644 index 0000000..793006c --- /dev/null +++ b/tests/assets/build_test_41/src/source/index.php @@ -0,0 +1 @@ +

\ No newline at end of file