├── .github
├── FUNDING.yml
├── workflows
│ ├── build.yml
│ ├── deploy.yml
│ └── update.yml
└── dependabot.yml
├── tests
├── test-sample.php
└── bootstrap.php
├── phpunit.xml.dist
├── .editorconfig
├── assets
└── main.js
├── package.json
├── vite.config.js
├── .distignore
├── readme.txt
├── Gruntfile.js
├── turbo-drive.php
├── .travis.yml
├── .phpcs.xml.dist
├── .gitignore
├── includes
└── class-turbo-drive-settings.php
└── bin
└── install-wp-tests.sh
/.github/FUNDING.yml:
--------------------------------------------------------------------------------
1 | github: [Romaixn]
2 |
--------------------------------------------------------------------------------
/.github/workflows/build.yml:
--------------------------------------------------------------------------------
1 | name: Build
2 | on:
3 | push:
4 |
5 | jobs:
6 | tag:
7 | name: Build
8 | runs-on: ubuntu-latest
9 | steps:
10 | - uses: actions/checkout@master
11 | - name: Build
12 | run: |
13 | npm install
14 | npm run build
15 |
--------------------------------------------------------------------------------
/tests/test-sample.php:
--------------------------------------------------------------------------------
1 | assertTrue(true);
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/.github/dependabot.yml:
--------------------------------------------------------------------------------
1 | version: 2
2 | updates:
3 | - package-ecosystem: 'npm' # See documentation for possible values
4 | directory: '/' # Location of package manifests
5 | open-pull-requests-limit: 25
6 | schedule:
7 | interval: 'daily'
8 | - package-ecosystem: 'github-actions' # See documentation for possible values
9 | directory: '/' # Location of package manifests
10 | open-pull-requests-limit: 25
11 | schedule:
12 | interval: 'daily'
13 |
--------------------------------------------------------------------------------
/phpunit.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
10 |
11 |
12 | ./tests/
13 | ./tests/test-sample.php
14 |
15 |
16 |
17 |
--------------------------------------------------------------------------------
/.editorconfig:
--------------------------------------------------------------------------------
1 | # This file is for unifying the coding style for different editors and IDEs
2 | # editorconfig.org
3 |
4 | # WordPress Coding Standards
5 | # https://make.wordpress.org/core/handbook/coding-standards/
6 |
7 | root = true
8 |
9 | [*]
10 | charset = utf-8
11 | end_of_line = lf
12 | insert_final_newline = true
13 | trim_trailing_whitespace = true
14 | indent_style = tab
15 | indent_size = 4
16 |
17 | [{.jshintrc,*.json,*.yml}]
18 | indent_style = space
19 | indent_size = 2
20 |
21 | [{*.txt,wp-config-sample.php}]
22 | end_of_line = crlf
23 |
--------------------------------------------------------------------------------
/assets/main.js:
--------------------------------------------------------------------------------
1 | import * as Turbo from "@hotwired/turbo"
2 |
3 | document.addEventListener("turbo:load", () => {
4 | if (window.turboDriveOptions && window.turboDriveOptions.progressBarColor) {
5 | let style = document.getElementById("turbo-progress-style");
6 | if (!style) {
7 | style = document.createElement("style");
8 | style.id = "turbo-progress-style";
9 | document.head.appendChild(style);
10 | }
11 |
12 | style.textContent = `.turbo-progress-bar { background-color: ${window.turboDriveOptions.progressBarColor} !important; }`;
13 | }
14 | });
15 |
--------------------------------------------------------------------------------
/.github/workflows/deploy.yml:
--------------------------------------------------------------------------------
1 | name: Deploy to WordPress.org
2 | on:
3 | push:
4 | tags:
5 | - "*"
6 | jobs:
7 | tag:
8 | name: Deploy to WordPress.org
9 | runs-on: ubuntu-latest
10 | steps:
11 | - uses: actions/checkout@master
12 | - name: Build
13 | run: |
14 | npm install
15 | npm run build
16 | - name: WordPress Plugin Deploy
17 | uses: 10up/action-wordpress-plugin-deploy@stable
18 | env:
19 | SLUG: 'td-turbo-drive'
20 | SVN_PASSWORD: ${{ secrets.SVN_PASSWORD }}
21 | SVN_USERNAME: ${{ secrets.SVN_USERNAME }}
22 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "turbo-drive",
3 | "version": "0.3.2",
4 | "main": "Gruntfile.js",
5 | "author": "Romain Herault",
6 | "scripts": {
7 | "dev": "wp-env start",
8 | "wp-env": "wp-env",
9 | "start": "grunt default",
10 | "readme": "grunt readme",
11 | "i18n": "grunt i18n",
12 | "build": "vite build"
13 | },
14 | "devDependencies": {
15 | "@wordpress/env": "^10.36.0",
16 | "grunt": "^1.6.1",
17 | "grunt-wp-i18n": "^1.0.4",
18 | "grunt-wp-readme-to-markdown": "^2.1.0",
19 | "vite": "^7.3.0"
20 | },
21 | "dependencies": {
22 | "@hotwired/turbo": "^8.0.20"
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/vite.config.js:
--------------------------------------------------------------------------------
1 | import { defineConfig } from 'vite'
2 | const { resolve } = require('path')
3 |
4 | // https://vitejs.dev/config
5 | export default defineConfig({
6 | build: {
7 | // output dir for production build
8 | outDir: resolve(__dirname, './dist'),
9 | emptyOutDir: true,
10 |
11 | // esbuild target
12 | target: 'es2018',
13 |
14 | // our entry
15 | rollupOptions: {
16 | input: {
17 | main: resolve( __dirname + '/assets/main.js')
18 | },
19 |
20 | output: {
21 | entryFileNames: `[name].js`,
22 | chunkFileNames: `[name].js`,
23 | assetFileNames: `[name].[ext]`
24 | }
25 | },
26 |
27 | // minifying switch
28 | minify: true,
29 | write: true
30 | },
31 | })
32 |
--------------------------------------------------------------------------------
/.distignore:
--------------------------------------------------------------------------------
1 | # A set of files you probably don't want in your WordPress.org distribution
2 | .babelrc
3 | .deployignore
4 | .distignore
5 | .editorconfig
6 | .eslintignore
7 | .eslintrc
8 | .git
9 | .gitignore
10 | .github
11 | .gitlab-ci.yml
12 | .travis.yml
13 | .DS_Store
14 | .*~
15 | Thumbs.db
16 | behat.yml
17 | bitbucket-pipelines.yml
18 | bin
19 | .circleci/config.yml
20 | composer.json
21 | composer.lock
22 | dependencies.yml
23 | Gruntfile.js
24 | package.json
25 | package-lock.json
26 | phpunit.xml
27 | phpunit.xml.dist
28 | multisite.xml
29 | multisite.xml.dist
30 | .phpcs.xml
31 | phpcs.xml
32 | .phpcs.xml.dist
33 | phpcs.xml.dist
34 | README.md
35 | webpack.config.js
36 | wp-cli.local.yml
37 | yarn.lock
38 | tests
39 | vendor
40 | node_modules
41 | *.sql
42 | *.tar.gz
43 | *.zip
44 | assets
45 | Dockerfile
46 | docker-compose.yml
47 | vite.config.js
48 |
--------------------------------------------------------------------------------
/readme.txt:
--------------------------------------------------------------------------------
1 | === Turbo Drive ===
2 | Contributors: rherault
3 | Donate link: https://github.com/sponsors/Romaixn
4 | Tags: turbo, swup, no refresh, optimize, spa
5 | Requires at least: 5.7.0
6 | Tested up to: 6.3.2
7 | Requires PHP: 7.4
8 | Stable tag: 0.3.2
9 | License: GPLv2 or later
10 | License URI: https://www.gnu.org/licenses/gpl-2.0.html
11 |
12 | Integrate Hotwired Turbo with WordPress, no page reload, no jQuery.
13 |
14 | == Description ==
15 |
16 | Integrate Hotwired Turbo with WordPress, no page reload, no jQuery.
17 |
18 | == Installation ==
19 |
20 | 1. Activate the plugin through the 'Plugins' menu in WordPress
21 |
22 | == Changelog ==
23 |
24 | = 0.3.2 =
25 | * Upgrading dependencies
26 |
27 | = 0.3.0 =
28 | * Change plugin name
29 |
30 | = 0.2.0 =
31 | * Add attribute to all assets to reload page if it change
32 |
33 | = 0.1.0 =
34 | * First release, little buggy
35 |
--------------------------------------------------------------------------------
/tests/bootstrap.php:
--------------------------------------------------------------------------------
1 | get_options();
26 | wp_localize_script('turbo-drive', 'turboDriveOptions', array(
27 | 'progressBarColor' => $options['progress_bar_color'],
28 | ));
29 | }, 10);
30 |
31 | add_action('admin_head', function () {
32 | echo '';
33 | }, 10);
34 |
35 | add_filter('script_loader_tag', function ($script_tag) {
36 | if (is_admin()) {
37 | return $script_tag;
38 | }
39 | global $current_screen;
40 | if ($current_screen instanceof \WP_Screen && $current_screen->is_block_editor()) {
41 | return $script_tag;
42 | }
43 |
44 | return str_replace(' src', ' data-turbo-track="reload" src', $script_tag);
45 | }, 10, 1);
46 |
47 | add_filter('style_loader_tag', function ($style_tag) {
48 | if (is_admin()) {
49 | return $style_tag;
50 | }
51 | global $current_screen;
52 | if ($current_screen instanceof \WP_Screen && $current_screen->is_block_editor()) {
53 | return $style_tag;
54 | }
55 |
56 | return str_replace(' href', ' data-turbo-track="reload" href', $style_tag);
57 | }, 10, 1);
58 |
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | sudo: false
2 | dist: trusty
3 |
4 | language: php
5 |
6 | notifications:
7 | email:
8 | on_success: never
9 | on_failure: change
10 |
11 | branches:
12 | only:
13 | - master
14 |
15 | cache:
16 | directories:
17 | - $HOME/.composer/cache
18 |
19 | matrix:
20 | include:
21 | - php: 7.4
22 | env: WP_VERSION=latest
23 | - php: 7.3
24 | env: WP_VERSION=latest
25 | - php: 7.2
26 | env: WP_VERSION=latest
27 | - php: 7.1
28 | env: WP_VERSION=latest
29 | - php: 7.0
30 | env: WP_VERSION=latest
31 | - php: 5.6
32 | env: WP_VERSION=4.5
33 | - php: 5.6
34 | env: WP_VERSION=latest
35 | - php: 5.6
36 | env: WP_VERSION=trunk
37 | - php: 5.6
38 | env: WP_TRAVISCI=phpcs
39 |
40 | before_script:
41 | - export PATH="$HOME/.composer/vendor/bin:$PATH"
42 | - |
43 | if [ -f ~/.phpenv/versions/$(phpenv version-name)/etc/conf.d/xdebug.ini ]; then
44 | phpenv config-rm xdebug.ini
45 | else
46 | echo "xdebug.ini does not exist"
47 | fi
48 | - |
49 | if [[ ! -z "$WP_VERSION" ]] ; then
50 | bash bin/install-wp-tests.sh wordpress_test root '' localhost $WP_VERSION
51 | composer global require "phpunit/phpunit=4.8.*|5.7.*"
52 | fi
53 | - |
54 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
55 | composer global require wp-coding-standards/wpcs
56 | composer global require phpcompatibility/php-compatibility
57 | composer global require phpcompatibility/phpcompatibility-paragonie
58 | composer global require phpcompatibility/phpcompatibility-wp
59 | phpcs --config-set installed_paths $HOME/.composer/vendor/wp-coding-standards/wpcs,$HOME/.composer/vendor/phpcompatibility/php-compatibility,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-paragonie,$HOME/.composer/vendor/phpcompatibility/phpcompatibility-wp
60 | fi
61 |
62 | script:
63 | - |
64 | if [[ ! -z "$WP_VERSION" ]] ; then
65 | phpunit
66 | WP_MULTISITE=1 phpunit
67 | fi
68 | - |
69 | if [[ "$WP_TRAVISCI" == "phpcs" ]] ; then
70 | phpcs
71 | fi
72 |
--------------------------------------------------------------------------------
/.phpcs.xml.dist:
--------------------------------------------------------------------------------
1 |
2 |
3 | Generally-applicable sniffs for WordPress plugins.
4 |
5 |
6 | .
7 | /vendor/
8 | /node_modules/
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
37 |
38 |
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/.github/workflows/update.yml:
--------------------------------------------------------------------------------
1 | name: Dependabot reviewer
2 |
3 | on: pull_request_target
4 |
5 | permissions:
6 | pull-requests: write
7 | contents: write
8 |
9 | jobs:
10 | review-dependabot-pr:
11 | runs-on: ubuntu-latest
12 | if: ${{ github.event.pull_request.user.login == 'dependabot[bot]' }}
13 | steps:
14 | - name: Dependabot metadata
15 | id: dependabot-metadata
16 | uses: dependabot/fetch-metadata@v2.4.0
17 | - name: Enable auto-merge for Dependabot PRs
18 | run: gh pr merge --auto --merge "$PR_URL"
19 | env:
20 | PR_URL: ${{github.event.pull_request.html_url}}
21 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
22 | - name: Approve patch and minor updates
23 | if: ${{steps.dependabot-metadata.outputs.update-type == 'version-update:semver-patch' || steps.dependabot-metadata.outputs.update-type == 'version-update:semver-minor'}}
24 | run: gh pr review $PR_URL --approve -b "I'm **approving** this pull request because **it includes a patch or minor update**"
25 | env:
26 | PR_URL: ${{github.event.pull_request.html_url}}
27 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
28 | - name: Approve major updates of development dependencies
29 | if: ${{steps.dependabot-metadata.outputs.update-type == 'version-update:semver-major' && steps.dependabot-metadata.outputs.dependency-type == 'direct:development'}}
30 | run: gh pr review $PR_URL --approve -b "I'm **approving** this pull request because **it includes a major update of a dependency used only in development**"
31 | env:
32 | PR_URL: ${{github.event.pull_request.html_url}}
33 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
34 | - name: Comment on major updates of non-development dependencies
35 | if: ${{steps.dependabot-metadata.outputs.update-type == 'version-update:semver-major' && steps.dependabot-metadata.outputs.dependency-type == 'direct:production'}}
36 | run: |
37 | gh pr comment $PR_URL --body "I'm **not approving** this PR because **it includes a major update of a dependency used in production**"
38 | gh pr edit $PR_URL --add-label "requires-manual-qa"
39 | env:
40 | PR_URL: ${{github.event.pull_request.html_url}}
41 | GITHUB_TOKEN: ${{secrets.GITHUB_TOKEN}}
42 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 | phpcs.xml
3 | phpunit.xml
4 | Thumbs.db
5 | wp-cli.local.yml
6 | node_modules/
7 | *.sql
8 | *.tar.gz
9 | *.zip
10 | dist/
11 |
12 | # User-specific stuff
13 | .idea/**/workspace.xml
14 | .idea/**/tasks.xml
15 | .idea/**/usage.statistics.xml
16 | .idea/**/dictionaries
17 | .idea/**/shelf
18 |
19 | # AWS User-specific
20 | .idea/**/aws.xml
21 |
22 | # Generated files
23 | .idea/**/contentModel.xml
24 |
25 | # Sensitive or high-churn files
26 | .idea/**/dataSources/
27 | .idea/**/dataSources.ids
28 | .idea/**/dataSources.local.xml
29 | .idea/**/sqlDataSources.xml
30 | .idea/**/dynamic.xml
31 | .idea/**/uiDesigner.xml
32 | .idea/**/dbnavigator.xml
33 |
34 | # Gradle
35 | .idea/**/gradle.xml
36 | .idea/**/libraries
37 |
38 | # Gradle and Maven with auto-import
39 | # When using Gradle or Maven with auto-import, you should exclude module files,
40 | # since they will be recreated, and may cause churn. Uncomment if using
41 | # auto-import.
42 | # .idea/artifacts
43 | # .idea/compiler.xml
44 | # .idea/jarRepositories.xml
45 | # .idea/modules.xml
46 | # .idea/*.iml
47 | # .idea/modules
48 | # *.iml
49 | # *.ipr
50 |
51 | # CMake
52 | cmake-build-*/
53 |
54 | # Mongo Explorer plugin
55 | .idea/**/mongoSettings.xml
56 |
57 | # File-based project format
58 | *.iws
59 |
60 | # IntelliJ
61 | out/
62 |
63 | # mpeltonen/sbt-idea plugin
64 | .idea_modules/
65 |
66 | # JIRA plugin
67 | atlassian-ide-plugin.xml
68 |
69 | # Cursive Clojure plugin
70 | .idea/replstate.xml
71 |
72 | # SonarLint plugin
73 | .idea/sonarlint/
74 |
75 | # Crashlytics plugin (for Android Studio and IntelliJ)
76 | com_crashlytics_export_strings.xml
77 | crashlytics.properties
78 | crashlytics-build.properties
79 | fabric.properties
80 |
81 | # Editor-based Rest Client
82 | .idea/httpRequests
83 |
84 | # Android studio 3.1+ serialized cache file
85 | .idea/caches/build_file_checksums.ser
86 |
87 | ### PhpStorm Patch ###
88 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721
89 |
90 | # *.iml
91 | # modules.xml
92 | # .idea/misc.xml
93 | # *.ipr
94 |
95 | # Sonarlint plugin
96 | # https://plugins.jetbrains.com/plugin/7973-sonarlint
97 | .idea/**/sonarlint/
98 |
99 | # SonarQube Plugin
100 | # https://plugins.jetbrains.com/plugin/7238-sonarqube-community-plugin
101 | .idea/**/sonarIssues.xml
102 |
103 | # Markdown Navigator plugin
104 | # https://plugins.jetbrains.com/plugin/7896-markdown-navigator-enhanced
105 | .idea/**/markdown-navigator.xml
106 | .idea/**/markdown-navigator-enh.xml
107 | .idea/**/markdown-navigator/
108 |
109 | # Cache file creation bug
110 | # See https://youtrack.jetbrains.com/issue/JBR-2257
111 | .idea/$CACHE_FILE$
112 |
113 | # CodeStream plugin
114 | # https://plugins.jetbrains.com/plugin/12206-codestream
115 | .idea/codestream.xml
116 |
117 | # Azure Toolkit for IntelliJ plugin
118 | # https://plugins.jetbrains.com/plugin/8053-azure-toolkit-for-intellij
119 | .idea/**/azureSettings.xml
120 |
--------------------------------------------------------------------------------
/includes/class-turbo-drive-settings.php:
--------------------------------------------------------------------------------
1 | '#29d',
38 | );
39 |
40 | /**
41 | * Constructor
42 | */
43 | private function __construct()
44 | {
45 | add_action('admin_menu', array( $this, 'add_settings_page' ));
46 | add_action('admin_init', array( $this, 'register_settings' ));
47 | }
48 |
49 | /**
50 | * Get the unique instance of the class
51 | *
52 | * @return Turbo_Drive_Settings
53 | */
54 | public static function get_instance()
55 | {
56 | if (self::$instance === null) {
57 | self::$instance = new self();
58 | }
59 |
60 | return self::$instance;
61 | }
62 |
63 | /**
64 | * Add settings page to admin menu
65 | */
66 | public function add_settings_page()
67 | {
68 | add_options_page(
69 | __('Turbo Drive Settings', 'turbo-drive'),
70 | __('Turbo Drive', 'turbo-drive'),
71 | 'manage_options',
72 | 'turbo-drive-settings',
73 | array( $this, 'render_settings_page' )
74 | );
75 | }
76 |
77 | /**
78 | * Register settings
79 | */
80 | public function register_settings()
81 | {
82 | register_setting(
83 | 'turbo_drive_settings_group',
84 | $this->option_name,
85 | array( $this, 'sanitize_options' )
86 | );
87 |
88 | add_settings_section(
89 | 'turbo_drive_general_section',
90 | __('General Settings', 'turbo-drive'),
91 | array( $this, 'render_general_section' ),
92 | 'turbo-drive-settings'
93 | );
94 |
95 | add_settings_field(
96 | 'progress_bar_color',
97 | __('Progress Bar Color', 'turbo-drive'),
98 | array( $this, 'render_progress_bar_color_field' ),
99 | 'turbo-drive-settings',
100 | 'turbo_drive_general_section'
101 | );
102 | }
103 |
104 | /**
105 | * Sanitize options before saving
106 | *
107 | * @param array $input Options to sanitize.
108 | * @return array Sanitized options.
109 | */
110 | public function sanitize_options($input)
111 | {
112 | $sanitized_input = array();
113 |
114 | // Sanitize progress bar color
115 | if (isset($input['progress_bar_color'])) {
116 | $sanitized_input['progress_bar_color'] = sanitize_hex_color($input['progress_bar_color']);
117 | if (empty($sanitized_input['progress_bar_color'])) {
118 | $sanitized_input['progress_bar_color'] = $this->default_options['progress_bar_color'];
119 | }
120 | }
121 |
122 | return $sanitized_input;
123 | }
124 |
125 | /**
126 | * Display general section description
127 | */
128 | public function render_general_section()
129 | {
130 | echo '
' . esc_html__('Configure Turbo Drive options for your site.', 'turbo-drive') . '
';
131 | }
132 |
133 | /**
134 | * Display progress bar color field
135 | */
136 | public function render_progress_bar_color_field()
137 | {
138 | $options = $this->get_options();
139 | $color = isset($options['progress_bar_color']) ? $options['progress_bar_color'] : $this->default_options['progress_bar_color'];
140 |
141 | echo '';
142 | echo '' . esc_html__('Choose the color of the progress bar that appears during page loads.', 'turbo-drive') . '
';
143 | }
144 |
145 | /**
146 | * Display settings page
147 | */
148 | public function render_settings_page()
149 | {
150 | if (! current_user_can('manage_options')) {
151 | return;
152 | }
153 |
154 | ?>
155 |
156 |
157 |
164 |
165 | option_name, $this->default_options);
176 | return wp_parse_args($options, $this->default_options);
177 | }
178 |
179 | /**
180 | * Get value of a specific option
181 | *
182 | * @param string $key Option key.
183 | * @param mixed $default Default value.
184 | * @return mixed
185 | */
186 | public function get_option($key, $default = null)
187 | {
188 | $options = $this->get_options();
189 |
190 | if (isset($options[$key])) {
191 | return $options[$key];
192 | }
193 |
194 | return $default !== null ? $default : $this->default_options[$key] ?? null;
195 | }
196 | }
197 |
--------------------------------------------------------------------------------
/bin/install-wp-tests.sh:
--------------------------------------------------------------------------------
1 | #!/usr/bin/env bash
2 |
3 | if [ $# -lt 3 ]; then
4 | echo "usage: $0 [db-host] [wp-version] [skip-database-creation]"
5 | exit 1
6 | fi
7 |
8 | DB_NAME=$1
9 | DB_USER=$2
10 | DB_PASS=$3
11 | DB_HOST=${4-localhost}
12 | WP_VERSION=${5-latest}
13 | SKIP_DB_CREATE=${6-false}
14 |
15 | TMPDIR=${TMPDIR-/tmp}
16 | TMPDIR=$(echo $TMPDIR | sed -e "s/\/$//")
17 | WP_TESTS_DIR=${WP_TESTS_DIR-$TMPDIR/wordpress-tests-lib}
18 | WP_CORE_DIR=${WP_CORE_DIR-$TMPDIR/wordpress}
19 |
20 | download() {
21 | if [ `which curl` ]; then
22 | curl -s "$1" > "$2";
23 | elif [ `which wget` ]; then
24 | wget -nv -O "$2" "$1"
25 | fi
26 | }
27 |
28 | if [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+\-(beta|RC)[0-9]+$ ]]; then
29 | WP_BRANCH=${WP_VERSION%\-*}
30 | WP_TESTS_TAG="branches/$WP_BRANCH"
31 |
32 | elif [[ $WP_VERSION =~ ^[0-9]+\.[0-9]+$ ]]; then
33 | WP_TESTS_TAG="branches/$WP_VERSION"
34 | elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0-9]+ ]]; then
35 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
36 | # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
37 | WP_TESTS_TAG="tags/${WP_VERSION%??}"
38 | else
39 | WP_TESTS_TAG="tags/$WP_VERSION"
40 | fi
41 | elif [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
42 | WP_TESTS_TAG="trunk"
43 | else
44 | # http serves a single offer, whereas https serves multiple. we only want one
45 | download http://api.wordpress.org/core/version-check/1.7/ /tmp/wp-latest.json
46 | grep '[0-9]+\.[0-9]+(\.[0-9]+)?' /tmp/wp-latest.json
47 | LATEST_VERSION=$(grep -o '"version":"[^"]*' /tmp/wp-latest.json | sed 's/"version":"//')
48 | if [[ -z "$LATEST_VERSION" ]]; then
49 | echo "Latest WordPress version could not be found"
50 | exit 1
51 | fi
52 | WP_TESTS_TAG="tags/$LATEST_VERSION"
53 | fi
54 | set -ex
55 |
56 | install_wp() {
57 |
58 | if [ -d $WP_CORE_DIR ]; then
59 | return;
60 | fi
61 |
62 | mkdir -p $WP_CORE_DIR
63 |
64 | if [[ $WP_VERSION == 'nightly' || $WP_VERSION == 'trunk' ]]; then
65 | mkdir -p $TMPDIR/wordpress-trunk
66 | rm -rf $TMPDIR/wordpress-trunk/*
67 | svn export --quiet https://core.svn.wordpress.org/trunk $TMPDIR/wordpress-trunk/wordpress
68 | mv $TMPDIR/wordpress-trunk/wordpress/* $WP_CORE_DIR
69 | else
70 | if [ $WP_VERSION == 'latest' ]; then
71 | local ARCHIVE_NAME='latest'
72 | elif [[ $WP_VERSION =~ [0-9]+\.[0-9]+ ]]; then
73 | # https serves multiple offers, whereas http serves single.
74 | download https://api.wordpress.org/core/version-check/1.7/ $TMPDIR/wp-latest.json
75 | if [[ $WP_VERSION =~ [0-9]+\.[0-9]+\.[0] ]]; then
76 | # version x.x.0 means the first release of the major version, so strip off the .0 and download version x.x
77 | LATEST_VERSION=${WP_VERSION%??}
78 | else
79 | # otherwise, scan the releases and get the most up to date minor version of the major release
80 | local VERSION_ESCAPED=`echo $WP_VERSION | sed 's/\./\\\\./g'`
81 | LATEST_VERSION=$(grep -o '"version":"'$VERSION_ESCAPED'[^"]*' $TMPDIR/wp-latest.json | sed 's/"version":"//' | head -1)
82 | fi
83 | if [[ -z "$LATEST_VERSION" ]]; then
84 | local ARCHIVE_NAME="wordpress-$WP_VERSION"
85 | else
86 | local ARCHIVE_NAME="wordpress-$LATEST_VERSION"
87 | fi
88 | else
89 | local ARCHIVE_NAME="wordpress-$WP_VERSION"
90 | fi
91 | download https://wordpress.org/${ARCHIVE_NAME}.tar.gz $TMPDIR/wordpress.tar.gz
92 | tar --strip-components=1 -zxmf $TMPDIR/wordpress.tar.gz -C $WP_CORE_DIR
93 | fi
94 |
95 | download https://raw.github.com/markoheijnen/wp-mysqli/master/db.php $WP_CORE_DIR/wp-content/db.php
96 | }
97 |
98 | install_test_suite() {
99 | # portable in-place argument for both GNU sed and Mac OSX sed
100 | if [[ $(uname -s) == 'Darwin' ]]; then
101 | local ioption='-i.bak'
102 | else
103 | local ioption='-i'
104 | fi
105 |
106 | # set up testing suite if it doesn't yet exist
107 | if [ ! -d $WP_TESTS_DIR ]; then
108 | # set up testing suite
109 | mkdir -p $WP_TESTS_DIR
110 | rm -rf $WP_TESTS_DIR/{includes,data}
111 | svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/includes/ $WP_TESTS_DIR/includes
112 | svn export --quiet --ignore-externals https://develop.svn.wordpress.org/${WP_TESTS_TAG}/tests/phpunit/data/ $WP_TESTS_DIR/data
113 | fi
114 |
115 | if [ ! -f wp-tests-config.php ]; then
116 | download https://develop.svn.wordpress.org/${WP_TESTS_TAG}/wp-tests-config-sample.php "$WP_TESTS_DIR"/wp-tests-config.php
117 | # remove all forward slashes in the end
118 | WP_CORE_DIR=$(echo $WP_CORE_DIR | sed "s:/\+$::")
119 | sed $ioption "s:dirname( __FILE__ ) . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
120 | sed $ioption "s:__DIR__ . '/src/':'$WP_CORE_DIR/':" "$WP_TESTS_DIR"/wp-tests-config.php
121 | sed $ioption "s/youremptytestdbnamehere/$DB_NAME/" "$WP_TESTS_DIR"/wp-tests-config.php
122 | sed $ioption "s/yourusernamehere/$DB_USER/" "$WP_TESTS_DIR"/wp-tests-config.php
123 | sed $ioption "s/yourpasswordhere/$DB_PASS/" "$WP_TESTS_DIR"/wp-tests-config.php
124 | sed $ioption "s|localhost|${DB_HOST}|" "$WP_TESTS_DIR"/wp-tests-config.php
125 | fi
126 |
127 | }
128 |
129 | recreate_db() {
130 | shopt -s nocasematch
131 | if [[ $1 =~ ^(y|yes)$ ]]
132 | then
133 | mysqladmin drop $DB_NAME -f --user="$DB_USER" --password="$DB_PASS"$EXTRA
134 | create_db
135 | echo "Recreated the database ($DB_NAME)."
136 | else
137 | echo "Leaving the existing database ($DB_NAME) in place."
138 | fi
139 | shopt -u nocasematch
140 | }
141 |
142 | create_db() {
143 | mysqladmin create $DB_NAME --user="$DB_USER" --password="$DB_PASS"$EXTRA
144 | }
145 |
146 | install_db() {
147 |
148 | if [ ${SKIP_DB_CREATE} = "true" ]; then
149 | return 0
150 | fi
151 |
152 | # parse DB_HOST for port or socket references
153 | local PARTS=(${DB_HOST//\:/ })
154 | local DB_HOSTNAME=${PARTS[0]};
155 | local DB_SOCK_OR_PORT=${PARTS[1]};
156 | local EXTRA=""
157 |
158 | if ! [ -z $DB_HOSTNAME ] ; then
159 | if [ $(echo $DB_SOCK_OR_PORT | grep -e '^[0-9]\{1,\}$') ]; then
160 | EXTRA=" --host=$DB_HOSTNAME --port=$DB_SOCK_OR_PORT --protocol=tcp"
161 | elif ! [ -z $DB_SOCK_OR_PORT ] ; then
162 | EXTRA=" --socket=$DB_SOCK_OR_PORT"
163 | elif ! [ -z $DB_HOSTNAME ] ; then
164 | EXTRA=" --host=$DB_HOSTNAME --protocol=tcp"
165 | fi
166 | fi
167 |
168 | # create database
169 | if [ $(mysql --user="$DB_USER" --password="$DB_PASS"$EXTRA --execute='show databases;' | grep ^$DB_NAME$) ]
170 | then
171 | echo "Reinstalling will delete the existing test database ($DB_NAME)"
172 | read -p 'Are you sure you want to proceed? [y/N]: ' DELETE_EXISTING_DB
173 | recreate_db $DELETE_EXISTING_DB
174 | else
175 | create_db
176 | fi
177 | }
178 |
179 | install_wp
180 | install_test_suite
181 | install_db
182 |
--------------------------------------------------------------------------------