Merge branch 'master' into tax-rate-auto-ordering
# Conflicts: # assets/css/admin.css
This commit is contained in:
commit
c61c08f405
File diff suppressed because one or more lines are too long
|
@ -306,7 +306,12 @@ table.wc_status_table {
|
|||
|
||||
#log-viewer-select {
|
||||
padding: 10px 0 8px;
|
||||
line-height: 180%;
|
||||
line-height: 28px;
|
||||
h2 {
|
||||
a {
|
||||
vertical-align: middle;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#log-viewer {
|
||||
|
|
File diff suppressed because one or more lines are too long
|
@ -547,6 +547,11 @@ html[dir="rtl"] .select2-container-multi .select2-choices li
|
|||
|
||||
background-color: #e4e4e4;
|
||||
}
|
||||
|
||||
.select2-container-multi .ui-sortable .select2-search-choice {
|
||||
cursor: move;
|
||||
}
|
||||
|
||||
html[dir="rtl"] .select2-container-multi .select2-choices .select2-search-choice
|
||||
{
|
||||
margin: 3px 5px 3px 0;
|
||||
|
|
|
@ -146,8 +146,19 @@ jQuery( function( $ ) {
|
|||
select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
|
||||
|
||||
$( this ).select2( select2_args ).addClass( 'enhanced' );
|
||||
|
||||
if( $( this ).data( 'sortable' ) === true ){
|
||||
$( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({
|
||||
containment: 'parent',
|
||||
start: function() { $( this ).select2( 'onSortStart' ); },
|
||||
update: function() { $( this ).select2( 'onSortEnd' ); }
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
|
||||
// Ajax customer search boxes
|
||||
$( ':input.wc-customer-search' ).filter( ':not(.enhanced)' ).each( function() {
|
||||
var select2_args = {
|
||||
|
@ -215,6 +226,15 @@ jQuery( function( $ ) {
|
|||
select2_args = $.extend( select2_args, getEnhancedSelectFormatString() );
|
||||
|
||||
$( this ).select2( select2_args ).addClass( 'enhanced' );
|
||||
|
||||
if( $( this ).data( 'sortable' ) === true ){
|
||||
$( this ).select2( 'container' ).find( 'ul.select2-choices' ).sortable({
|
||||
containment: 'parent',
|
||||
start: function() { $( this ).select2( 'onSortStart' ); },
|
||||
update: function() { $( this ).select2( 'onSortEnd' ); }
|
||||
});
|
||||
}
|
||||
|
||||
});
|
||||
})
|
||||
|
||||
|
|
|
@ -1 +1 @@
|
|||
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}a(document.body).on("wc-enhanced-select-init",function(){a(":input.wc-enhanced-select, :input.chosen_select").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-enhanced-select-nostd, :input.chosen_select_nostd").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!0,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-product-search").filter(":not(.enhanced)").each(function(){var c={allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:a(this).data("action")||"woocommerce_json_search_products_and_variations",security:wc_enhanced_select_params.search_products_nonce,exclude:a(this).data("exclude"),include:a(this).data("include"),limit:a(this).data("limit")}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")}),a(":input.wc-customer-search").filter(":not(.enhanced)").each(function(){var c={allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:"woocommerce_json_search_customers",security:wc_enhanced_select_params.search_customers_nonce,exclude:a(this).data("exclude")}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced")})}).on("wc_backbone_modal_before_remove",function(){a(":input.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search").select2("close")}).trigger("wc-enhanced-select-init")});
|
||||
jQuery(function(a){function b(){var a={formatMatches:function(a){return 1===a?wc_enhanced_select_params.i18n_matches_1:wc_enhanced_select_params.i18n_matches_n.replace("%qty%",a)},formatNoMatches:function(){return wc_enhanced_select_params.i18n_no_matches},formatAjaxError:function(){return wc_enhanced_select_params.i18n_ajax_error},formatInputTooShort:function(a,b){var c=b-a.length;return 1===c?wc_enhanced_select_params.i18n_input_too_short_1:wc_enhanced_select_params.i18n_input_too_short_n.replace("%qty%",c)},formatInputTooLong:function(a,b){var c=a.length-b;return 1===c?wc_enhanced_select_params.i18n_input_too_long_1:wc_enhanced_select_params.i18n_input_too_long_n.replace("%qty%",c)},formatSelectionTooBig:function(a){return 1===a?wc_enhanced_select_params.i18n_selection_too_long_1:wc_enhanced_select_params.i18n_selection_too_long_n.replace("%qty%",a)},formatLoadMore:function(){return wc_enhanced_select_params.i18n_load_more},formatSearching:function(){return wc_enhanced_select_params.i18n_searching}};return a}a(document.body).on("wc-enhanced-select-init",function(){a(":input.wc-enhanced-select, :input.chosen_select").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-enhanced-select-nostd, :input.chosen_select_nostd").filter(":not(.enhanced)").each(function(){var c=a.extend({minimumResultsForSearch:10,allowClear:!0,placeholder:a(this).data("placeholder")},b());a(this).select2(c).addClass("enhanced")}),a(":input.wc-product-search").filter(":not(.enhanced)").each(function(){var c={allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:a(this).data("action")||"woocommerce_json_search_products_and_variations",security:wc_enhanced_select_params.search_products_nonce,exclude:a(this).data("exclude"),include:a(this).data("include"),limit:a(this).data("limit")}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced"),a(this).data("sortable")===!0&&a(this).select2("container").find("ul.select2-choices").sortable({containment:"parent",start:function(){a(this).select2("onSortStart")},update:function(){a(this).select2("onSortEnd")}})}),a(":input.wc-customer-search").filter(":not(.enhanced)").each(function(){var c={allowClear:!!a(this).data("allow_clear"),placeholder:a(this).data("placeholder"),minimumInputLength:a(this).data("minimum_input_length")?a(this).data("minimum_input_length"):"3",escapeMarkup:function(a){return a},ajax:{url:wc_enhanced_select_params.ajax_url,dataType:"json",quietMillis:250,data:function(b){return{term:b,action:"woocommerce_json_search_customers",security:wc_enhanced_select_params.search_customers_nonce,exclude:a(this).data("exclude")}},results:function(b){var c=[];return b&&a.each(b,function(a,b){c.push({id:a,text:b})}),{results:c}},cache:!0}};a(this).data("multiple")===!0?(c.multiple=!0,c.initSelection=function(b,c){var d=a.parseJSON(b.attr("data-selected")),e=[];return a(b.val().split(",")).each(function(a,b){e.push({id:b,text:d[b]})}),c(e)},c.formatSelection=function(a){return'<div class="selected-option" data-id="'+a.id+'">'+a.text+"</div>"}):(c.multiple=!1,c.initSelection=function(a,b){var c={id:a.val(),text:a.attr("data-selected")};return b(c)}),c=a.extend(c,b()),a(this).select2(c).addClass("enhanced"),a(this).data("sortable")===!0&&a(this).select2("container").find("ul.select2-choices").sortable({containment:"parent",start:function(){a(this).select2("onSortStart")},update:function(){a(this).select2("onSortEnd")}})})}).on("wc_backbone_modal_before_remove",function(){a(":input.wc-enhanced-select, :input.wc-product-search, :input.wc-customer-search").select2("close")}).trigger("wc-enhanced-select-init")});
|
|
@ -55,7 +55,7 @@ jQuery( function( $ ) {
|
|||
$( 'input#createaccount' ).change( this.toggle_create_account ).change();
|
||||
}
|
||||
},
|
||||
init_payment_methods: function() {
|
||||
init_payment_methods: function( selectedPaymentMethod ) {
|
||||
var $payment_methods = $( '.woocommerce-checkout' ).find( 'input[name="payment_method"]' );
|
||||
|
||||
// If there is one method, we can hide the radio input
|
||||
|
@ -63,6 +63,11 @@ jQuery( function( $ ) {
|
|||
$payment_methods.eq(0).hide();
|
||||
}
|
||||
|
||||
// If there was a previously selected method, check that one.
|
||||
if ( selectedPaymentMethod ) {
|
||||
$( '#' + selectedPaymentMethod ).prop( 'checked', true );
|
||||
}
|
||||
|
||||
// If there are none selected, select the first.
|
||||
if ( 0 === $payment_methods.filter( ':checked' ).length ) {
|
||||
$payment_methods.eq(0).prop( 'checked', true );
|
||||
|
@ -271,6 +276,9 @@ jQuery( function( $ ) {
|
|||
url: wc_checkout_params.wc_ajax_url.toString().replace( '%%endpoint%%', 'update_order_review' ),
|
||||
data: data,
|
||||
success: function( data ) {
|
||||
|
||||
var selectedPaymentMethod = $( '.woocommerce-checkout input[name="payment_method"]:checked' ).attr( 'id' );
|
||||
|
||||
// Reload the page if requested
|
||||
if ( 'true' === data.reload ) {
|
||||
window.location.reload();
|
||||
|
@ -321,7 +329,7 @@ jQuery( function( $ ) {
|
|||
}
|
||||
|
||||
// Re-init methods
|
||||
wc_checkout_form.init_payment_methods();
|
||||
wc_checkout_form.init_payment_methods( selectedPaymentMethod );
|
||||
|
||||
// Fire updated_checkout e
|
||||
$( document.body ).trigger( 'updated_checkout' );
|
||||
|
|
File diff suppressed because one or more lines are too long
File diff suppressed because it is too large
Load Diff
|
@ -1429,7 +1429,7 @@ class WC_Product {
|
|||
* @return bool
|
||||
*/
|
||||
public function enable_dimensions_display() {
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', true );
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1441,6 +1441,15 @@ class WC_Product {
|
|||
return $this->get_dimensions() ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have dimensions set?
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_dimensions() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product length.
|
||||
* @return string
|
||||
|
@ -1483,6 +1492,15 @@ class WC_Product {
|
|||
return $this->get_weight() ? true : false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have a weight set?
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_weight() {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns formatted dimensions.
|
||||
* @return string
|
||||
|
@ -1498,7 +1516,7 @@ class WC_Product {
|
|||
$dimensions .= ' ' . get_option( 'woocommerce_dimension_unit' );
|
||||
}
|
||||
|
||||
return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this );
|
||||
return apply_filters( 'woocommerce_product_dimensions', $dimensions, $this );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -205,7 +205,13 @@ class WC_Admin_Status {
|
|||
$viewed_log = current( $logs );
|
||||
}
|
||||
|
||||
include_once( dirname( __FILE__ ) . '/views/html-admin-page-status-logs.php' );
|
||||
$handle = ! empty( $viewed_log ) ? self::get_log_file_handle( $viewed_log ) : '';
|
||||
|
||||
if ( ! empty( $_REQUEST[ 'handle' ] ) ) {
|
||||
self::remove_log();
|
||||
}
|
||||
|
||||
include_once( 'views/html-admin-page-status-logs.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -240,6 +246,16 @@ class WC_Admin_Status {
|
|||
return $version ;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the log file handle.
|
||||
*
|
||||
* @param string $filename
|
||||
* @return string
|
||||
*/
|
||||
public static function get_log_file_handle( $filename ) {
|
||||
return substr( $filename, 0, strlen( $filename ) > 37 ? strlen( $filename ) - 37 : strlen( $filename ) - 4 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the template files.
|
||||
* @param string $template_path
|
||||
|
@ -342,4 +358,21 @@ class WC_Admin_Status {
|
|||
|
||||
return $update_theme_version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove/delete the chosen file.
|
||||
*/
|
||||
public static function remove_log() {
|
||||
if ( empty( $_REQUEST[ '_wpnonce' ] ) || ! wp_verify_nonce( $_REQUEST[ '_wpnonce' ], 'remove_log' ) ) {
|
||||
wp_die( __( 'Action failed. Please refresh the page and retry.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
if ( ! empty( $_REQUEST[ 'handle' ] ) ) {
|
||||
$logger = new WC_Logger();
|
||||
$logger->remove( $_REQUEST[ 'handle' ] );
|
||||
}
|
||||
|
||||
wp_safe_redirect( esc_url_raw( admin_url( 'admin.php?page=wc-status&tab=logs' ) ) );
|
||||
exit();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -242,14 +242,14 @@ class WC_Admin_Report {
|
|||
|
||||
$key = is_array( $value['meta_key'] ) ? $value['meta_key'][0] . '_array' : $value['meta_key'];
|
||||
|
||||
if ( strtolower( $value['operator'] ) == 'in' ) {
|
||||
if ( strtolower( $value['operator'] ) == 'in' || strtolower( $value['operator'] ) == 'not in' ) {
|
||||
|
||||
if ( is_array( $value['meta_value'] ) ) {
|
||||
$value['meta_value'] = implode( "','", $value['meta_value'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $value['meta_value'] ) ) {
|
||||
$where_value = "IN ('{$value['meta_value']}')";
|
||||
$where_value = "{$value['operator']} ('{$value['meta_value']}')";
|
||||
}
|
||||
} else {
|
||||
$where_value = "{$value['operator']} '{$value['meta_value']}'";
|
||||
|
@ -289,14 +289,14 @@ class WC_Admin_Report {
|
|||
|
||||
foreach ( $where as $value ) {
|
||||
|
||||
if ( strtolower( $value['operator'] ) == 'in' ) {
|
||||
if ( strtolower( $value['operator'] ) == 'in' || strtolower( $value['operator'] ) == 'not in' ) {
|
||||
|
||||
if ( is_array( $value['value'] ) ) {
|
||||
$value['value'] = implode( "','", $value['value'] );
|
||||
}
|
||||
|
||||
if ( ! empty( $value['value'] ) ) {
|
||||
$where_value = "IN ('{$value['value']}')";
|
||||
$where_value = "{$value['operator']} ('{$value['value']}')";
|
||||
}
|
||||
} else {
|
||||
$where_value = "{$value['operator']} '{$value['value']}'";
|
||||
|
|
|
@ -11,7 +11,12 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
<?php if ( $logs ) : ?>
|
||||
<div id="log-viewer-select">
|
||||
<div class="alignleft">
|
||||
<h2><?php printf( __( 'Log file: %s (%s)', 'woocommerce' ), esc_html( $viewed_log ), date_i18n( get_option( 'date_format') . ' ' . get_option( 'time_format'), filemtime( WC_LOG_DIR . $viewed_log ) ) ); ?></h2>
|
||||
<h2>
|
||||
<?php echo esc_html( $viewed_log ); ?>
|
||||
<?php if ( ! empty( $handle ) ) : ?>
|
||||
<a class="page-title-action" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'handle' => $handle ), admin_url( 'admin.php?page=wc-status&tab=logs' ) ), 'remove_log' ) ); ?>" class="button"><?php esc_html_e( 'Delete Log', 'woocommerce');?></a>
|
||||
<?php endif; ?>
|
||||
</h2>
|
||||
</div>
|
||||
<div class="alignright">
|
||||
<form action="<?php echo admin_url( 'admin.php?page=wc-status&tab=logs' ); ?>" method="post">
|
||||
|
@ -26,7 +31,7 @@ if ( ! defined( 'ABSPATH' ) ) {
|
|||
<div class="clear"></div>
|
||||
</div>
|
||||
<div id="log-viewer">
|
||||
<textarea cols="70" rows="25"><?php echo esc_textarea( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></textarea>
|
||||
<textarea cols="70" rows="40"><?php echo esc_textarea( file_get_contents( WC_LOG_DIR . $viewed_log ) ); ?></textarea>
|
||||
</div>
|
||||
<?php else : ?>
|
||||
<div class="updated woocommerce-message inline"><p><?php _e( 'There are currently no logs to view.', 'woocommerce' ); ?></p></div>
|
||||
|
|
|
@ -0,0 +1,747 @@
|
|||
<?php
|
||||
/**
|
||||
* REST API WC System Status controller
|
||||
*
|
||||
* Handles requests to the /system_status endpoint.
|
||||
*
|
||||
* @author WooThemes
|
||||
* @category API
|
||||
* @package WooCommerce/API
|
||||
* @since 2.7.0
|
||||
*/
|
||||
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @package WooCommerce/API
|
||||
* @extends WC_REST_Controller
|
||||
*/
|
||||
class WC_REST_System_Status_Controller extends WC_REST_Controller {
|
||||
|
||||
/**
|
||||
* Endpoint namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'wc/v1';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'system_status';
|
||||
|
||||
/**
|
||||
* Register the routes for coupons.
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route( $this->namespace, '/' . $this->rest_base, array(
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_items' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_collection_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check whether a given request has permission to view system status.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|boolean
|
||||
*/
|
||||
public function get_items_permissions_check( $request ) {
|
||||
if ( ! wc_rest_check_manager_permissions( 'system_status', 'read' ) ) {
|
||||
return new WP_Error( 'woocommerce_rest_cannot_view', __( 'Sorry, you cannot view.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a system status info, by section.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
$schema = $this->get_item_schema();
|
||||
$mappings = $this->get_item_mappings();
|
||||
$response = array();
|
||||
|
||||
foreach ( $mappings as $section => $values ) {
|
||||
settype( $values, $schema['properties'][ $section ]['type'] );
|
||||
foreach ( $values as $key => $value ) {
|
||||
if ( isset( $schema['properties'][ $section ]['properties'][ $key ]['type'] ) ) {
|
||||
settype( $values[ $key ], $schema['properties'][ $section ]['properties'][ $key ]['type'] );
|
||||
}
|
||||
}
|
||||
$response[ $section ] = $values;
|
||||
}
|
||||
|
||||
return rest_ensure_response( $response );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the system status schema, conforming to JSON Schema.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
$schema = array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'system_status',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'environment' => array(
|
||||
'description' => __( 'Environment', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'properties' => array(
|
||||
'home_url' => array(
|
||||
'description' => __( 'Home URL', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'site_url' => array(
|
||||
'description' => __( 'Site URL', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wc_version' => array(
|
||||
'description' => __( 'WooCommerce Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'log_directory' => array(
|
||||
'description' => __( 'Log Directory', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'log_directory_writable' => array(
|
||||
'description' => __( 'Is Log Directory Writable?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wp_version' => array(
|
||||
'description' => __( 'WordPress Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wp_multisite' => array(
|
||||
'description' => __( 'Is WordPress Multisite?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wp_memory_limit' => array(
|
||||
'description' => __( 'WordPress Memory Limit', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wp_debug_mode' => array(
|
||||
'description' => __( 'Is WordPress Debug Mode Active?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'wp_cron' => array(
|
||||
'description' => __( 'Are WordPress Cron Jobs Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'language' => array(
|
||||
'description' => __( 'WordPress Language', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'server_info' => array(
|
||||
'description' => __( 'Server Info', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'php_version' => array(
|
||||
'description' => __( 'PHP Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'php_post_max_size' => array(
|
||||
'description' => __( 'PHP Post Max Size', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'php_max_execution_time' => array(
|
||||
'description' => __( 'PHP Max Execution Time', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'php_max_input_vars' => array(
|
||||
'description' => __( 'PHP Max Input Vars', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'curl_version' => array(
|
||||
'description' => __( 'cURL Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'suhosin_installed' => array(
|
||||
'description' => __( 'Is SUHOSIN Installed?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'max_upload_size' => array(
|
||||
'description' => __( 'Max Upload Size', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'mysql_version' => array(
|
||||
'description' => __( 'MySQL Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'default_timezone' => array(
|
||||
'description' => __( 'Default Timezone', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'fsockopen_or_curl_enabled' => array(
|
||||
'description' => __( 'Is fsockopen/cURL Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'soapclient_enabled' => array(
|
||||
'description' => __( 'Is SoapClient Class Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'domdocument_enabled' => array(
|
||||
'description' => __( 'Is DomDocument Class Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'gzip_enabled' => array(
|
||||
'description' => __( 'Is GZip Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'mbstring_enabled' => array(
|
||||
'description' => __( 'Is mbstring Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'remote_post_successful' => array(
|
||||
'description' => __( 'Remote POST Successful?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'remote_post_response' => array(
|
||||
'description' => __( 'Remote POST Response', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'remote_get_successful' => array(
|
||||
'description' => __( 'Remote GET Successful?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'remote_get_response' => array(
|
||||
'description' => __( 'Remote GET Response', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
'database' => array(
|
||||
'description' => __( 'Database', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'properties' => array(
|
||||
'wc_database_version' => array(
|
||||
'description' => __( 'WC Database Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'database_prefix' => array(
|
||||
'description' => __( 'Database Prefix', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'maxmind_geoip_database' => array(
|
||||
'description' => __( 'MaxMind GeoIP Database', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'database_tables' => array(
|
||||
'description' => __( 'Database Tables', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
)
|
||||
),
|
||||
'active_plugins' => array(
|
||||
'description' => __( 'Active Plugins', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'theme' => array(
|
||||
'description' => __( 'Theme', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'properties' => array(
|
||||
'name' => array(
|
||||
'description' => __( 'Theme Name', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'version' => array(
|
||||
'description' => __( 'Theme Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'author_url' => array(
|
||||
'description' => __( 'Theme Author URL', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'is_child_theme' => array(
|
||||
'description' => __( 'Is this theme a child theme?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'has_woocommerce_support' => array(
|
||||
'description' => __( 'Does the theme declare WooCommerce support?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'overrides' => array(
|
||||
'description' => __( 'Template Overrides', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'parent_name' => array(
|
||||
'description' => __( 'Parent Theme Name', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'parent_version' => array(
|
||||
'description' => __( 'Parent Theme Version', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'parent_author_url' => array(
|
||||
'description' => __( 'Parent Theme Author URL', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'format' => 'uri',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
)
|
||||
),
|
||||
'settings' => array(
|
||||
'description' => __( 'Settings', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'properties' => array(
|
||||
'api_enabled' => array(
|
||||
'description' => __( 'REST API Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'force_ssl' => array(
|
||||
'description' => __( 'SSL Forced?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'currency' => array(
|
||||
'description' => __( 'Currency', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'currency_symbol' => array(
|
||||
'description' => __( 'Currency Symbol', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'currency_position' => array(
|
||||
'description' => __( 'Currency Position', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'thousand_separator' => array(
|
||||
'description' => __( 'Thousand Separator', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'decimal_separator' => array(
|
||||
'description' => __( 'Decimal Separator', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'number_of_decimals' => array(
|
||||
'description' => __( 'Number of Decimals', 'woocommerce' ),
|
||||
'type' => 'integer',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'geolocation_enabled' => array(
|
||||
'description' => __( 'Geolocation Enabled?', 'woocommerce' ),
|
||||
'type' => 'boolean',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'taxonomies' => array(
|
||||
'description' => __( 'Taxonomy Terms for Product/Order Statuses', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
)
|
||||
),
|
||||
'pages' => array(
|
||||
'description' => __( 'WooCommerce Pages', 'woocommerce' ),
|
||||
'type' => 'array',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
return $this->add_additional_fields_schema( $schema );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return an array of sections and the data associated with each.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_item_mappings() {
|
||||
return array(
|
||||
'environment' => $this->get_environment_info(),
|
||||
'database' => $this->get_database_info(),
|
||||
'active_plugins' => $this->get_active_plugins(),
|
||||
'theme' => $this->get_theme_info(),
|
||||
'settings' => $this->get_settings(),
|
||||
'pages' => $this->get_pages(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of environment information. Includes thing like software
|
||||
* versions, and various server settings.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_environment_info() {
|
||||
global $wpdb;
|
||||
|
||||
// Figure out cURL version, if installed.
|
||||
$curl_version = '';
|
||||
if ( function_exists( 'curl_version' ) ) {
|
||||
$curl_version = curl_version();
|
||||
$curl_version = $curl_version['version'] . ', ' . $curl_version['ssl_version'];
|
||||
}
|
||||
|
||||
// WP memory limit
|
||||
$wp_memory_limit = wc_let_to_num( WP_MEMORY_LIMIT );
|
||||
if ( function_exists( 'memory_get_usage' ) ) {
|
||||
$wp_memory_limit = max( $wp_memory_limit, wc_let_to_num( @ini_get( 'memory_limit' ) ) );
|
||||
}
|
||||
|
||||
// Test POST requests
|
||||
$post_response = wp_safe_remote_post( 'https://www.paypal.com/cgi-bin/webscr', array(
|
||||
'timeout' => 60,
|
||||
'user-agent' => 'WooCommerce/' . WC()->version,
|
||||
'httpversion' => '1.1',
|
||||
'body' => array(
|
||||
'cmd' => '_notify-validate'
|
||||
)
|
||||
) );
|
||||
$post_response_successful = false;
|
||||
if ( ! is_wp_error( $post_response ) && $post_response['response']['code'] >= 200 && $post_response['response']['code'] < 300 ) {
|
||||
$post_response_successful = true;
|
||||
}
|
||||
|
||||
// Test GET requests
|
||||
$get_response = wp_safe_remote_get( 'https://woocommerce.com/wc-api/product-key-api?request=ping&network=' . ( is_multisite() ? '1' : '0' ) );
|
||||
$get_response_successful = false;
|
||||
if ( ! is_wp_error( $post_response ) && $post_response['response']['code'] >= 200 && $post_response['response']['code'] < 300 ) {
|
||||
$get_response_successful = true;
|
||||
}
|
||||
|
||||
// Return all environment info. Described by JSON Schema.
|
||||
return array(
|
||||
'home_url' => get_option( 'home' ),
|
||||
'site_url' => get_option( 'siteurl' ),
|
||||
'version' => WC()->version,
|
||||
'log_directory' => WC_LOG_DIR,
|
||||
'log_directory_writable' => ( @fopen( WC_LOG_DIR . 'test-log.log', 'a' ) ? true : false ),
|
||||
'wp_version' => get_bloginfo('version'),
|
||||
'wp_multisite' => is_multisite(),
|
||||
'wp_memory_limit' => $wp_memory_limit,
|
||||
'wp_debug_mode' => ( defined( 'WP_DEBUG' ) && WP_DEBUG ),
|
||||
'wp_cron' => ! ( defined( 'DISABLE_WP_CRON' ) && DISABLE_WP_CRON ),
|
||||
'language' => get_locale(),
|
||||
'server_info' => $_SERVER['SERVER_SOFTWARE'],
|
||||
'php_version' => phpversion(),
|
||||
'php_post_max_size' => wc_let_to_num( ini_get( 'post_max_size' ) ),
|
||||
'php_max_execution_time' => ini_get( 'max_execution_time' ),
|
||||
'php_max_input_vars' => ini_get( 'max_input_vars' ),
|
||||
'curl_version' => $curl_version,
|
||||
'suhosin_installed' => extension_loaded( 'suhosin' ),
|
||||
'max_upload_size' => wp_max_upload_size(),
|
||||
'mysql_version' => ( ! empty( $wpdb->is_mysql ) ? $wpdb->db_version() : '' ),
|
||||
'default_timezone' => date_default_timezone_get(),
|
||||
'fsockopen_or_curl_enabled' => ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ),
|
||||
'soapclient_enabled' => class_exists( 'SoapClient' ),
|
||||
'domdocument_enabled' => class_exists( 'DOMDocument' ),
|
||||
'gzip_enabled' => is_callable( 'gzopen' ),
|
||||
'mbstring_enabled' => extension_loaded( 'mbstring' ),
|
||||
'remote_post_successful' => $post_response_successful,
|
||||
'remote_post_response' => ( is_wp_error( $post_response ) ? $post_response->get_error_message() : $post_response['response']['code'] ),
|
||||
'remote_get_successful' => $get_response_successful,
|
||||
'remote_get_response' => ( is_wp_error( $get_response ) ? $get_response->get_error_message() : $get_response['response']['code'] ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get array of database information. Version, prefix, and table existence.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_database_info() {
|
||||
global $wpdb;
|
||||
|
||||
// WC Core tables to check existence of
|
||||
$tables = array(
|
||||
'woocommerce_sessions',
|
||||
'woocommerce_api_keys',
|
||||
'woocommerce_attribute_taxonomies',
|
||||
'woocommerce_downloadable_product_permissions',
|
||||
'woocommerce_order_items',
|
||||
'woocommerce_order_itemmeta',
|
||||
'woocommerce_tax_rates',
|
||||
'woocommerce_tax_rate_locations',
|
||||
'woocommerce_shipping_zones',
|
||||
'woocommerce_shipping_zone_locations',
|
||||
'woocommerce_shipping_zone_methods',
|
||||
'woocommerce_payment_tokens',
|
||||
'woocommerce_payment_tokenmeta',
|
||||
);
|
||||
|
||||
if ( get_option( 'db_version' ) < 34370 ) {
|
||||
$tables[] = 'woocommerce_termmeta';
|
||||
}
|
||||
$table_exists = array();
|
||||
foreach ( $tables as $table ) {
|
||||
$table_exists[ $table ] = ( $wpdb->get_var( $wpdb->prepare( "SHOW TABLES LIKE %s;", $wpdb->prefix . $table ) ) === $wpdb->prefix . $table );
|
||||
}
|
||||
|
||||
// Return all database info. Described by JSON Schema.
|
||||
return array(
|
||||
'wc_database_version' => get_option( 'woocommerce_db_version' ),
|
||||
'database_prefix' => $wpdb->prefix,
|
||||
'maxmind_geoip_database' => WC_Geolocation::get_local_database_path(),
|
||||
'database_tables' => $table_exists,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of plugins active on the site.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_plugins() {
|
||||
require_once( ABSPATH . 'wp-admin/includes/plugin.php' );
|
||||
|
||||
// Get both site plugins and network plugins
|
||||
$active_plugins = (array) get_option( 'active_plugins', array() );
|
||||
if ( is_multisite() ) {
|
||||
$network_activated_plugins = array_keys( get_site_option( 'active_sitewide_plugins', array() ) );
|
||||
$active_plugins = array_merge( $active_plugins, $network_activated_plugins );
|
||||
}
|
||||
|
||||
$active_plugins_data = array();
|
||||
foreach ( $active_plugins as $plugin ) {
|
||||
$data = get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
|
||||
// convert plugin data to json response format.
|
||||
$active_plugins_data[] = array(
|
||||
'name' => $data['Name'],
|
||||
'version' => $data['Version'],
|
||||
'url' => $data['PluginURI'],
|
||||
'author_name' => $data['AuthorName'],
|
||||
'author_url' => esc_url_raw( $data['AuthorURI'] ),
|
||||
);
|
||||
}
|
||||
|
||||
return $active_plugins_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get info on the current active theme, info on parent theme (if presnet)
|
||||
* and a list of template overrides.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_theme_info() {
|
||||
$active_theme = wp_get_theme();
|
||||
|
||||
// Get parent theme info if this theme is a child theme, otherwise
|
||||
// pass empty info in the response.
|
||||
if ( is_child_theme() ) {
|
||||
$parent_theme = wp_get_theme( $active_theme->Template );
|
||||
$parent_theme_info = array(
|
||||
'parent_name' => $parent_theme->Name,
|
||||
'parentversion' => $parent_theme->Version,
|
||||
'parent_author_url' => $parent_theme->{'Author URI'},
|
||||
);
|
||||
} else {
|
||||
$parent_theme_info = array( 'parent_theme_name' => '', 'parent_theme_version' => '', 'parent_theme_author_url' => '' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Scan the theme directory for all WC templates to see if our theme
|
||||
* overrides any of them.
|
||||
*/
|
||||
$override_files = array();
|
||||
$scan_files = WC_Admin_Status::scan_template_files( WC()->plugin_path() . '/templates/' );
|
||||
foreach ( $scan_files as $file ) {
|
||||
if ( file_exists( get_stylesheet_directory() . '/' . $file ) ) {
|
||||
$theme_file = get_stylesheet_directory() . '/' . $file;
|
||||
} elseif ( file_exists( get_stylesheet_directory() . '/woocommerce/' . $file ) ) {
|
||||
$theme_file = get_stylesheet_directory() . '/woocommerce/' . $file;
|
||||
} elseif ( file_exists( get_template_directory() . '/' . $file ) ) {
|
||||
$theme_file = get_template_directory() . '/' . $file;
|
||||
} elseif ( file_exists( get_template_directory() . '/woocommerce/' . $file ) ) {
|
||||
$theme_file = get_template_directory() . '/woocommerce/' . $file;
|
||||
} else {
|
||||
$theme_file = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $theme_file ) ) {
|
||||
$override_files[] = str_replace( WP_CONTENT_DIR . '/themes/', '', $theme_file );
|
||||
}
|
||||
}
|
||||
|
||||
$active_theme_info = array(
|
||||
'name' => $active_theme->Name,
|
||||
'version' => $active_theme->Version,
|
||||
'author_url' => esc_url_raw( $active_theme->{'Author URI'} ),
|
||||
'is_child_theme' => is_child_theme(),
|
||||
'has_woocommerce_support' => ( current_theme_supports( 'woocommerce' ) || in_array( $active_theme->template, wc_get_core_supported_themes() ) ),
|
||||
'overrides' => $override_files,
|
||||
);
|
||||
|
||||
return array_merge( $active_theme_info, $parent_theme_info );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get some setting values for the site that are useful for debugging
|
||||
* purposes. For full settings access, use the settings api.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_settings() {
|
||||
// Get a list of terms used for product/order taxonomies
|
||||
$term_response = array();
|
||||
$terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
|
||||
foreach ( $terms as $term ) {
|
||||
$term_response[ $term->slug ] = strtolower( $term->name );
|
||||
}
|
||||
|
||||
// Return array of useful settings for debugging.
|
||||
return array(
|
||||
'api_enabled' => 'yes' === get_option( 'woocommerce_api_enabled' ),
|
||||
'force_ssl' => 'yes' === get_option( 'woocommerce_force_ssl_checkout' ),
|
||||
'currency' => get_woocommerce_currency(),
|
||||
'currency_symbol' => get_woocommerce_currency_symbol(),
|
||||
'currency_position' => get_option( 'woocommerce_currency_pos' ),
|
||||
'thousand_separator' => wc_get_price_thousand_separator(),
|
||||
'decimal_separator' => wc_get_price_decimal_separator(),
|
||||
'number_of_decimals' => wc_get_price_decimals(),
|
||||
'geolocation_enabled' => in_array( get_option( 'woocommerce_default_customer_address' ), array( 'geolocation_ajax', 'geolocation' ) ),
|
||||
'taxonomies' => $term_response,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a mini-report on WC pages and if they are configured correctly:
|
||||
* Present, visible, and including the correct shortcode.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_pages() {
|
||||
// WC pages to check against
|
||||
$check_pages = array(
|
||||
_x( 'Shop Base', 'Page setting', 'woocommerce' ) => array(
|
||||
'option' => 'woocommerce_shop_page_id',
|
||||
'shortcode' => '',
|
||||
),
|
||||
_x( 'Cart', 'Page setting', 'woocommerce' ) => array(
|
||||
'option' => 'woocommerce_cart_page_id',
|
||||
'shortcode' => '[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']',
|
||||
),
|
||||
_x( 'Checkout', 'Page setting', 'woocommerce' ) => array(
|
||||
'option' => 'woocommerce_checkout_page_id',
|
||||
'shortcode' => '[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']',
|
||||
),
|
||||
_x( 'My Account', 'Page setting', 'woocommerce' ) => array(
|
||||
'option' => 'woocommerce_myaccount_page_id',
|
||||
'shortcode' => '[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']',
|
||||
),
|
||||
);
|
||||
|
||||
$pages_output = array();
|
||||
foreach ( $check_pages as $page_name => $values ) {
|
||||
$errors = array();
|
||||
$page_id = get_option( $values['option'] );
|
||||
$page_set = $page_exists = $page_visible = false;
|
||||
$shortcode_present = $shortcode_required = false;
|
||||
|
||||
// Page checks
|
||||
if ( $page_id ) {
|
||||
$page_set = true;
|
||||
}
|
||||
if ( get_post( $page_id ) ) {
|
||||
$page_exists = true;
|
||||
}
|
||||
if ( 'publish' === get_post_status( $page_id ) ) {
|
||||
$page_visible = true;
|
||||
}
|
||||
|
||||
// Shortcode checks
|
||||
if ( $values['shortcode'] && get_post( $page_id ) ) {
|
||||
$shortcode_required = true;
|
||||
$page = get_post( $page_id );
|
||||
if ( strstr( $page->post_content, $values['shortcode'] ) ) {
|
||||
$shortcode_present = true;
|
||||
}
|
||||
}
|
||||
|
||||
// Wrap up our findings into an output array
|
||||
$pages_output[] = array(
|
||||
'page_name' => $page_name,
|
||||
'page_id' => $page_id,
|
||||
'page_set' => $page_set,
|
||||
'page_exists' => $page_exists,
|
||||
'page_visible' => $page_visible,
|
||||
'shortcode_required' => $shortcode_required,
|
||||
'shortcode_present' => $shortcode_present,
|
||||
);
|
||||
}
|
||||
|
||||
return $pages_output;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get any query params needed.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_collection_params() {
|
||||
return array(
|
||||
'context' => $this->get_context_param( array( 'default' => 'view' ) ),
|
||||
);
|
||||
}
|
||||
|
||||
}
|
|
@ -167,6 +167,7 @@ class WC_API extends WC_Legacy_API {
|
|||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-taxes-controller.php' );
|
||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhook-deliveries.php' );
|
||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-webhooks-controller.php' );
|
||||
include_once( dirname( __FILE__ ) . '/api/class-wc-rest-system-status-controller.php' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -200,6 +201,7 @@ class WC_API extends WC_Legacy_API {
|
|||
'WC_REST_Taxes_Controller',
|
||||
'WC_REST_Webhook_Deliveries_Controller',
|
||||
'WC_REST_Webhooks_Controller',
|
||||
'WC_REST_System_Status_Controller',
|
||||
);
|
||||
|
||||
foreach ( $controllers as $controller ) {
|
||||
|
|
|
@ -211,11 +211,6 @@ class WC_Form_Handler {
|
|||
$user->user_email = $account_email;
|
||||
}
|
||||
|
||||
if ( ! empty( $pass1 ) && ! wp_check_password( $pass_cur, $current_user->user_pass, $current_user->ID ) ) {
|
||||
wc_add_notice( __( 'Your current password is incorrect.', 'woocommerce' ), 'error' );
|
||||
$save_pass = false;
|
||||
}
|
||||
|
||||
if ( ! empty( $pass_cur ) && empty( $pass1 ) && empty( $pass2 ) ) {
|
||||
wc_add_notice( __( 'Please fill out all password fields.', 'woocommerce' ), 'error' );
|
||||
$save_pass = false;
|
||||
|
@ -228,6 +223,9 @@ class WC_Form_Handler {
|
|||
} elseif ( ( ! empty( $pass1 ) || ! empty( $pass2 ) ) && $pass1 !== $pass2 ) {
|
||||
wc_add_notice( __( 'New passwords do not match.', 'woocommerce' ), 'error' );
|
||||
$save_pass = false;
|
||||
} elseif ( ! empty( $pass1 ) && ! wp_check_password( $pass_cur, $current_user->user_pass, $current_user->ID ) ) {
|
||||
wc_add_notice( __( 'Your current password is incorrect.', 'woocommerce' ), 'error' );
|
||||
$save_pass = false;
|
||||
}
|
||||
|
||||
if ( $pass1 && $save_pass ) {
|
||||
|
@ -873,9 +871,12 @@ class WC_Form_Handler {
|
|||
if ( ! empty( $_POST['login'] ) && wp_verify_nonce( $nonce_value, 'woocommerce-login' ) ) {
|
||||
|
||||
try {
|
||||
$creds = array();
|
||||
$username = trim( $_POST['username'] );
|
||||
$creds = array(
|
||||
'user_password' => $_POST['password'],
|
||||
'remember' => isset( $_POST['rememberme'] ),
|
||||
);
|
||||
|
||||
$username = trim( $_POST['username'] );
|
||||
$validation_error = new WP_Error();
|
||||
$validation_error = apply_filters( 'woocommerce_process_login_errors', $validation_error, $_POST['username'], $_POST['password'] );
|
||||
|
||||
|
@ -904,10 +905,17 @@ class WC_Form_Handler {
|
|||
$creds['user_login'] = $username;
|
||||
}
|
||||
|
||||
$creds['user_password'] = $_POST['password'];
|
||||
$creds['remember'] = isset( $_POST['rememberme'] );
|
||||
$secure_cookie = is_ssl() ? true : false;
|
||||
$user = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), $secure_cookie );
|
||||
// On multisite, ensure user exists on current site, if not add them before allowing login.
|
||||
if ( is_multisite() ) {
|
||||
$user_data = get_user_by( 'login', $username );
|
||||
|
||||
if ( $user_data && ! is_user_member_of_blog( $user_data->ID, get_current_blog_id() ) ) {
|
||||
add_user_to_blog( get_current_blog_id(), $user_data->ID, 'customer' );
|
||||
}
|
||||
}
|
||||
|
||||
// Perform the login
|
||||
$user = wp_signon( apply_filters( 'woocommerce_login_credentials', $creds ), is_ssl() );
|
||||
|
||||
if ( is_wp_error( $user ) ) {
|
||||
$message = $user->get_error_message();
|
||||
|
|
|
@ -72,6 +72,9 @@ class WC_Install {
|
|||
'wc_update_260_refunds',
|
||||
'wc_update_260_db_version',
|
||||
),
|
||||
'2.7.0' => array(
|
||||
'wc_update_270_webhooks',
|
||||
),
|
||||
);
|
||||
|
||||
/** @var object Background update class */
|
||||
|
|
|
@ -124,4 +124,29 @@ class WC_Logger {
|
|||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove/delete the chosen file.
|
||||
*
|
||||
* @param string $handle
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function remove( $handle ) {
|
||||
$removed = false;
|
||||
$file = wc_get_log_file_path( $handle );
|
||||
|
||||
if ( is_file( $file ) && is_writable( $file ) ) {
|
||||
// Close first to be certain no processes keep it alive after it is unlinked.
|
||||
$this->close( $handle );
|
||||
$removed = unlink( $file );
|
||||
} elseif ( is_file( trailingslashit( WC_LOG_DIR ) . $handle . '.log' ) && is_writable( trailingslashit( WC_LOG_DIR ) . $handle . '.log' ) ) {
|
||||
$this->close( $handle );
|
||||
$removed = unlink( trailingslashit( WC_LOG_DIR ) . $handle . '.log' );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_log_remove', $handle, $removed );
|
||||
|
||||
return $removed;
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -610,7 +610,7 @@ class WC_Product_Variable extends WC_Product {
|
|||
'price_html' => apply_filters( 'woocommerce_show_variation_price', $variation->get_price() === "" || $this->get_variation_price( 'min' ) !== $this->get_variation_price( 'max' ), $this, $variation ) ? '<span class="price">' . $variation->get_price_html() . '</span>' : '',
|
||||
'availability_html' => $availability_html,
|
||||
'sku' => $variation->get_sku(),
|
||||
'weight' => $variation->get_weight() . ' ' . esc_attr( get_option('woocommerce_weight_unit' ) ),
|
||||
'weight' => $variation->get_weight() ? $variation->get_weight() . ' ' . esc_attr( get_option('woocommerce_weight_unit' ) ) : '',
|
||||
'dimensions' => $variation->get_dimensions(),
|
||||
'min_qty' => 1,
|
||||
'max_qty' => $variation->backorders_allowed() ? '' : $variation->get_stock_quantity(),
|
||||
|
@ -723,6 +723,33 @@ class WC_Product_Variable extends WC_Product {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have a weight set?
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_weight() {
|
||||
return (bool) get_post_meta( $this->id, '_child_has_weight', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Does a child have dimensions set?
|
||||
* @since 2.7.0
|
||||
* @return boolean
|
||||
*/
|
||||
public function child_has_dimensions() {
|
||||
return (bool) get_post_meta( $this->id, '_child_has_dimensions', true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether or not we are showing dimensions on the product page.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function enable_dimensions_display() {
|
||||
return apply_filters( 'wc_product_enable_dimensions_display', true ) && ( $this->has_dimensions() || $this->has_weight() || $this->child_has_weight() || $this->child_has_dimensions() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Sync the variable product with it's children.
|
||||
*/
|
||||
|
@ -740,6 +767,8 @@ class WC_Product_Variable extends WC_Product {
|
|||
// No published variations - product won't be purchasable.
|
||||
if ( ! $children ) {
|
||||
update_post_meta( $product_id, '_price', '' );
|
||||
delete_post_meta( $product_id, '_child_has_weight' );
|
||||
delete_post_meta( $product_id, '_child_has_dimensions' );
|
||||
delete_transient( 'wc_products_onsale' );
|
||||
|
||||
if ( is_admin() && 'publish' === get_post_status( $product_id ) ) {
|
||||
|
@ -826,6 +855,22 @@ class WC_Product_Variable extends WC_Product {
|
|||
add_post_meta( $product_id, '_price', $max_price, false );
|
||||
delete_transient( 'wc_products_onsale' );
|
||||
|
||||
// Sync weights
|
||||
foreach ( $children as $child_id ) {
|
||||
if ( get_post_meta( $child_id, '_weight', true ) ) {
|
||||
update_post_meta( $product_id, '_child_has_weight', true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sync dimensions
|
||||
foreach ( $children as $child_id ) {
|
||||
if ( get_post_meta( $child_id, '_height', true ) || get_post_meta( $child_id, '_width', true ) || get_post_meta( $child_id, '_length', true ) ) {
|
||||
update_post_meta( $product_id, '_child_has_dimensions', true );
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// Sync attributes
|
||||
self::sync_attributes( $product_id, $children );
|
||||
|
||||
|
|
|
@ -331,7 +331,14 @@ class WC_Shipping {
|
|||
}
|
||||
|
||||
// Check if we need to recalculate shipping for this package
|
||||
$package_hash = 'wc_ship_' . md5( json_encode( $package ) . WC_Cache_Helper::get_transient_version( 'shipping' ) );
|
||||
$package_to_hash = $package;
|
||||
|
||||
// Remove data objects so hashes are consistent
|
||||
foreach ( $package_to_hash['contents'] as $item_id => $item ) {
|
||||
unset( $package_to_hash['contents'][ $item_id ]['data'] );
|
||||
}
|
||||
|
||||
$package_hash = 'wc_ship_' . md5( json_encode( $package_to_hash ) . WC_Cache_Helper::get_transient_version( 'shipping' ) );
|
||||
$status_options = get_option( 'woocommerce_status_options', array() );
|
||||
$session_key = 'shipping_for_package_' . $package_key;
|
||||
$stored_rates = WC()->session->get( $session_key );
|
||||
|
|
|
@ -270,6 +270,10 @@ class WC_Webhook {
|
|||
break;
|
||||
|
||||
case 'product':
|
||||
// bulk and quick edit action hooks return a product object instead of an ID
|
||||
if ( 'updated' === $event && is_a( $resource_id, 'WC_Product' ) ) {
|
||||
$resource_id = $resource_id->get_id();
|
||||
}
|
||||
$payload = WC()->api->WC_API_Products->get_product( $resource_id );
|
||||
break;
|
||||
|
||||
|
@ -581,6 +585,8 @@ class WC_Webhook {
|
|||
'product.updated' => array(
|
||||
'woocommerce_process_product_meta',
|
||||
'woocommerce_api_edit_product',
|
||||
'woocommerce_product_quick_edit_save',
|
||||
'woocommerce_product_bulk_edit_save',
|
||||
),
|
||||
'product.deleted' => array(
|
||||
'wp_trash_post',
|
||||
|
|
|
@ -668,6 +668,9 @@ function wc_format_postcode( $postcode, $country ) {
|
|||
case 'JP' :
|
||||
$postcode = trim( substr_replace( $postcode, '-', 3, 0 ) );
|
||||
break;
|
||||
case 'PL' :
|
||||
$postcode = trim( substr_replace( $postcode, '-', -3, 0 ) );
|
||||
break;
|
||||
case 'PT' :
|
||||
$postcode = trim( substr_replace( $postcode, '-', 4, 0 ) );
|
||||
break;
|
||||
|
|
|
@ -306,9 +306,10 @@ function wc_rest_check_product_term_permissions( $taxonomy, $context = 'read', $
|
|||
*/
|
||||
function wc_rest_check_manager_permissions( $object, $context = 'read' ) {
|
||||
$objects = array(
|
||||
'reports' => 'view_woocommerce_reports',
|
||||
'settings' => 'manage_woocommerce',
|
||||
'attributes' => 'manage_product_terms',
|
||||
'reports' => 'view_woocommerce_reports',
|
||||
'settings' => 'manage_woocommerce',
|
||||
'system_status' => 'manage_woocommerce',
|
||||
'attributes' => 'manage_product_terms',
|
||||
);
|
||||
|
||||
$permission = current_user_can( $objects[ $object ] );
|
||||
|
|
|
@ -344,23 +344,31 @@ function wc_product_post_class( $classes, $class = '', $post_id = '' ) {
|
|||
* @param array $exclude Keys to exclude.
|
||||
* @param string $current_key Current key we are outputting.
|
||||
*/
|
||||
function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '' ) {
|
||||
function wc_query_string_form_fields( $values = null, $exclude = array(), $current_key = '', $return = false ) {
|
||||
if ( is_null( $values ) ) {
|
||||
$values = $_GET;
|
||||
}
|
||||
$html = '';
|
||||
|
||||
foreach ( $values as $key => $value ) {
|
||||
if ( in_array( $key, $exclude ) ) {
|
||||
if ( in_array( $key, $exclude, true ) ) {
|
||||
continue;
|
||||
}
|
||||
if ( $current_key ) {
|
||||
$key = $current_key . '[' . $key . ']';
|
||||
}
|
||||
if ( is_array( $value ) ) {
|
||||
wc_query_string_form_fields( $value, $exclude, $key );
|
||||
$html .= wc_query_string_form_fields( $value, $exclude, $key, true );
|
||||
} else {
|
||||
echo '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
|
||||
$html .= '<input type="hidden" name="' . esc_attr( $key ) . '" value="' . esc_attr( $value ) . '" />';
|
||||
}
|
||||
}
|
||||
|
||||
if ( $return ) {
|
||||
return $html;
|
||||
} else {
|
||||
echo $html;
|
||||
}
|
||||
}
|
||||
|
||||
/** Template pages ********************************************************/
|
||||
|
@ -1141,7 +1149,7 @@ if ( ! function_exists( 'woocommerce_default_product_tabs' ) ) {
|
|||
}
|
||||
|
||||
// Additional information tab - shows attributes
|
||||
if ( $product && ( $product->has_attributes() || ( $product->enable_dimensions_display() && ( $product->has_dimensions() || $product->has_weight() ) ) ) ) {
|
||||
if ( $product && ( $product->has_attributes() || $product->enable_dimensions_display() ) ) {
|
||||
$tabs['additional_information'] = array(
|
||||
'title' => __( 'Additional Information', 'woocommerce' ),
|
||||
'priority' => 20,
|
||||
|
@ -1748,10 +1756,13 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
|
|||
$thumbnail_id = get_woocommerce_term_meta( $category->term_id, 'thumbnail_id', true );
|
||||
|
||||
if ( $thumbnail_id ) {
|
||||
$image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size );
|
||||
$image = $image[0];
|
||||
$image = wp_get_attachment_image_src( $thumbnail_id, $small_thumbnail_size );
|
||||
$image = $image[0];
|
||||
$image_srcset = function_exists( 'wp_get_attachment_image_srcset' ) ? wp_get_attachment_image_srcset( $thumbnail_id, $small_thumbnail_size ) : false;
|
||||
$image_sizes = function_exists( 'wp_get_attachment_image_sizes' ) ? wp_get_attachment_image_sizes( $thumbnail_id, $small_thumbnail_size ) : false;
|
||||
} else {
|
||||
$image = wc_placeholder_img_src();
|
||||
$image = wc_placeholder_img_src();
|
||||
$image_srcset = $image_sizes = false;
|
||||
}
|
||||
|
||||
if ( $image ) {
|
||||
|
@ -1759,7 +1770,12 @@ if ( ! function_exists( 'woocommerce_subcategory_thumbnail' ) ) {
|
|||
// Ref: https://core.trac.wordpress.org/ticket/23605
|
||||
$image = str_replace( ' ', '%20', $image );
|
||||
|
||||
echo '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" width="' . esc_attr( $dimensions['width'] ) . '" height="' . esc_attr( $dimensions['height'] ) . '" />';
|
||||
// Add responsive image markup if available
|
||||
if ( $image_srcset && $image_sizes ) {
|
||||
echo '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" width="' . esc_attr( $dimensions['width'] ) . '" height="' . esc_attr( $dimensions['height'] ) . '" srcset="' . esc_attr( $image_srcset ) . '" sizes="' . esc_attr( $image_sizes ) . '" />';
|
||||
} else {
|
||||
echo '<img src="' . esc_url( $image ) . '" alt="' . esc_attr( $category->name ) . '" width="' . esc_attr( $dimensions['width'] ) . '" height="' . esc_attr( $dimensions['height'] ) . '" />';
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -2037,11 +2053,19 @@ if ( ! function_exists( 'get_product_search_form' ) ) {
|
|||
* @return string
|
||||
*/
|
||||
function get_product_search_form( $echo = true ) {
|
||||
global $product_search_form_index;
|
||||
|
||||
ob_start();
|
||||
|
||||
if ( empty( $product_search_form_index ) ) {
|
||||
$product_search_form_index = 0;
|
||||
}
|
||||
|
||||
do_action( 'pre_get_product_search_form' );
|
||||
|
||||
wc_get_template( 'product-searchform.php' );
|
||||
wc_get_template( 'product-searchform.php', array(
|
||||
'index' => $product_search_form_index++,
|
||||
) );
|
||||
|
||||
$form = apply_filters( 'get_product_search_form', ob_get_clean() );
|
||||
|
||||
|
|
|
@ -970,3 +970,20 @@ function wc_update_260_refunds() {
|
|||
function wc_update_260_db_version() {
|
||||
WC_Install::update_db_version( '2.6.0' );
|
||||
}
|
||||
|
||||
function wc_update_270_webhooks() {
|
||||
/**
|
||||
* Make sure product.update webhooks get the woocommerce_product_quick_edit_save
|
||||
* and woocommerce_product_bulk_edit_save hooks.
|
||||
*/
|
||||
$product_update_webhooks = get_posts( array(
|
||||
'posts_per_page' => -1,
|
||||
'post_type' => 'shop_webhook',
|
||||
'meta_key' => '_topic',
|
||||
'meta_value' => 'product.updated'
|
||||
) );
|
||||
foreach ( $product_update_webhooks as $product_update_webhook ) {
|
||||
$webhook = new WC_Webhook( $product_update_webhook->ID );
|
||||
$webhook->set_topic( 'product.updated' );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -68,45 +68,6 @@ class WC_Widget_Price_Filter extends WC_Widget {
|
|||
|
||||
wp_enqueue_script( 'wc-price-slider' );
|
||||
|
||||
// Remember current filters/search
|
||||
$fields = '';
|
||||
|
||||
if ( get_search_query() ) {
|
||||
$fields .= '<input type="hidden" name="s" value="' . get_search_query() . '" />';
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['post_type'] ) ) {
|
||||
$fields .= '<input type="hidden" name="post_type" value="' . esc_attr( $_GET['post_type'] ) . '" />';
|
||||
}
|
||||
|
||||
if ( ! empty ( $_GET['product_cat'] ) ) {
|
||||
$fields .= '<input type="hidden" name="product_cat" value="' . esc_attr( $_GET['product_cat'] ) . '" />';
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['product_tag'] ) ) {
|
||||
$fields .= '<input type="hidden" name="product_tag" value="' . esc_attr( $_GET['product_tag'] ) . '" />';
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['orderby'] ) ) {
|
||||
$fields .= '<input type="hidden" name="orderby" value="' . esc_attr( $_GET['orderby'] ) . '" />';
|
||||
}
|
||||
|
||||
if ( ! empty( $_GET['min_rating'] ) ) {
|
||||
$fields .= '<input type="hidden" name="min_rating" value="' . esc_attr( $_GET['min_rating'] ) . '" />';
|
||||
}
|
||||
|
||||
if ( $_chosen_attributes = WC_Query::get_layered_nav_chosen_attributes() ) {
|
||||
foreach ( $_chosen_attributes as $attribute => $data ) {
|
||||
$taxonomy_filter = 'filter_' . str_replace( 'pa_', '', $attribute );
|
||||
|
||||
$fields .= '<input type="hidden" name="' . esc_attr( $taxonomy_filter ) . '" value="' . esc_attr( implode( ',', $data['terms'] ) ) . '" />';
|
||||
|
||||
if ( 'or' == $data['query_type'] ) {
|
||||
$fields .= '<input type="hidden" name="' . esc_attr( str_replace( 'pa_', 'query_type_', $attribute ) ) . '" value="or" />';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Find min and max price in current result set
|
||||
$prices = $this->get_filtered_price();
|
||||
$min = floor( $prices->min_price );
|
||||
|
@ -152,7 +113,7 @@ class WC_Widget_Price_Filter extends WC_Widget {
|
|||
<div class="price_label" style="display:none;">
|
||||
' . __( 'Price:', 'woocommerce' ) . ' <span class="from"></span> — <span class="to"></span>
|
||||
</div>
|
||||
' . $fields . '
|
||||
' . wc_query_string_form_fields( null, array( 'min_price', 'max_price' ), '', true ) . '
|
||||
<div class="clear"></div>
|
||||
</div>
|
||||
</div>
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
=== WooCommerce ===
|
||||
Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, woothemes, BFTrick
|
||||
Contributors: automattic, mikejolley, jameskoster, claudiosanches, jshreve, coderkevin, woothemes, BFTrick, iCaleb
|
||||
Tags: ecommerce, e-commerce, store, sales, sell, shop, cart, checkout, downloadable, downloads, paypal, storefront
|
||||
Requires at least: 4.4
|
||||
Tested up to: 4.5
|
||||
|
@ -164,6 +164,8 @@ Yes you can! Join in on our [GitHub repository](http://github.com/woothemes/wooc
|
|||
* Improved handling of shop page rewrite rules to allow subpages.
|
||||
* Redirect to login after password reset.
|
||||
* When using authorizations in PayPal standard, automatically capture funds when the order goes processing/completed.
|
||||
* On multisite, when a user logs into a store with an account on a site, but not the current site, rather than error, add the user to the current site as a customer.
|
||||
* Show variable weights/dimensions even when parent values are not set.
|
||||
|
||||
[See changelog for all versions](https://raw.githubusercontent.com/woothemes/woocommerce/master/CHANGELOG.txt).
|
||||
|
||||
|
|
|
@ -16,16 +16,14 @@
|
|||
* @version 2.5.0
|
||||
*/
|
||||
|
||||
// Exit if accessed directly
|
||||
if ( ! defined( 'ABSPATH' ) ) {
|
||||
exit;
|
||||
}
|
||||
|
||||
?>
|
||||
|
||||
<form role="search" method="get" class="woocommerce-product-search" action="<?php echo esc_url( home_url( '/' ) ); ?>">
|
||||
<label class="screen-reader-text" for="woocommerce-product-search-field"><?php _e( 'Search for:', 'woocommerce' ); ?></label>
|
||||
<input type="search" id="woocommerce-product-search-field" class="search-field" placeholder="<?php echo esc_attr_x( 'Search Products…', 'placeholder', 'woocommerce' ); ?>" value="<?php echo get_search_query(); ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label', 'woocommerce' ); ?>" />
|
||||
<label class="screen-reader-text" for="woocommerce-product-search-field-<?php echo isset( $index ) ? absint( $index ) : 0; ?>"><?php _e( 'Search for:', 'woocommerce' ); ?></label>
|
||||
<input type="search" id="woocommerce-product-search-field-<?php echo isset( $index ) ? absint( $index ) : 0; ?>" class="search-field" placeholder="<?php echo esc_attr_x( 'Search Products…', 'placeholder', 'woocommerce' ); ?>" value="<?php echo get_search_query(); ?>" name="s" title="<?php echo esc_attr_x( 'Search for:', 'label', 'woocommerce' ); ?>" />
|
||||
<input type="submit" value="<?php echo esc_attr_x( 'Search', 'submit button', 'woocommerce' ); ?>" />
|
||||
<input type="hidden" name="post_type" value="product" />
|
||||
</form>
|
||||
|
|
|
@ -33,17 +33,17 @@ ob_start();
|
|||
|
||||
<?php if ( $product->enable_dimensions_display() ) : ?>
|
||||
|
||||
<?php if ( $product->has_weight() ) : $has_row = true; ?>
|
||||
<?php if ( $product->has_weight() || get_post_meta( $product->id, '_child_has_weight', true ) ) : $has_row = true; ?>
|
||||
<tr class="<?php if ( ( $alt = $alt * -1 ) === 1 ) echo 'alt'; ?>">
|
||||
<th><?php _e( 'Weight', 'woocommerce' ) ?></th>
|
||||
<td class="product_weight"><?php echo wc_format_localized_decimal( $product->get_weight() ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ); ?></td>
|
||||
<td class="product_weight"><?php echo $product->get_weight() ? wc_format_localized_decimal( $product->get_weight() ) . ' ' . esc_attr( get_option( 'woocommerce_weight_unit' ) ) : __( 'N/A', 'woocommerce' ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
<?php if ( $product->has_dimensions() ) : $has_row = true; ?>
|
||||
<?php if ( $product->has_dimensions() || get_post_meta( $product->id, '_child_has_dimensions', true ) ) : $has_row = true; ?>
|
||||
<tr class="<?php if ( ( $alt = $alt * -1 ) === 1 ) echo 'alt'; ?>">
|
||||
<th><?php _e( 'Dimensions', 'woocommerce' ) ?></th>
|
||||
<td class="product_dimensions"><?php echo $product->get_dimensions(); ?></td>
|
||||
<td class="product_dimensions"><?php echo $product->get_dimensions() ? $product->get_dimensions() : __( 'N/A', 'woocommerce' ); ?></td>
|
||||
</tr>
|
||||
<?php endif; ?>
|
||||
|
||||
|
|
|
@ -0,0 +1,189 @@
|
|||
<?php
|
||||
/**
|
||||
* System Status REST Tests
|
||||
* @package WooCommerce\Tests\API
|
||||
* @since 2.7
|
||||
*/
|
||||
class WC_Tests_REST_System_Status extends WC_REST_Unit_Test_Case {
|
||||
|
||||
/**
|
||||
* Setup our test server.
|
||||
*/
|
||||
public function setUp() {
|
||||
parent::setUp();
|
||||
$this->endpoint = new WC_REST_System_Status_Controller();
|
||||
$this->user = $this->factory->user->create( array(
|
||||
'role' => 'administrator',
|
||||
) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test route registration.
|
||||
*/
|
||||
public function test_register_routes() {
|
||||
$routes = $this->server->get_routes();
|
||||
$this->assertArrayHasKey( '/wc/v1/system_status', $routes );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure system status cannot be accessed without valid creds
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_without_permission() {
|
||||
wp_set_current_user( 0 );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$this->assertEquals( 401, $response->get_status() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure root properties are present.
|
||||
* (environment, theme, database, etc).
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_returns_root_properties() {
|
||||
wp_set_current_user( $this->user );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
|
||||
$this->assertArrayHasKey( 'environment', $data );
|
||||
$this->assertArrayHasKey( 'database', $data );
|
||||
$this->assertArrayHasKey( 'active_plugins', $data );
|
||||
$this->assertArrayHasKey( 'theme', $data );
|
||||
$this->assertArrayHasKey( 'settings', $data );
|
||||
$this->assertArrayHasKey( 'pages', $data );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure environment response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_environment() {
|
||||
wp_set_current_user( $this->user );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
$environment = $data['environment'];
|
||||
|
||||
// Make sure all expected data is present
|
||||
$this->assertEquals( 30, count( $environment ) );
|
||||
|
||||
// Test some responses to make sure they match up
|
||||
$this->assertEquals( get_option( 'home' ), $environment['home_url'] );
|
||||
$this->assertEquals( get_option( 'siteurl' ), $environment['site_url'] );
|
||||
$this->assertEquals( WC()->version, $environment['version'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure database response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_database() {
|
||||
global $wpdb;
|
||||
wp_set_current_user( $this->user );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
$database = $data['database'];
|
||||
|
||||
$this->assertEquals( get_option( 'woocommerce_db_version' ), $database['wc_database_version'] );
|
||||
$this->assertEquals( $wpdb->prefix, $database['database_prefix'] );
|
||||
$this->assertEquals( WC_Geolocation::get_local_database_path(), $database['maxmind_geoip_database'] );
|
||||
$this->assertArrayHasKey( 'woocommerce_payment_tokens', $database['database_tables'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure active plugins response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_active_plugins() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$actual_plugins = array( 'hello.php' );
|
||||
update_option( 'active_plugins', $actual_plugins );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
update_option( 'active_plugins', array() );
|
||||
|
||||
$data = $response->get_data();
|
||||
$plugins = $data['active_plugins'];
|
||||
|
||||
$this->assertEquals( 1, count( $plugins ) );
|
||||
$this->assertEquals( 'Hello Dolly', $plugins[0]['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure theme response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_theme() {
|
||||
wp_set_current_user( $this->user );
|
||||
$active_theme = wp_get_theme();
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
$theme = $data['theme'];
|
||||
|
||||
$this->assertEquals( 9, count( $theme ) );
|
||||
$this->assertEquals( $active_theme->Name, $theme['name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure settings response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_settings() {
|
||||
wp_set_current_user( $this->user );
|
||||
|
||||
$term_response = array();
|
||||
$terms = get_terms( 'product_type', array( 'hide_empty' => 0 ) );
|
||||
foreach ( $terms as $term ) {
|
||||
$term_response[ $term->slug ] = strtolower( $term->name );
|
||||
}
|
||||
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
$settings = $data['settings'];
|
||||
|
||||
$this->assertEquals( 10, count( $settings ) );
|
||||
$this->assertEquals( ( 'yes' === get_option( 'woocommerce_api_enabled' ) ), $settings['api_enabled'] );
|
||||
$this->assertEquals( get_woocommerce_currency(), $settings['currency'] );
|
||||
$this->assertEquals( $term_response, $settings['taxonomies'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test to make sure pages response is correct.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_get_system_status_info_pages() {
|
||||
wp_set_current_user( $this->user );
|
||||
$response = $this->server->dispatch( new WP_REST_Request( 'GET', '/wc/v1/system_status' ) );
|
||||
$data = $response->get_data();
|
||||
$pages = $data['pages'];
|
||||
$this->assertEquals( 4, count( $pages ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Test system status schema.
|
||||
*
|
||||
* @since 2.7.0
|
||||
*/
|
||||
public function test_system_status_schema() {
|
||||
$request = new WP_REST_Request( 'OPTIONS', '/wc/v1/system_status' );
|
||||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertEquals( 6, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'environment', $properties );
|
||||
$this->assertArrayHasKey( 'database', $properties );
|
||||
$this->assertArrayHasKey( 'active_plugins', $properties );
|
||||
$this->assertArrayHasKey( 'theme', $properties );
|
||||
$this->assertArrayHasKey( 'settings', $properties );
|
||||
$this->assertArrayHasKey( 'pages', $properties );
|
||||
}
|
||||
|
||||
}
|
|
@ -0,0 +1,7 @@
|
|||
<?php
|
||||
|
||||
// autoload.php @generated by Composer
|
||||
|
||||
require_once __DIR__ . '/composer' . '/autoload_real.php';
|
||||
|
||||
return ComposerAutoloaderInit0a41505776925130d875dad51bde4180::getLoader();
|
|
@ -0,0 +1,413 @@
|
|||
<?php
|
||||
|
||||
/*
|
||||
* This file is part of Composer.
|
||||
*
|
||||
* (c) Nils Adermann <naderman@naderman.de>
|
||||
* Jordi Boggiano <j.boggiano@seld.be>
|
||||
*
|
||||
* For the full copyright and license information, please view the LICENSE
|
||||
* file that was distributed with this source code.
|
||||
*/
|
||||
|
||||
namespace Composer\Autoload;
|
||||
|
||||
/**
|
||||
* ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
|
||||
*
|
||||
* $loader = new \Composer\Autoload\ClassLoader();
|
||||
*
|
||||
* // register classes with namespaces
|
||||
* $loader->add('Symfony\Component', __DIR__.'/component');
|
||||
* $loader->add('Symfony', __DIR__.'/framework');
|
||||
*
|
||||
* // activate the autoloader
|
||||
* $loader->register();
|
||||
*
|
||||
* // to enable searching the include path (eg. for PEAR packages)
|
||||
* $loader->setUseIncludePath(true);
|
||||
*
|
||||
* In this example, if you try to use a class in the Symfony\Component
|
||||
* namespace or one of its children (Symfony\Component\Console for instance),
|
||||
* the autoloader will first look for the class under the component/
|
||||
* directory, and it will then fallback to the framework/ directory if not
|
||||
* found before giving up.
|
||||
*
|
||||
* This class is loosely based on the Symfony UniversalClassLoader.
|
||||
*
|
||||
* @author Fabien Potencier <fabien@symfony.com>
|
||||
* @author Jordi Boggiano <j.boggiano@seld.be>
|
||||
* @see http://www.php-fig.org/psr/psr-0/
|
||||
* @see http://www.php-fig.org/psr/psr-4/
|
||||
*/
|
||||
class ClassLoader
|
||||
{
|
||||
// PSR-4
|
||||
private $prefixLengthsPsr4 = array();
|
||||
private $prefixDirsPsr4 = array();
|
||||
private $fallbackDirsPsr4 = array();
|
||||
|
||||
// PSR-0
|
||||
private $prefixesPsr0 = array();
|
||||
private $fallbackDirsPsr0 = array();
|
||||
|
||||
private $useIncludePath = false;
|
||||
private $classMap = array();
|
||||
|
||||
private $classMapAuthoritative = false;
|
||||
|
||||
public function getPrefixes()
|
||||
{
|
||||
if (!empty($this->prefixesPsr0)) {
|
||||
return call_user_func_array('array_merge', $this->prefixesPsr0);
|
||||
}
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
public function getPrefixesPsr4()
|
||||
{
|
||||
return $this->prefixDirsPsr4;
|
||||
}
|
||||
|
||||
public function getFallbackDirs()
|
||||
{
|
||||
return $this->fallbackDirsPsr0;
|
||||
}
|
||||
|
||||
public function getFallbackDirsPsr4()
|
||||
{
|
||||
return $this->fallbackDirsPsr4;
|
||||
}
|
||||
|
||||
public function getClassMap()
|
||||
{
|
||||
return $this->classMap;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $classMap Class to filename map
|
||||
*/
|
||||
public function addClassMap(array $classMap)
|
||||
{
|
||||
if ($this->classMap) {
|
||||
$this->classMap = array_merge($this->classMap, $classMap);
|
||||
} else {
|
||||
$this->classMap = $classMap;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix, either
|
||||
* appending or prepending to the ones previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 root directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*/
|
||||
public function add($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr0
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr0 = array_merge(
|
||||
$this->fallbackDirsPsr0,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
$first = $prefix[0];
|
||||
if (!isset($this->prefixesPsr0[$first][$prefix])) {
|
||||
$this->prefixesPsr0[$first][$prefix] = (array) $paths;
|
||||
|
||||
return;
|
||||
}
|
||||
if ($prepend) {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixesPsr0[$first][$prefix]
|
||||
);
|
||||
} else {
|
||||
$this->prefixesPsr0[$first][$prefix] = array_merge(
|
||||
$this->prefixesPsr0[$first][$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace, either
|
||||
* appending or prepending to the ones previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
* @param bool $prepend Whether to prepend the directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function addPsr4($prefix, $paths, $prepend = false)
|
||||
{
|
||||
if (!$prefix) {
|
||||
// Register directories for the root namespace.
|
||||
if ($prepend) {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
(array) $paths,
|
||||
$this->fallbackDirsPsr4
|
||||
);
|
||||
} else {
|
||||
$this->fallbackDirsPsr4 = array_merge(
|
||||
$this->fallbackDirsPsr4,
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
} elseif (!isset($this->prefixDirsPsr4[$prefix])) {
|
||||
// Register directories for a new namespace.
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
} elseif ($prepend) {
|
||||
// Prepend directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
(array) $paths,
|
||||
$this->prefixDirsPsr4[$prefix]
|
||||
);
|
||||
} else {
|
||||
// Append directories for an already registered namespace.
|
||||
$this->prefixDirsPsr4[$prefix] = array_merge(
|
||||
$this->prefixDirsPsr4[$prefix],
|
||||
(array) $paths
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-0 directories for a given prefix,
|
||||
* replacing any others previously set for this prefix.
|
||||
*
|
||||
* @param string $prefix The prefix
|
||||
* @param array|string $paths The PSR-0 base directories
|
||||
*/
|
||||
public function set($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr0 = (array) $paths;
|
||||
} else {
|
||||
$this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers a set of PSR-4 directories for a given namespace,
|
||||
* replacing any others previously set for this namespace.
|
||||
*
|
||||
* @param string $prefix The prefix/namespace, with trailing '\\'
|
||||
* @param array|string $paths The PSR-4 base directories
|
||||
*
|
||||
* @throws \InvalidArgumentException
|
||||
*/
|
||||
public function setPsr4($prefix, $paths)
|
||||
{
|
||||
if (!$prefix) {
|
||||
$this->fallbackDirsPsr4 = (array) $paths;
|
||||
} else {
|
||||
$length = strlen($prefix);
|
||||
if ('\\' !== $prefix[$length - 1]) {
|
||||
throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
|
||||
}
|
||||
$this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
|
||||
$this->prefixDirsPsr4[$prefix] = (array) $paths;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns on searching the include path for class files.
|
||||
*
|
||||
* @param bool $useIncludePath
|
||||
*/
|
||||
public function setUseIncludePath($useIncludePath)
|
||||
{
|
||||
$this->useIncludePath = $useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Can be used to check if the autoloader uses the include path to check
|
||||
* for classes.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function getUseIncludePath()
|
||||
{
|
||||
return $this->useIncludePath;
|
||||
}
|
||||
|
||||
/**
|
||||
* Turns off searching the prefix and fallback directories for classes
|
||||
* that have not been registered with the class map.
|
||||
*
|
||||
* @param bool $classMapAuthoritative
|
||||
*/
|
||||
public function setClassMapAuthoritative($classMapAuthoritative)
|
||||
{
|
||||
$this->classMapAuthoritative = $classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Should class lookup fail if not found in the current class map?
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function isClassMapAuthoritative()
|
||||
{
|
||||
return $this->classMapAuthoritative;
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers this instance as an autoloader.
|
||||
*
|
||||
* @param bool $prepend Whether to prepend the autoloader or not
|
||||
*/
|
||||
public function register($prepend = false)
|
||||
{
|
||||
spl_autoload_register(array($this, 'loadClass'), true, $prepend);
|
||||
}
|
||||
|
||||
/**
|
||||
* Unregisters this instance as an autoloader.
|
||||
*/
|
||||
public function unregister()
|
||||
{
|
||||
spl_autoload_unregister(array($this, 'loadClass'));
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the given class or interface.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
* @return bool|null True if loaded, null otherwise
|
||||
*/
|
||||
public function loadClass($class)
|
||||
{
|
||||
if ($file = $this->findFile($class)) {
|
||||
includeFile($file);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Finds the path to the file where the class is defined.
|
||||
*
|
||||
* @param string $class The name of the class
|
||||
*
|
||||
* @return string|false The path if found, false otherwise
|
||||
*/
|
||||
public function findFile($class)
|
||||
{
|
||||
// work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
|
||||
if ('\\' == $class[0]) {
|
||||
$class = substr($class, 1);
|
||||
}
|
||||
|
||||
// class map lookup
|
||||
if (isset($this->classMap[$class])) {
|
||||
return $this->classMap[$class];
|
||||
}
|
||||
if ($this->classMapAuthoritative) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$file = $this->findFileWithExtension($class, '.php');
|
||||
|
||||
// Search for Hack files if we are running on HHVM
|
||||
if ($file === null && defined('HHVM_VERSION')) {
|
||||
$file = $this->findFileWithExtension($class, '.hh');
|
||||
}
|
||||
|
||||
if ($file === null) {
|
||||
// Remember that this class does not exist.
|
||||
return $this->classMap[$class] = false;
|
||||
}
|
||||
|
||||
return $file;
|
||||
}
|
||||
|
||||
private function findFileWithExtension($class, $ext)
|
||||
{
|
||||
// PSR-4 lookup
|
||||
$logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
|
||||
|
||||
$first = $class[0];
|
||||
if (isset($this->prefixLengthsPsr4[$first])) {
|
||||
foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-4 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr4 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 lookup
|
||||
if (false !== $pos = strrpos($class, '\\')) {
|
||||
// namespaced class name
|
||||
$logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
|
||||
. strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
|
||||
} else {
|
||||
// PEAR-like class name
|
||||
$logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
|
||||
}
|
||||
|
||||
if (isset($this->prefixesPsr0[$first])) {
|
||||
foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
|
||||
if (0 === strpos($class, $prefix)) {
|
||||
foreach ($dirs as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 fallback dirs
|
||||
foreach ($this->fallbackDirsPsr0 as $dir) {
|
||||
if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
|
||||
// PSR-0 include paths.
|
||||
if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
|
||||
return $file;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Scope isolated include.
|
||||
*
|
||||
* Prevents access to $this/self from included files.
|
||||
*/
|
||||
function includeFile($file)
|
||||
{
|
||||
include $file;
|
||||
}
|
|
@ -0,0 +1,21 @@
|
|||
|
||||
Copyright (c) 2015 Nils Adermann, Jordi Boggiano
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is furnished
|
||||
to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// autoload_classmap.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// autoload_namespaces.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
|
@ -0,0 +1,9 @@
|
|||
<?php
|
||||
|
||||
// autoload_psr4.php @generated by Composer
|
||||
|
||||
$vendorDir = dirname(dirname(__FILE__));
|
||||
$baseDir = dirname($vendorDir);
|
||||
|
||||
return array(
|
||||
);
|
|
@ -0,0 +1,45 @@
|
|||
<?php
|
||||
|
||||
// autoload_real.php @generated by Composer
|
||||
|
||||
class ComposerAutoloaderInit0a41505776925130d875dad51bde4180
|
||||
{
|
||||
private static $loader;
|
||||
|
||||
public static function loadClassLoader($class)
|
||||
{
|
||||
if ('Composer\Autoload\ClassLoader' === $class) {
|
||||
require __DIR__ . '/ClassLoader.php';
|
||||
}
|
||||
}
|
||||
|
||||
public static function getLoader()
|
||||
{
|
||||
if (null !== self::$loader) {
|
||||
return self::$loader;
|
||||
}
|
||||
|
||||
spl_autoload_register(array('ComposerAutoloaderInit0a41505776925130d875dad51bde4180', 'loadClassLoader'), true, true);
|
||||
self::$loader = $loader = new \Composer\Autoload\ClassLoader();
|
||||
spl_autoload_unregister(array('ComposerAutoloaderInit0a41505776925130d875dad51bde4180', 'loadClassLoader'));
|
||||
|
||||
$map = require __DIR__ . '/autoload_namespaces.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->set($namespace, $path);
|
||||
}
|
||||
|
||||
$map = require __DIR__ . '/autoload_psr4.php';
|
||||
foreach ($map as $namespace => $path) {
|
||||
$loader->setPsr4($namespace, $path);
|
||||
}
|
||||
|
||||
$classMap = require __DIR__ . '/autoload_classmap.php';
|
||||
if ($classMap) {
|
||||
$loader->addClassMap($classMap);
|
||||
}
|
||||
|
||||
$loader->register(true);
|
||||
|
||||
return $loader;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue