diff --git a/CHANGELOG.md b/CHANGELOG.md index 3ab5e26a..3e05bb19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,6 +21,9 @@ - [#837](https://github.com/leonstafford/wp2static/pull/837): Require PHP 7.4 or later; bump dependencies @leonstafford - [#811](https://github.com/leonstafford/wp2static/issues/811): Optimize FilesHelper::getListOfLocalFilesByDir @bookwyrm - [#805](https://github.com/leonstafford/wp2static/issues/805): Fix warning on cache page when there are no deployment namespaces @john-shaffer + - [#840](https://github.com/leonstafford/wp2static/pull/840): Add preliminary support for [Bedrock](https://roots.io/bedrock/) by using home URL instead of site URL in several places. This is a potentially breaking change for anyone with `WP_HOME` differing from `WP_SITEURL`. @oriolarcas, @john-shaffer + - Use `wp2static_set_wordpress_home_url` filter in post-processing instead of `wp2static_set_wordpress_site_url`. + - Add integration tests for Bedrock. ## WP2Static 7.1.7 (2021-09-04) diff --git a/integration-tests/clj/wp2static_test/main.clj b/integration-tests/clj/wp2static_test/main.clj index e21b8e1c..544c24d6 100644 --- a/integration-tests/clj/wp2static_test/main.clj +++ b/integration-tests/clj/wp2static_test/main.clj @@ -92,9 +92,18 @@ (str "bedrock.sh exited with code " code) {:code code})))) bedrock) - :name "Bedrock Initializer" + :name "Bedrock" :join? true - :open-f (fn [_] (popen ["bash" "bedrock.sh"]))})) + :open-f (fn [_] (popen ["bash" "bedrock.sh"])) + + :features {:sitemaps? false} + :paths {:cli "bedrock/web/wp" + :doc-root "bedrock/web" + :plugins "bedrock/web/app/plugins" + :site "/wp/" + :uploads "bedrock/web/app/uploads" + :wp-content "bedrock/web/wp/wp-content"} + :urls {:home "http://localhost:7001"}})) (defn wordpress [] (shell-process @@ -106,9 +115,18 @@ (str "wordpress.sh exited with code " code) {:code code})))) wordpress) - :name "WordPress Initializer" + :name "WordPress" :join? true - :open-f (fn [_] (popen ["bash" "wordpress.sh"]))})) + :open-f (fn [_] (popen ["bash" "wordpress.sh"])) + + :features {:sitemaps? true} + :paths {:cli "wordpress" + :doc-root "wordpress" + :plugins "wordpress/wp-content/plugins" + :site "/" + :uploads "wordpress/wp-content/uploads" + :wp-content "wordpress/wp-content"} + :urls {:home "http://localhost:7000"}})) (defn system-map [] (component/system-map @@ -117,6 +135,7 @@ :nginx (component/using (nginx) [:wordpress]) :php-fpm (component/using (php-fpm) [:mariadb]) :wordpress (component/using (wordpress) [:mariadb :php-fpm]) + :wordpresses (component/using {} [:bedrock :wordpress]) :wp2static (component/using (wp2static) [:bedrock :wordpress]))) (defonce system (atom nil)) diff --git a/integration-tests/clj/wp2static_test/test.clj b/integration-tests/clj/wp2static_test/test.clj index 6ff44a86..6287f9f8 100644 --- a/integration-tests/clj/wp2static_test/test.clj +++ b/integration-tests/clj/wp2static_test/test.clj @@ -29,7 +29,7 @@ result)) (defn wp-cli! [opts & args] - (apply sh! opts "wp" (concat args ["--path=wordpress"]))) + (apply sh! opts "wp" (concat args [(str "--path=" (:path opts "wordpress"))]))) (defn test [opts] ;; https://clojureverse.org/t/why-doesnt-my-program-exit/3754/8 @@ -42,3 +42,8 @@ `(let [~name (main/start!)] (core/clean-wp2static-cache!) ~@body)) + +(defmacro testing [[wp string] & body] + `(clojure.test/testing (str "[" (:name ~wp) "] " ~string) + ~@body)) + diff --git a/integration-tests/test/wp2static_test/crawl_test.clj b/integration-tests/test/wp2static_test/crawl_test.clj index a3e6c45a..ea32d16e 100644 --- a/integration-tests/test/wp2static_test/crawl_test.clj +++ b/integration-tests/test/wp2static_test/crawl_test.clj @@ -3,12 +3,17 @@ [clojure.test :refer :all] [wp2static-test.test :as test])) -(defn get-crawled-file [path] - (slurp (str "wordpress/wp-content/uploads/wp2static-crawled-site/" path))) +(defn get-crawled-file [wp path] + (slurp (str (get-in wp [:paths :uploads]) "/wp2static-crawled-site/" path))) (deftest test-crawled-site - (test/with-test-system [_] - (test/wp-cli! {} "wp2static" "detect") - (test/wp-cli! {} "wp2static" "crawl") - (is (str/includes? (get-crawled-file "index.html") "Welcome to WordPress")) - (is (str/includes? (get-crawled-file "robots.txt") "Sitemap: http://localhost:7000/wp-sitemap.xml")))) + (test/with-test-system [system {}] + (doseq [wp (vals (:wordpresses system)) + :let [wp-cli! #(apply test/wp-cli! {:path (get-in wp [:paths :cli])} %&)]] + (test/testing [wp "Crawling works"] + (wp-cli! "wp2static" "detect") + (wp-cli! "wp2static" "crawl") + (is (str/includes? (get-crawled-file wp "index.html") + "Welcome to WordPress")) + (is (str/includes? (get-crawled-file wp "robots.txt") + (str "Disallow: " (get-in wp [:paths :site]) "wp-admin/"))))))) diff --git a/integration-tests/test/wp2static_test/detect_test.clj b/integration-tests/test/wp2static_test/detect_test.clj index c2d8b897..3e532902 100644 --- a/integration-tests/test/wp2static_test/detect_test.clj +++ b/integration-tests/test/wp2static_test/detect_test.clj @@ -3,8 +3,16 @@ [clojure.test :refer :all] [wp2static-test.test :as test])) -(defn get-crawled-file [path] - (slurp (str "wordpress/wp-content/uploads/wp2static-crawled-site/" path))) +(defn get-crawled-file [wp path] + (slurp (str (get-in wp [:paths :uploads]) "/wp2static-crawled-site/" path))) + +(defmacro with-robots-txt [wp s & body] + `(let [path# (str (get-in ~wp [:paths :doc-root]) "/robots.txt")] + (try + (spit path# ~s) + (do ~@body) + (finally + (test/sh! {} "rm" "-f" path#))))) (def robots-sitemap-404 "User-agent: * @@ -20,16 +28,21 @@ Sitemap: http://localhost:7000/does-not-exist.xml") http://localhost:7000/does-not-exist.xml") (deftest test-robots-404 - (testing "robots.txt sitemap URLs that return 404s are ignored" - (test/with-test-system [_] - (try - (spit "wordpress/robots.txt" robots-sitemap-404) - (spit "wordpress/wp-content/sitemap.xml" sitemap-with-404) - (is (zero? (:exit (test/wp-cli! - {:expect-warnings {#".*Got 404 for sitemap.*" 1}} - "wp2static" "detect")))) - (finally - (test/sh! {} "rm" "wordpress/robots.txt" "wordpress/wp-content/sitemap.xml")))))) + (test/with-test-system [system {}] + (doseq [wp (vals (:wordpresses system)) + :let [wp-cli! #(apply test/wp-cli! {:path (get-in wp [:paths :cli])} %&)]] + (when (get-in wp [:features :sitemaps?]) + (test/testing [wp "robots.txt sitemap URLs that return 404s are ignored"] + (with-robots-txt wp robots-sitemap-404 + (let [sitemap-path (str (get-in wp [:paths :wp-content]) "/sitemap.xml")] + (try + (spit sitemap-path sitemap-with-404) + (is (zero? (:exit (test/wp-cli! + {:expect-warnings {#".*Got 404 for sitemap.*" 1} + :path (get-in wp [:paths :cli])} + "wp2static" "detect")))) + (finally + (test/sh! {} "rm" "-f" sitemap-path)))))))))) (def robots-sitemap-slashes "User-agent: * @@ -39,12 +52,13 @@ Allow: /wp-admin/admin-ajax.php Sitemap: http://localhost:7000//wp-sitemap.xml") (deftest test-robots-sitemap-slashes - (testing "robots.txt sitemap URLs with double slashes are processed" - (test/with-test-system [_] - (try - (spit "wordpress/robots.txt" robots-sitemap-slashes) - (test/wp-cli! {} "wp2static" "detect") - (test/wp-cli! {} "wp2static" "crawl") - (is (str/includes? (get-crawled-file "wp-sitemap-posts-post-1.xml") "http://localhost:7000/hello-world/")) - (finally - (test/sh! {} "rm" "wordpress/robots.txt")))))) + (test/with-test-system [system {}] + (doseq [wp (vals (:wordpresses system)) + :let [wp-cli! #(apply test/wp-cli! {:path (get-in wp [:paths :cli])} %&)]] + (when (get-in wp [:features :sitemaps?]) + (test/testing [wp "robots.txt sitemap URLs with double slashes are processed"] + (with-robots-txt wp robots-sitemap-slashes + (wp-cli! "wp2static" "detect") + (wp-cli! "wp2static" "crawl") + (is (str/includes? (get-crawled-file wp "wp-sitemap-posts-post-1.xml") + (str (get-in wp [:paths :home] "hello-world/")))))))))) diff --git a/integration-tests/test/wp2static_test/options_test.clj b/integration-tests/test/wp2static_test/options_test.clj index 4f2094f4..862f8926 100644 --- a/integration-tests/test/wp2static_test/options_test.clj +++ b/integration-tests/test/wp2static_test/options_test.clj @@ -20,19 +20,24 @@ function processQueueImmediately_filter ( $val ) { add_filter( 'wp2static_option_processQueueImmediately', 'processQueueImmediately_filter' );") (deftest test-option-filters - (test/with-test-system [_] - (testing "wp2static_option_* filters work" - (is (= "0" (-> (test/wp-cli! {} "wp2static" "options" "get" "processQueueImmediately") - :out - str/trim))) - (try - (test/sh! {} "mkdir" "wordpress/wp-content/plugins/options-test") - (spit "wordpress/wp-content/plugins/options-test/options-test.php" - options-test-filters) - (test/wp-cli! {} "plugin" "activate" "options-test") - (is (= "1" (-> (test/wp-cli! {} "wp2static" "options" "get" "processQueueImmediately") + (test/with-test-system [system {}] + (doseq [wp (vals (:wordpresses system)) + :let [wp-cli! #(apply test/wp-cli! {:path (get-in wp [:paths :cli])} %&) + plugins-dir (get-in wp [:paths :plugins])]] + (test/testing [wp "wp2static_option_* filters work"] + (is (= "0" (-> (test/wp-cli! {} "wp2static" "options" "get" "processQueueImmediately") :out str/trim))) - (test/wp-cli! {} "plugin" "deactivate" "options-test") - (finally - (test/sh! {} "rm" "-rf" "wordpress/wp-content/plugins/options-test")))))) + (try + (test/sh! {} "mkdir" "options-test" + :dir plugins-dir) + (spit (str plugins-dir "/options-test/options-test.php") + options-test-filters) + (wp-cli! "plugin" "activate" "options-test") + (is (= "1" (-> (wp-cli! "wp2static" "options" "get" "processQueueImmediately") + :out + str/trim))) + (wp-cli! "plugin" "deactivate" "options-test") + (finally + (test/sh! {} "rm" "-rf" "options-test" + :dir plugins-dir))))))) diff --git a/integration-tests/test/wp2static_test/post_process_test.clj b/integration-tests/test/wp2static_test/post_process_test.clj index dd4bd3c0..4a07420d 100644 --- a/integration-tests/test/wp2static_test/post_process_test.clj +++ b/integration-tests/test/wp2static_test/post_process_test.clj @@ -3,16 +3,20 @@ [clojure.test :refer :all] [wp2static-test.test :as test])) -(defn get-processed-file [path] - (slurp (str "wordpress/wp-content/uploads/wp2static-processed-site/" path))) +(defn get-processed-file [wp path] + (slurp (str (get-in wp [:paths :uploads]) "/wp2static-processed-site/" path))) (deftest test-processed-site - (test/with-test-system [_] - (test/wp-cli! {} "wp2static" "detect") - (test/wp-cli! {} "wp2static" "crawl") - (test/wp-cli! {} "wp2static" "post_process") - (let [index (get-processed-file "index.html")] - (is (str/includes? index "Welcome to WordPress")) - (testing "Rewrites work" - (is (str/includes? index "")) - (is (str/includes? (get-processed-file "robots.txt") "Sitemap: https://example.com/wp-sitemap.xml")))))) + (test/with-test-system [system {}] + (doseq [wp (vals (:wordpresses system)) + :let [wp-cli! #(apply test/wp-cli! {:path (get-in wp [:paths :cli])} %&)]] + (test/testing [wp "Post-processing works"] + (wp-cli! "wp2static" "detect") + (wp-cli! "wp2static" "crawl") + (wp-cli! "wp2static" "post_process") + (let [index (get-processed-file wp "index.html")] + (is (str/includes? index "Welcome to WordPress")) + (testing "& URL rewriting works" + (is (str/includes? index "")) + (when (get-in wp [:features :sitemaps?]) + (is (str/includes? (get-processed-file wp "robots.txt") "Sitemap: https://example.com/wp-sitemap.xml"))))))))) diff --git a/src/Crawler.php b/src/Crawler.php index 654553c4..c79ed67e 100755 --- a/src/Crawler.php +++ b/src/Crawler.php @@ -113,7 +113,9 @@ public function crawlSite( string $static_site_path ) : void { $urls = []; foreach ( $crawlable_paths as $root_relative_path ) { - $absolute_uri = new URL( $this->site_path . $root_relative_path ); + $absolute_uri = new URL( + rtrim( SiteInfo::getURL( 'home' ), '/' ) . $root_relative_path + ); $urls[] = [ 'url' => $absolute_uri->get(), 'path' => $root_relative_path, diff --git a/src/DetectSitemapsURLs.php b/src/DetectSitemapsURLs.php index fee16c53..1602b825 100644 --- a/src/DetectSitemapsURLs.php +++ b/src/DetectSitemapsURLs.php @@ -14,7 +14,7 @@ class DetectSitemapsURLs { * @return string[] list of URLs * @throws WP2StaticException */ - public static function detect( string $wp_site_url ) : array { + public static function detect() : array { $sitemaps_urls = []; $parser = new SitemapParser( 'WP2Static.com', @@ -27,14 +27,13 @@ public static function detect( string $wp_site_url ) : array { ] ); - $site_path = rtrim( SiteInfo::getURL( 'site' ), '/' ); - $port_override = apply_filters( 'wp2static_curl_port', null ); - $base_uri = $site_path; + $wp_site_url = SiteInfo::getURL( 'home' ); + $base_uri = rtrim( $wp_site_url, '/' ); if ( $port_override ) { $base_uri = "{$base_uri}:{$port_override}"; diff --git a/src/DetectThemeAssets.php b/src/DetectThemeAssets.php index c6d966ad..7afb7de0 100755 --- a/src/DetectThemeAssets.php +++ b/src/DetectThemeAssets.php @@ -43,11 +43,18 @@ public static function detect( string $theme_type ) : array { $detected_filename = str_replace( - $site_path, - '/', + $template_path, + $template_url, $filename ); + $detected_filename = + str_replace( + get_home_url(), + '/', + $detected_filename + ); + if ( $path_crawlable ) { if ( is_string( $detected_filename ) ) { array_push( diff --git a/src/FilesHelper.php b/src/FilesHelper.php index 5fdd109d..864571b4 100755 --- a/src/FilesHelper.php +++ b/src/FilesHelper.php @@ -39,21 +39,17 @@ public static function deleteDirWithFiles( string $dir ) : void { * Get public URLs for all files in a local directory. * * @param string $dir + * @param string $base_url * @param array $filenames_to_ignore * @param array $file_extensions_to_ignore * @return string[] list of relative, urlencoded URLs */ public static function getListOfLocalFilesByDir( string $dir, + string $base_url, array $filenames_to_ignore, array $file_extensions_to_ignore ) : array { - $site_path = SiteInfo::getPath( 'site' ); - - if ( ! is_string( $site_path ) ) { - return []; - } - $files = []; if ( is_dir( $dir ) ) { @@ -72,7 +68,19 @@ public static function getListOfLocalFilesByDir( ); if ( $path_crawlable ) { - $url = str_replace( $site_path, '/', $filename ); + $url = + str_replace( + $dir, + $base_url, + $filename + ); + + $url = + str_replace( + get_home_url(), + '/', + $url + ); if ( is_string( $url ) ) { $files[] = $url; diff --git a/src/SimpleRewriter.php b/src/SimpleRewriter.php index f2f6337a..9ed73edf 100644 --- a/src/SimpleRewriter.php +++ b/src/SimpleRewriter.php @@ -50,21 +50,21 @@ public static function rewriteFileContents( string $file_contents ) : string CoreOptions::getValue( 'deploymentURL' ) ); - $wordpress_site_url = apply_filters( - 'wp2static_set_wordpress_site_url', - untrailingslashit( SiteInfo::getUrl( 'site' ) ) + $wordpress_home_url = apply_filters( + 'wp2static_set_wordpress_home_url', + untrailingslashit( SiteInfo::getUrl( 'home' ) ) ); - $wordpress_site_url = untrailingslashit( $wordpress_site_url ); + $wordpress_home_url = untrailingslashit( $wordpress_home_url ); $destination_url = untrailingslashit( $destination_url ); $destination_url_rel = URLHelper::getProtocolRelativeURL( $destination_url ); $destination_url_rel_c = addcslashes( $destination_url_rel, '/' ); $replacement_patterns = [ - $wordpress_site_url => $destination_url, - URLHelper::getProtocolRelativeURL( $wordpress_site_url ) => + $wordpress_home_url => $destination_url, + URLHelper::getProtocolRelativeURL( $wordpress_home_url ) => URLHelper::getProtocolRelativeURL( $destination_url ), - addcslashes( URLHelper::getProtocolRelativeURL( $wordpress_site_url ), '/' ) => + addcslashes( URLHelper::getProtocolRelativeURL( $wordpress_home_url ), '/' ) => addcslashes( URLHelper::getProtocolRelativeURL( $destination_url ), '/' ), ]; diff --git a/src/URLDetector.php b/src/URLDetector.php index 495ff920..2405eb77 100755 --- a/src/URLDetector.php +++ b/src/URLDetector.php @@ -82,6 +82,7 @@ public static function detectURLs() : string { $arrays_to_merge[] = FilesHelper::getListOfLocalFilesByDir( SiteInfo::getPath( 'uploads' ), + SiteInfo::getUrl( 'uploads' ), $filenames_to_ignore, $file_extensions_to_ignore ); @@ -90,7 +91,7 @@ public static function detectURLs() : string { $detect_sitemaps = apply_filters( 'wp2static_detect_sitemaps', 1 ); if ( $detect_sitemaps ) { - $arrays_to_merge[] = DetectSitemapsURLs::detect( SiteInfo::getURL( 'site' ) ); + $arrays_to_merge[] = DetectSitemapsURLs::detect(); } $detect_parent_theme = apply_filters( 'wp2static_detect_parent_theme', 1 ); diff --git a/tests/unit/FileHelperTest.php b/tests/unit/FileHelperTest.php index 0a0863e7..dc829a23 100644 --- a/tests/unit/FileHelperTest.php +++ b/tests/unit/FileHelperTest.php @@ -147,6 +147,7 @@ public function testGetListOfLocalFilesByDir() { ]; $actual = FilesHelper::getListOfLocalFilesByDir( $filepath, + '/', $filenames_to_ignore, $file_extensions_to_ignore ); @@ -161,6 +162,7 @@ public function testGetListOfLocalFilesByDir() { ]; $actual = FilesHelper::getListOfLocalFilesByDir( $filepath, + '/', $filenames_to_ignore, $file_extensions_to_ignore ); @@ -173,6 +175,7 @@ public function testGetListOfLocalFilesByDir() { ]; $actual = FilesHelper::getListOfLocalFilesByDir( $filepath, + '/', $filenames_to_ignore, $file_extensions_to_ignore ); diff --git a/tests/unit/SimpleRewriterTest.php b/tests/unit/SimpleRewriterTest.php index 9d5813ad..258b39af 100644 --- a/tests/unit/SimpleRewriterTest.php +++ b/tests/unit/SimpleRewriterTest.php @@ -52,6 +52,10 @@ public function testRewrite() { ->shouldreceive( 'getValue' ) ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'https://bar.com' ); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -115,6 +119,10 @@ public function testRewriteFileContents( $raw_html, $expected ) { ->shouldreceive( 'getValue' ) ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'https://bar.com' ); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -135,6 +143,10 @@ public function testRewriteFileContentsHttpToHttps() { ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'https://bar.com' ) ->getMock(); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'http://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -154,6 +166,10 @@ public function testRewriteFileContentsHttpsToHttp() { ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'http://bar.com' ) ->getMock(); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -195,6 +211,10 @@ public function testRewriteFileContentsHostsToRewrite() { ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'http://bar.com' ) ->getMock(); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -216,6 +236,10 @@ public function testRewriteFileContentsDestinationUrlFilter( $raw_html, $expecte ->shouldreceive( 'getValue' ) ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'https://bar.com' ); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] ) @@ -245,6 +269,10 @@ public function testRewriteFileContentsSiteUrlFilter( $raw_html, $expected ) { ->shouldreceive( 'getValue' ) ->withArgs( [ 'deploymentURL' ] ) ->andReturn( 'https://bar.com' ); + Mockery::mock( 'overload:\WP2Static\SiteInfo' ) + ->shouldreceive( 'getUrl' ) + ->withArgs( [ 'home' ] ) + ->andReturn( 'https://foo.com/' ); Mockery::mock( 'overload:\WP2Static\SiteInfo' ) ->shouldreceive( 'getUrl' ) ->withArgs( [ 'site' ] )