diff --git a/.editorconfig b/.editorconfig index a1eb91244c..dca2b15957 100644 --- a/.editorconfig +++ b/.editorconfig @@ -3,6 +3,7 @@ root = true [*] indent_style = space indent_size = 2 +trim_trailing_whitespace = true [*.{php,js,css,scss}] end_of_line = lf diff --git a/.travis.yml b/.travis.yml index c7daa9d3ef..65447f1685 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,5 +1,10 @@ language: php +addons: + apt: + packages: + - oracle-java8-set-default + notifications: email: on_success: never @@ -10,13 +15,12 @@ php: - "5.5" env: - - WP_VERSION=latest WP_MULTISITE=1 - -services: - - elasticsearch + - WP_VERSION=latest WP_MULTISITE=1 ES_VERSION="5.0.2" + - WP_VERSION=latest WP_MULTISITE=1 ES_VERSION="5.2.2" + - WP_VERSION=latest WP_MULTISITE=1 ES_VERSION="5.5.1" before_install: - - curl -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-5.2.2.deb && sudo dpkg -i --force-confnew elasticsearch-5.2.2.deb && sudo service elasticsearch restart + - curl -O https://artifacts.elastic.co/downloads/elasticsearch/elasticsearch-$ES_VERSION.deb && sudo dpkg -i --force-confnew elasticsearch-$ES_VERSION.deb && sudo service elasticsearch restart before_script: - composer install --dev diff --git a/Gruntfile.js b/Gruntfile.js index ff4c8076fc..44319e8c4c 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -9,20 +9,15 @@ module.exports = function ( grunt ) { uglify : { production : { - options : { - beautify : false, - preserveComments : false, - mangle : { - except : ['jQuery'] - } - }, - files : { 'assets/js/dashboard.min.js' : [ 'assets/js/src/dashboard.js' ], 'assets/js/admin.min.js' : [ 'assets/js/src/admin.js' + ], + 'features/autosuggest/assets/js/autosuggest.min.js': [ + 'features/autosuggest/assets/js/src/autosuggest.js' ] } } @@ -36,11 +31,9 @@ module.exports = function ( grunt ) { map : true }, - files : { - expand : true, - flatten : true, - src : ['assets/css/admin.css'], - dest : 'assets/css' + files: { + 'assets/css/admin.css': ['assets/css/admin.css'], + 'features/autosuggest/assets/css/autosuggest.min.css': ['features/autosuggest/assets/css/autosuggest.css'] } }, @@ -49,13 +42,10 @@ module.exports = function ( grunt ) { target : { - files : [{ - expand : true, - cwd : 'assets/css', - src : ['admin.css'], - dest : 'assets/css', - ext : '.min.css' - }] + files: { + 'assets/css/admin.min.css': ['assets/css/admin.css'], + 'features/autosuggest/assets/css/autosuggest.min.css': ['features/autosuggest/assets/css/autosuggest.css'] + } } @@ -72,7 +62,8 @@ module.exports = function ( grunt ) { }, files : { - 'assets/css/admin.css' : 'assets/css/admin.scss', + 'assets/css/admin.css': 'assets/css/admin.scss', + 'features/autosuggest/assets/css/autosuggest.css': 'features/autosuggest/assets/css/autosuggest.scss' } } @@ -100,7 +91,8 @@ module.exports = function ( grunt ) { scripts : { files : [ - 'assets/js/src/*.js' + 'assets/js/src/*.js', + 'features/autosuggest/assets/js/src/*.js' ], tasks : ['uglify:production'] @@ -108,7 +100,8 @@ module.exports = function ( grunt ) { styles : { files : [ - 'assets/css/*.scss' + 'assets/css/*.scss', + 'features/autosuggest/assets/css/*.scss' ], tasks : ['sass', 'autoprefixer', 'cssmin'] } diff --git a/README.md b/README.md index 9a7c466106..627dafc522 100644 --- a/README.md +++ b/README.md @@ -19,7 +19,7 @@ ElasticPress integrates with the [WP_Query](http://codex.wordpress.org/Class_Ref ## Requirements -* [Elasticsearch](https://www.elastic.co) 1.7 - 5.2 (2.0+ highly recommended) +* [Elasticsearch](https://www.elastic.co) 1.7+ (5.0+ highly recommended) * [WordPress](http://wordpress.org) 3.7.1+ ## Installation @@ -60,6 +60,10 @@ Optionally index all of your content, including private and unpublished content, Indexes text inside of popular file types, and adds those files types to search results. +### Autosuggest + +Suggest relevant content as text is entered into the search field. + ## `WP_Query` and the ElasticPress Query Integration ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passed (see below) to the query object. If the search feature is activated (which it is by default), all queries with the `s` parameter will be integrated with as well. ElasticPress converts `WP_Query` arguments to Elasticsearch readable queries. Supported `WP_Query` parameters are listed and explained below. ElasticPress also adds some extra `WP_query` arguments for extra functionality. @@ -78,7 +82,7 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe 'posts_per_page' => 20, ) ); ``` - + Get all posts with a specific category slug ```php new WP_Query( array( @@ -122,8 +126,10 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe ) ); ``` - ```tax_query``` accepts an array of arrays where each inner array *only* supports ```taxonomy``` (string), ```field``` (string), and - ```terms``` (string|array) parameters. ```field``` must be set to `slug`, `name`, or `term_id`. The default value for `field` is `term_id`. ```terms``` must be a string or an array of term slug(s), name(s), or id(s). + ```tax_query``` accepts an array of arrays where each inner array *only* supports ```taxonomy``` (string), ```field``` (string), `operator` (string), and + ```terms``` (string|array) parameters. ```field``` must be set to `slug`, `name`, or `term_id`. The default value for `field` is `term_id`. ```terms``` must be a string or an array of term slug(s), name(s), or id(s). `operator` defaults to `in` and also supports `not in` and `and`. + + The outer array supports the `relation` parameter. Acceptable values are `and` and `or`. The default is `and`. * The following shorthand parameters can be used for querying posts by specific dates: @@ -157,7 +163,7 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe containing the following parameters ```after```, ```before```, ```inclusive```, ```compare```, ```column```, and ```relation```. ```column``` is used to query specific columns from the ```wp_posts``` table. This will return posts which are created after January 1st 2012 and January 3rd 2012 8AM GMT: - + ```php new WP_Query( array( 's' => 'search phrase', @@ -173,7 +179,7 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe ), ) ); ``` - + Currently only the ```AND``` value is supported for the ```relation``` parameter. ```inclusive``` is used on after/before options to determine whether exact value should be matched or not. If inclusive is used @@ -254,9 +260,9 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe ) ); ``` - ```meta_query``` accepts an array of arrays where each inner array *only* supports ```key``` (string), + ```meta_query``` accepts an array of arrays where each inner array *only* supports ```key``` (string), ```type``` (string), ```value``` (string|array|int), and ```compare``` (string) parameters. ```compare``` supports the following: - + * ```=``` - Posts will be returned that have a post meta key corresponding to ```key``` and a value that equals the value passed to ```value```. * ```!=``` - Posts will be returned that have a post meta key corresponding to ```key``` and a value that does NOT equal the value passed to ```value```. * ```>``` - Posts will be returned that have a post meta key corresponding to ```key``` and a value that is greater than the value passed to ```value```. @@ -288,9 +294,9 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe Possible values for ```relation``` are ```OR``` and ```AND```. If ```relation``` is set to ```AND```, all inner queries must be true for a post to be returned. If ```relation``` is set to ```OR```, only one of the inner meta queries must be true for the post to be returned. - ```type``` supports the following values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', - 'DECIMAL', 'SIGNED', 'TIME', and 'UNSIGNED'. By default WordPress casts meta values to these types - in MySQL so some of these don't make sense in the context of Elasticsearch. ElasticPress does no "runtime" + ```type``` supports the following values: 'NUMERIC', 'BINARY', 'CHAR', 'DATE', 'DATETIME', + 'DECIMAL', 'SIGNED', 'TIME', and 'UNSIGNED'. By default WordPress casts meta values to these types + in MySQL so some of these don't make sense in the context of Elasticsearch. ElasticPress does no "runtime" casting but instead compares the value to a different type compiled during indexing * `NUMERIC` - Compares query `value` to integer version of stored meta value. @@ -303,7 +309,7 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe * `DATETIME` - Compares query `value` to date/time version of stored meta value. Query `value` must be formatted like `2012-01-02 05:00:00` or `yyyy:mm:dd hh:mm:ss`. * `TIME` - Compares query `value` to time version of stored meta value. Query `value` must be formatted like `17:00:00` or `hh:mm:ss`. - If no type is specified, ElasticPress will just deduce the type from the comparator used. ```type``` + If no type is specified, ElasticPress will just deduce the type from the comparator used. ```type``` is very rarely needed to be used. * ```meta_key``` (*string*) @@ -341,11 +347,11 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe * ```author``` (*int*) Show posts associated with certain author ID. - + * ```author_name``` (*string*) Show posts associated with certain author. Use ```user_nicename``` (NOT name). - + * ```orderby``` (*string*) Order results by field name instead of relevance. Supports: ```title```, ```modified```, `meta_value`, `meta_value_num`, ```type```, ```name```, ```date```, and ```relevance```; anything else will be interpretted as a document path i.e. `meta.my_key.long` or `meta.my_key.raw`. You can sort by multiple fields as well i.e. `title meta.my_key.raw` @@ -353,11 +359,11 @@ ElasticPress integrates with `WP_Query` if the `ep_integrate` parameter is passe * ```order``` (*string*) Which direction to order results in. Accepts ```ASC``` and ```DESC```. Default is ```DESC```. - + * ```post_parent``` (*int*) Show posts that have the specified post parent. - + The following are special parameters that are only supported by ElasticPress. @@ -428,7 +434,7 @@ The following are special parameters that are only supported by ElasticPress. * ```aggs``` (*array*) Add aggregation results to your search result. For example: - + ```php new WP_Query( array( 's' => 'search phrase', diff --git a/assets/css/admin.css b/assets/css/admin.css index 276f2e9db8..6c5e5baf60 100644 --- a/assets/css/admin.css +++ b/assets/css/admin.css @@ -243,7 +243,7 @@ h2.ep-list-features { .ep-feature .settings .action-wrap { clear: both; text-align: right; - margin-top: 10px; + padding-top: 15px; vertical-align: middle; } .ep-feature .settings .action-wrap a { cursor: pointer; @@ -264,15 +264,31 @@ h2.ep-list-features { .ep-feature .settings .field { clear: both; - overflow: initial; } + overflow: initial; + padding-top: 15px; } + .ep-feature .settings .field:first-child { + padding-top: 0; } + .ep-feature .settings .field label { + margin: 0.25em 0 0.5em; + display: inline-block; } + .ep-feature .settings .field div { + padding-top: 5px; } .ep-feature .settings .field > label, .ep-feature .settings .field .field-name { display: block; float: left; - margin-right: 3em; } + width: 25%; + padding-right: 1.5em; + box-sizing: border-box; } .ep-feature .settings .field .input-wrap { + width: 75%; display: block; - float: left; } + float: right; } + .ep-feature .settings .field .field-description { + font-style: italic; + margin-top: 4px; + margin-bottom: 0; + color: #666; } .ep-feature .settings .field .disabled { color: #c4c3c3; } .ep-feature .settings .field .disabled input { @@ -397,4 +413,5 @@ h2.ep-list-features { vertical-align: middle; display: inline-block; padding-top: .5em; } } + /*# sourceMappingURL=admin.css.map */ \ No newline at end of file diff --git a/assets/css/admin.css.map b/assets/css/admin.css.map index 8fb15cdb2d..f0ef6dca42 100644 --- a/assets/css/admin.css.map +++ b/assets/css/admin.css.map @@ -1 +1,9 @@ -{"version":3,"sources":["admin.scss"],"names":[],"mappings":"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","file":"admin.css"} \ No newline at end of file +{ + "version": 3, + "file": "admin.css", + "sources": [ + "admin.scss" + ], + "names": [], + "mappings": "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" +} \ No newline at end of file diff --git a/assets/css/admin.min.css b/assets/css/admin.min.css index 996ba0e519..9edc26df19 100644 --- a/assets/css/admin.min.css +++ b/assets/css/admin.min.css @@ -1 +1 @@ -.wrap .notice,.wrap>h2{z-index:2;position:relative}.wrap h2{color:#888;line-height:1.75;margin:.5em 0 .75em}#wpbody #update-nag,#wpbody .update-nag{margin-left:-20px;width:100%;margin-top:0;margin-bottom:20px}h2.ep-list-features{display:none}.ep-header-menu{background-color:#fff;position:relative;margin-left:-20px;padding-left:20px;padding-right:20px;padding-top:5px;padding-bottom:5px;border-bottom:2px solid #ddd;z-index:2}.ep-header-menu:after{content:' ';clear:both;display:block}.ep-header-menu img{float:left}.ep-header-menu .icons{float:right;padding-right:3px;height:39px;line-height:39px;display:inline-block}.ep-header-menu .icons .dashicons-update{font-size:29px;margin-right:10px;top:-3px}.ep-header-menu .icons a{font-size:27px;vertical-align:middle;color:inherit;position:relative;top:-3px;margin-left:8px;cursor:pointer}.ep-header-menu .icons .dashicons-controls-pause,.ep-header-menu .icons .dashicons-controls-play,.ep-header-menu .icons .dashicons-no{top:1px;font-size:30px}.ep-header-menu .cancel-sync,.ep-header-menu .pause-sync,.ep-header-menu .resume-sync{display:none}.ep-header-menu .sync-status{display:none;color:#666;bottom:-1px;position:relative;margin-right:8px;vertical-align:middle;font-style:italic}.ep-header-menu .progress-bar{margin-bottom:-5px;height:5px;position:absolute;bottom:0;left:0;background-color:#d84440}.ep-features{overflow:auto}.error-overlay.cant-connect,.error-overlay.syncing{content:' ';display:block;position:fixed;top:46px;left:0;right:0;bottom:0;opacity:.6;background-color:#fff;z-index:1}@media (min-width:768px){.error-overlay,.error-overlay.cant-connect,.error-overlay.syncing{top:32px;left:160px}}.ep-feature .postbox{margin-bottom:0}.ep-feature .postbox .hndle{cursor:inherit}.ep-feature .postbox .hndle .settings-button{float:right;display:inline-block;font-size:13px;background-color:#efefef;border-radius:4px;padding:4px 7px;margin-top:-4px;cursor:pointer;color:inherit;position:relative;padding-left:23px}.ep-feature .settings-button:before{content:"\f140";font:400 19px/1 dashicons;display:inline-block;color:#72777c;padding:0 5px 0 0;vertical-align:middle;top:4px;position:absolute;left:1px}.ep-feature .settings-button:after{border-radius:50%;content:' ';display:inline-block;vertical-align:middle;width:8px;height:8px;margin-left:10px;margin-top:-2px}.feature-requirements-status-2.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid red}.feature-requirements-status-2.ep-feature .settings .requirements-status-notice{border-color:red}.feature-requirements-status-1.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid #e3e600}.feature-requirements-status-1.ep-feature.feature-active .postbox .hndle .settings-button:after{background-color:#e3e600}.feature-requirements-status-1.ep-feature .settings .requirements-status-notice{border-color:#e3e600}.feature-requirements-status-0.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid #6aa000}.feature-requirements-status-0.ep-feature.feature-active .postbox .hndle .settings-button:after{background-color:#6aa000}.feature-requirements-status-0.ep-feature .settings .requirements-status-notice{border-color:#6aa000}.ep-feature{position:relative;vertical-align:top;margin-bottom:20px}.ep-feature.saving .action-wrap:before{content:' ';vertical-align:middle;margin-right:1.4em;top:4px;border-radius:50%;width:8px;height:8px;display:inline-block;font-size:7px;position:relative;text-indent:-9999em;border-top:5px solid #ccc;border-right:5px solid #ccc;border-bottom:5px solid #ccc;border-left:5px solid #999;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:load8 1.1s infinite linear;animation:load8 1.1s infinite linear}.ep-feature .description,.ep-feature .settings{margin-bottom:0;text-align:left}.ep-feature .settings{display:none;overflow:auto}.ep-feature .settings h3{margin-top:0;font-size:inherit;font-weight:700}.ep-feature.show-settings .settings{display:block}.ep-feature.show-settings .description{display:none}.ep-feature.show-settings .settings-button:before{content:"\f142"}.ep-feature .settings .requirements-status-notice{border-left:4px solid #6aa000;background-color:#efefef;padding:8px 12px;margin-bottom:10px}.ep-feature .settings .action-wrap{clear:both;text-align:right;margin-top:10px;vertical-align:middle}.ep-feature .settings .action-wrap a{cursor:pointer;display:inline-block}.ep-feature .settings .action-wrap .no-dash-sync{color:#aaa;line-height:27px;padding-right:8px;display:none}.ep-feature .settings .action-wrap a.disabled{cursor:default}.ep-feature .settings .action-wrap .cancel{margin-top:4px;margin-right:6px}.ep-feature.dash-sync-disabled .settings .action-wrap .no-dash-sync{display:inline}.ep-feature .settings .field{clear:both;overflow:initial}.ep-feature .settings .field .field-name,.ep-feature .settings .field>label{display:block;float:left;margin-right:3em}.ep-feature .settings .field .input-wrap{display:block;float:left}.ep-feature .settings .field .disabled{color:#c4c3c3}.ep-feature .settings .field .disabled input{cursor:default}.ep-feature .long{display:none}.ep-feature .long p:last-child{margin-bottom:0}.ep-feature.show-full .long{display:block}.ep-feature .collapse,.ep-feature .learn-more{cursor:pointer}.ep-feature.show-full .learn-more{display:none}.ep-feature .learn-more:after{content:"\f140";font-family:dashicons;font-size:1.5em;vertical-align:middle;top:-.07em;position:relative}.ep-feature .collapse:after{content:"\f142";font-family:dashicons;font-size:1.5em;vertical-align:middle;top:-.07em;position:relative}.intro h2{padding:9px 15px 4px 0}.wrap.intro{margin-top:30px;margin-bottom:30px;overflow:auto}.wrap.intro .error,.wrap.intro .is-dismissible,.wrap.intro .notice,.wrap.intro .updated{display:none!important}.features-screenshot{display:none}.setup-message{text-align:center;background-color:#e63e3b;margin:20px -20px 0 -20px;padding:2em 0;clear:both}.setup-message .setup-button{border-radius:5px;background-color:#d73c38;color:#f19ea4;display:inline-block;margin:0 .75em;text-decoration:none;padding:.75em 3em;box-shadow:1px 1px 3px 1px rgba(0,0,0,.25)}.setup-message .setup-button-primary{background-color:#fff;color:#d84440}@-webkit-keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@media (min-width:768px){.intro .left{float:left;width:30%}.features-screenshot{margin:0 auto;max-width:1000px;width:70%;display:block;height:auto;float:right}.ep-features .left{display:block;float:left;box-sizing:border-box;padding-right:10px;width:50%}.ep-features .right{display:block;float:right;box-sizing:border-box;padding-left:10px;width:50%}.ep-feature .feature-message{float:left;padding:0;vertical-align:middle;display:inline-block;padding-top:.5em}} \ No newline at end of file +.wrap .notice,.wrap>h2{z-index:2;position:relative}.wrap h2{color:#888;line-height:1.75;margin:.5em 0 .75em}#wpbody #update-nag,#wpbody .update-nag{margin-left:-20px;width:100%;margin-top:0;margin-bottom:20px}h2.ep-list-features{display:none}.ep-header-menu{background-color:#fff;position:relative;margin-left:-20px;padding-left:20px;padding-right:20px;padding-top:5px;padding-bottom:5px;border-bottom:2px solid #ddd;z-index:2}.ep-header-menu:after{content:' ';clear:both;display:block}.ep-header-menu img{float:left}.ep-header-menu .icons{float:right;padding-right:3px;height:39px;line-height:39px;display:inline-block}.ep-header-menu .icons .dashicons-update{font-size:29px;margin-right:10px;top:-3px}.ep-header-menu .icons a{font-size:27px;vertical-align:middle;color:inherit;position:relative;top:-3px;margin-left:8px;cursor:pointer}.ep-header-menu .icons .dashicons-controls-pause,.ep-header-menu .icons .dashicons-controls-play,.ep-header-menu .icons .dashicons-no{top:1px;font-size:30px}.ep-header-menu .cancel-sync,.ep-header-menu .pause-sync,.ep-header-menu .resume-sync{display:none}.ep-header-menu .sync-status{display:none;color:#666;bottom:-1px;position:relative;margin-right:8px;vertical-align:middle;font-style:italic}.ep-header-menu .progress-bar{margin-bottom:-5px;height:5px;position:absolute;bottom:0;left:0;background-color:#d84440}.ep-features{overflow:auto}.error-overlay.cant-connect,.error-overlay.syncing{content:' ';display:block;position:fixed;top:46px;left:0;right:0;bottom:0;opacity:.6;background-color:#fff;z-index:1}@media (min-width:768px){.error-overlay,.error-overlay.cant-connect,.error-overlay.syncing{top:32px;left:160px}}.ep-feature .postbox{margin-bottom:0}.ep-feature .postbox .hndle{cursor:inherit}.ep-feature .postbox .hndle .settings-button{float:right;display:inline-block;font-size:13px;background-color:#efefef;border-radius:4px;padding:4px 7px;margin-top:-4px;cursor:pointer;color:inherit;position:relative;padding-left:23px}.ep-feature .settings-button:before{content:"\f140";font:400 19px/1 dashicons;display:inline-block;color:#72777c;padding:0 5px 0 0;vertical-align:middle;top:4px;position:absolute;left:1px}.ep-feature .settings-button:after{border-radius:50%;content:' ';display:inline-block;vertical-align:middle;width:8px;height:8px;margin-left:10px;margin-top:-2px}.feature-requirements-status-2.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid red}.feature-requirements-status-2.ep-feature .settings .requirements-status-notice{border-color:red}.feature-requirements-status-1.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid #e3e600}.feature-requirements-status-1.ep-feature.feature-active .postbox .hndle .settings-button:after{background-color:#e3e600}.feature-requirements-status-1.ep-feature .settings .requirements-status-notice{border-color:#e3e600}.feature-requirements-status-0.ep-feature .postbox .hndle .settings-button:after{background-color:transparent;border:1px solid #6aa000}.feature-requirements-status-0.ep-feature.feature-active .postbox .hndle .settings-button:after{background-color:#6aa000}.feature-requirements-status-0.ep-feature .settings .requirements-status-notice{border-color:#6aa000}.ep-feature{position:relative;vertical-align:top;margin-bottom:20px}.ep-feature.saving .action-wrap:before{content:' ';vertical-align:middle;margin-right:1.4em;top:4px;border-radius:50%;width:8px;height:8px;display:inline-block;font-size:7px;position:relative;text-indent:-9999em;border-top:5px solid #ccc;border-right:5px solid #ccc;border-bottom:5px solid #ccc;border-left:5px solid #999;-webkit-transform:translateZ(0);-ms-transform:translateZ(0);transform:translateZ(0);-webkit-animation:load8 1.1s infinite linear;animation:load8 1.1s infinite linear}.ep-feature .description,.ep-feature .settings{margin-bottom:0;text-align:left}.ep-feature .settings{display:none;overflow:auto}.ep-feature .settings h3{margin-top:0;font-size:inherit;font-weight:700}.ep-feature.show-settings .settings{display:block}.ep-feature.show-settings .description{display:none}.ep-feature.show-settings .settings-button:before{content:"\f142"}.ep-feature .settings .requirements-status-notice{border-left:4px solid #6aa000;background-color:#efefef;padding:8px 12px;margin-bottom:10px}.ep-feature .settings .action-wrap{clear:both;text-align:right;padding-top:15px;vertical-align:middle}.ep-feature .settings .action-wrap a{cursor:pointer;display:inline-block}.ep-feature .settings .action-wrap .no-dash-sync{color:#aaa;line-height:27px;padding-right:8px;display:none}.ep-feature .settings .action-wrap a.disabled{cursor:default}.ep-feature .settings .action-wrap .cancel{margin-top:4px;margin-right:6px}.ep-feature.dash-sync-disabled .settings .action-wrap .no-dash-sync{display:inline}.ep-feature .settings .field{clear:both;overflow:initial;padding-top:15px}.ep-feature .settings .field:first-child{padding-top:0}.ep-feature .settings .field label{margin:.25em 0 .5em;display:inline-block}.ep-feature .settings .field div{padding-top:5px}.ep-feature .settings .field .field-name,.ep-feature .settings .field>label{display:block;float:left;width:25%;padding-right:1.5em;box-sizing:border-box}.ep-feature .settings .field .input-wrap{width:75%;display:block;float:right}.ep-feature .settings .field .field-description{font-style:italic;margin-top:4px;margin-bottom:0;color:#666}.ep-feature .settings .field .disabled{color:#c4c3c3}.ep-feature .settings .field .disabled input{cursor:default}.ep-feature .long{display:none}.ep-feature .long p:last-child{margin-bottom:0}.ep-feature.show-full .long{display:block}.ep-feature .collapse,.ep-feature .learn-more{cursor:pointer}.ep-feature.show-full .learn-more{display:none}.ep-feature .learn-more:after{content:"\f140";font-family:dashicons;font-size:1.5em;vertical-align:middle;top:-.07em;position:relative}.ep-feature .collapse:after{content:"\f142";font-family:dashicons;font-size:1.5em;vertical-align:middle;top:-.07em;position:relative}.intro h2{padding:9px 15px 4px 0}.wrap.intro{margin-top:30px;margin-bottom:30px;overflow:auto}.wrap.intro .error,.wrap.intro .is-dismissible,.wrap.intro .notice,.wrap.intro .updated{display:none!important}.features-screenshot{display:none}.setup-message{text-align:center;background-color:#e63e3b;margin:20px -20px 0 -20px;padding:2em 0;clear:both}.setup-message .setup-button{border-radius:5px;background-color:#d73c38;color:#f19ea4;display:inline-block;margin:0 .75em;text-decoration:none;padding:.75em 3em;box-shadow:1px 1px 3px 1px rgba(0,0,0,.25)}.setup-message .setup-button-primary{background-color:#fff;color:#d84440}@-webkit-keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@keyframes load8{0%{-webkit-transform:rotate(0);transform:rotate(0)}100%{-webkit-transform:rotate(360deg);transform:rotate(360deg)}}@media (min-width:768px){.intro .left{float:left;width:30%}.features-screenshot{margin:0 auto;max-width:1000px;width:70%;display:block;height:auto;float:right}.ep-features .left{display:block;float:left;box-sizing:border-box;padding-right:10px;width:50%}.ep-features .right{display:block;float:right;box-sizing:border-box;padding-left:10px;width:50%}.ep-feature .feature-message{float:left;padding:0;vertical-align:middle;display:inline-block;padding-top:.5em}} \ No newline at end of file diff --git a/assets/css/admin.scss b/assets/css/admin.scss index 8a1a047ce6..911cc9c4c6 100644 --- a/assets/css/admin.scss +++ b/assets/css/admin.scss @@ -301,7 +301,7 @@ h2.ep-list-features { .ep-feature .settings .action-wrap { clear: both; text-align: right; - margin-top: 10px; + padding-top: 15px; vertical-align: middle; a { @@ -335,17 +335,41 @@ h2.ep-list-features { .ep-feature .settings .field { clear: both; overflow: initial; + padding-top: 15px; + + &:first-child { + padding-top: 0; + } + + label { + margin: 0.25em 0 0.5em; + display: inline-block; + } + + div { + padding-top: 5px; + } > label, .field-name { display: block; float: left; - margin-right: 3em; + width: 25%; + padding-right: 1.5em; + box-sizing: border-box; } .input-wrap { + width: 75%; display: block; - float: left; + float: right; + } + + .field-description { + font-style: italic; + margin-top: 4px; + margin-bottom: 0; + color: #666; } .disabled { diff --git a/assets/js/admin.min.js b/assets/js/admin.min.js index 4c19f8bc7e..20a581a24e 100644 --- a/assets/js/admin.min.js +++ b/assets/js/admin.min.js @@ -1 +1 @@ -!function(a){"use strict";a(".notice").on("click",".notice-dismiss",function(b){var c=b.delegateTarget.getAttribute("data-ep-notice");c&&a.ajax({method:"post",data:{nonce:epAdmin.nonce,action:"ep_notice_dismiss",notice:c},url:ajaxurl})})}(jQuery); \ No newline at end of file +!function(t){"use strict";t(".notice").on("click",".notice-dismiss",function(e){var i=e.delegateTarget.getAttribute("data-ep-notice");i&&t.ajax({method:"post",data:{nonce:epAdmin.nonce,action:"ep_notice_dismiss",notice:i},url:ajaxurl})})}(jQuery); \ No newline at end of file diff --git a/assets/js/dashboard.min.js b/assets/js/dashboard.min.js index fb9b98ba7b..ec3ed79b64 100644 --- a/assets/js/dashboard.min.js +++ b/assets/js/dashboard.min.js @@ -1 +1 @@ -!function(a){function b(){if(0===q)i.css({width:"1%"});else{var a=parseInt(q)/parseInt(r)*100;i.css({width:a+"%"})}if("initialsync"===o){var b=epDash.sync_initial;j.text(b),j.show(),i.show(),m.show(),h.addClass("syncing"),n.hide(),l.hide(),k.hide()}else if("sync"===o){var b=epDash.sync_syncing+" "+parseInt(q)+"/"+parseInt(r);e&&(b+=" ("+e.url+")"),j.text(b),j.show(),i.show(),m.show(),h.addClass("syncing"),n.hide(),l.hide(),k.hide()}else if("pause"===o){var b=epDash.sync_paused;r&&0!==r&&(b+=" "+parseInt(q)+"/"+parseInt(r)),e&&(b+=" ("+e.url+")"),j.text(b),j.show(),i.show(),m.hide(),h.addClass("syncing"),n.show(),l.show(),k.hide()}else if("wpcli"===o){var b=epDash.sync_wpcli;j.text(b),j.show(),i.hide(),m.hide(),h.addClass("syncing"),n.hide(),l.hide(),k.hide()}else if("error"===o){if(j.text(epDash.sync_error),j.show(),k.show(),n.hide(),l.hide(),m.hide(),h.removeClass("syncing"),i.hide(),p){var c=g.find(".ep-feature-"+p);c.removeClass("feature-syncing")}p=null,setTimeout(function(){j.hide()},7e3)}else if("cancel"===o){if(j.hide(),i.hide(),m.hide(),h.removeClass("syncing"),n.hide(),l.hide(),k.show(),p){var c=g.find(".ep-feature-"+p);c.removeClass("feature-syncing")}p=null}else if("finished"===o){if(j.text(epDash.sync_complete),j.show(),i.hide(),m.hide(),n.hide(),l.hide(),k.show(),h.removeClass("syncing"),p){var c=g.find(".ep-feature-"+p);c.removeClass("feature-syncing")}p=null,setTimeout(function(){j.hide()},7e3)}}function c(){a.ajax({method:"post",url:ajaxurl,data:{action:"ep_cancel_index",nonce:epDash.nonce}})}function d(){a.ajax({method:"post",url:ajaxurl,data:{action:"ep_index",feature_sync:p,nonce:epDash.nonce}}).done(function(a){if("sync"===o){if(r=a.data.found_posts,q=a.data.offset,a.data.site_stack&&(f=a.data.site_stack),a.data.current_site&&(e=a.data.current_site),f&&f.length)return o="sync",b(),void d();0!==a.data.found_posts||a.data.start?(o="sync",b(),d()):(o="finished",b())}}).error(function(a){a&&a.status&&parseInt(a.status)>=400&&parseInt(a.status)<600&&(o="error",b(),c())})}var e,f,g=a(document.getElementsByClassName("ep-features")),h=a(document.getElementsByClassName("error-overlay")),i=a(document.getElementsByClassName("progress-bar")),j=a(document.getElementsByClassName("sync-status")),k=a(document.getElementsByClassName("start-sync")),l=a(document.getElementsByClassName("resume-sync")),m=a(document.getElementsByClassName("pause-sync")),n=a(document.getElementsByClassName("cancel-sync")),o="sync",p=!1,q=0,r=0;g.on("click",".learn-more, .collapse",function(b){$feature=a(this).parents(".ep-feature"),$feature.toggleClass("show-full")}),g.on("click",".settings-button",function(b){$feature=a(this).parents(".ep-feature"),$feature.toggleClass("show-settings")}),g.on("click",".save-settings",function(c){if(c.preventDefault(),!a(this).hasClass("disabled")){var e=c.target.getAttribute("data-feature"),f=g.find(".ep-feature-"+e),h={};f.find(".setting-field").each(function(){var b=a(this).attr("type"),c=a(this).attr("data-field-name"),d=a(this).attr("value");"radio"===b&&a(this).attr("checked")&&(h[c]=d)}),f.addClass("saving"),a.ajax({method:"post",url:ajaxurl,data:{action:"ep_save_feature",feature:e,nonce:epDash.nonce,settings:h}}).done(function(c){setTimeout(function(){f.removeClass("saving"),"1"===h.active?f.addClass("feature-active"):f.removeClass("feature-active"),c.data.reindex&&(o="initialsync",b(),a('[data-ep-notice="no-sync"], [data-ep-notice="auto-activate-sync"], [data-ep-notice="upgrade-sync"]').remove(),o="sync",f.addClass("feature-syncing"),p=e,d())},700)}).error(function(){setTimeout(function(){f.removeClass("saving"),f.removeClass("feature-active"),f.removeClass("feature-syncing")},700)})}}),epDash.index_meta?epDash.index_meta.wpcli_sync?(o="wpcli",b()):(q=epDash.index_meta.offset,r=epDash.index_meta.found_posts,epDash.index_meta.feature_sync&&(p=epDash.index_meta.feature_sync),epDash.index_meta.current_site&&(e=epDash.index_meta.current_site),epDash.index_meta.site_stack&&(f=epDash.index_meta.site_stack),f&&f.length?epDash.auto_start_index?(o="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),b(),d()):(o="pause",b()):0!==r||epDash.index_meta.start?epDash.auto_start_index?(o="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),b(),d()):(o="pause",b()):(o="finished",b())):epDash.auto_start_index&&(o="initialsync",b(),o="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),d()),k.on("click",function(){o="initialsync",b(),a('[data-ep-notice="no-sync"], [data-ep-notice="auto-activate-sync"], [data-ep-notice="upgrade-sync"]').remove(),o="sync",d()}),m.on("click",function(){o="pause",b()}),l.on("click",function(){o="sync",b(),d()}),n.on("click",function(){o="cancel",b(),c()})}(jQuery); \ No newline at end of file +!function(e){function t(){if(0===y)d.css({width:"1%"});else{var e=parseInt(y)/parseInt(_)*100;d.css({width:e+"%"})}if("initialsync"===f){t=epDash.sync_initial;r.text(t),r.show(),d.show(),h.show(),o.addClass("syncing"),p.hide(),l.hide(),u.hide()}else if("sync"===f){t=epDash.sync_syncing+" "+parseInt(y)+"/"+parseInt(_);n&&(t+=" ("+n.url+")"),r.text(t),r.show(),d.show(),h.show(),o.addClass("syncing"),p.hide(),l.hide(),u.hide()}else if("pause"===f){t=epDash.sync_paused;_&&0!==_&&(t+=" "+parseInt(y)+"/"+parseInt(_)),n&&(t+=" ("+n.url+")"),r.text(t),r.show(),d.show(),h.hide(),o.addClass("syncing"),p.show(),l.show(),u.hide()}else if("wpcli"===f){var t=epDash.sync_wpcli;r.text(t),r.show(),d.hide(),h.hide(),o.addClass("syncing"),p.hide(),l.hide(),u.hide()}else if("error"===f)r.text(epDash.sync_error),r.show(),u.show(),p.hide(),l.hide(),h.hide(),o.removeClass("syncing"),d.hide(),m&&(s=c.find(".ep-feature-"+m)).removeClass("feature-syncing"),m=null,setTimeout(function(){r.hide()},7e3);else if("cancel"===f)r.hide(),d.hide(),h.hide(),o.removeClass("syncing"),p.hide(),l.hide(),u.show(),m&&(s=c.find(".ep-feature-"+m)).removeClass("feature-syncing"),m=null;else if("finished"===f){if(r.text(epDash.sync_complete),r.show(),d.hide(),h.hide(),p.hide(),l.hide(),u.show(),o.removeClass("syncing"),m){var s=c.find(".ep-feature-"+m);s.removeClass("feature-syncing")}m=null,setTimeout(function(){r.hide()},7e3)}}function s(){e.ajax({method:"post",url:ajaxurl,data:{action:"ep_cancel_index",nonce:epDash.nonce}})}function a(){e.ajax({method:"post",url:ajaxurl,data:{action:"ep_index",feature_sync:m,nonce:epDash.nonce}}).done(function(e){if("sync"===f){if(_=e.data.found_posts,y=e.data.offset,e.data.site_stack&&(i=e.data.site_stack),e.data.current_site&&(n=e.data.current_site),i&&i.length)return f="sync",t(),void a();0!==e.data.found_posts||e.data.start?(f="sync",t(),a()):(f="finished",t())}}).error(function(e){e&&e.status&&parseInt(e.status)>=400&&parseInt(e.status)<600&&(f="error",t(),s())})}var n,i,c=e(document.getElementsByClassName("ep-features")),o=e(document.getElementsByClassName("error-overlay")),d=e(document.getElementsByClassName("progress-bar")),r=e(document.getElementsByClassName("sync-status")),u=e(document.getElementsByClassName("start-sync")),l=e(document.getElementsByClassName("resume-sync")),h=e(document.getElementsByClassName("pause-sync")),p=e(document.getElementsByClassName("cancel-sync")),f="sync",m=!1,y=0,_=0;c.on("click",".learn-more, .collapse",function(t){$feature=e(this).parents(".ep-feature"),$feature.toggleClass("show-full")}),c.on("click",".settings-button",function(t){$feature=e(this).parents(".ep-feature"),$feature.toggleClass("show-settings")}),c.on("click",".save-settings",function(s){if(s.preventDefault(),!e(this).hasClass("disabled")){var n=s.target.getAttribute("data-feature"),i=c.find(".ep-feature-"+n),o={};i.find(".setting-field").each(function(){var t=e(this).attr("type"),s=e(this).attr("data-field-name"),a=e(this).attr("value");"radio"===t?e(this).attr("checked")&&(o[s]=a):o[s]=a}),i.addClass("saving"),e.ajax({method:"post",url:ajaxurl,data:{action:"ep_save_feature",feature:n,nonce:epDash.nonce,settings:o}}).done(function(s){setTimeout(function(){i.removeClass("saving"),"1"===o.active?i.addClass("feature-active"):i.removeClass("feature-active"),s.data.reindex&&(f="initialsync",t(),e('[data-ep-notice="no-sync"], [data-ep-notice="auto-activate-sync"], [data-ep-notice="upgrade-sync"]').remove(),f="sync",i.addClass("feature-syncing"),m=n,a())},700)}).error(function(){setTimeout(function(){i.removeClass("saving"),i.removeClass("feature-active"),i.removeClass("feature-syncing")},700)})}}),epDash.index_meta?epDash.index_meta.wpcli_sync?(f="wpcli",t()):(y=epDash.index_meta.offset,_=epDash.index_meta.found_posts,epDash.index_meta.feature_sync&&(m=epDash.index_meta.feature_sync),epDash.index_meta.current_site&&(n=epDash.index_meta.current_site),epDash.index_meta.site_stack&&(i=epDash.index_meta.site_stack),i&&i.length?epDash.auto_start_index?(f="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),t(),a()):(f="pause",t()):0!==_||epDash.index_meta.start?epDash.auto_start_index?(f="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),t(),a()):(f="pause",t()):(f="finished",t())):epDash.auto_start_index&&(f="initialsync",t(),f="sync",history.pushState({},document.title,document.location.pathname+document.location.search.replace(/&do_sync/,"")),a()),u.on("click",function(){f="initialsync",t(),e('[data-ep-notice="no-sync"], [data-ep-notice="auto-activate-sync"], [data-ep-notice="upgrade-sync"]').remove(),f="sync",a()}),h.on("click",function(){f="pause",t()}),l.on("click",function(){f="sync",t(),a()}),p.on("click",function(){f="cancel",t(),s()})}(jQuery); \ No newline at end of file diff --git a/assets/js/src/dashboard.js b/assets/js/src/dashboard.js index 4a5dd0c952..e1f822a147 100644 --- a/assets/js/src/dashboard.js +++ b/assets/js/src/dashboard.js @@ -49,6 +49,8 @@ if ( $( this ).attr( 'checked' ) ) { settings[ name ] = value; } + } else { + settings[ name ] = value; } }); diff --git a/classes/class-ep-api.php b/classes/class-ep-api.php index f44e076746..b4b0b3e879 100644 --- a/classes/class-ep-api.php +++ b/classes/class-ep-api.php @@ -28,7 +28,7 @@ public function __construct() { } /** * ES plugins - * + * * @var array * @since 2.2 */ @@ -36,7 +36,7 @@ public function __construct() { } /** * ES version number - * + * * @var string * @since 2.2 */ @@ -100,7 +100,7 @@ public function index_post( $post, $blocking = true ) { 'blocking' => $blocking, ); - $request = ep_remote_request( $path, apply_filters( 'ep_index_post_request_args', $request_args, $post ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_index_post_request_args', $request_args, $post ), array(), 'index_post' ); do_action( 'ep_index_post_retrieve_raw_response', $request, $post, $path ); @@ -138,7 +138,7 @@ public function refresh_index() { $request_args = array( 'method' => 'POST' ); - $request = ep_remote_request( '_refresh', apply_filters( 'ep_refresh_index_request_args', $request_args ) ); + $request = ep_remote_request( '_refresh', apply_filters( 'ep_refresh_index_request_args', $request_args ), array(), 'refresh_index' ); if ( ! is_wp_error( $request ) ) { if ( isset( $request['response']['code'] ) && 200 === $request['response']['code'] ) { @@ -210,9 +210,12 @@ public function query( $args, $query_args, $scope = 'current' ) { $request_args = array( 'body' => json_encode( apply_filters( 'ep_search_args', $args, $scope, $query_args ) ), 'method' => 'POST', + 'headers' => array( + 'Content-Type' => 'application/json', + ), ); - $request = ep_remote_request( $path, apply_filters( 'ep_search_request_args', $request_args, $args, $scope, $query_args ), $query_args ); + $request = ep_remote_request( $path, apply_filters( 'ep_search_request_args', $request_args, $args, $scope, $query_args ), $query_args, 'query' ); $remote_req_res_code = intval( wp_remote_retrieve_response_code( $request ) ); @@ -308,7 +311,7 @@ public function delete_post( $post_id, $blocking = true ) { $request_args = array( 'method' => 'DELETE', 'timeout' => 15, 'blocking' => $blocking ); - $request = ep_remote_request( $path, apply_filters( 'ep_delete_post_request_args', $request_args, $post_id ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_delete_post_request_args', $request_args, $post_id ), array(), 'delete_post' ); if ( ! is_wp_error( $request ) ) { $response_body = wp_remote_retrieve_body( $request ); @@ -371,7 +374,7 @@ public function get_post( $post_id ) { $request_args = array( 'method' => 'GET' ); - $request = ep_remote_request( $path, apply_filters( 'ep_get_post_request_args', $request_args, $post_id ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_get_post_request_args', $request_args, $post_id ), array(), 'get_post' ); if ( ! is_wp_error( $request ) ) { $response_body = wp_remote_retrieve_body( $request ); @@ -398,7 +401,7 @@ public function delete_network_alias() { $request_args = array( 'method' => 'DELETE' ); - $request = ep_remote_request( $path, apply_filters( 'ep_delete_network_alias_request_args', $request_args ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_delete_network_alias_request_args', $request_args ), array(), 'delete_network_alias' ); if ( ! is_wp_error( $request ) && ( 200 >= wp_remote_retrieve_response_code( $request ) && 300 > wp_remote_retrieve_response_code( $request ) ) ) { $response_body = wp_remote_retrieve_body( $request ); @@ -438,9 +441,10 @@ public function create_network_alias( $indexes ) { $request_args = array( 'body' => json_encode( $args ), 'method' => 'POST', + 'timeout' => 25, ); - $request = ep_remote_request( $path, apply_filters( 'ep_create_network_alias_request_args', $request_args, $args, $indexes ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_create_network_alias_request_args', $request_args, $args, $indexes ), array(), 'create_network_alias' ); if ( ! is_wp_error( $request ) && ( 200 >= wp_remote_retrieve_response_code( $request ) && 300 > wp_remote_retrieve_response_code( $request ) ) ) { $response_body = wp_remote_retrieve_body( $request ); @@ -466,6 +470,8 @@ public function put_mapping() { if ( ! $es_version || version_compare( $es_version, '5.0' ) < 0 ) { $mapping_file = 'pre-5-0.php'; + } elseif ( version_compare( $es_version, '5.2' ) >= 0 ) { + $mapping_file = '5-2.php'; } else { $mapping_file = '5-0.php'; } @@ -502,9 +508,10 @@ public function put_mapping() { $request_args = array( 'body' => json_encode( $mapping ), 'method' => 'PUT', + 'timeout' => 30, ); - $request = ep_remote_request( $index, apply_filters( 'ep_put_mapping_request_args', $request_args ) ); + $request = ep_remote_request( $index, apply_filters( 'ep_put_mapping_request_args', $request_args ), array(), 'put_mapping' ); $request = apply_filters( 'ep_config_mapping_request', $request, $index, $mapping ); @@ -593,7 +600,7 @@ public function prepare_post( $post_id ) { 'post_mime_type' => $post->post_mime_type, 'permalink' => get_permalink( $post_id ), 'terms' => $this->prepare_terms( $post ), - 'post_meta' => $this->prepare_meta( $post ), + 'meta' => $this->prepare_meta_types( $this->prepare_meta( $post ) ), // post_meta removed in 2.4 'date_terms' => $this->prepare_date_terms( $post_date ), 'comment_count' => $comment_count, 'comment_status' => $comment_status, @@ -608,8 +615,6 @@ public function prepare_post( $post_id ) { */ $post_args = apply_filters( 'ep_post_sync_args', $post_args, $post_id ); - $post_args['meta'] = $this->prepare_meta_types( $post_args['post_meta'] ); - $post_args = apply_filters( 'ep_post_sync_args_post_prepare_meta', $post_args, $post_id ); // Turn back on updated_postmeta hook @@ -620,7 +625,7 @@ public function prepare_post( $post_id ) { /** * Prepare text for ES: Strip html, strip line breaks, etc. - * + * * @param string $content * @since 2.2 * @return string @@ -671,7 +676,7 @@ private function prepare_terms( $post ) { $selected_taxonomies = array(); foreach ( $taxonomies as $taxonomy ) { - if ( $taxonomy->public ) { + if ( $taxonomy->public || $taxonomy->publicly_queryable ) { $selected_taxonomies[] = $taxonomy; } } @@ -687,6 +692,11 @@ private function prepare_terms( $post ) { $allow_hierarchy = apply_filters( 'ep_sync_terms_allow_hierarchy', false ); foreach ( $selected_taxonomies as $taxonomy ) { + // We check if the $taxonomy object as name property. Backward compatibility since WP_Taxonomy introduced in WP 4.7 + if ( ! property_exists( $taxonomy, 'name' ) ) { + continue; + } + $object_terms = get_the_terms( $post->ID, $taxonomy->name ); if ( ! $object_terms || is_wp_error( $object_terms ) ) { @@ -901,9 +911,9 @@ public function delete_index( $index_name = null ) { $index = ( null === $index_name ) ? ep_get_index_name() : sanitize_text_field( $index_name ); - $request_args = array( 'method' => 'DELETE' ); + $request_args = array( 'method' => 'DELETE', 'timeout' => 30, ); - $request = ep_remote_request( $index, apply_filters( 'ep_delete_index_request_args', $request_args ) ); + $request = ep_remote_request( $index, apply_filters( 'ep_delete_index_request_args', $request_args ), array(), 'delete_index' ); // 200 means the delete was successful // 404 means the index was non-existent, but we should still pass this through as we will occasionally want to delete an already deleted index @@ -929,7 +939,7 @@ public function index_exists( $index_name = null ) { $request_args = array( 'method' => 'HEAD' ); - $request = ep_remote_request( $index, apply_filters( 'ep_index_exists_request_args', $request_args, $index_name ) ); + $request = ep_remote_request( $index, apply_filters( 'ep_index_exists_request_args', $request_args, $index_name ), array(), 'index_exists' ); // 200 means the index exists // 404 means the index was non-existent @@ -1071,7 +1081,7 @@ public function format_args( $args ) { if ( ! empty( $args['tax_query'] ) ) { $tax_filter = array(); $tax_must_not_filter = array(); - + // Main tax_query array for ES $es_tax_query = array(); @@ -1089,16 +1099,45 @@ public function format_args( $args ) { $terms_obj = array( 'terms.' . $single_tax_query['taxonomy'] . '.' . $field => $terms, ); - - /* - * add support for "NOT IN" operator - * - * @since 2.1 - */ - if ( ! empty( $single_tax_query['operator'] ) && 'NOT IN' === $single_tax_query['operator'] ) { + + $operator = ( ! empty( $single_tax_query['operator'] ) ) ? strtolower( $single_tax_query['operator'] ) : 'in'; + + if ( 'not in' === $operator ) { + /** + * add support for "NOT IN" operator + * + * @since 2.1 + */ + // If "NOT IN" than it should filter as must_not $tax_must_not_filter[]['terms'] = $terms_obj; + } elseif ( 'and' === $operator ) { + /** + * add support for "and" operator + * + * @since 2.4 + */ + + $and_nest = array( + 'bool' => array( + 'must' => array() + ), + ); + + foreach ( $terms as $term ) { + $and_nest['bool']['must'][] = array( + 'terms' => array( + 'terms.' . $single_tax_query['taxonomy'] . '.' . $field => (array) $term, + ) + ); + } + + $tax_filter[] = $and_nest; } else { + /** + * Default to IN operator + */ + // Add the tax query filter $tax_filter[]['terms'] = $terms_obj; } @@ -1114,15 +1153,15 @@ public function format_args( $args ) { $es_tax_query[$relation] = $tax_filter; } - + if ( ! empty( $tax_must_not_filter ) ) { $es_tax_query['must_not'] = $tax_must_not_filter; } - + if( ! empty( $es_tax_query ) ) { $filter['bool']['must'][]['bool'] = $es_tax_query; } - + $use_filters = true; } @@ -1193,7 +1232,7 @@ public function format_args( $args ) { $use_filters = true; } - + /** * Add support for post_mime_type * @@ -1210,7 +1249,7 @@ public function format_args( $args ) { 'post_mime_type' => (array)$args['post_mime_type'], ), ); - + $use_filters = true; } elseif( is_string( $args['post_mime_type'] ) ) { $filter['bool']['must'][] = array( @@ -1218,7 +1257,7 @@ public function format_args( $args ) { 'post_mime_type' => $args['post_mime_type'] . ".*", ), ); - + $use_filters = true; } } @@ -1294,7 +1333,7 @@ public function format_args( $args ) { if ( ! empty( $args['meta_query'] ) && ! empty( $args['meta_query']['relation'] ) && 'or' === strtolower( $args['meta_query']['relation'] ) ) { $relation = 'should'; } - + // get meta query filter $meta_filter = $this->build_meta_query( $meta_queries ); @@ -1337,7 +1376,8 @@ public function format_args( $args ) { if ( in_array( 'author_name', $search_field_args ) ) { $search_fields[] = 'post_author.login'; - unset( $search_field_args['author_name'] ); + $author_name_index = array_search( 'author_name', $search_field_args ); + unset( $search_field_args[ $author_name_index ] ); } $search_fields = array_merge( $search_field_args, $search_fields ); @@ -1399,7 +1439,7 @@ public function format_args( $args ) { 'boost' => 1, ); } - + /** * Order by 'rand' support * @@ -1516,6 +1556,30 @@ public function format_args( $args ) { $formatted_args['post_filter'] = $filter; } + /** + * Support fields. + */ + if ( isset( $args['fields'] ) ) { + switch ( $args['fields'] ) { + case 'ids': + $formatted_args['_source'] = array( + 'include' => array( + 'post_id', + ), + ); + break; + + case 'id=>parent': + $formatted_args['_source'] = array( + 'include' => array( + 'post_id', + 'post_parent', + ), + ); + break; + } + } + /** * Aggregations */ @@ -1541,7 +1605,7 @@ public function format_args( $args ) { } return apply_filters( 'ep_formatted_args', $formatted_args, $args ); } - + /** * Build Elasticsearch filter query for WP meta_query * @@ -1553,9 +1617,9 @@ public function format_args( $args ) { */ public function build_meta_query( $meta_queries ){ $meta_filter = array(); - + if ( ! empty( $meta_queries ) ) { - + $meta_query_type_mapping = array( 'numeric' => 'long', 'binary' => 'raw', @@ -1567,9 +1631,9 @@ public function build_meta_query( $meta_queries ){ 'time' => 'time', 'unsigned' => 'long', ); - + foreach( $meta_queries as $single_meta_query ) { - + /** * There is a strange case where meta_query looks like this: * array( @@ -1588,26 +1652,26 @@ public function build_meta_query( $meta_queries ){ if ( is_array( $single_meta_query ) && empty( $single_meta_query['key'] ) ) { reset( $single_meta_query ); $first_key = key( $single_meta_query ); - + if ( is_array( $single_meta_query[$first_key] ) ) { $single_meta_query = $single_meta_query[$first_key]; } } - + if ( ! empty( $single_meta_query['key'] ) ) { - + $terms_obj = false; - + $compare = '='; if ( ! empty( $single_meta_query['compare'] ) ) { $compare = strtolower( $single_meta_query['compare'] ); } - + $type = null; if ( ! empty( $single_meta_query['type'] ) ) { $type = strtolower( $single_meta_query['type'] ); } - + // Comparisons need to look at different paths if ( in_array( $compare, array( 'exists', 'not exists' ) ) ) { $meta_key_path = 'meta.' . $single_meta_query['key']; @@ -1623,7 +1687,7 @@ public function build_meta_query( $meta_queries ){ } else { $meta_key_path = 'meta.' . $single_meta_query['key'] . '.raw'; } - + switch ( $compare ) { case 'not in': case '!=': @@ -1640,7 +1704,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case 'exists': $terms_obj = array( @@ -1648,7 +1712,7 @@ public function build_meta_query( $meta_queries ){ 'field' => $meta_key_path, ), ); - + break; case 'not exists': $terms_obj = array( @@ -1662,7 +1726,7 @@ public function build_meta_query( $meta_queries ){ ), ), ); - + break; case '>=': if ( isset( $single_meta_query['value'] ) ) { @@ -1680,7 +1744,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case 'between': if ( isset( $single_meta_query['value'] ) && is_array( $single_meta_query['value'] ) && 2 === count( $single_meta_query['value'] ) ) { @@ -1705,7 +1769,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case '<=': if ( isset( $single_meta_query['value'] ) ) { @@ -1723,7 +1787,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case '>': if ( isset( $single_meta_query['value'] ) ) { @@ -1741,7 +1805,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case '<': if ( isset( $single_meta_query['value'] ) ) { @@ -1759,7 +1823,7 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; case 'like': if ( isset( $single_meta_query['value'] ) ) { @@ -1781,10 +1845,10 @@ public function build_meta_query( $meta_queries ){ ), ); } - + break; } - + // Add the meta query filter if ( false !== $terms_obj ) { $meta_filter[] = $terms_obj; @@ -1816,7 +1880,7 @@ public function build_meta_query( $meta_queries ){ if ( ! empty( $single_meta_query['relation'] ) && 'or' === strtolower( $single_meta_query['relation'] ) ) { $relation = 'should'; } - + $meta_filter[] = array( 'bool' => array( $relation => $this->build_meta_query( $single_meta_query ), @@ -1825,7 +1889,7 @@ public function build_meta_query( $meta_queries ){ } } } - + return $meta_filter; } @@ -1878,7 +1942,7 @@ public function bulk_index_posts( $body ) { 'timeout' => 30, ); - $request = ep_remote_request( $path, apply_filters( 'ep_bulk_index_posts_request_args', $request_args, $body ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_bulk_index_posts_request_args', $request_args, $body ), array(), 'bulk_index_posts' ); if ( is_wp_error( $request ) ) { return $request; @@ -2023,7 +2087,7 @@ protected function parse_orderby( $orderbys, $default_order, $args ) { return $sort; } - + /** * Get Order by args Array * @@ -2036,7 +2100,7 @@ protected function get_orderby_array( $orderbys ){ if ( ! is_array( $orderbys ) ) { $orderbys = explode( ' ', $orderbys ); } - + return $orderbys; } @@ -2060,10 +2124,15 @@ public function get_query_log() { * @param string $path Site URL to retrieve. * @param array $args Optional. Request arguments. Default empty array. * @param array $query_args Optional. The query args originally passed to WP_Query + * @param string Type of request, used for debugging * * @return WP_Error|array The response or WP_Error on failure. */ - public function remote_request( $path, $args = array(), $query_args = array() ) { + public function remote_request( $path, $args = array(), $query_args = array(), $type = null ) { + + if ( empty( $args['method'] ) ) { + $args['method'] = 'GET'; + } $query = array( 'time_start' => microtime( true ), @@ -2089,7 +2158,11 @@ public function remote_request( $path, $args = array(), $query_args = array() ) $request = wp_remote_request( $query['url'], $args ); //try the existing host to avoid unnecessary calls - if ( false === $request || is_wp_error( $request ) || ( isset( $request['response']['code'] ) && 0 !== strpos( $request['response']['code'], '20' ) ) ) { + $request_response_code = (int) wp_remote_retrieve_response_code( $request ); + + $is_valid_res = ( $request_response_code >= 200 && $request_response_code <= 299 ); + + if ( false === $request || is_wp_error( $request ) || ! $is_valid_res ) { $failures++; if ( $failures >= apply_filters( 'ep_max_remote_request_tries', 1, $path, $args ) ) { @@ -2113,6 +2186,8 @@ public function remote_request( $path, $args = array(), $query_args = array() ) $query['request'] = $request; $this->_add_query_log( $query ); + do_action( 'ep_remote_request', $query, $type ); + return $request; } @@ -2203,7 +2278,7 @@ public function get_elasticsearch_info( $force = false ) { /** * Try a different endpoint in case the plugins url is restricted - * + * * @since 2.2.1 */ @@ -2311,7 +2386,7 @@ public function get_cluster_status() { /** * Get a pipeline - * + * * @param string $id * @since 2.3 * @return WP_Error|bool|array @@ -2323,7 +2398,7 @@ public function get_pipeline( $id ) { 'method' => 'GET', ); - $request = ep_remote_request( $path, apply_filters( 'ep_get_pipeline_args', $request_args ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_get_pipeline_args', $request_args ), array(), 'get_pipeline' ); if ( is_wp_error( $request ) ) { return $request; @@ -2346,7 +2421,7 @@ public function get_pipeline( $id ) { /** * Put a pipeline - * + * * @param string $id * @param array $args * @since 2.3 @@ -2360,7 +2435,7 @@ public function create_pipeline( $id, $args ) { 'method' => 'PUT', ); - $request = ep_remote_request( $path, apply_filters( 'ep_get_pipeline_args', $request_args ) ); + $request = ep_remote_request( $path, apply_filters( 'ep_get_pipeline_args', $request_args ), array(), 'create_pipeline' ); if ( is_wp_error( $request ) ) { return $request; @@ -2413,7 +2488,7 @@ public function get_index_status( $blog_id = null ) { } - $request = ep_remote_request( $path, array( 'method' => 'GET' ) ); + $request = ep_remote_request( $path, array( 'method' => 'GET' ), array(), 'get_index_status' ); } @@ -2464,7 +2539,7 @@ public function get_search_status( $blog_id = null ) { } - $request = ep_remote_request( $path, array( 'method' => 'GET' ) ); + $request = ep_remote_request( $path, array( 'method' => 'GET' ), array(), 'get_search_status' ); } @@ -2591,8 +2666,8 @@ function ep_format_request_headers() { return EP_API::factory()->format_request_headers(); } -function ep_remote_request( $path, $args = array(), $query_args = array() ) { - return EP_API::factory()->remote_request( $path, $args, $query_args ); +function ep_remote_request( $path, $args = array(), $query_args = array(), $type = null ) { + return EP_API::factory()->remote_request( $path, $args, $query_args, $type ); } function ep_get_query_log() { diff --git a/classes/class-ep-config.php b/classes/class-ep-config.php index fc4d7d7ac4..f2ac221f9f 100644 --- a/classes/class-ep-config.php +++ b/classes/class-ep-config.php @@ -54,7 +54,7 @@ public function is_indexing() { } /** - * Check if wpcli indexing is occuring + * Check if wpcli indexing is occurring * * @since 2.1 * @return boolean diff --git a/classes/class-ep-dashboard.php b/classes/class-ep-dashboard.php index 600db777f4..6002e96f2a 100644 --- a/classes/class-ep-dashboard.php +++ b/classes/class-ep-dashboard.php @@ -273,6 +273,8 @@ public function maybe_notice( $force = false ) { $notice = 'need-setup'; } + $notice = apply_filters( 'ep_admin_notice_type', $notice ); + switch ( $notice ) { case 'bad-host': if ( defined( 'EP_IS_NETWORK' ) && EP_IS_NETWORK ) { @@ -285,21 +287,21 @@ public function maybe_notice( $force = false ) { ?>
-

try your host again, or you may need to change your settings.', 'elasticpress' ), esc_url( add_query_arg( 'ep-retry', 1 ) ), esc_url( $url ) ); ?>

-
+

try your host again, or you may need to change your settings.', 'elasticpress' ) ), esc_url( add_query_arg( 'ep-retry', 1 ) ), esc_url( $url ) ); ?>

+
-

-
+

+
-

+

-

quick set up process to get the plugin working.', 'elasticpress' ), esc_url( $url ) ); ?>

+

quick set up process to get the plugin working.', 'elasticpress' ) ), esc_url( $url ) ); ?>

-

sync to get the plugin working.', 'elasticpress' ), esc_url( $url ) ); ?>

-
+

sync to get the plugin working.', 'elasticpress' ) ), esc_url( $url ) ); ?>

+
-

run a sync.', 'elasticpress' ), esc_url( $url ) ); ?>

+

run a sync.', 'elasticpress' ) ), esc_url( $url ) ); ?>

-

title ) ); ?>

+

title ) ); ?>

-

+

-

-
+

+ -
-
-
-
- +
+
+
+
+
+ +
-
- feature_box_settings_cb ) ) { - call_user_func( $this->feature_box_settings_cb, $this ); - return; - } - do_action( 'ep_feature_box_settings', $this->slug, $this ); - ?> + feature_box_settings_cb ) ) { + call_user_func( $this->feature_box_settings_cb, $this ); + return; + } + + do_action( 'ep_feature_box_settings_' . $this->slug, $this ); + + ?> +
diff --git a/classes/class-ep-features.php b/classes/class-ep-features.php index 2eb51af15b..ca8fe99f0c 100644 --- a/classes/class-ep-features.php +++ b/classes/class-ep-features.php @@ -27,7 +27,7 @@ class EP_Features { */ public function setup() { add_action( 'plugins_loaded', array( $this, 'handle_feature_activation' ), 12 ); - add_action( 'plugins_loaded', array( $this, 'setup_features' ), 11 ); + add_action( 'init', array( $this, 'setup_features' ), 0 ); } /** diff --git a/classes/class-ep-wp-query-integration.php b/classes/class-ep-wp-query-integration.php index a245bf21eb..ab4faaf7cd 100644 --- a/classes/class-ep-wp-query-integration.php +++ b/classes/class-ep-wp-query-integration.php @@ -47,6 +47,9 @@ public function setup() { // Nukes the FOUND_ROWS() database query add_filter( 'found_posts_query', array( $this, 'filter_found_posts_query' ), 5, 2 ); + // Support "fields". + add_filter( 'posts_pre_query', array( $this, 'posts_fields' ), 10, 2 ); + // Query and filter in EP_Posts to WP_Query add_filter( 'the_posts', array( $this, 'filter_the_posts' ), 10, 2 ); @@ -188,6 +191,36 @@ public function filter_found_posts_query( $sql, $query ) { return ''; } + /** + * Workaround for when WP_Query short circuits for special fields arguments. + * + * @since 2.4.0 + * + * @param array $posts + * Return an array of post data to short-circuit WP's query, + * or null to allow WP to run its normal queries. + * @param WP_Query $query + * WP_Query object. + * + * @return array + * An array of fields. + */ + public function posts_fields( $posts, $query ) { + // Make sure the query is EP enabled. + if ( ! ep_elasticpress_enabled( $query ) || apply_filters( 'ep_skip_query_integration', false, $query ) || ! isset( $this->posts_by_query[ spl_object_hash( $query ) ] ) ) { + return $posts; + } + + // Determine how we should return the posts. The official WP_Query + // supports: ids, id=>parent and post objects. + $fields = $query->get( 'fields', '' ); + if ( 'ids' === $fields || 'id=>parent' === $fields ) { + return $this->posts_by_query[ spl_object_hash( $query ) ]; + } + + return $posts; + } + /** * Filter query string used for get_posts(). Query for posts and save for later. * Return a query that will return nothing. @@ -268,67 +301,136 @@ public function filter_posts_request( $request, $query ) { $query->max_num_pages = ceil( $ep_query['found_posts'] / $query->get( 'posts_per_page' ) ); $query->elasticsearch_success = true; - foreach ( $ep_query['posts'] as $post_array ) { - $post = new stdClass(); + // Determine how we should format the results from ES based on the fields + // parameter. + $fields = $query->get( 'fields', '' ); + switch ( $fields ) { + case 'ids' : + $new_posts = $this->format_hits_as_ids( $ep_query['posts'], $new_posts ); + break; + + case 'id=>parent' : + $new_posts = $this->format_hits_as_id_parents( $ep_query['posts'], $new_posts ); + break; + + default: + $new_posts = $this->format_hits_as_posts( $ep_query['posts'], $new_posts ); + break; + } - $post->ID = $post_array['post_id']; - $post->site_id = get_current_blog_id(); + do_action( 'ep_wp_query_non_cached_search', $new_posts, $ep_query, $query ); + } - if ( ! empty( $post_array['site_id'] ) ) { - $post->site_id = $post_array['site_id']; - } - // ep_search_request_args - $post_return_args = apply_filters( 'ep_search_post_return_args', - array( - 'post_type', - 'post_author', - 'post_name', - 'post_status', - 'post_title', - 'post_parent', - 'post_content', - 'post_excerpt', - 'post_date', - 'post_date_gmt', - 'post_modified', - 'post_modified_gmt', - 'post_mime_type', - 'comment_count', - 'comment_status', - 'ping_status', - 'menu_order', - 'permalink', - 'terms', - 'post_meta', - 'meta', - ) - ); - - foreach ( $post_return_args as $key ) { - if( $key === 'post_author' ) { - $post->$key = $post_array[$key]['id']; - } elseif ( isset( $post_array[ $key ] ) ) { - $post->$key = $post_array[$key]; - } - } + $this->posts_by_query[spl_object_hash( $query )] = $new_posts; - $post->elasticsearch = true; // Super useful for debugging + do_action( 'ep_wp_query_search', $new_posts, $ep_query, $query ); - if ( $post ) { - $new_posts[] = $post; + return "SELECT * FROM $wpdb->posts WHERE 1=0"; + } + + /** + * Format the ES hits/results as post objects. + * + * @since 2.4.0 + * + * @param array $posts The posts that should be formatted. + * @param array $new_posts Array of posts from cache. + * + * @return array + */ + protected function format_hits_as_posts( $posts, $new_posts ) { + foreach ( $posts as $post_array ) { + $post = new stdClass(); + + $post->ID = $post_array['post_id']; + $post->site_id = get_current_blog_id(); + + if ( ! empty( $post_array['site_id'] ) ) { + $post->site_id = $post_array['site_id']; + } + // ep_search_request_args + $post_return_args = apply_filters( 'ep_search_post_return_args', + array( + 'post_type', + 'post_author', + 'post_name', + 'post_status', + 'post_title', + 'post_parent', + 'post_content', + 'post_excerpt', + 'post_date', + 'post_date_gmt', + 'post_modified', + 'post_modified_gmt', + 'post_mime_type', + 'comment_count', + 'comment_status', + 'ping_status', + 'menu_order', + 'permalink', + 'terms', + 'post_meta', + 'meta', + ) + ); + + foreach ( $post_return_args as $key ) { + if( $key === 'post_author' ) { + $post->$key = $post_array[$key]['id']; + } elseif ( isset( $post_array[ $key ] ) ) { + $post->$key = $post_array[$key]; } } - do_action( 'ep_wp_query_non_cached_search', $new_posts, $ep_query, $query ); + $post->elasticsearch = true; // Super useful for debugging + + if ( $post ) { + $new_posts[] = $post; + } } - $this->posts_by_query[spl_object_hash( $query )] = $new_posts; + return $new_posts; + } - do_action( 'ep_wp_query_search', $new_posts, $ep_query, $query ); + /** + * Format the ES hits/results as an array of ids. + * + * @since 2.4.0 + * + * @param array $posts The posts that should be formatted. + * @param array $new_posts Array of posts from cache. + * + * @return array + */ + protected function format_hits_as_ids( $posts, $new_posts ) { + foreach ( $posts as $post_array ) { + $new_posts[] = $post_array['post_id']; + } - return "SELECT * FROM $wpdb->posts WHERE 1=0"; + return $new_posts; } + /** + * Format the ES hits/results as objects containing id and parent id. + * + * @since 2.4.0 + * + * @param array $posts The posts that should be formatted. + * @param array $new_posts Array of posts from cache. + * + * @return array + */ + protected function format_hits_as_id_parents( $posts, $new_posts ) { + foreach ( $posts as $post_array ) { + $post = new stdClass(); + $post->ID = $post_array['post_id']; + $post->post_parent = $post_array['post_parent']; + $post->elasticsearch = true; // Super useful for debugging + $new_posts[] = $post; + } + return $new_posts; + } /** * Return a singleton instance of the current class diff --git a/composer.lock b/composer.lock index c4d29b4ec0..c0a4fdd33a 100644 --- a/composer.lock +++ b/composer.lock @@ -9,16 +9,16 @@ "packages-dev": [ { "name": "composer/ca-bundle", - "version": "1.0.6", + "version": "1.0.7", "source": { "type": "git", "url": "https://github.com/composer/ca-bundle.git", - "reference": "a795611394b3c05164fd0eb291b492b39339cba4" + "reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/ca-bundle/zipball/a795611394b3c05164fd0eb291b492b39339cba4", - "reference": "a795611394b3c05164fd0eb291b492b39339cba4", + "url": "https://api.github.com/repos/composer/ca-bundle/zipball/b17e6153cb7f33c7e44eb59578dc12eee5dc8e12", + "reference": "b17e6153cb7f33c7e44eb59578dc12eee5dc8e12", "shasum": "" }, "require": { @@ -27,6 +27,7 @@ "php": "^5.3.2 || ^7.0" }, "require-dev": { + "phpunit/phpunit": "^4.5", "psr/log": "^1.0", "symfony/process": "^2.5 || ^3.0" }, @@ -63,27 +64,27 @@ "ssl", "tls" ], - "time": "2016-11-02T18:11:27+00:00" + "time": "2017-03-06T11:59:08+00:00" }, { "name": "composer/composer", - "version": "1.3.0", + "version": "1.4.2", "source": { "type": "git", "url": "https://github.com/composer/composer.git", - "reference": "e53f9e5381e70f76e098136343e27d92601eade7" + "reference": "489e09ee6c3ba431fbeeef9147afdaeb6f91b647" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/e53f9e5381e70f76e098136343e27d92601eade7", - "reference": "e53f9e5381e70f76e098136343e27d92601eade7", + "url": "https://api.github.com/repos/composer/composer/zipball/489e09ee6c3ba431fbeeef9147afdaeb6f91b647", + "reference": "489e09ee6c3ba431fbeeef9147afdaeb6f91b647", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", "composer/semver": "^1.0", "composer/spdx-licenses": "^1.0", - "justinrainbow/json-schema": "^1.6 || ^2.0 || ^3.0 || ^4.0", + "justinrainbow/json-schema": "^3.0 || ^4.0 || ^5.0", "php": "^5.3.2 || ^7.0", "psr/log": "^1.0", "seld/cli-prompt": "^1.0", @@ -109,7 +110,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -140,20 +141,20 @@ "dependency", "package" ], - "time": "2016-12-23T23:47:04+00:00" + "time": "2017-05-17T06:17:53+00:00" }, { "name": "composer/installers", - "version": "v1.2.0", + "version": "v1.3.0", "source": { "type": "git", "url": "https://github.com/composer/installers.git", - "reference": "d78064c68299743e0161004f2de3a0204e33b804" + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/installers/zipball/d78064c68299743e0161004f2de3a0204e33b804", - "reference": "d78064c68299743e0161004f2de3a0204e33b804", + "url": "https://api.github.com/repos/composer/installers/zipball/79ad876c7498c0bbfe7eed065b8651c93bfd6045", + "reference": "79ad876c7498c0bbfe7eed065b8651c93bfd6045", "shasum": "" }, "require": { @@ -195,12 +196,16 @@ "keywords": [ "Craft", "Dolibarr", + "Eliasis", "Hurad", "ImageCMS", + "Kanboard", "MODX Evo", "Mautic", + "Maya", "OXID", "Plentymarkets", + "Porto", "RadPHP", "SMF", "Thelia", @@ -223,9 +228,11 @@ "fuelphp", "grav", "installer", + "itop", "joomla", "kohana", "laravel", + "lavalite", "lithium", "magento", "mako", @@ -240,6 +247,7 @@ "roundcube", "shopware", "silverstripe", + "sydes", "symfony", "typo3", "wordpress", @@ -247,7 +255,7 @@ "zend", "zikula" ], - "time": "2016-08-13T20:53:52+00:00" + "time": "2017-04-24T06:37:16+00:00" }, { "name": "composer/semver", @@ -313,16 +321,16 @@ }, { "name": "composer/spdx-licenses", - "version": "1.1.5", + "version": "1.1.6", "source": { "type": "git", "url": "https://github.com/composer/spdx-licenses.git", - "reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13" + "reference": "2603a0d7ddc00a015deb576fa5297ca43dee6b1c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/96c6a07b05b716e89a44529d060bc7f5c263cb13", - "reference": "96c6a07b05b716e89a44529d060bc7f5c263cb13", + "url": "https://api.github.com/repos/composer/spdx-licenses/zipball/2603a0d7ddc00a015deb576fa5297ca43dee6b1c", + "reference": "2603a0d7ddc00a015deb576fa5297ca43dee6b1c", "shasum": "" }, "require": { @@ -370,7 +378,7 @@ "spdx", "validator" ], - "time": "2016-09-28T07:17:45+00:00" + "time": "2017-04-03T19:08:52+00:00" }, { "name": "doctrine/instantiator", @@ -428,24 +436,25 @@ }, { "name": "justinrainbow/json-schema", - "version": "4.1.0", + "version": "5.2.1", "source": { "type": "git", "url": "https://github.com/justinrainbow/json-schema.git", - "reference": "d39c56a46b3ebe1f3696479966cd2b9f50aaa24f" + "reference": "429be236f296ca249d61c65649cdf2652f4a5e80" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/d39c56a46b3ebe1f3696479966cd2b9f50aaa24f", - "reference": "d39c56a46b3ebe1f3696479966cd2b9f50aaa24f", + "url": "https://api.github.com/repos/justinrainbow/json-schema/zipball/429be236f296ca249d61c65649cdf2652f4a5e80", + "reference": "429be236f296ca249d61c65649cdf2652f4a5e80", "shasum": "" }, "require": { "php": ">=5.3.3" }, "require-dev": { + "friendsofphp/php-cs-fixer": "^2.1", "json-schema/json-schema-test-suite": "1.2.0", - "phpdocumentor/phpdocumentor": "~2", + "phpdocumentor/phpdocumentor": "^2.7", "phpunit/phpunit": "^4.8.22" }, "bin": [ @@ -454,7 +463,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "4.0.x-dev" + "dev-master": "5.0.x-dev" } }, "autoload": { @@ -490,20 +499,20 @@ "json", "schema" ], - "time": "2016-12-22T16:43:46+00:00" + "time": "2017-05-16T21:06:09+00:00" }, { "name": "mustache/mustache", - "version": "v2.11.1", + "version": "v2.12.0", "source": { "type": "git", "url": "https://github.com/bobthecow/mustache.php.git", - "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f" + "reference": "fe8fe72e9d580591854de404cc59a1b83ca4d19e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/a3f6d55996dd28b58f3a909d474189a3c1aa693f", - "reference": "a3f6d55996dd28b58f3a909d474189a3c1aa693f", + "url": "https://api.github.com/repos/bobthecow/mustache.php/zipball/fe8fe72e9d580591854de404cc59a1b83ca4d19e", + "reference": "fe8fe72e9d580591854de404cc59a1b83ca4d19e", "shasum": "" }, "require": { @@ -536,57 +545,7 @@ "mustache", "templating" ], - "time": "2016-07-31T06:18:27+00:00" - }, - { - "name": "mustangostang/spyc", - "version": "0.6.1", - "source": { - "type": "git", - "url": "https://github.com/mustangostang/spyc.git", - "reference": "022532641d61d383fd3ae666982bd46e61e5915e" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/mustangostang/spyc/zipball/022532641d61d383fd3ae666982bd46e61e5915e", - "reference": "022532641d61d383fd3ae666982bd46e61e5915e", - "shasum": "" - }, - "require": { - "php": ">=5.3.1" - }, - "require-dev": { - "phpunit/phpunit": "4.3.*@dev" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "0.5.x-dev" - } - }, - "autoload": { - "files": [ - "Spyc.php" - ] - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "mustangostang", - "email": "vlad.andersen@gmail.com" - } - ], - "description": "A simple YAML loader/dumper class for PHP", - "homepage": "https://github.com/mustangostang/spyc/", - "keywords": [ - "spyc", - "yaml", - "yml" - ], - "time": "2016-10-21T00:03:34+00:00" + "time": "2017-07-11T12:54:05+00:00" }, { "name": "nb/oxymel", @@ -631,16 +590,16 @@ }, { "name": "phpdocumentor/reflection-docblock", - "version": "2.0.4", + "version": "2.0.5", "source": { "type": "git", "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8" + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8", - "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8", + "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/e6a969a640b00d8daa3c66518b0405fb41ae0c4b", + "reference": "e6a969a640b00d8daa3c66518b0405fb41ae0c4b", "shasum": "" }, "require": { @@ -676,31 +635,31 @@ "email": "mike.vanriel@naenius.com" } ], - "time": "2015-02-03T12:10:50+00:00" + "time": "2016-01-25T08:17:30+00:00" }, { "name": "phpspec/prophecy", - "version": "v1.6.2", + "version": "v1.7.0", "source": { "type": "git", "url": "https://github.com/phpspec/prophecy.git", - "reference": "6c52c2722f8460122f96f86346600e1077ce22cb" + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb", - "reference": "6c52c2722f8460122f96f86346600e1077ce22cb", + "url": "https://api.github.com/repos/phpspec/prophecy/zipball/93d39f1f7f9326d746203c7c056f300f7f126073", + "reference": "93d39f1f7f9326d746203c7c056f300f7f126073", "shasum": "" }, "require": { "doctrine/instantiator": "^1.0.2", "php": "^5.3|^7.0", "phpdocumentor/reflection-docblock": "^2.0|^3.0.2", - "sebastian/comparator": "^1.1", - "sebastian/recursion-context": "^1.0|^2.0" + "sebastian/comparator": "^1.1|^2.0", + "sebastian/recursion-context": "^1.0|^2.0|^3.0" }, "require-dev": { - "phpspec/phpspec": "^2.0", + "phpspec/phpspec": "^2.5|^3.2", "phpunit/phpunit": "^4.8 || ^5.6.5" }, "type": "library", @@ -739,7 +698,7 @@ "spy", "stub" ], - "time": "2016-11-21T14:58:47+00:00" + "time": "2017-03-02T20:05:34+00:00" }, { "name": "phpunit/php-code-coverage", @@ -893,25 +852,30 @@ }, { "name": "phpunit/php-timer", - "version": "1.0.8", + "version": "1.0.9", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-timer.git", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260" + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260", - "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260", + "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", + "reference": "3dcf38ca72b158baf0bc245e9184d3fdffa9c46f", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4|~5" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", + "extra": { + "branch-alias": { + "dev-master": "1.0-dev" + } + }, "autoload": { "classmap": [ "src/" @@ -933,20 +897,20 @@ "keywords": [ "timer" ], - "time": "2016-05-12T18:03:57+00:00" + "time": "2017-02-26T11:10:40+00:00" }, { "name": "phpunit/php-token-stream", - "version": "1.4.9", + "version": "1.4.11", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-token-stream.git", - "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b" + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b", - "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b", + "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/e03f8f67534427a787e21a385a67ec3ca6978ea7", + "reference": "e03f8f67534427a787e21a385a67ec3ca6978ea7", "shasum": "" }, "require": { @@ -982,20 +946,20 @@ "keywords": [ "tokenizer" ], - "time": "2016-11-15T14:06:22+00:00" + "time": "2017-02-27T10:12:30+00:00" }, { "name": "phpunit/phpunit", - "version": "4.8.31", + "version": "4.8.36", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3" + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/98b2b39a520766bec663ff5b7ff1b729db9dbfe3", - "reference": "98b2b39a520766bec663ff5b7ff1b729db9dbfe3", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/46023de9a91eec7dfb06cc56cb4e260017298517", + "reference": "46023de9a91eec7dfb06cc56cb4e260017298517", "shasum": "" }, "require": { @@ -1054,7 +1018,7 @@ "testing", "xunit" ], - "time": "2016-12-09T02:45:31+00:00" + "time": "2017-06-21T08:07:12+00:00" }, { "name": "phpunit/phpunit-mock-objects", @@ -1255,16 +1219,16 @@ }, { "name": "sebastian/comparator", - "version": "1.2.2", + "version": "1.2.4", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/comparator.git", - "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f" + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/6a1ed12e8b2409076ab22e3897126211ff8b1f7f", - "reference": "6a1ed12e8b2409076ab22e3897126211ff8b1f7f", + "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", + "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be", "shasum": "" }, "require": { @@ -1315,27 +1279,27 @@ "compare", "equality" ], - "time": "2016-11-19T09:18:40+00:00" + "time": "2017-01-29T09:50:25+00:00" }, { "name": "sebastian/diff", - "version": "1.4.1", + "version": "1.4.3", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/diff.git", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e" + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e", - "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e", + "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/7f066a26a962dbe58ddea9f72a4e82874a3975a4", + "reference": "7f066a26a962dbe58ddea9f72a4e82874a3975a4", "shasum": "" }, "require": { - "php": ">=5.3.3" + "php": "^5.3.3 || ^7.0" }, "require-dev": { - "phpunit/phpunit": "~4.8" + "phpunit/phpunit": "^4.8.35 || ^5.7 || ^6.0" }, "type": "library", "extra": { @@ -1367,7 +1331,7 @@ "keywords": [ "diff" ], - "time": "2015-12-08T07:14:41+00:00" + "time": "2017-05-22T07:24:03+00:00" }, { "name": "sebastian/environment", @@ -1539,16 +1503,16 @@ }, { "name": "sebastian/recursion-context", - "version": "1.0.2", + "version": "1.0.5", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/recursion-context.git", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791" + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/913401df809e99e4f47b27cdd781f4a258d58791", - "reference": "913401df809e99e4f47b27cdd781f4a258d58791", + "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7", + "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7", "shasum": "" }, "require": { @@ -1588,7 +1552,7 @@ ], "description": "Provides functionality to recursively process PHP variables", "homepage": "http://www.github.com/sebastianbergmann/recursion-context", - "time": "2015-11-11T19:50:13+00:00" + "time": "2016-10-03T07:41:43+00:00" }, { "name": "sebastian/version", @@ -1627,16 +1591,16 @@ }, { "name": "seld/cli-prompt", - "version": "1.0.2", + "version": "1.0.3", "source": { "type": "git", "url": "https://github.com/Seldaek/cli-prompt.git", - "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4" + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", - "reference": "8cbe10923cae5bcd7c5a713f6703fc4727c8c1b4", + "url": "https://api.github.com/repos/Seldaek/cli-prompt/zipball/a19a7376a4689d4d94cab66ab4f3c816019ba8dd", + "reference": "a19a7376a4689d4d94cab66ab4f3c816019ba8dd", "shasum": "" }, "require": { @@ -1671,25 +1635,28 @@ "input", "prompt" ], - "time": "2016-04-18T09:31:41+00:00" + "time": "2017-03-18T11:32:45+00:00" }, { "name": "seld/jsonlint", - "version": "1.5.0", + "version": "1.6.1", "source": { "type": "git", "url": "https://github.com/Seldaek/jsonlint.git", - "reference": "19495c181d6d53a0a13414154e52817e3b504189" + "reference": "50d63f2858d87c4738d5b76a7dcbb99fa8cf7c77" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/19495c181d6d53a0a13414154e52817e3b504189", - "reference": "19495c181d6d53a0a13414154e52817e3b504189", + "url": "https://api.github.com/repos/Seldaek/jsonlint/zipball/50d63f2858d87c4738d5b76a7dcbb99fa8cf7c77", + "reference": "50d63f2858d87c4738d5b76a7dcbb99fa8cf7c77", "shasum": "" }, "require": { "php": "^5.3 || ^7.0" }, + "require-dev": { + "phpunit/phpunit": "^4.5" + }, "bin": [ "bin/jsonlint" ], @@ -1717,7 +1684,7 @@ "parser", "validator" ], - "time": "2016-11-14T17:59:58+00:00" + "time": "2017-06-18T15:11:04+00:00" }, { "name": "seld/phar-utils", @@ -1765,16 +1732,16 @@ }, { "name": "symfony/config", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/config.git", - "reference": "b522856007b258f46d5ee35d3b7b235c11e76e86" + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/config/zipball/b522856007b258f46d5ee35d3b7b235c11e76e86", - "reference": "b522856007b258f46d5ee35d3b7b235c11e76e86", + "url": "https://api.github.com/repos/symfony/config/zipball/0b8541d18507d10204a08384640ff6df3c739ebe", + "reference": "0b8541d18507d10204a08384640ff6df3c739ebe", "shasum": "" }, "require": { @@ -1817,25 +1784,25 @@ ], "description": "Symfony Config Component", "homepage": "https://symfony.com", - "time": "2016-12-10T08:21:45+00:00" + "time": "2017-04-12T14:07:15+00:00" }, { "name": "symfony/console", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "d5643cd095e5e37d31e004bb2606b5dd7e96602f" + "reference": "46e65f8d98c9ab629bbfcc16a4ff023f61c37fb2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/d5643cd095e5e37d31e004bb2606b5dd7e96602f", - "reference": "d5643cd095e5e37d31e004bb2606b5dd7e96602f", + "url": "https://api.github.com/repos/symfony/console/zipball/46e65f8d98c9ab629bbfcc16a4ff023f61c37fb2", + "reference": "46e65f8d98c9ab629bbfcc16a4ff023f61c37fb2", "shasum": "" }, "require": { "php": ">=5.3.9", - "symfony/debug": "~2.7,>=2.7.2|~3.0.0", + "symfony/debug": "^2.7.2|~3.0.0", "symfony/polyfill-mbstring": "~1.0" }, "require-dev": { @@ -1878,20 +1845,20 @@ ], "description": "Symfony Console Component", "homepage": "https://symfony.com", - "time": "2016-12-06T11:59:35+00:00" + "time": "2017-07-03T08:04:30+00:00" }, { "name": "symfony/debug", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/debug.git", - "reference": "62a68f640456f6761d752c62d81631428ef0d8a1" + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/debug/zipball/62a68f640456f6761d752c62d81631428ef0d8a1", - "reference": "62a68f640456f6761d752c62d81631428ef0d8a1", + "url": "https://api.github.com/repos/symfony/debug/zipball/8470d7701177a88edeb0cec59b44d50ef4477e9b", + "reference": "8470d7701177a88edeb0cec59b44d50ef4477e9b", "shasum": "" }, "require": { @@ -1903,7 +1870,7 @@ }, "require-dev": { "symfony/class-loader": "~2.2|~3.0.0", - "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0" + "symfony/http-kernel": "~2.3.24|~2.5.9|^2.6.2|~3.0.0" }, "type": "library", "extra": { @@ -1935,20 +1902,20 @@ ], "description": "Symfony Debug Component", "homepage": "https://symfony.com", - "time": "2016-11-15T12:53:17+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/dependency-injection", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/dependency-injection.git", - "reference": "51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7" + "reference": "66d2e252262749e0f3c735c183e4562c72ffb8c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7", - "reference": "51a7b5385fb0f42e5edbdb2cfbad1a011ecdaee7", + "url": "https://api.github.com/repos/symfony/dependency-injection/zipball/66d2e252262749e0f3c735c183e4562c72ffb8c8", + "reference": "66d2e252262749e0f3c735c183e4562c72ffb8c8", "shasum": "" }, "require": { @@ -1998,20 +1965,20 @@ ], "description": "Symfony DependencyInjection Component", "homepage": "https://symfony.com", - "time": "2016-12-08T14:41:31+00:00" + "time": "2017-06-14T00:55:24+00:00" }, { "name": "symfony/event-dispatcher", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/event-dispatcher.git", - "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934" + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", - "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934", + "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/1377400fd641d7d1935981546aaef780ecd5bf6d", + "reference": "1377400fd641d7d1935981546aaef780ecd5bf6d", "shasum": "" }, "require": { @@ -2019,7 +1986,7 @@ }, "require-dev": { "psr/log": "~1.0", - "symfony/config": "~2.0,>=2.0.5|~3.0.0", + "symfony/config": "^2.0.5|~3.0.0", "symfony/dependency-injection": "~2.6|~3.0.0", "symfony/expression-language": "~2.6|~3.0.0", "symfony/stopwatch": "~2.3|~3.0.0" @@ -2058,20 +2025,20 @@ ], "description": "Symfony EventDispatcher Component", "homepage": "https://symfony.com", - "time": "2016-10-13T01:43:15+00:00" + "time": "2017-06-02T07:47:27+00:00" }, { "name": "symfony/filesystem", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "a3784111af9f95f102b6411548376e1ae7c93898" + "reference": "b8c9c18eacc525c980d27c7a2c8fd1e09e0ed4c7" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898", - "reference": "a3784111af9f95f102b6411548376e1ae7c93898", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/b8c9c18eacc525c980d27c7a2c8fd1e09e0ed4c7", + "reference": "b8c9c18eacc525c980d27c7a2c8fd1e09e0ed4c7", "shasum": "" }, "require": { @@ -2107,20 +2074,20 @@ ], "description": "Symfony Filesystem Component", "homepage": "https://symfony.com", - "time": "2016-10-18T04:28:30+00:00" + "time": "2017-06-20T23:27:56+00:00" }, { "name": "symfony/finder", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "c0f10576335743b881ac1ed39d18c0fa66048775" + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/c0f10576335743b881ac1ed39d18c0fa66048775", - "reference": "c0f10576335743b881ac1ed39d18c0fa66048775", + "url": "https://api.github.com/repos/symfony/finder/zipball/4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", + "reference": "4f4e84811004e065a3bb5ceeb1d9aa592630f9ad", "shasum": "" }, "require": { @@ -2156,20 +2123,20 @@ ], "description": "Symfony Finder Component", "homepage": "https://symfony.com", - "time": "2016-12-13T09:38:12+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { "name": "symfony/polyfill-mbstring", - "version": "v1.3.0", + "version": "v1.4.0", "source": { "type": "git", "url": "https://github.com/symfony/polyfill-mbstring.git", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4" + "reference": "f29dca382a6485c3cbe6379f0c61230167681937" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4", - "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4", + "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/f29dca382a6485c3cbe6379f0c61230167681937", + "reference": "f29dca382a6485c3cbe6379f0c61230167681937", "shasum": "" }, "require": { @@ -2181,7 +2148,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "1.3-dev" + "dev-master": "1.4-dev" } }, "autoload": { @@ -2215,20 +2182,20 @@ "portable", "shim" ], - "time": "2016-11-14T01:06:16+00:00" + "time": "2017-06-09T14:24:12+00:00" }, { "name": "symfony/process", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "1a1bd056395540d0bc549d39818316513565d278" + "reference": "57e52a0a6a80ea0aec4fc1b785a7920a95cb88a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/1a1bd056395540d0bc549d39818316513565d278", - "reference": "1a1bd056395540d0bc549d39818316513565d278", + "url": "https://api.github.com/repos/symfony/process/zipball/57e52a0a6a80ea0aec4fc1b785a7920a95cb88a8", + "reference": "57e52a0a6a80ea0aec4fc1b785a7920a95cb88a8", "shasum": "" }, "require": { @@ -2264,20 +2231,20 @@ ], "description": "Symfony Process Component", "homepage": "https://symfony.com", - "time": "2016-11-24T00:43:03+00:00" + "time": "2017-07-03T08:04:30+00:00" }, { "name": "symfony/translation", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "edbe67e8f729885b55421d5cc58223d48540df07" + "reference": "a89af885b8c6d0142c79a02ca9cc059ed25d40d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/edbe67e8f729885b55421d5cc58223d48540df07", - "reference": "edbe67e8f729885b55421d5cc58223d48540df07", + "url": "https://api.github.com/repos/symfony/translation/zipball/a89af885b8c6d0142c79a02ca9cc059ed25d40d8", + "reference": "a89af885b8c6d0142c79a02ca9cc059ed25d40d8", "shasum": "" }, "require": { @@ -2290,7 +2257,7 @@ "require-dev": { "psr/log": "~1.0", "symfony/config": "~2.8", - "symfony/intl": "~2.4|~3.0.0", + "symfony/intl": "~2.7.25|^2.8.18|~3.2.5", "symfony/yaml": "~2.2|~3.0.0" }, "suggest": { @@ -2328,20 +2295,20 @@ ], "description": "Symfony Translation Component", "homepage": "https://symfony.com", - "time": "2016-11-18T21:10:01+00:00" + "time": "2017-06-24T16:44:49+00:00" }, { "name": "symfony/yaml", - "version": "v2.8.15", + "version": "v2.8.24", "source": { "type": "git", "url": "https://github.com/symfony/yaml.git", - "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff" + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/yaml/zipball/befb26a3713c97af90d25dd12e75621ef14d91ff", - "reference": "befb26a3713c97af90d25dd12e75621ef14d91ff", + "url": "https://api.github.com/repos/symfony/yaml/zipball/4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", + "reference": "4c29dec8d489c4e37cf87ccd7166cd0b0e6a45c5", "shasum": "" }, "require": { @@ -2377,32 +2344,84 @@ ], "description": "Symfony Yaml Component", "homepage": "https://symfony.com", - "time": "2016-11-14T16:15:57+00:00" + "time": "2017-06-01T20:52:29+00:00" }, { - "name": "wp-cli/php-cli-tools", - "version": "v0.11.1", + "name": "wp-cli/autoload-splitter", + "version": "v0.1.3", "source": { "type": "git", - "url": "https://github.com/wp-cli/php-cli-tools.git", - "reference": "5311a4b99103c0505db015a334be4952654d6e21" + "url": "https://github.com/wp-cli/autoload-splitter.git", + "reference": "446f73de57ab4e7bf38a4ba2779cd3630905185c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/5311a4b99103c0505db015a334be4952654d6e21", - "reference": "5311a4b99103c0505db015a334be4952654d6e21", + "url": "https://api.github.com/repos/wp-cli/autoload-splitter/zipball/446f73de57ab4e7bf38a4ba2779cd3630905185c", + "reference": "446f73de57ab4e7bf38a4ba2779cd3630905185c", "shasum": "" }, "require": { - "php": ">= 5.3.0" + "composer-plugin-api": "^1.1" + }, + "type": "composer-plugin", + "extra": { + "class": "WP_CLI\\AutoloadSplitter\\ComposerPlugin" }, - "type": "library", "autoload": { - "psr-0": { - "cli": "lib/" + "psr-4": { + "WP_CLI\\AutoloadSplitter\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Alain Schlesser", + "email": "alain.schlesser@gmail.com", + "homepage": "https://www.alainschlesser.com" + } + ], + "description": "Composer plugin for splitting a generated autoloader into two distinct parts.", + "homepage": "https://wp-cli.org", + "time": "2017-05-03T06:21:26+00:00" + }, + { + "name": "wp-cli/cache-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/cache-command.git", + "reference": "d7102d5573d050befc81be5470b5df553e66cc6e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/cache-command/zipball/d7102d5573d050befc81be5470b5df553e66cc6e", + "reference": "d7102d5573d050befc81be5470b5df553e66cc6e", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "cache", + "transient" + ] + }, + "autoload": { + "psr-4": { + "": "src/" }, "files": [ - "lib/cli/cli.php" + "cache-command.php" ] }, "notification-url": "https://packagist.org/downloads/", @@ -2411,90 +2430,1411 @@ ], "authors": [ { - "name": "James Logsdon", - "email": "jlogsdon@php.net", - "role": "Developer" + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage object and transient caches.", + "homepage": "https://github.com/wp-cli/cache-command", + "time": "2017-05-30T18:00:27+00:00" + }, + { + "name": "wp-cli/checksum-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/checksum-command.git", + "reference": "2b74567a660951380083f02224a21746b2697008" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/checksum-command/zipball/2b74567a660951380083f02224a21746b2697008", + "reference": "2b74567a660951380083f02224a21746b2697008", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" }, + "bundled": true, + "commands": [ + "checksum core" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "checksum-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ { "name": "Daniel Bachhuber", - "email": "daniel@handbuilt.co", - "role": "Maintainer" + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" } ], - "description": "Console utilities for PHP", - "homepage": "http://github.com/wp-cli/php-cli-tools", - "keywords": [ - "cli", - "console" - ], - "time": "2016-02-08T14:34:01+00:00" + "description": "Verify WordPress core checksums.", + "homepage": "https://github.com/wp-cli/checksum-command", + "time": "2017-05-30T18:55:36+00:00" }, { - "name": "wp-cli/wp-cli", - "version": "v1.0.0", + "name": "wp-cli/config-command", + "version": "v1.1.3", "source": { "type": "git", - "url": "https://github.com/wp-cli/wp-cli.git", - "reference": "62d10c72aa1e77f7bf0a84dd495369c41fe12a2e" + "url": "https://github.com/wp-cli/config-command.git", + "reference": "8c043f9312a5c35cd7e37a7551d835f46ed0586e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/62d10c72aa1e77f7bf0a84dd495369c41fe12a2e", - "reference": "62d10c72aa1e77f7bf0a84dd495369c41fe12a2e", + "url": "https://api.github.com/repos/wp-cli/config-command/zipball/8c043f9312a5c35cd7e37a7551d835f46ed0586e", + "reference": "8c043f9312a5c35cd7e37a7551d835f46ed0586e", "shasum": "" }, - "require": { - "composer/composer": "^1.0.0", - "composer/semver": "~1.0", - "mustache/mustache": "~2.4", - "mustangostang/spyc": "~0.5", - "nb/oxymel": "~0.1.0", - "php": ">=5.3.29", - "ramsey/array_column": "~1.1", - "rmccue/requests": "~1.6", - "symfony/config": "~2.7", - "symfony/console": "~2.7", - "symfony/debug": "~2.7", - "symfony/dependency-injection": "~2.7", - "symfony/event-dispatcher": "~2.7", - "symfony/filesystem": "~2.7", - "symfony/finder": "~2.7", - "symfony/process": "~2.1", - "symfony/translation": "~2.7", - "symfony/yaml": "~2.7", - "wp-cli/php-cli-tools": "~0.11.1" + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "config", + "config create", + "config get", + "config path" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "config-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage the wp-config.php file.", + "homepage": "https://github.com/wp-cli/config-command", + "time": "2017-07-06T21:17:20+00:00" + }, + { + "name": "wp-cli/core-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/core-command.git", + "reference": "22e0caa140897f87d9e618fc075f80325a6151ee" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/core-command/zipball/22e0caa140897f87d9e618fc075f80325a6151ee", + "reference": "22e0caa140897f87d9e618fc075f80325a6151ee", + "shasum": "" }, "require-dev": { - "behat/behat": "2.5.*", - "phpunit/phpunit": "3.7.*" + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" }, - "suggest": { - "psy/psysh": "Enhanced `wp shell` functionality" + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "core check-update", + "core download", + "core install", + "core is-installed", + "core multisite-convert", + "core multisite-install", + "core update", + "core update-db", + "core version" + ] }, - "bin": [ - "bin/wp.bat", - "bin/wp" + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "core-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" ], - "type": "library", + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Download, install, update and manage a WordPress install.", + "homepage": "https://github.com/wp-cli/core-command", + "time": "2017-05-30T18:56:42+00:00" + }, + { + "name": "wp-cli/cron-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/cron-command.git", + "reference": "1cf8564c0c025520658a8ec872e606bdd7fef319" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/cron-command/zipball/1cf8564c0c025520658a8ec872e606bdd7fef319", + "reference": "1cf8564c0c025520658a8ec872e606bdd7fef319", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "cron test", + "cron event delete", + "cron event list", + "cron event run", + "cron event schedule", + "cron schedule list" + ] + }, "autoload": { - "psr-0": { - "WP_CLI": "php" + "psr-4": { + "": "src/" }, - "classmap": [ - "php/export" + "files": [ + "cron-command.php" ] }, "notification-url": "https://packagist.org/downloads/", "license": [ "MIT" ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage WP-Cron events and schedules.", + "homepage": "https://github.com/wp-cli/cron-command", + "time": "2017-05-30T18:58:24+00:00" + }, + { + "name": "wp-cli/db-command", + "version": "v1.1.0", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/db-command.git", + "reference": "4c65adbd92e81df140beaa985f101b2905561666" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/db-command/zipball/4c65adbd92e81df140beaa985f101b2905561666", + "reference": "4c65adbd92e81df140beaa985f101b2905561666", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "db create", + "db drop", + "db reset", + "db check", + "db optimize", + "db repair", + "db cli", + "db query", + "db export", + "db import", + "db tables", + "db size" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "db-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Perform basic database operations using credentials stored in wp-config.php.", + "homepage": "https://github.com/wp-cli/db-command", + "time": "2017-05-30T18:57:35+00:00" + }, + { + "name": "wp-cli/entity-command", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/entity-command.git", + "reference": "5f925201062c7a308f6cbbfc56bc8dec20d2ff80" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/entity-command/zipball/5f925201062c7a308f6cbbfc56bc8dec20d2ff80", + "reference": "5f925201062c7a308f6cbbfc56bc8dec20d2ff80", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "comment", + "comment meta", + "menu", + "menu item", + "menu location", + "network meta", + "post", + "post meta", + "post term", + "post-type", + "site", + "taxonomy", + "term", + "term meta", + "user", + "user meta", + "user term" + ] + }, + "autoload": { + "psr-4": { + "": "src/", + "WP_CLI\\": "src/WP_CLI" + }, + "files": [ + "entity-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage WordPress core entities.", + "homepage": "https://github.com/wp-cli/entity-command", + "time": "2017-06-29T22:26:09+00:00" + }, + { + "name": "wp-cli/eval-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/eval-command.git", + "reference": "996c2ed3ad5bd796abaabe7ed0ce5c368fab62d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/eval-command/zipball/996c2ed3ad5bd796abaabe7ed0ce5c368fab62d1", + "reference": "996c2ed3ad5bd796abaabe7ed0ce5c368fab62d1", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "eval", + "eval-file" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "eval-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Execute arbitrary PHP code.", + "homepage": "https://github.com/wp-cli/eval-command", + "time": "2017-05-30T19:00:48+00:00" + }, + { + "name": "wp-cli/export-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/export-command.git", + "reference": "3507dae2dad0f8bb71070bc0c284ffed304caf21" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/export-command/zipball/3507dae2dad0f8bb71070bc0c284ffed304caf21", + "reference": "3507dae2dad0f8bb71070bc0c284ffed304caf21", + "shasum": "" + }, + "require": { + "nb/oxymel": "~0.1.0", + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "export" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "export-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Export WordPress content to a WXR file.", + "homepage": "https://github.com/wp-cli/export-command", + "time": "2017-05-30T19:01:34+00:00" + }, + { + "name": "wp-cli/extension-command", + "version": "v1.1.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/extension-command.git", + "reference": "8489bc23aad242796cba15f78ce75192b1774ea5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/extension-command/zipball/8489bc23aad242796cba15f78ce75192b1774ea5", + "reference": "8489bc23aad242796cba15f78ce75192b1774ea5", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "plugin activate", + "plugin deactivate", + "plugin delete", + "plugin get", + "plugin install", + "plugin is-installed", + "plugin list", + "plugin path", + "plugin search", + "plugin status", + "plugin toggle", + "plugin uninstall", + "plugin update", + "theme activate", + "theme delete", + "theme disable", + "theme enable", + "theme get", + "theme install", + "theme is-installed", + "theme list", + "theme mod get", + "theme mod set", + "theme mod remove", + "theme path", + "theme search", + "theme status", + "theme update" + ] + }, + "autoload": { + "psr-4": { + "": "src/", + "WP_CLI\\": "src/WP_CLI" + }, + "files": [ + "extension-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage WordPress plugins and themes.", + "homepage": "https://github.com/wp-cli/extension-command", + "time": "2017-06-08T09:01:02+00:00" + }, + { + "name": "wp-cli/import-command", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/import-command.git", + "reference": "3d10d138e6f7c4715535fdb3b5a436cc3d143fea" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/import-command/zipball/3d10d138e6f7c4715535fdb3b5a436cc3d143fea", + "reference": "3d10d138e6f7c4715535fdb3b5a436cc3d143fea", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "bundled": true, + "commands": [ + "import" + ] + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "import-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Import content from a WXR file.", + "homepage": "https://github.com/wp-cli/import-command", + "time": "2017-07-04T13:14:43+00:00" + }, + { + "name": "wp-cli/language-command", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/language-command.git", + "reference": "5812cac811de1c166b89cf6c78a2c1ff606e1dc4" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/language-command/zipball/5812cac811de1c166b89cf6c78a2c1ff606e1dc4", + "reference": "5812cac811de1c166b89cf6c78a2c1ff606e1dc4", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "language core activate", + "language core install", + "language core list", + "language core uninstall", + "language core update" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "language-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage language packs.", + "homepage": "https://github.com/wp-cli/language-command", + "time": "2017-05-30T21:29:09+00:00" + }, + { + "name": "wp-cli/media-command", + "version": "v1.0.3", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/media-command.git", + "reference": "dfa3b80a8d7fbc9fb90753d5bf59ba7efd541530" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/media-command/zipball/dfa3b80a8d7fbc9fb90753d5bf59ba7efd541530", + "reference": "dfa3b80a8d7fbc9fb90753d5bf59ba7efd541530", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "media import", + "media regenerate" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "media-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Import and regenerate attachments.", + "homepage": "https://github.com/wp-cli/media-command", + "time": "2017-06-16T08:49:06+00:00" + }, + { + "name": "wp-cli/mustangostang-spyc", + "version": "0.6.3", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/spyc.git", + "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/spyc/zipball/6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", + "reference": "6aa0b4da69ce9e9a2c8402dab8d43cf32c581cc7", + "shasum": "" + }, + "require": { + "php": ">=5.3.1" + }, + "require-dev": { + "phpunit/phpunit": "4.3.*@dev" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-master": "0.5.x-dev" + } + }, + "autoload": { + "psr-4": { + "Mustangostang\\": "src/" + }, + "files": [ + "includes/functions.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "mustangostang", + "email": "vlad.andersen@gmail.com" + } + ], + "description": "A simple YAML loader/dumper class for PHP (WP-CLI fork)", + "homepage": "https://github.com/mustangostang/spyc/", + "time": "2017-04-25T11:26:20+00:00" + }, + { + "name": "wp-cli/package-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/package-command.git", + "reference": "1163c1e571388c73c54d68a5013c3817b6113dbf" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/package-command/zipball/1163c1e571388c73c54d68a5013c3817b6113dbf", + "reference": "1163c1e571388c73c54d68a5013c3817b6113dbf", + "shasum": "" + }, + "require": { + "composer/composer": "^1.2.0", + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "package browse", + "package install", + "package list", + "package update", + "package uninstall" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "package-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage WP-CLI packages.", + "homepage": "https://github.com/wp-cli/package-command", + "time": "2017-05-30T19:28:38+00:00" + }, + { + "name": "wp-cli/php-cli-tools", + "version": "v0.11.3", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/php-cli-tools.git", + "reference": "09075e5a5ba804df43e148f887cbf4466bebfa2c" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/php-cli-tools/zipball/09075e5a5ba804df43e148f887cbf4466bebfa2c", + "reference": "09075e5a5ba804df43e148f887cbf4466bebfa2c", + "shasum": "" + }, + "require": { + "php": ">= 5.3.0" + }, + "type": "library", + "autoload": { + "psr-0": { + "cli": "lib/" + }, + "files": [ + "lib/cli/cli.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "James Logsdon", + "email": "jlogsdon@php.net", + "role": "Developer" + }, + { + "name": "Daniel Bachhuber", + "email": "daniel@handbuilt.co", + "role": "Maintainer" + } + ], + "description": "Console utilities for PHP", + "homepage": "http://github.com/wp-cli/php-cli-tools", + "keywords": [ + "cli", + "console" + ], + "time": "2017-06-08T12:06:09+00:00" + }, + { + "name": "wp-cli/rewrite-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/rewrite-command.git", + "reference": "fe4067a3d64359c171306bc7757ec333f409b8d1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/rewrite-command/zipball/fe4067a3d64359c171306bc7757ec333f409b8d1", + "reference": "fe4067a3d64359c171306bc7757ec333f409b8d1", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "rewrite flush", + "rewrite list", + "rewrite structure" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "rewrite-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage rewrite rules.", + "homepage": "https://github.com/wp-cli/rewrite-command", + "time": "2017-05-30T19:40:20+00:00" + }, + { + "name": "wp-cli/role-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/role-command.git", + "reference": "fd90b81e85b4d66f47cb3ec51fd1cf27e8bc4a5f" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/role-command/zipball/fd90b81e85b4d66f47cb3ec51fd1cf27e8bc4a5f", + "reference": "fd90b81e85b4d66f47cb3ec51fd1cf27e8bc4a5f", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "role create", + "role delete", + "role exists", + "role list", + "role reset", + "cap add", + "cap list", + "cap remove" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "role-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage user roles and capabilities.", + "homepage": "https://github.com/wp-cli/role-command", + "time": "2017-05-30T21:23:36+00:00" + }, + { + "name": "wp-cli/scaffold-command", + "version": "v1.0.4", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/scaffold-command.git", + "reference": "8015b662c232565d86962894618e38b5e5d43de1" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/scaffold-command/zipball/8015b662c232565d86962894618e38b5e5d43de1", + "reference": "8015b662c232565d86962894618e38b5e5d43de1", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "scaffold", + "scaffold _s", + "scaffold child-theme", + "scaffold plugin", + "scaffold plugin-tests", + "scaffold post-type", + "scaffold taxonomy", + "scaffold theme-tests" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "scaffold-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Generate code for post types, taxonomies, plugins, child themes, etc.", + "homepage": "https://github.com/wp-cli/scaffold-command", + "time": "2017-05-30T21:18:58+00:00" + }, + { + "name": "wp-cli/search-replace-command", + "version": "v1.0.2", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/search-replace-command.git", + "reference": "bb99b41e3b908f4256c8b7918118a96bb80c1bd6" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/search-replace-command/zipball/bb99b41e3b908f4256c8b7918118a96bb80c1bd6", + "reference": "bb99b41e3b908f4256c8b7918118a96bb80c1bd6", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "search-replace" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/", + "WP_CLI\\": "src/WP_CLI" + }, + "files": [ + "search-replace-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Search/replace strings in the database.", + "homepage": "https://github.com/wp-cli/search-replace-command", + "time": "2017-06-28T19:27:14+00:00" + }, + { + "name": "wp-cli/server-command", + "version": "v1.0.5", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/server-command.git", + "reference": "fb8f7e048b9d7a29d99e019c0a33a71542a856c9" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/server-command/zipball/fb8f7e048b9d7a29d99e019c0a33a71542a856c9", + "reference": "fb8f7e048b9d7a29d99e019c0a33a71542a856c9", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "server" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "server-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Launch PHP's built-in web server for this specific WordPress installation.", + "homepage": "https://github.com/wp-cli/server-command", + "time": "2017-05-30T19:41:53+00:00" + }, + { + "name": "wp-cli/shell-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/shell-command.git", + "reference": "827ccfe2eceda7a75e9b244e0044fb6f7aac52f5" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/shell-command/zipball/827ccfe2eceda7a75e9b244e0044fb6f7aac52f5", + "reference": "827ccfe2eceda7a75e9b244e0044fb6f7aac52f5", + "shasum": "" + }, + "require": { + "wp-cli/wp-cli": "*" + }, + "require-dev": { + "behat/behat": "~2.5" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "shell" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/", + "WP_CLI\\": "src/WP_CLI" + }, + "files": [ + "shell-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Interactive PHP console.", + "homepage": "https://github.com/wp-cli/shell-command", + "time": "2017-05-30T19:43:29+00:00" + }, + { + "name": "wp-cli/super-admin-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/super-admin-command.git", + "reference": "3dc1bfc6bef14e11ff33ef691892b1ad1610d128" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/super-admin-command/zipball/3dc1bfc6bef14e11ff33ef691892b1ad1610d128", + "reference": "3dc1bfc6bef14e11ff33ef691892b1ad1610d128", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "super-admin add", + "super-admin list", + "super-admin remove" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "super-admin-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage super admins on WordPress multisite.", + "homepage": "https://github.com/wp-cli/super-admin-command", + "time": "2017-05-30T19:44:45+00:00" + }, + { + "name": "wp-cli/widget-command", + "version": "v1.0.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/widget-command.git", + "reference": "68b5955a7a18d568f69775decbd79ebfbe691d3e" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/widget-command/zipball/68b5955a7a18d568f69775decbd79ebfbe691d3e", + "reference": "68b5955a7a18d568f69775decbd79ebfbe691d3e", + "shasum": "" + }, + "require-dev": { + "behat/behat": "~2.5", + "wp-cli/wp-cli": "*" + }, + "type": "wp-cli-package", + "extra": { + "branch-alias": { + "dev-master": "1.x-dev" + }, + "commands": [ + "widget add", + "widget deactivate", + "widget delete", + "widget list", + "widget move", + "widget reset", + "widget update", + "sidebar list" + ], + "bundled": true + }, + "autoload": { + "psr-4": { + "": "src/" + }, + "files": [ + "widget-command.php" + ] + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Daniel Bachhuber", + "email": "daniel@runcommand.io", + "homepage": "https://runcommand.io" + } + ], + "description": "Manage widgets and sidebars.", + "homepage": "https://github.com/wp-cli/widget-command", + "time": "2017-05-30T21:14:12+00:00" + }, + { + "name": "wp-cli/wp-cli", + "version": "v1.2.1", + "source": { + "type": "git", + "url": "https://github.com/wp-cli/wp-cli.git", + "reference": "9a9b6a63e08e7827669677faa97312972c0f1da2" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/wp-cli/wp-cli/zipball/9a9b6a63e08e7827669677faa97312972c0f1da2", + "reference": "9a9b6a63e08e7827669677faa97312972c0f1da2", + "shasum": "" + }, + "require": { + "composer/composer": "^1.2.0", + "composer/semver": "~1.0", + "mustache/mustache": "~2.4", + "php": ">=5.3.29", + "ramsey/array_column": "~1.1", + "rmccue/requests": "~1.6", + "symfony/config": "^2.7|^3.0", + "symfony/console": "^2.7|^3.0", + "symfony/debug": "^2.7|^3.0", + "symfony/dependency-injection": "^2.7|^3.0", + "symfony/event-dispatcher": "^2.7|^3.0", + "symfony/filesystem": "^2.7|^3.0", + "symfony/finder": "^2.7|^3.0", + "symfony/process": "^2.1|^3.0", + "symfony/translation": "^2.7|^3.0", + "symfony/yaml": "^2.7|^3.0", + "wp-cli/autoload-splitter": "^0.1", + "wp-cli/cache-command": "^1.0", + "wp-cli/checksum-command": "^1.0", + "wp-cli/config-command": "^1.0", + "wp-cli/core-command": "^1.0", + "wp-cli/cron-command": "^1.0", + "wp-cli/db-command": "^1.0", + "wp-cli/entity-command": "^1.0", + "wp-cli/eval-command": "^1.0", + "wp-cli/export-command": "^1.0", + "wp-cli/extension-command": "^1.0", + "wp-cli/import-command": "^1.0", + "wp-cli/language-command": "^1.0", + "wp-cli/media-command": "^1.0", + "wp-cli/mustangostang-spyc": "^0.6.3", + "wp-cli/package-command": "^1.0", + "wp-cli/php-cli-tools": "~0.11.2", + "wp-cli/rewrite-command": "^1.0", + "wp-cli/role-command": "^1.0", + "wp-cli/scaffold-command": "^1.0", + "wp-cli/search-replace-command": "^1.0", + "wp-cli/server-command": "^1.0", + "wp-cli/shell-command": "^1.0", + "wp-cli/super-admin-command": "^1.0", + "wp-cli/widget-command": "^1.0" + }, + "require-dev": { + "behat/behat": "2.5.*", + "phpunit/phpunit": "3.7.*", + "pyrech/composer-changelogs": "dev-php53 as 1.5.1", + "roave/security-advisories": "dev-master" + }, + "suggest": { + "psy/psysh": "Enhanced `wp shell` functionality" + }, + "bin": [ + "bin/wp.bat", + "bin/wp" + ], + "type": "library", + "extra": { + "autoload-splitter": { + "splitter-logic": "WP_CLI\\AutoloadSplitter", + "splitter-location": "php/WP_CLI/AutoloadSplitter.php", + "split-target-prefix-true": "autoload_commands", + "split-target-prefix-false": "autoload_framework" + } + }, + "autoload": { + "psr-0": { + "WP_CLI": "php" + }, + "psr-4": { + "": "php/commands/src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], "description": "A command line interface for WordPress", "homepage": "http://wp-cli.org", "keywords": [ "cli", "wordpress" ], - "time": "2016-11-29T19:33:53+00:00" + "time": "2017-06-06T12:14:53+00:00" }, { "name": "wpackagist-plugin/woocommerce", @@ -2506,7 +3846,7 @@ }, "dist": { "type": "zip", - "url": "https://downloads.wordpress.org/plugin/woocommerce.zip", + "url": "https://downloads.wordpress.org/plugin/woocommerce.zip?timestamp=1498667669", "reference": null, "shasum": null }, @@ -2515,7 +3855,7 @@ }, "type": "wordpress-plugin", "homepage": "https://wordpress.org/plugins/woocommerce/", - "time": "2016-07-26T17:31:18+00:00" + "time": "2017-06-28T17:34:29+00:00" } ], "aliases": [], diff --git a/elasticpress.php b/elasticpress.php index 09ef3d9fdf..804227edcf 100644 --- a/elasticpress.php +++ b/elasticpress.php @@ -3,7 +3,7 @@ /** * Plugin Name: ElasticPress * Description: A fast and flexible search and query engine for WordPress. - * Version: 2.3.2 + * Version: 2.4 * Author: Taylor Lovett, Matt Gross, Aaron Holbrook, 10up * Author URI: http://10up.com * License: GPLv2 or later @@ -22,18 +22,18 @@ define( 'EP_URL', plugin_dir_url( __FILE__ ) ); define( 'EP_PATH', plugin_dir_path( __FILE__ ) ); -define( 'EP_VERSION', '2.3.2' ); +define( 'EP_VERSION', '2.4' ); /** * We compare the current ES version to this compatibility version number. Compatibility is true when: * * EP_ES_VERSION_MIN <= YOUR ES VERSION <= EP_ES_VERSION_MAX - * + * * We don't check minor releases so if your ES version if 5.1.1, we consider that 5.1 in our comparison. * * @since 2.2 */ -define( 'EP_ES_VERSION_MAX', '5.3' ); +define( 'EP_ES_VERSION_MAX', '5.6' ); define( 'EP_ES_VERSION_MIN', '1.7' ); require_once( 'classes/class-ep-config.php' ); @@ -59,6 +59,7 @@ require_once( 'features/protected-content/protected-content.php' ); require_once( 'features/woocommerce/woocommerce.php' ); require_once( 'features/documents/documents.php' ); +require_once( 'features/autosuggest/autosuggest.php' ); /** * WP CLI Commands @@ -138,7 +139,7 @@ function ep_handle_upgrades() { */ function ep_setup_misc() { load_plugin_textdomain( 'elasticpress', false, basename( dirname( __FILE__ ) ) . '/lang' ); // Load any available translations first. - + if ( is_user_logged_in() && ! defined( 'WP_EP_DEBUG' ) ) { require_once( ABSPATH . 'wp-admin/includes/plugin.php' ); define( 'WP_EP_DEBUG', is_plugin_active( 'debug-bar-elasticpress/debug-bar-elasticpress.php' ) ); diff --git a/features/autosuggest/assets/css/autosuggest.css b/features/autosuggest/assets/css/autosuggest.css new file mode 100644 index 0000000000..5444120f3e --- /dev/null +++ b/features/autosuggest/assets/css/autosuggest.css @@ -0,0 +1,37 @@ +/** + * ElasticPress Autosuggest + * http://github.com/10up/ElasticPress-Autosuggest + * + * Copyright (c) 2014 Aaron Holbrook, 10up + * Licensed under the GPLv2+ license. + */ +.ep-autosuggest-container { + position: relative; } + .ep-autosuggest-container .ep-autosuggest { + display: none; + background: white; + position: absolute; + border: 1px solid #ccc; + -webkit-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + -moz-box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + box-shadow: 0 2px 4px rgba(0, 0, 0, 0.2); + width: 100%; + z-index: 200; } + .ep-autosuggest-container .ep-autosuggest > ul { + margin: 0 !important; + list-style: none; } + .ep-autosuggest-container .ep-autosuggest > ul > li { + font-family: sans-serif; } + .ep-autosuggest-container .ep-autosuggest > ul > li > span { + display: block; + color: #000; + padding: 2px 10px; + cursor: pointer; } + .ep-autosuggest-container .ep-autosuggest > ul > li > span:hover, .ep-autosuggest-container .ep-autosuggest > ul > li > span:active { + background-color: #EEEEEE; + text-decoration: none; } + .ep-autosuggest-container .selected { + background-color: #EEE; + text-decoration: none; } + +/*# sourceMappingURL=autosuggest.css.map */ \ No newline at end of file diff --git a/features/autosuggest/assets/css/autosuggest.css.map b/features/autosuggest/assets/css/autosuggest.css.map new file mode 100644 index 0000000000..327fb8647a --- /dev/null +++ b/features/autosuggest/assets/css/autosuggest.css.map @@ -0,0 +1,9 @@ +{ + "version": 3, + "file": "autosuggest.css", + "sources": [ + "autosuggest.scss" + ], + "names": [], + "mappings": "AAAA;;;;;;GAMG;AAEH,AAAA,yBAAyB,CAAC;EACzB,QAAQ,EAAE,QAAQ,GAwClB;EAzCD,AAGC,yBAHwB,CAGxB,eAAe,CAAC;IACf,OAAO,EAAE,IAAI;IACb,UAAU,EAAE,KAAK;IAEjB,QAAQ,EAAE,QAAQ;IAElB,MAAM,EAAE,cAAc;IAEtB,kBAAkB,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAmB;IACjD,eAAe,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAmB;IAC9C,UAAU,EAAE,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,kBAAmB;IAEzC,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,GAAG,GAmBZ;IAnCF,AAiBI,yBAjBqB,CAGxB,eAAe,GAcZ,EAAE,CAAC;MACJ,MAAM,EAAE,YAAY;MACpB,UAAU,EAAE,IAAI,GAehB;MAlCH,AAoBK,yBApBoB,CAGxB,eAAe,GAcZ,EAAE,GAGD,EAAE,CAAC;QACJ,WAAW,EAAE,UAAU,GAYvB;QAjCJ,AAsBM,yBAtBmB,CAGxB,eAAe,GAcZ,EAAE,GAGD,EAAE,GAED,IAAI,CAAC;UACN,OAAO,EAAE,KAAK;UACd,KAAK,EAAE,IAAI;UACX,OAAO,EAAE,QAAQ;UACjB,MAAM,EAAE,OAAO,GAMf;UAhCL,AAsBM,yBAtBmB,CAGxB,eAAe,GAcZ,EAAE,GAGD,EAAE,GAED,IAAI,AAKL,MAAO,EA3BZ,AAsBM,yBAtBmB,CAGxB,eAAe,GAcZ,EAAE,GAGD,EAAE,GAED,IAAI,AAML,OAAQ,CAAC;YACR,gBAAgB,EAAE,OAAO;YACzB,eAAe,EAAE,IAAI,GACrB;EA/BN,AAqCC,yBArCwB,CAqCxB,SAAS,CAAC;IACT,gBAAgB,EAAE,IAAI;IACtB,eAAe,EAAE,IAAI,GACrB" +} \ No newline at end of file diff --git a/features/autosuggest/assets/css/autosuggest.min.css b/features/autosuggest/assets/css/autosuggest.min.css new file mode 100644 index 0000000000..44a8b75f99 --- /dev/null +++ b/features/autosuggest/assets/css/autosuggest.min.css @@ -0,0 +1 @@ +.ep-autosuggest-container{position:relative}.ep-autosuggest-container .ep-autosuggest{display:none;background:#fff;position:absolute;border:1px solid #ccc;-webkit-box-shadow:0 2px 4px rgba(0,0,0,.2);-moz-box-shadow:0 2px 4px rgba(0,0,0,.2);box-shadow:0 2px 4px rgba(0,0,0,.2);width:100%;z-index:200}.ep-autosuggest-container .ep-autosuggest>ul{margin:0!important;list-style:none}.ep-autosuggest-container .ep-autosuggest>ul>li{font-family:sans-serif}.ep-autosuggest-container .ep-autosuggest>ul>li>span{display:block;color:#000;padding:2px 10px;cursor:pointer}.ep-autosuggest-container .ep-autosuggest>ul>li>span:active,.ep-autosuggest-container .ep-autosuggest>ul>li>span:hover{background-color:#eee;text-decoration:none}.ep-autosuggest-container .selected{background-color:#eee;text-decoration:none} \ No newline at end of file diff --git a/features/autosuggest/assets/css/autosuggest.scss b/features/autosuggest/assets/css/autosuggest.scss new file mode 100644 index 0000000000..82effdcd92 --- /dev/null +++ b/features/autosuggest/assets/css/autosuggest.scss @@ -0,0 +1,50 @@ +/** + * ElasticPress Autosuggest + * http://github.com/10up/ElasticPress-Autosuggest + * + * Copyright (c) 2014 Aaron Holbrook, 10up + * Licensed under the GPLv2+ license. + */ + +.ep-autosuggest-container { + position: relative; + + .ep-autosuggest { + display: none; + background: white; + + position: absolute; + + border: 1px solid #ccc; + + -webkit-box-shadow: 0 2px 4px rgba( 0, 0, 0, .2 ); + -moz-box-shadow: 0 2px 4px rgba( 0, 0, 0, .2 ); + box-shadow: 0 2px 4px rgba( 0, 0, 0, .2 ); + + width: 100%; + z-index: 200; + > ul { + margin: 0 !important; + list-style: none; + > li { + font-family: sans-serif; + > span { + display: block; + color: #000; + padding: 2px 10px; + cursor: pointer; + &:hover, + &:active { + background-color: #EEEEEE; + text-decoration: none; + } + } + } + } + } + + .selected { + background-color: #EEE; + text-decoration: none; + } +} \ No newline at end of file diff --git a/features/autosuggest/assets/js/autosuggest.min.js b/features/autosuggest/assets/js/autosuggest.min.js new file mode 100644 index 0000000000..b0fc52cef0 --- /dev/null +++ b/features/autosuggest/assets/js/autosuggest.min.js @@ -0,0 +1 @@ +!function(e){"use strict";function t(e){e.closest("form").submit()}function s(e,t){e.val(t)}function o(e,t){return window.location.href=t}function n(e,n){if("navigate"===epas.action)return o(e,n.dataset.url);s(e,n.innerText),t(e)}function a(e,t){var s=null;return function(){var o=this,n=arguments;window.clearTimeout(s),s=window.setTimeout(function(){e.apply(o,n)},t)}}function i(t,s,o){"all"!==s&&void 0!==s&&""!==s||(s="all");var n={sort:[{_score:{order:"desc"}}],query:{multi_match:{query:t,fields:o}}};return"string"==typeof s&&"all"!==s&&(s=s.split(",")),e.isArray(s)&&(n.post_filter={bool:{must:[{terms:{"post_type.raw":s}}]}}),n}function r(t){return jQuery.support.cors=!0,e.ajax({url:epas.endpointUrl,type:"post",dataType:"json",crossDomain:!0,data:JSON.stringify(t)})}function u(t,s){var o,a=s.closest(".ep-autosuggest-container").find(".ep-autosuggest"),i=a.find(".autosuggest-list");for(i.empty(),e(".autosuggest-item").off(),t.length>0?a.show():a.hide(),o=0;o'+r+"").appendTo(i)}e(".autosuggest-item").on("click",function(e){n(s,e.srcElement)}),s.off("keydown"),s.on("keydown",function(e){if(38!==e.keyCode&&40!==e.keyCode&&13!==e.keyCode);else{var t,o=s.closest(".ep-autosuggest-container").find(".autosuggest-list li"),a=o.filter(".selected");switch(e.keyCode){case 38:t=a.prev();break;case 40:o.hasClass("selected")?t=a.next():(o.first().addClass("selected"),t=o.first());break;case 13:return o.hasClass("selected")?(n(s,a.children("span").get(0)),!1):void 0}if(t.is("li")?(a.removeClass("selected"),t.addClass("selected")):o.removeClass("selected"),38===e.keyCode)return!1}})}function l(){e(".autosuggest-list").empty(),e(".ep-autosuggest").hide()}if(epas.endpointUrl&&""!==epas.endpointUrl){var c=e('.ep-autosuggest, input[type="search"], .search-field'),d=e('
    ');c.each(function(t,s){var o=e('
    '),n=e(s);n.attr("autocomplete","off"),o.insertAfter(n);var a=n.siblings("label");n.closest("form").find(".ep-autosuggest-container").append(a).append(n),d.clone().insertAfter(n),n.trigger("elasticpress.input.moved")}),d.css({top:c.outerHeight()-1,"background-color":c.css("background-color")}),e(c).each(function(t,s){e(s).on("keyup keydown keypress",function(e){38!==e.keyCode&&40!==e.keyCode||e.preventDefault(),27===e.keyCode&&l()})}),c.each(function(t,s){var o=e(s);o.on("keyup",a(function(t){if(38!==t.keyCode&&40!==t.keyCode&&13!==t.keyCode&&27!==t.keyCode){var s=o.val(),n=epas.postType,a=epas.searchFields;s.length>=2?r(i(s,n,a)).done(function(t){if(t._shards.successful>0){var s={},n=[];e.each(t.hits.hits,function(e,t){var o=t._source.post_title,a=t._source.permalink,i=t._source.post_id;s[i]||(s[i]=!0,n.push({text:o,url:a}))}),0===n.length?l():u(n,o)}else l()}):0===s.length&&l()}},200))}),window.epasAPI={hideAutosuggestBox:l,updateAutosuggestBox:u,esSearch:r,buildSearchQuery:i}}}(jQuery); \ No newline at end of file diff --git a/features/autosuggest/assets/js/src/autosuggest.js b/features/autosuggest/assets/js/src/autosuggest.js new file mode 100644 index 0000000000..aabaee7fed --- /dev/null +++ b/features/autosuggest/assets/js/src/autosuggest.js @@ -0,0 +1,355 @@ +/** + * ElasticPress Autosuggest + * http://github.com/10up/ElasticPress-Autosuggest + * + * Copyright (c) 2014 Aaron Holbrook, 10up + * Licensed under the GPLv2+ license. + */ +( function( $ ) { + 'use strict'; + + // No host/index set + if ( ! epas.endpointUrl || '' === epas.endpointUrl ) { + return; + } + + /** + * Submit the search form + * @param object $localInput + */ + function submitSearchForm( $localInput ) { + $localInput.closest( 'form' ).submit(); + } + + /** + * Take selected item and fill the search input + * @param event + */ + function selectAutosuggestItem( $localInput, text ) { + $localInput.val( text ); + } + + /** + * Navigate to the selected item + * @param event + */ + function goToAutosuggestItem( $localInput, url ) { + return window.location.href = url; + } + + /** + * Respond to an item selection based on the predefined behavior. + * If epas.action is set to "navigate", redirects the browser to the URL of the selected item + * If epas.action is set to any other value (default "search"), fill in the value and perform the search + * + * @param $localInput + * @param element + */ + function selectItem( $localInput, element ) { + + if ( 'navigate' === epas.action ) { + return goToAutosuggestItem( $localInput, element.dataset.url ); + } + + selectAutosuggestItem( $localInput, element.innerText ); + submitSearchForm( $localInput ); + } + + /** + * Simple throttling function for waiting a set amount of time after the last keypress + * So we don't overload the server with too many requests at once + * + * @param fn + * @param delay + * @returns {Function} + */ + function debounce( fn, delay ) { + var timer = null; + + return function() { + var context = this, + args = arguments; + + window.clearTimeout(timer); + + timer = window.setTimeout( function () { + fn.apply( context, args ); + }, delay ); + }; + } + + /** + * Build the search query from the search text + * + * @param searchText + * @returns object + */ + function buildSearchQuery( searchText, postType, searchFields ) { + if ( postType === 'all' || typeof( postType ) === 'undefined' || postType === '' ) { + postType = 'all'; + } + + var query = { + sort: [ + { + _score: { + order: 'desc' + } + } + ], + query: { + multi_match: { + query: searchText, + fields: searchFields + } + } + }; + + // If we're specifying post types, do it in an array + if ( typeof postType === 'string' && postType !== 'all' ) { + postType = postType.split(','); + } + + // Then add it as a filter to the end of the query + if ( $.isArray( postType ) ) { + query.post_filter = { + bool: { + must: [{ + terms: { 'post_type.raw': postType } + }] + } + }; + } + + return query; + } + + /** + * Build the ajax request + * + * @param query + * @returns AJAX object request + */ + function esSearch( query ) { + + // Fixes <=IE9 jQuery AJAX bug that prevents ajax request from firing + jQuery.support.cors = true; + + return $.ajax( { + url: epas.endpointUrl, + type: 'post', + dataType: 'json', + crossDomain: true, + data: JSON.stringify( query ) + } ); + } + + /** + * Update the auto suggest box with new options or hide if none + * + * @param options + * @return void + */ + function updateAutosuggestBox( options, $localInput ) { + var i, + itemString, + $localESContainer = $localInput.closest( '.ep-autosuggest-container' ).find( '.ep-autosuggest' ), + $localSuggestList = $localESContainer.find( '.autosuggest-list' ); + + $localSuggestList.empty(); + + // Don't listen to potentially previously set items + $( '.autosuggest-item' ).off(); + + if ( options.length > 0 ) { + $localESContainer.show(); + } else { + $localESContainer.hide(); + } + + for ( i = 0; i < options.length; ++i ) { + var text = options[i].text.toLowerCase(); + var url = options[i].url; + itemString = '
  • ' + text + '
  • '; + $( itemString ).appendTo( $localSuggestList ); + } + + // Listen to items to auto-fill search box and submit form + $( '.autosuggest-item' ).on( 'click', function( event ) { + selectItem( $localInput, event.srcElement ); + } ); + + $localInput.off( 'keydown' ); + + // Listen to the input for up and down navigation between autosuggest items + $localInput.on( 'keydown', function( event ) { + if ( event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 13 ) { + var $results = $localInput.closest( '.ep-autosuggest-container' ).find( '.autosuggest-list li' ); + var $current = $results.filter( '.selected' ); + var $next; + + switch ( event.keyCode ) { + case 38: // Up + $next = $current.prev(); + break; + case 40: // Down + if ( ! $results.hasClass( 'selected' ) ) { + $results.first().addClass( 'selected' ); + $next = $results.first(); + } else { + $next = $current.next(); + } + break; + case 13: // Enter + if ( $results.hasClass( 'selected' ) ) { + selectItem( $localInput, $current.children('span').get(0) ); + return false; + } else { + // No item selected + return; + } + break; + } + + // only check next element if up and down key pressed + if ( $next.is( 'li' ) ) { + $current.removeClass( 'selected' ); + $next.addClass( 'selected' ); + } else { + $results.removeClass( 'selected' ); + } + + // keep cursor from heading back to the beginning in the input + if( event.keyCode === 38 ) { + return false; + } + + return; + } + + } ); + } + + /** + * Hide the auto suggest box + * + * @return void + */ + function hideAutosuggestBox() { + $( '.autosuggest-list' ).empty(); + $( '.ep-autosuggest' ).hide(); + } + + var $epInput = $( '.ep-autosuggest, input[type="search"], .search-field' ); + var $epAutosuggest = $( '
      ' ); + + /** + * Build the auto-suggest container + */ + $epInput.each( function( key, input ) { + var $epContainer = $( '
      ' ); + var $input = $( input ); + + // Disable autocomplete + $input.attr( 'autocomplete', 'off' ); + + $epContainer.insertAfter( $input ); + var $epLabel = $input.siblings( 'label' ); + $input + .closest( 'form' ) + .find( '.ep-autosuggest-container' ) + .append( $epLabel ) + .append( $input ); + + $epAutosuggest.clone().insertAfter( $input ); + + $input.trigger( 'elasticpress.input.moved' ); + } ); + + $epAutosuggest.css( { + top: $epInput.outerHeight() - 1, + 'background-color': $epInput.css( 'background-color' ) + } ); + + /** + * Singular bindings for up and down to prevent normal actions so we can use them to navigate + * our autosuggest list + * Listen to the escape key to close the autosuggest box + */ + $( $epInput ).each( function( key, value ) { + $( value ).on( 'keyup keydown keypress', function( event ) { + if ( event.keyCode === 38 || event.keyCode === 40) { + event.preventDefault(); + } + if ( event.keyCode === 27 ) { + hideAutosuggestBox(); + } + } ); + } ); + + /** + * Listen for any keyup events, throttle them to a min threshold of time + * and then send them for a query to the Elasticsearch server + * + */ + $epInput.each( function( key, localInput ) { + var $localInput = $( localInput ); + $localInput.on( 'keyup', debounce( function( event ) { + if ( event.keyCode === 38 || event.keyCode === 40 || event.keyCode === 13 || event.keyCode === 27 ) { + return; + } + + var val = $localInput.val(); + var query; + var request; + var postType = epas.postType; + var searchFields = epas.searchFields; + + if ( val.length >= 2 ) { + query = buildSearchQuery( val, postType, searchFields ); + request = esSearch( query ); + + request.done( function( response ) { + if ( response._shards.successful > 0 ) { + var usedPosts = {}; + var filteredObjects = []; + + $.each( response.hits.hits, function( index, element ){ + var text = element._source.post_title; + var url = element._source.permalink; + var postId = element._source.post_id; + + if( ! usedPosts[ postId ] ) { + usedPosts[ postId ] = true; + + filteredObjects.push( { + 'text': text, + 'url': url + } ); + } + } ); + + if ( 0 === filteredObjects.length ) { + hideAutosuggestBox(); + } else { + updateAutosuggestBox( filteredObjects, $localInput ); + } + } else { + hideAutosuggestBox(); + } + } ); + } else if ( 0 === val.length ) { + hideAutosuggestBox(); + } + }, 200 ) ); + } ); + + // Publically expose API + window.epasAPI = { + hideAutosuggestBox: hideAutosuggestBox, + updateAutosuggestBox: updateAutosuggestBox, + esSearch: esSearch, + buildSearchQuery: buildSearchQuery + }; + +} )( jQuery ); diff --git a/features/autosuggest/autosuggest.php b/features/autosuggest/autosuggest.php new file mode 100644 index 0000000000..74b02250a6 --- /dev/null +++ b/features/autosuggest/autosuggest.php @@ -0,0 +1,240 @@ + +

      + +

      + get_settings(); + + if ( ! $settings ) { + $settings = array(); + } + + $settings = wp_parse_args( $settings, $feature->default_settings ); + + if ( preg_match( '#elasticpress\.io#i', $host ) ) { + return; + } + ?> + +
      +
      +
      + +

      +
      +
      + + 'text', + 'analyzer' => 'edge_ngram_analyzer', + 'search_analyzer' => 'standard', + ); + + $mapping['settings']['analysis']['analyzer']['edge_ngram_analyzer'] = array( + 'type' => 'custom', + 'tokenizer' => 'standard', + 'filter' => array( + 'lowercase', + 'edge_ngram', + ), + ); + + $mapping['mappings']['post']['properties']['term_suggest'] = array( + 'type' => 'text', + 'analyzer' => 'edge_ngram_analyzer', + 'search_analyzer' => 'standard', + ); + + return $mapping; +} + +/** + * Add term suggestions to be indexed + * + * @param $post_args + * @param $post_id + * @since 2.4 + * @return array + */ +function ep_autosuggest_filter_term_suggest( $post_args, $post_id ) { + $suggest = array(); + + if ( ! empty( $post_args['terms'] ) ) { + foreach ( $post_args['terms'] as $taxonomy ) { + foreach ( $taxonomy as $term ) { + $suggest[] = $term['name']; + } + } + } + + if ( ! empty( $suggest ) ) { + $post_args['term_suggest'] = $suggest; + } + + return $post_args; +} + +/** + * Enqueue our autosuggest script + * + * @since 2.4 + */ +function ep_autosuggest_enqueue_scripts() { + $feature = ep_get_registered_feature( 'autosuggest' ); + + $host = ep_get_host(); + + $endpoint_url = false; + + if ( preg_match( '#elasticpress\.io#i', $host ) ) { + $endpoint_url = $host . '/' . ep_get_index_name() . '/post/_search'; + } else { + $settings = $feature->get_settings(); + + if ( ! $settings ) { + $settings = array(); + } + + $settings = wp_parse_args( $settings, $feature->default_settings ); + + if ( empty( $settings['endpoint_url'] ) ) { + return; + } + + $endpoint_url = $settings['endpoint_url']; + } + + $js_url = ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) ? EP_URL . 'features/autosuggest/assets/js/src/autosuggest.js' : EP_URL . 'features/autosuggest/assets/js/autosuggest.min.js'; + $css_url = ( defined( 'SCRIPT_DEBUG' ) && true === SCRIPT_DEBUG ) ? EP_URL . 'features/autosuggest/assets/css/autosuggest.css' : EP_URL . 'features/autosuggest/assets/css/autosuggest.min.css'; + + wp_enqueue_script( + 'elasticpress-autosuggest', + $js_url, + array( 'jquery' ), + EP_VERSION, + true + ); + + wp_enqueue_style( + 'elasticpress-autosuggest', + $css_url, + array(), + EP_VERSION + ); + + /** + * Output variables to use in Javascript + * index: the Elasticsearch index name + * endpointUrl: the Elasticsearch autosuggest endpoint url + * postType: which post types to use for suggestions + * action: the action to take when selecting an item. Possible values are "search" and "navigate". + */ + wp_localize_script( 'elasticpress-autosuggest', 'epas', apply_filters( 'ep_autosuggest_options', array( + 'endpointUrl' => esc_url( untrailingslashit( $endpoint_url ) ), + 'postType' => apply_filters( 'ep_term_suggest_post_type', 'all' ), + 'searchFields' => apply_filters( 'ep_term_suggest_search_fields', array( + 'post_title.suggest', + 'term_suggest', + ) ), + 'action' => 'navigate', + ) ) ); +} + +/** + * Determine WC feature reqs status + * + * @param EP_Feature_Requirements_Status $status + * @since 2.4 + * @return EP_Feature_Requirements_Status + */ +function ep_autosuggest_requirements_status( $status ) { + $host = ep_get_host(); + + $status->code = 1; + + $status->message = array(); + + $status->message[] = esc_html__( 'This feature modifies the site’s default user experience by presenting a list of suggestions below detected search fields as text is entered into the field.', 'elasticpress' ); + + if ( ! preg_match( '#elasticpress\.io#i', $host ) ) { + $status->message[] = wp_kses_post( __( "You aren't using ElasticPress.io so we can't be sure your host is properly secured. Autosuggest requires a publicly accessible endpoint, which can expose private content and allow data modification if improperly configured.", 'elasticpress' ) ); + } + + return $status; +} + +/** + * Add autosuggest setting fields + * + * @since 2.4 + */ +function ep_autosuggest_setup_settings() { + add_action( 'ep_feature_box_settings_autosuggest', 'ep_autosugguest_settings', 10, 1 ); +} +add_action( 'admin_init', 'ep_autosuggest_setup_settings' ); + +/** + * Register the feature + * + * @since 2.4 + */ +ep_register_feature( 'autosuggest', array( + 'title' => 'Autosuggest', + 'setup_cb' => 'ep_autosuggest_setup', + 'feature_box_summary_cb' => 'ep_autosuggest_feature_box_summary', + 'feature_box_long_cb' => 'ep_autosuggest_feature_box_long', + 'requires_install_reindex' => true, + 'requirements_status_cb' => 'ep_autosuggest_requirements_status', + 'default_settings' => array( + 'endpoint_url' => '', + ), +) ); diff --git a/features/documents/documents.php b/features/documents/documents.php index 4dc065f45a..9d881524e8 100644 --- a/features/documents/documents.php +++ b/features/documents/documents.php @@ -10,20 +10,20 @@ function ep_documents_setup() { add_filter( 'ep_post_sync_args', 'ep_documents_post_sync_args', 999, 2 ); add_filter( 'ep_indexable_post_status', 'ep_documents_indexable_post_status', 999, 1 ); add_filter( 'ep_bulk_index_post_request_path', 'ep_documents_bulk_index_post_request_path', 999, 1 ); - add_filter( 'pre_get_posts', 'search_attachment_post_type' ); - add_filter( 'ep_config_mapping', 'attachments_mapping' ); + add_filter( 'pre_get_posts', 'ep_documents_search_attachment_post_type' ); + add_filter( 'ep_config_mapping', 'ep_documents_attachments_mapping' ); add_action( 'ep_cli_put_mapping', 'ep_documents_create_pipeline' ); add_action( 'ep_dashboard_put_mapping', 'ep_documents_create_pipeline' ); } /** * Add attachments mapping - * + * * @param array $mapping * @since 2.3 * @return array */ -function attachments_mapping( $mapping ) { +function ep_documents_attachments_mapping( $mapping ) { $mapping['mappings']['post']['properties']['attachments'] = array( 'type' => 'object', ); @@ -36,11 +36,11 @@ function attachments_mapping( $mapping ) { * add the attachment post type to post_type and inherit to post_status. If post_status is not set, * we assume publish/inherit is wanted. post_type should always be set. We also add allowed mime types. * If mime types are already set, append. - * + * * @param WP_Query $query * @since 2.3 */ -function search_attachment_post_type( $query ) { +function ep_documents_search_attachment_post_type( $query ) { if ( is_admin() ) { return; } @@ -103,7 +103,7 @@ function ep_documents_index_post_request_path( $path, $post ) { $path = trailingslashit( $index ) . 'post/' . $post['ID'] . '?pipeline=' . apply_filters( 'ep_documents_pipeline_id', ep_get_index_name() . '-attachment' ); } } - + return $path; } @@ -127,19 +127,19 @@ function ep_documents_post_sync_args( $post_args, $post_id ) { } $allowed_ingest_mime_types = ep_documents_get_allowed_ingest_mime_types(); - + if ( 'attachment' == get_post_type( $post_id ) && in_array( get_post_mime_type( $post_id ), $allowed_ingest_mime_types ) ) { $file_name = get_attached_file( $post_id ); $exist = $wp_filesystem->exists( $file_name, false, 'f' ); if ( $exist ) { $file_content = $wp_filesystem->get_contents( $file_name ); - + $post_args['attachments'][] = array( 'data' => base64_encode( $file_content ), ); } } - + return $post_args; } @@ -154,9 +154,9 @@ function ep_filter_ep_search_fields( $search_fields ) { if ( ! is_array( $search_fields ) ) { return $search_fields; } - + $search_fields[] = 'attachments.attachment.content'; - + return $search_fields; } @@ -171,7 +171,7 @@ function ep_documents_indexable_post_status( $statuses ) { if ( ! array_search( 'inherit', $statuses ) ) { $statuses[] = 'inherit'; } - + return $statuses; } @@ -199,8 +199,8 @@ function ep_documents_requirements_status( $status ) { $plugins = ep_get_elasticsearch_plugins(); $status->code = 1; - $status->message = []; - + $status->message = array(); + // Ingest attachment plugin is required for this feature if ( empty( $plugins ) || empty( $plugins['ingest-attachment'] ) ) { $status->code = 2; @@ -208,7 +208,7 @@ function ep_documents_requirements_status( $status ) { } else { $status->message[] = __( "This feature modifies the default user experience for your visitors by adding popular document file types to search results. All supported documents uploaded to your media library will appear in search results.", 'elasticpress' ); } - + return $status; } @@ -225,7 +225,7 @@ function ep_documents_feature_box_summary() { /** * Output feature box long - * + * * @since 2.3 */ function ep_documents_feature_box_long() { @@ -258,7 +258,7 @@ function ep_documents_create_pipeline() { ), ), ); - + ep_create_pipeline( apply_filters( 'ep_documents_pipeline_id', ep_get_index_name() . '-attachment' ), $args ); } diff --git a/features/protected-content/protected-content.php b/features/protected-content/protected-content.php index d67b5c4e8b..fcc797e4a3 100644 --- a/features/protected-content/protected-content.php +++ b/features/protected-content/protected-content.php @@ -109,7 +109,7 @@ function ep_pc_feature_box_summary() { */ function ep_pc_feature_box_long() { ?> -

      We recommend using a secured Elasticsearch setup, such as ElasticPress.io, to prevent potential exposure of content not intended for the public.', 'elasticpress' ); ?>

      +

      We recommend using a secured Elasticsearch setup, such as ElasticPress.io, to prevent potential exposure of content not intended for the public.', 'elasticpress' ) ); ?>

      array( - 'query' => $formatted_args['query'], - 'exp' => array( - 'post_date_gmt' => array( - 'scale' => apply_filters( 'epwr_scale', '14d', $formatted_args, $args ), - 'decay' => apply_filters( 'epwr_decay', .25, $formatted_args, $args ), - 'offset' => apply_filters( 'epwr_offset', '7d', $formatted_args, $args ), + $feature = ep_get_registered_feature( 'search' ); + $settings = array(); + if ( $feature ) { + $settings = $feature->get_settings(); + } + + $settings = wp_parse_args( $settings, array( + 'decaying_enabled' => true, + ) ); + if ( (bool)$settings['decaying_enabled'] ) { + $date_score = array( + 'function_score' => array( + 'query' => $formatted_args['query'], + 'exp' => array( + 'post_date_gmt' => array( + 'scale' => apply_filters( 'epwr_scale', '14d', $formatted_args, $args ), + 'decay' => apply_filters( 'epwr_decay', .25, $formatted_args, $args ), + 'offset' => apply_filters( 'epwr_offset', '7d', $formatted_args, $args ), + ), ), + 'score_mode' => 'avg', + 'boost_mode' => apply_filters( 'epwr_boost_mode', 'sum', $formatted_args, $args ), ), - 'score_mode' => 'avg', - 'boost_mode' => 'sum' - ), - ); + ); - $formatted_args['query'] = $date_score; + $formatted_args['query'] = $date_score; + } } return $formatted_args; @@ -234,9 +246,14 @@ function ep_integrate_search_queries( $enabled, $query ) { } else if ( method_exists( $query, 'is_search' ) && $query->is_search() && ! empty( $query->query_vars['s'] ) ) { $enabled = true; + /** + * WordPress have to be version 4.6 or newer to have "fields" support + * since it requires the "posts_pre_query" filter. + * + * @see WP_Query::get_posts + */ $fields = $query->get( 'fields' ); - - if ( ! empty( $fields ) ) { + if ( ! version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) && ! empty( $fields ) ) { $enabled = false; } } @@ -244,6 +261,32 @@ function ep_integrate_search_queries( $enabled, $query ) { return $enabled; } +/** + * Display decaying settings on dashboard. + * + * @since 2.4 + * + * @param EP_Feature $feature Feature object. + * + * @return void + */ +function ep_integrate_search_box_settings( $feature ) { + $decaying_settings = $feature->get_settings(); + if ( ! $decaying_settings ) { + $decaying_settings = array(); + } + $decaying_settings = wp_parse_args( $decaying_settings, $feature->default_settings ); + ?> +
      +
      +
      +
      + +
      +
      + 'ep_search_feature_box_summary', 'feature_box_long_cb' => 'ep_search_feature_box_long', 'requires_install_reindex' => false, + 'default_settings' => array( + 'decaying_enabled' => true, + ), ) ); diff --git a/features/woocommerce/woocommerce.php b/features/woocommerce/woocommerce.php index 3e7e517b5e..324f122a11 100644 --- a/features/woocommerce/woocommerce.php +++ b/features/woocommerce/woocommerce.php @@ -133,10 +133,17 @@ function ep_wc_convert_post_object_to_id( $posts ) { * @return array */ function ep_wc_whitelist_taxonomies( $taxonomies, $post ) { + $woo_taxonomies = array(); + $product_type = get_taxonomy( 'product_type' ); - $product_visibility = get_taxonomy( 'product_visibility' ); + if( false !== $product_type ){ + $woo_taxonomies[] = $product_type; + } - $woo_taxonomies = array( $product_type, $product_visibility ); + $product_visibility = get_taxonomy( 'product_visibility' ); + if( false !== $product_visibility ){ + $woo_taxonomies[] = $product_visibility; + } /** * Note product_shipping_class, product_cat, and product_tag are already public. Make @@ -234,6 +241,7 @@ function ep_wc_translate_args( $query ) { 'product_type', 'pa_sort-by', 'product_visibility', + 'product_shipping_class', ); /** @@ -266,21 +274,27 @@ function ep_wc_translate_args( $query ) { if ( ! empty( $term ) ) { $integrate = true; - $terms = array( $term ); + $terms = (array)$term; + $children_terms = array(); // to add child terms to the tax query if ( is_taxonomy_hierarchical( $taxonomy ) ) { - $term_object = get_term_by( 'slug', $term, $taxonomy ); - $children = get_term_children( $term_object->term_id, $taxonomy ); - if ( $children ) { - foreach ( $children as $child ) { - $child_object = get_term( $child, $taxonomy ); - $terms[] = $child_object->slug; + foreach ( $terms as $term ) { + $term_object = get_term_by( 'slug', $term, $taxonomy ); + if ( $term_object && property_exists( $term_object, 'term_id' ) ) { + $children = get_term_children( $term_object->term_id, $taxonomy ); + if ( $children ) { + foreach ( $children as $child ) { + $child_object = get_term( $child, $taxonomy ); + if ( $child_object && ! is_wp_error( $child_object ) && property_exists( $child_object, 'slug' ) ) { + $children_terms[] = $child_object->slug; + } + } + } } } - } - + $terms = array_merge( $terms, $children_terms ); $tax_query[] = array( 'taxonomy' => $taxonomy, 'field' => 'slug', @@ -331,10 +345,13 @@ function ep_wc_translate_args( $query ) { } /** - * We can't support any special fields parameters + * WordPress have to be version 4.6 or newer to have "fields" support + * since it requires the "posts_pre_query" filter. + * + * @see WP_Query::get_posts */ $fields = $query->get( 'fields', false ); - if ( 'ids' === $fields || 'id=>parent' === $fields ) { + if ( ! version_compare( get_bloginfo( 'version' ), '4.6', '>=' ) && ( 'ids' === $fields || 'id=>parent' === $fields ) ) { $query->set( 'fields', 'default' ); } @@ -407,6 +424,7 @@ function ep_wc_translate_args( $query ) { '_billing_first_name', '_shipping_first_name', '_shipping_last_name', + '_items', ) ) ); $query->set( 'search_fields', $search_fields ); @@ -564,7 +582,7 @@ function ep_wc_bypass_order_permissions_check( $override, $post_id ) { */ function ep_wc_search_order( $wp ){ global $pagenow; - if ( 'edit.php' != $pagenow || 'shop_order' !== $wp->query_vars['post_type'] || + if ( 'edit.php' != $pagenow || empty( $wp->query_vars['post_type'] ) || 'shop_order' !== $wp->query_vars['post_type'] || ( empty( $wp->query_vars['s'] ) && empty( $wp->query_vars['shop_order_search'] ) ) ) { return; } @@ -584,6 +602,45 @@ function ep_wc_search_order( $wp ){ } } +/** + * Add order items as a searchable string. + * + * This mimics how WooCommerce currently does in the order_itemmeta + * table. They combine the titles of the products and put them in a + * meta field called "Items". + * + * @since 2.4 + * + * @param array $post_args + * @param string|int $post_id + * + * @return array + */ +function ep_wc_add_order_items_search( $post_args, $post_id ) { + // Make sure it is only WooCommerce orders we touch. + if ( 'shop_order' !== $post_args['post_type'] ) { + return $post_args; + } + + // Get order items. + $order = wc_get_order( $post_id ); + $item_meta = array(); + foreach ( $order->get_items() as $delta => $product_item ) { + // WooCommerce 3.x uses WC_Order_Item_Product instance while 2.x an array + if ( is_object( $product_item ) && method_exists( $product_item, 'get_name' ) ) { + $item_meta['_items'][] = $product_item->get_name( 'edit' ); + } elseif ( is_array( $product_item ) && isset( $product_item[ 'name' ] ) ) { + $item_meta['_items'][] = $product_item[ 'name' ]; + } + } + + // Prepare order items. + $item_meta['_items'] = empty( $item_meta['_items'] ) ? '' : implode( '|', $item_meta['_items'] ); + $post_args['meta'] = array_merge( $post_args['meta'], EP_API::factory()->prepare_meta_types( $item_meta ) ); + + return $post_args; +} + /** * Setup all feature filters * @@ -599,6 +656,7 @@ function ep_wc_setup() { add_filter( 'woocommerce_unfiltered_product_ids', 'ep_wc_convert_post_object_to_id', 10, 4 ); add_filter( 'ep_sync_taxonomies', 'ep_wc_whitelist_taxonomies', 10, 2 ); add_filter( 'ep_post_sync_args_post_prepare_meta', 'ep_wc_remove_legacy_meta', 10, 2 ); + add_filter( 'ep_post_sync_args_post_prepare_meta', 'ep_wc_add_order_items_search', 20, 2 ); add_action( 'pre_get_posts', 'ep_wc_translate_args', 11, 1 ); add_action( 'parse_query', 'ep_wc_search_order', 11, 1 ); } @@ -606,7 +664,7 @@ function ep_wc_setup() { /** * Output feature box summary - * + * * @since 2.1 */ function ep_wc_feature_box_summary() { @@ -617,7 +675,7 @@ function ep_wc_feature_box_summary() { /** * Output feature box long - * + * * @since 2.1 */ function ep_wc_feature_box_long() { diff --git a/includes/dashboard-page.php b/includes/dashboard-page.php index d01e78d3b4..40138b3ec2 100644 --- a/includes/dashboard-page.php +++ b/includes/dashboard-page.php @@ -25,7 +25,7 @@
      registered_features; ?> - array( - 'index.mapping.total_fields.limit' => apply_filters( 'ep_total_field_limit', 5000 ), - 'index.max_result_window' => apply_filters( 'ep_max_result_window', 1000000 ), + 'index.mapping.total_fields.limit' => apply_filters( 'ep_total_field_limit', 5000 ), + 'index.max_result_window' => apply_filters( 'ep_max_result_window', 1000000 ), 'analysis' => array( 'analyzer' => array( 'default' => array( diff --git a/includes/mappings/5-2.php b/includes/mappings/5-2.php new file mode 100644 index 0000000000..c4dff2ce8a --- /dev/null +++ b/includes/mappings/5-2.php @@ -0,0 +1,354 @@ + array( + 'index.mapping.total_fields.limit' => apply_filters( 'ep_total_field_limit', 5000 ), + 'index.max_result_window' => apply_filters( 'ep_max_result_window', 1000000 ), + 'analysis' => array( + 'analyzer' => array( + 'default' => array( + 'tokenizer' => 'standard', + 'filter' => array( 'standard', 'ewp_word_delimiter', 'lowercase', 'stop', 'ewp_snowball' ), + 'language' => apply_filters( 'ep_analyzer_language', 'english', 'analyzer_default' ), + ), + 'shingle_analyzer' => array( + 'type' => 'custom', + 'tokenizer' => 'standard', + 'filter' => array( 'lowercase', 'shingle_filter' ), + ), + 'ewp_lowercase' => array( + 'type' => 'custom', + 'tokenizer' => 'keyword', + 'filter' => array( 'lowercase' ), + ), + ), + 'filter' => array( + 'shingle_filter' => array( + 'type' => 'shingle', + 'min_shingle_size' => 2, + 'max_shingle_size' => 5, + ), + 'ewp_word_delimiter' => array( + 'type' => 'word_delimiter', + 'preserve_original' => true, + ), + 'ewp_snowball' => array( + 'type' => 'snowball', + 'language' => apply_filters( 'ep_analyzer_language', 'english', 'filter_ewp_snowball' ), + ), + 'edge_ngram' => array( + 'side' => 'front', + 'max_gram' => 10, + 'min_gram' => 3, + 'type' => 'edgeNGram', + ), + ), + 'normalizer' => array( + 'lowerasciinormalizer' => array( + 'type' => 'custom', + 'filter' => array( 'lowercase', 'asciifolding' ), + ), + ), + ), + ), + 'mappings' => array( + 'post' => array( + 'date_detection' => false, + 'dynamic_templates' => array( + array( + 'template_meta' => array( + 'path_match' => 'post_meta.*', + 'mapping' => array( + 'type' => 'text', + 'path' => 'full', + 'fields' => array( + '{name}' => array( + 'type' => 'text', + ), + 'raw' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + ), + ), + ), + ), + ), + array( + 'template_meta_types' => array( + 'path_match' => 'meta.*', + 'mapping' => array( + 'type' => 'object', + 'path' => 'full', + 'properties' => array( + 'value' => array( + 'type' => 'text', + 'fields' => array( + 'sortable' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + 'normalizer' => 'lowerasciinormalizer', + ), + 'raw' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + ), + ), + ), + 'raw' => array( /* Left for backwards compat */ + 'type' => 'keyword', + 'ignore_above' => 10922, + ), + 'long' => array( + 'type' => 'long', + ), + 'double' => array( + 'type' => 'double', + ), + 'boolean' => array( + 'type' => 'boolean', + ), + 'date' => array( + 'type' => 'date', + 'format' => 'yyyy-MM-dd', + ), + 'datetime' => array( + 'type' => 'date', + 'format' => 'yyyy-MM-dd HH:mm:ss', + ), + 'time' => array( + 'type' => 'date', + 'format' => 'HH:mm:ss', + ), + ), + ), + ), + ), + array( + 'template_terms' => array( + 'path_match' => 'terms.*', + 'mapping' => array( + 'type' => 'object', + 'path' => 'full', + 'properties' => array( + 'name' => array( + 'type' => 'text', + 'fields' => array( + 'raw' => array( + 'type' => 'keyword', + ), + 'sortable' => array( + 'type' => 'keyword', + 'normalizer' => 'lowerasciinormalizer', + ), + ), + ), + 'term_id' => array( + 'type' => 'long', + ), + 'term_taxonomy_id' => array( + 'type' => 'long', + ), + 'parent' => array( + 'type' => 'long', + ), + 'slug' => array( + 'type' => 'keyword', + ), + ), + ), + ), + ), + array( + 'term_suggest' => array( + 'path_match' => 'term_suggest_*', + 'mapping' => array( + 'type' => 'completion', + 'analyzer' => 'default', + ), + ), + ), + ), + '_all' => array( + 'analyzer' => 'simple', + ), + 'properties' => array( + 'post_id' => array( + 'type' => 'long', + ), + 'ID' => array( + 'type' => 'long', + ), + 'post_author' => array( + 'type' => 'object', + 'properties' => array( + 'display_name' => array( + 'type' => 'text', + 'fields' => array( + 'raw' => array( + 'type' => 'keyword', + ), + 'sortable' => array( + 'type' => 'keyword', + 'normalizer' => 'lowerasciinormalizer', + ), + ), + ), + 'login' => array( + 'type' => 'text', + 'fields' => array( + 'raw' => array( + 'type' => 'keyword', + ), + 'sortable' => array( + 'type' => 'keyword', + 'normalizer' => 'lowerasciinormalizer', + ), + ), + ), + 'id' => array( + 'type' => 'long', + ), + 'raw' => array( + 'type' => 'keyword', + ), + ), + ), + 'post_date' => array( + 'type' => 'date', + 'format' => 'YYYY-MM-dd HH:mm:ss', + ), + 'post_date_gmt' => array( + 'type' => 'date', + 'format' => 'YYYY-MM-dd HH:mm:ss', + ), + 'post_title' => array( + 'type' => 'text', + 'fields' => array( + 'post_title' => array( + 'type' => 'text', + 'analyzer' => 'standard', + ), + 'raw' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + ), + 'sortable' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + 'normalizer' => 'lowerasciinormalizer', + ), + ), + ), + 'post_excerpt' => array( + 'type' => 'text', + ), + 'post_content' => array( + 'type' => 'text', + ), + 'post_status' => array( + 'type' => 'keyword', + ), + 'post_name' => array( + 'type' => 'text', + 'fields' => array( + 'post_name' => array( + 'type' => 'text', + ), + 'raw' => array( + 'type' => 'keyword', + 'ignore_above' => 10922, + ), + ), + ), + 'post_modified' => array( + 'type' => 'date', + 'format' => 'YYYY-MM-dd HH:mm:ss', + ), + 'post_modified_gmt' => array( + 'type' => 'date', + 'format' => 'YYYY-MM-dd HH:mm:ss', + ), + 'post_parent' => array( + 'type' => 'long', + ), + 'post_type' => array( + 'type' => 'text', + 'fields' => array( + 'post_type' => array( + 'type' => 'text', + ), + 'raw' => array( + 'type' => 'keyword', + ), + ), + ), + 'post_mime_type' => array( + 'type' => 'keyword', + ), + 'permalink' => array( + 'type' => 'keyword', + ), + 'guid' => array( + 'type' => 'keyword', + ), + 'terms' => array( + 'type' => 'object', + ), + 'post_meta' => array( + 'type' => 'object', + ), + 'meta' => array( + 'type' => 'object', + ), + 'date_terms' => array( + 'type' => 'object', + 'properties' => array( + 'year' => array( //4 digit year (e.g. 2011) + 'type' => 'integer', + ), + 'month' => array( //Month number (from 1 to 12) alternate name 'monthnum' + 'type' => 'integer', + ), + 'm' => array( //YearMonth (For e.g.: 201307) + 'type' => 'integer', + ), + 'week' => array( //Week of the year (from 0 to 53) alternate name 'w' + 'type' => 'integer', + ), + 'day' => array( //Day of the month (from 1 to 31) + 'type' => 'integer', + ), + 'dayofweek' => array( //Accepts numbers 1-7 (1 is Sunday) + 'type' => 'integer', + ), + 'dayofweek_iso' => array( //Accepts numbers 1-7 (1 is Monday) + 'type' => 'integer', + ), + 'dayofyear' => array( //Accepts numbers 1-366 + 'type' => 'integer', + ), + 'hour' => array( //Hour (from 0 to 23) + 'type' => 'integer', + ), + 'minute' => array( //Minute (from 0 to 59) + 'type' => 'integer', + ), + 'second' => array( //Second (0 to 59) + 'type' => 'integer', + ), + ), + ), + ), + ), + ), +); diff --git a/includes/settings-page.php b/includes/settings-page.php index 16e9fd4601..2a54a5c0f8 100644 --- a/includes/settings-page.php +++ b/includes/settings-page.php @@ -39,7 +39,7 @@ - + diff --git a/lang/elasticpress.pot b/lang/elasticpress.pot index 787d221db5..64d683c26d 100644 --- a/lang/elasticpress.pot +++ b/lang/elasticpress.pot @@ -2,9 +2,9 @@ # This file is distributed under the GPLv2 or later. msgid "" msgstr "" -"Project-Id-Version: ElasticPress 2.3.2\n" +"Project-Id-Version: ElasticPress 2.4\n" "Report-Msgid-Bugs-To: https://wordpress.org/support/plugin/elasticpress\n" -"POT-Creation-Date: 2017-06-30 17:19:05+00:00\n" +"POT-Creation-Date: 2017-10-04 22:21:05+00:00\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" @@ -143,27 +143,27 @@ msgstr "" msgid "Unable to reach Elasticsearch Server! Check that service is running." msgstr "" -#: classes/class-ep-api.php:2137 +#: classes/class-ep-api.php:2183 msgid "" "Invalid response from ElasticPress server. Please contact your " "administrator." msgstr "" -#: classes/class-ep-api.php:2150 +#: classes/class-ep-api.php:2196 msgid "" "Site not indexed.

      Please run: wp elasticpress index --setup " "--network-wide using WP-CLI. Or use the index button on the left of " "this screen.

      " msgstr "" -#: classes/class-ep-api.php:2154 +#: classes/class-ep-api.php:2200 msgid "" "Site not indexed.

      Please run: wp elasticpress index --setup " "using WP-CLI. Or use the index button on the left of this screen.

      " msgstr "" -#: classes/class-ep-api.php:2289 classes/class-ep-api.php:2401 -#: classes/class-ep-api.php:2452 +#: classes/class-ep-api.php:2335 classes/class-ep-api.php:2447 +#: classes/class-ep-api.php:2498 msgid "Elasticsearch Host is not available." msgstr "" @@ -171,101 +171,101 @@ msgstr "" msgid "Dashboard" msgstr "" -#: classes/class-ep-dashboard.php:288 +#: classes/class-ep-dashboard.php:290 msgid "" "There is a problem with connecting to your Elasticsearch host. ElasticPress " "can try your host again, or you may need to change your settings." msgstr "" -#: classes/class-ep-dashboard.php:295 +#: classes/class-ep-dashboard.php:297 msgid "" "Your Elasticsearch version %s is above the maximum required Elasticsearch " "version %s. ElasticPress may or may not work properly." msgstr "" -#: classes/class-ep-dashboard.php:302 +#: classes/class-ep-dashboard.php:304 msgid "" "Your Elasticsearch version %s is below the minimum required Elasticsearch " "version %s. ElasticPress may or may not work properly." msgstr "" -#: classes/class-ep-dashboard.php:315 +#: classes/class-ep-dashboard.php:317 msgid "" "Thanks for installing ElasticPress! You will need to run through a quick set up process to get the plugin working." msgstr "" -#: classes/class-ep-dashboard.php:328 +#: classes/class-ep-dashboard.php:330 msgid "" "ElasticPress is almost ready. You will need to complete a sync to get the plugin working." msgstr "" -#: classes/class-ep-dashboard.php:341 +#: classes/class-ep-dashboard.php:343 msgid "" "The new version of ElasticPress requires that you run a " "sync." msgstr "" -#: classes/class-ep-dashboard.php:356 +#: classes/class-ep-dashboard.php:358 msgid "" "The ElasticPress %s feature has been auto-activated! You will need to run a sync for it to work." msgstr "" -#: classes/class-ep-dashboard.php:364 +#: classes/class-ep-dashboard.php:366 msgid "" "Dashboard sync is disabled. The ElasticPress %s feature has been " "auto-activated! You will need to reindex using WP-CLI for it to work." msgstr "" -#: classes/class-ep-dashboard.php:371 +#: classes/class-ep-dashboard.php:373 msgid "" "Dashboard sync is disabled. The new version of ElasticPress requires that " "you to reindex using WP-CLI." msgstr "" -#: classes/class-ep-dashboard.php:378 +#: classes/class-ep-dashboard.php:380 msgid "" "Dashboard sync is disabled. You will need to index using WP-CLI to finish " "setup." msgstr "" -#: classes/class-ep-dashboard.php:739 +#: classes/class-ep-dashboard.php:741 msgid "Sync complete" msgstr "" -#: classes/class-ep-dashboard.php:740 +#: classes/class-ep-dashboard.php:742 msgid "Sync paused" msgstr "" -#: classes/class-ep-dashboard.php:741 +#: classes/class-ep-dashboard.php:743 msgid "Syncing" msgstr "" -#: classes/class-ep-dashboard.php:742 +#: classes/class-ep-dashboard.php:744 msgid "Starting sync" msgstr "" -#: classes/class-ep-dashboard.php:743 -msgid "WP CLI sync is occuring. Refresh the page to see if it's finished" +#: classes/class-ep-dashboard.php:745 +msgid "WP CLI sync is occurring. Refresh the page to see if it's finished" msgstr "" -#: classes/class-ep-dashboard.php:744 +#: classes/class-ep-dashboard.php:746 msgid "An error occured while syncing" msgstr "" -#: classes/class-ep-dashboard.php:781 +#: classes/class-ep-dashboard.php:783 msgid "Security error!" msgstr "" -#: classes/class-ep-dashboard.php:895 classes/class-ep-dashboard.php:896 +#: classes/class-ep-dashboard.php:897 classes/class-ep-dashboard.php:898 #: classes/class-ep-feature.php:274 includes/settings-page.php:27 msgid "Settings" msgstr "" -#: classes/class-ep-dashboard.php:904 classes/class-ep-dashboard.php:905 +#: classes/class-ep-dashboard.php:906 classes/class-ep-dashboard.php:907 msgid "Welcome" msgstr "" @@ -277,23 +277,23 @@ msgstr "" msgid "Collapse" msgstr "" -#: classes/class-ep-feature.php:277 +#: classes/class-ep-feature.php:278 msgid "Status" msgstr "" -#: classes/class-ep-feature.php:279 +#: classes/class-ep-feature.php:280 features/search/search.php:283 msgid "Enabled" msgstr "" -#: classes/class-ep-feature.php:280 +#: classes/class-ep-feature.php:281 features/search/search.php:284 msgid "Disabled" msgstr "" -#: classes/class-ep-feature.php:294 +#: classes/class-ep-feature.php:298 msgid "Setting adjustments to this feature require a re-sync. Use WP-CLI." msgstr "" -#: classes/class-ep-feature.php:297 +#: classes/class-ep-feature.php:301 msgid "Save" msgstr "" @@ -315,6 +315,42 @@ msgstr "" msgid "The following values do not describe a valid date: month %1$s, day %2$s." msgstr "" +#: features/autosuggest/autosuggest.php:10 +msgid "Suggest relevant content as text is entered into the search field." +msgstr "" + +#: features/autosuggest/autosuggest.php:21 +msgid "" +"Input fields of type \"search\" or with the CSS class \"search-field\" or " +"\"ep-autosuggest\" will be enhanced with autosuggest functionality. As text " +"is entered into the search field, suggested content will appear below it, " +"based on top search results for the text. Suggestions link directly to the " +"content." +msgstr "" + +#: features/autosuggest/autosuggest.php:58 +msgid "Endpoint URL" +msgstr "" + +#: features/autosuggest/autosuggest.php:61 +msgid "This address will be exposed to the public." +msgstr "" + +#: features/autosuggest/autosuggest.php:206 +msgid "" +"This feature modifies the site’s default user experience by presenting a " +"list of suggestions below detected search fields as text is entered into " +"the field." +msgstr "" + +#: features/autosuggest/autosuggest.php:209 +msgid "" +"You aren't using ElasticPress.io so " +"we can't be sure your host is properly secured. Autosuggest requires a " +"publicly accessible endpoint, which can expose private content and allow " +"data modification if improperly configured." +msgstr "" + #: features/documents/documents.php:207 msgid "" "The assertTrue( ! empty( $this->fired_actions['ep_wp_query_search'] ) ); } - + /** * Test case for when index is deleted, request for Elasticsearch should fall back to WP Query - * + * * @group search */ public function testSearchIndexDeleted(){ global $wpdb; - + ep_activate_feature( 'search' ); EP_Features::factory()->setup_features(); // Need to call this since it's hooked to init ep_search_setup(); - + $post_ids = array(); - + ep_create_and_sync_post(); ep_create_and_sync_post(); ep_create_and_sync_post( array( 'post_content' => 'findme' ) ); - + ep_refresh_index(); - + add_action( 'ep_wp_query_search', array( $this, 'action_wp_query_search' ), 10, 0 ); - + $args = array( 's' => 'findme', ); - + $query = new WP_Query( $args ); - + $this->assertTrue( "SELECT * FROM {$wpdb->posts} WHERE 1=0" == $query->request ); - + ep_delete_index(); - + $query = new WP_Query( $args ); - + $this->assertTrue( "SELECT * FROM {$wpdb->posts} WHERE 1=0" != $query->request ); } + + /** + * Test if decaying is enabled. + * + * @since 2.4 + * @group search + */ + public function testDecayingEnabled() { + delete_site_option( 'ep_feature_requirement_statuses' ); + delete_site_option( 'ep_feature_settings' ); + + EP_Features::factory()->handle_feature_activation(); + EP_Features::factory()->setup_features(); + + ep_update_feature( 'search', array( + 'active' => true, + 'decaying_enabled' => true, + ) ); + + ep_create_and_sync_post( array( 'post_content' => 'findme test 1', 'tags_input' => array( 'one', 'two' ) ) ); + ep_refresh_index(); + + add_filter( 'ep_formatted_args', array( $this, 'catch_ep_formatted_args' ) ); + $query = new WP_Query( array( + 's' => 'test', + ) ); + $this->assertTrue( isset( $this->fired_actions['ep_formatted_args'] ) ); + $this->assertTrue( isset( + $this->fired_actions['ep_formatted_args']['query'], + $this->fired_actions['ep_formatted_args']['query']['function_score'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['scale'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['decay'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['offset'] + ) ); + } + + /** + * Test if decaying is disabled. + * + * @since 2.4 + * @group search + */ + public function testDecayingDisabled() { + delete_site_option( 'ep_feature_requirement_statuses' ); + delete_site_option( 'ep_feature_settings' ); + + EP_Features::factory()->handle_feature_activation(); + EP_Features::factory()->setup_features(); + + ep_update_feature( 'search', array( + 'active' => true, + 'decaying_enabled' => false, + ) ); + + ep_create_and_sync_post( array( 'post_content' => 'findme test 1', 'tags_input' => array( 'one', 'two' ) ) ); + ep_refresh_index(); + + add_filter( 'ep_formatted_args', array( $this, 'catch_ep_formatted_args' ) ); + $query = new WP_Query( array( + 's' => 'test', + ) ); + $this->assertTrue( isset( $this->fired_actions['ep_formatted_args'] ) ); + $this->assertTrue( ! isset( + $this->fired_actions['ep_formatted_args']['query']['function_score'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['scale'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['decay'], + $this->fired_actions['ep_formatted_args']['query']['function_score']['exp']['post_date_gmt']['offset'] + ) ); + $this->assertTrue( isset( + $this->fired_actions['ep_formatted_args']['query']['bool'], + $this->fired_actions['ep_formatted_args']['query']['bool']['should'] + ) ); + } + + /** + * Catch ES query args. + * + * @group search + * @param array $args ES query args. + */ + public function catch_ep_formatted_args( $args ) { + $this->fired_actions['ep_formatted_args'] = $args; + } } diff --git a/tests/includes/class-ep-test-base.php b/tests/includes/class-ep-test-base.php index 975d0449d9..e845ea2185 100644 --- a/tests/includes/class-ep-test-base.php +++ b/tests/includes/class-ep-test-base.php @@ -2,25 +2,6 @@ class EP_Test_Base extends WP_UnitTestCase { - /** - * Prevents weird MySQLi error. - * - * @since 1.0 - */ - public function __construct() { - if ( property_exists( __CLASS__, 'ignore_files' ) ) { - self::$ignore_files = true; - } - $this->plugin_path = str_replace( '/tests/includes', '', dirname( __FILE__ ) ); - } - - /** - * Stores the root path for the plugin - * - * @var string - */ - protected $plugin_path = ''; - /** * Helps us keep track of actions that have fired * diff --git a/tests/test-single-site.php b/tests/test-single-site.php index 53fab64116..e34c4a18d7 100644 --- a/tests/test-single-site.php +++ b/tests/test-single-site.php @@ -1223,7 +1223,7 @@ public function testSearchMetaQuery() { $this->assertEquals( 2, $query->post_count ); $this->assertEquals( 2, $query->found_posts ); - + // Only check for fields which are provided in search_fields. $args = array( 's' => 'findme', @@ -1663,7 +1663,7 @@ public function testSearchPostMetaNumMultipleOrderbyQuery() { * @group single-site */ public function testSearchPostDateOrderbyQuery() { - ep_create_and_sync_post( array( 'post_title' => 'ordertes 333' ) ); + ep_create_and_sync_post( array( 'post_title' => 'ordertesr' ) ); sleep( 3 ); ep_create_and_sync_post( array( 'post_title' => 'ordertest 111' ) ); @@ -1685,7 +1685,7 @@ public function testSearchPostDateOrderbyQuery() { $this->assertEquals( 3, $query->found_posts ); $this->assertEquals( 'Ordertest 222', $query->posts[0]->post_title ); $this->assertEquals( 'ordertest 111', $query->posts[1]->post_title ); - $this->assertEquals( 'ordertes 333', $query->posts[2]->post_title ); + $this->assertEquals( 'ordertesr', $query->posts[2]->post_title ); } /** @@ -1877,7 +1877,7 @@ public function testSearchDefaultOrderbyASCOrderQuery() { $this->assertEquals( 'ordertestt', $query->posts[0]->post_title ); $this->assertEquals( 'Ordertest', $query->posts[1]->post_title ); } - + /** * Test orderby random * @@ -1888,16 +1888,16 @@ public function testRandOrderby() { ep_create_and_sync_post( array( 'post_title' => 'ordertest 1' ) ); ep_create_and_sync_post( array( 'post_title' => 'ordertest 2' ) ); ep_create_and_sync_post( array( 'post_title' => 'ordertest 3' ) ); - + ep_refresh_index(); - + $args = array( 'ep_integrate' => true, 'orderby' => 'rand', ); - + $query = new WP_Query( $args ); - + /* Since it's test for random order, can't check against exact post ID or content but only found posts and post count. */ @@ -2302,7 +2302,7 @@ public function testMetaQueryAdvanced() { /** * Test a query that searches and filters by a meta value like the query - * + * * @since 1.5 * @group single-site */ @@ -2330,16 +2330,16 @@ public function testMetaQueryLike() { $this->assertEquals( 3, $query->post_count ); $this->assertEquals( 3, $query->found_posts ); } - + public function testMetaQueryMultipleArray() { ep_create_and_sync_post( array( 'post_content' => 'findme' ), array( 'meta_key_1' => '1' ) ); ep_create_and_sync_post( array( 'post_content' => 'findme' ), array( 'meta_key_1' => '1' ) ); ep_create_and_sync_post( array( 'post_content' => 'findme' ), array( 'meta_key_1' => '1', 'meta_key_2' => '4' ) ); ep_create_and_sync_post( array( 'post_content' => 'findme' ), array( 'meta_key_1' => '1', 'meta_key_2' => '0' ) ); ep_create_and_sync_post( array( 'post_content' => 'findme' ), array( 'meta_key_1' => '1', 'meta_key_3' => '4' ) ); - + ep_refresh_index(); - + $args = array( 's' => 'findme', 'meta_query' => array( @@ -2350,12 +2350,12 @@ public function testMetaQueryMultipleArray() { ) ), ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 2, $query->post_count ); $this->assertEquals( 2, $query->found_posts ); - + $args = array( 's' => 'findme', 'meta_query' => array( @@ -2378,9 +2378,9 @@ public function testMetaQueryMultipleArray() { ), ), ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 2, $query->post_count ); $this->assertEquals( 2, $query->found_posts ); } @@ -2562,7 +2562,7 @@ public function testCachedResultIsNotInCache() { /** * Test if $post object values exist after receiving odd values from the 'ep_search_post_return_args' filter. - * + * * @link https://github.com/10up/ElasticPress/issues/306 * @group single-site */ @@ -2600,7 +2600,7 @@ public function mock_indexable_post_status( $post_statuses ) { /** * Test invalid post date time - * + * * @group single-site */ public function testPostInvalidDateTime(){ @@ -3161,7 +3161,7 @@ public function testMetaValueTypeQueryDatetime() { $this->assertEquals( 1, $query->post_count ); } - + /* * Test a post_parent query * @group single-site @@ -3187,7 +3187,7 @@ public function testPostParentQuery() { /** * Test register feature - * + * * @since 2.1 * @group single-site */ @@ -3204,7 +3204,7 @@ public function testRegisterFeature() { /** * Test setup features - * + * * @since 2.1 * @group single-site */ @@ -3227,7 +3227,7 @@ public function testSetupFeatures() { $this->assertTrue( $feature->is_active() ); } - + /** * Test Tax Query NOT IN operator * @@ -3237,9 +3237,9 @@ public function testSetupFeatures() { public function testTaxQueryNotIn() { ep_create_and_sync_post( array( 'post_content' => 'findme test 1', 'tags_input' => array( 'one', 'two' ) ) ); ep_create_and_sync_post( array( 'post_content' => 'findme test 2', 'tags_input' => array( 'one' ) ) ); - + ep_refresh_index(); - + $args = array( 's' => 'findme', 'tax_query' => array( @@ -3250,12 +3250,12 @@ public function testTaxQueryNotIn() { ) ) ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 2, $query->post_count ); $this->assertEquals( 2, $query->found_posts ); - + $args = array( 's' => 'findme', 'tax_query' => array( @@ -3272,13 +3272,13 @@ public function testTaxQueryNotIn() { ) ) ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 1, $query->post_count ); $this->assertEquals( 1, $query->found_posts ); } - + /** * Test post_mime_type query * @@ -3288,20 +3288,20 @@ function testPostMimeTypeQuery() { ep_create_and_sync_post( array( 'post_type' => 'attachment', 'post_mime_type' => 'image/jpeg', 'post_status' => 'inherit' ) ); ep_create_and_sync_post( array( 'post_type' => 'attachment', 'post_mime_type' => 'image/jpeg', 'post_status' => 'inherit' ) ); ep_create_and_sync_post( array( 'post_type' => 'attachment', 'post_mime_type' => 'application/pdf', 'post_status' => 'inherit' ) ); - + ep_refresh_index(); - + $args = array( 'ep_integrate' => true, 'post_mime_type' => 'image', 'post_type' => 'attachment', 'post_status' => 'inherit' ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 2, $query->post_count ); - + $args = array( 'ep_integrate' => true, 'post_mime_type' => array( @@ -3311,9 +3311,132 @@ function testPostMimeTypeQuery() { 'post_type' => 'attachment', 'post_status' => 'inherit' ); - + $query = new WP_Query( $args ); - + $this->assertEquals( 3, $query->found_posts ); } + + /** + * Test Tax Query IN operator + * + * @since 2.4 + * @group single-site + */ + public function testTaxQueryOperatorIn() { + ep_create_and_sync_post( array( 'post_content' => 'findme test 1', 'tags_input' => array( 'one', 'two' ) ) ); + ep_create_and_sync_post( array( 'post_content' => 'findme test 2', 'tags_input' => array( 'one' ) ) ); + + ep_refresh_index(); + + $args = array( + 's' => 'findme', + 'tax_query' => array( + array( + 'taxonomy' => 'post_tag', + 'terms' => array( 'one', 'two' ), + 'field' => 'slug', + ) + ) + ); + + $query = new WP_Query( $args ); + + $this->assertEquals( 2, $query->post_count ); + $this->assertEquals( 2, $query->found_posts ); + + $args = array( + 's' => 'findme', + 'tax_query' => array( + array( + 'taxonomy' => 'post_tag', + 'terms' => array( 'one', 'two' ), + 'field' => 'slug', + 'operator' => 'in', + ) + ) + ); + + $query = new WP_Query( $args ); + + $this->assertEquals( 2, $query->post_count ); + $this->assertEquals( 2, $query->found_posts ); + } + + /** + * Test Tax Query and operator + * + * @since 2.4 + * @group single-site + */ + public function testTaxQueryOperatorAnd() { + $this->assertEquals( 1, 1 ); + ep_create_and_sync_post( array( 'post_content' => 'findme test 1', 'tags_input' => array( 'one', 'two' ) ) ); + ep_create_and_sync_post( array( 'post_content' => 'findme test 2', 'tags_input' => array( 'one' ) ) ); + + ep_refresh_index(); + + $args = array( + 's' => 'findme', + 'tax_query' => array( + array( + 'taxonomy' => 'post_tag', + 'terms' => array( 'one', 'two' ), + 'field' => 'slug', + 'operator' => 'and', + ) + ) + ); + + $query = new WP_Query( $args ); + + $this->assertEquals( 1, $query->post_count ); + $this->assertEquals( 1, $query->found_posts ); + } + + /** + * If a taxonomy is not public but is publicly queryable, it should return a result. + * + * @link https://github.com/10up/ElasticPress/issues/890 + * @group single-site + * @since 2.4 + */ + public function testCustomTaxonomyPublic() { + + $post_id = ep_create_and_sync_post(); + $post = get_post( $post_id ); + + $taxName = rand_str( 32 ); + register_taxonomy( $taxName, $post->post_type, array( 'label' => $taxName, + 'public' => false, + 'publicly_queryable' => true + ) ); + register_taxonomy_for_object_type( $taxName, $post->post_type ); + + $term1Name = rand_str( 32 ); + $term1 = wp_insert_term( $term1Name, $taxName ); + + wp_set_object_terms( $post_id, array( $term1['term_id'] ), $taxName, true ); + + ep_sync_post( $post_id ); + ep_refresh_index(); + + $args = array( + 's' => 'test', + 'tax_query' => array( + array( + 'taxonomy' => $taxName, + 'terms' => array( $term1Name ), + 'field' => 'name', + ) + ) + ); + + $query = new WP_Query( $args ); + + $this->assertEquals( $query->post_count, 1 ); + $this->assertEquals( $query->found_posts, 1 ); + $this->assertTrue( isset( $query->posts[0]->elasticsearch ) ); + } + }