Merge branch 'master' into update/exclude-compiled-assets-from-git

This commit is contained in:
Gerhard 2019-07-09 10:57:40 +02:00
commit 7038c73ab4
248 changed files with 6085 additions and 11339 deletions

View File

@ -18,7 +18,6 @@ ratings:
- "includes/*"
exclude_paths:
- "tests/"
- "apigen/"
- "sample-data/"
- "i18n/"
- "includes/api/legacy/"

1
.gitattributes vendored
View File

@ -1,5 +1,4 @@
/.* export-ignore
apigen* export-ignore
CODE_OF_CONDUCT.md export-ignore
CHANGELOG.txt export-ignore
composer.* export-ignore

View File

@ -42,16 +42,30 @@ https://woocommerce.com/contact-us/
- [WooExperts](https://woocommerce.com/experts/)
- [Codeable](https://codeable.io/)
## Build process
The source code found in GitHub doesn't contains any compiled CSS or JS files, also doesn't include some features like Blocks and REST API, requiring a build process.
In a terminal go to your WooCommerce installation, and run:
```bash
npm install
composer install
npm run build
```
Note that it's required to have installed [Node.js to run NPM](https://nodejs.org/en/) and [Composer](https://getcomposer.org/).
## Coding Guidelines
- **Ensure you stick to the [WordPress Coding Standards](https://make.wordpress.org/core/handbook/best-practices/coding-standards/php/)**
- Install our pre-commit hook using composer. It'll help with the Coding Standards. To install run `composer install` from the command line within the woocommerce plugin directory.
- Run our build process described in the section above, it will install our pre-commit hook, code sniffs, dependencies, and more.
- Ensure you use LF line endings in your code editor. Use [EditorConfig](http://editorconfig.org/) if your editor supports it so that indentation, line endings and other settings are auto configured.
- When committing, reference your issue number (#1234) and include a note about the fix.
- Ensure that your code is compatible with PHP 5.2+.
- Push the changes to your fork and submit a pull request on the master branch of the WooCommerce repository. Existing maintenance branches will be maintained by WooCommerce developers.
Please **don't** modify the changelog or update the .pot files. These will be maintained by the WooCommerce team.
Please **don't** modify the changelog, it will be maintained by the WooCommerce team.
## Translating WooCommerce

3
.gitignore vendored
View File

@ -31,9 +31,6 @@ none
# Windows junk
Thumbs.db
# ApiGen
/wc-apidocs/
# Behat/CLI Tests
tests/cli/installer
tests/cli/composer.phar

View File

@ -23,7 +23,6 @@ checks:
verify_property_names: false
filter:
excluded_paths:
- apigen/
- sample-data/
- i18n/
- includes/api/legacy/

View File

@ -19,15 +19,11 @@ php:
env:
- WP_VERSION=latest WP_MULTISITE=0
# Additional tests against stable PHP (min recommended version is 5.6) and past supported versions of WP
# Additional tests against stable PHP (min version is 5.6)
# and code coverage report.
matrix:
fast_finish: true
include:
- php: 5.3
dist: precise
- php: 5.2
dist: precise
- name: "Coding standard check"
php: 7.2
env: WP_VERSION=latest WP_MULTISITE=0 RUN_PHPCS=1
@ -59,18 +55,10 @@ before_script:
echo "xdebug.ini does not exist"
fi
- |
# Install WP Test suite, install PHPUnit globally if needed:
# Install WP Test suite, install PHPUnit globally:
if [[ ! -z "$WP_VERSION" ]]; then
bash tests/bin/install.sh woocommerce_test root '' localhost $WP_VERSION
# PHP 5.2 does not have composer, do not try to run it.
if [[ ${TRAVIS_PHP_VERSION:0:3} != "5.2" ]]; then
composer global require "phpunit/phpunit=4.8.*|6.5.*"
fi
fi
- |
# Install wpcs globally if needed:
if [[ ${RUN_PHPCS} == 1 ]] && [[ ${TRAVIS_PHP_VERSION:0:3} != "5.2" ]]; then
composer require woocommerce/woocommerce-sniffs
composer global require "phpunit/phpunit=4.8.*|6.5.*"
fi
script:

View File

@ -1,5 +1,51 @@
== Changelog ==
= 3.6.4 - 2019-05-27 =
* Enhancement - Add notice to install WooCommerce Admin. #23659
* Fix - Tracks: Add check for OBW is-opting-in. #23772
* Fix - Use HTTP protocol for schema.org's availability. #23774
* Fix - Coupon usage limit checks based on email never ran when orders are created via wp-admin. #23775
* Fix - Duplicate out of stock notices when navigating from cart to checkout and back to cart. #23791
* Fix - Remove sensitive information from refund reason when manually refunding an order, and move it to an order note. #23739
* Tweak - Tracks: set cookie on admin_init instead of wp_loaded. #23787
* Dev - Fixed number of arguments for all occurrences of the woocommerce_valid_order_statuses_for_cancel filter. #23704
* Dev - REST API - Stop order creation if invalid data is sent. #23325
* Dev - Introduce new wc_load_cart function for dynamically loading and initializing the cart. #23794
= 3.6.3 - 2019-05-16 =
* Fix - State not required for Serbia. #23430
* Fix - # symbol in product category name broke product export. #23454
* Fix - XML export caused fatal errors due to Action Scheduler adding invalid characters. #23456
* Fix - Invalid password messages when password contains backslashes. #23499
* Fix - Dismiss button in WC admin notices "legacy_shipping" and "no_shipping_methods" were not clickable. #23517
* Fix - WC $wpdb->tables not defined early enough. #23529
* Fix - Tracks JS not printed on last page of OBW. #23519
* Fix - Error in the logic used to build fields for external products when the query string contained full-stops, pluses or spaces in the values of the parameters. #23535
* Fix - UI page width issue on OBW. #23526
* Fix - Customer address not auto populated on checkout after registering and filling in address prior. #23528
* Fix - Available WooCommerce extension updates not showing in System Status report. #23601
* Fix - wc_change_get_terms_defaults throwing undefined index notices. #23611
* Fix - System Status report alway showing checkmark next to Connected to WooCommerce.com. #23617
* Fix - State field never populated when loading customer address on order via wp-admin. #23615
* Fix - Order sorting not working in wp-admin when Yoast SEO active. #23590
* Fix - Attribute ordering not working in product edit screen. #23625
* Fix - Tracks reporting incorrect order totals due to refunds being excluded in calculation. #23671
* Fix - Reload state options when creating a new order in WP-Admin and changing country. #23602
* Fix - New webhooks not showing in the webhook admin list page when you have object caching enabled. #23713
* Fix - Missing coupon expiry dates, restore coupons expiry_date backward compatibility. #23714
* Fix - Bulk stock update could result in all products set to out of stock, change ensures consistency between db and Product instance in memory. #23534
* Fix - Dashboard stats widget including unpublished products in out of stock and low in stock counts. #23734
* Fix - PayPal payment not captured when you transition an order from a custom order status to completed or processing. #23634
* Tweak - Confirm before saving empty list of countries to sell to in settings. #23597
* Tweak - Change default WC API version used when creating webhooks to the latest WC API version. #23515
* Tweak - Report a bug button now points to the new issue template in GitHub. #23580
* Tweak - Do not display taxes in totals columns when taxes not enabled. #23579
* Tweak - WC WP-CLI upgrade routine mimics wp-admin upgrade when no updates found by setting DB version to current version. #23666
* Tweak - Template caching now cache based on WC_VERSION to avoid issues with symlinked plugin folders. #23546
* Tweak - OBW payment gateway selection defaults. #23690
* Localization - Add Serbia locale defaults. #23428
* Localization - Add address format for Serbia. #23429
= 3.6.2 - 2019-04-24 =
* Fix - Fix CSS classname conflict with themes due to missing product object global. #23377
* Fix - Fix security check on email template preview page. #23356
@ -3502,7 +3548,7 @@
* Feature - Allow setting the product post type slug to a static (non-translatable) text, mainly to be used for translating and WPML setups.
* Feature - Added lost password shortcode / email notification (thanks Max Rice).
* Feature - Simplified permalink/base settings now found in Settings > Permalinks.
* Feature - Support more permalink structures (from https://codex.wordpress.org/Using_Permalinks)
* Feature - Support more permalink structures (from https://wordpress.org/support/article/using-permalinks/)
* Feature - Added option to resend order emails, checkboxes select which one.
* Feature - New layered nav current filters widget. This lists active filters from all layered nav for de-selection.
* Feature - Added the option to sell products individually (only allow 1 in the cart).

View File

@ -197,7 +197,6 @@ module.exports = function( grunt ) {
options: {
potFilename: 'woocommerce.pot',
exclude: [
'apigen/.*',
'vendor/.*',
'tests/.*',
'tmp/.*'
@ -230,7 +229,6 @@ module.exports = function( grunt ) {
files: {
src: [
'**/*.php', // Include all files
'!apigen/**', // Exclude apigen/
'!includes/libraries/**', // Exclude libraries/
'!node_modules/**', // Exclude node_modules/
'!tests/**', // Exclude tests/
@ -247,13 +245,6 @@ module.exports = function( grunt ) {
stdout: true,
stderr: true
},
apidocs: {
command: [
'vendor/bin/apigen generate -q',
'cd apigen',
'php hook-docs.php'
].join( '&&' )
},
e2e_test: {
command: 'npm run --silent test:single tests/e2e-tests/' + grunt.option( 'file' )
},
@ -295,9 +286,6 @@ module.exports = function( grunt ) {
// Clean the directory.
clean: {
apidocs: {
src: [ 'wc-apidocs' ]
},
blocks: {
src: [
'<%= dirs.js %>/blocks',
@ -315,7 +303,6 @@ module.exports = function( grunt ) {
dist: {
src: [
'**/*.php', // Include all php files.
'!apigen/**',
'!includes/api/legacy/**',
'!includes/libraries/**',
'!node_modules/**',
@ -444,11 +431,6 @@ module.exports = function( grunt ) {
'copy'
]);
grunt.registerTask( 'docs', [
'clean:apidocs',
'shell:apidocs'
]);
grunt.registerTask( 'contributors', [
'prompt:contributors',
'shell:contributors'

View File

@ -1,22 +0,0 @@
destination: wc-apidocs
templateConfig: apigen/theme-woocommerce/config.neon
extensions: [php]
source:
- woocommerce.php
- includes
exclude:
- includes/libraries/
- includes/api/legacy/
- api/legacy/
- libraries/
charset: [UTF-8]
main: WC
title: WooCommerce Code Reference
baseUrl: https://docs.woocommerce.com/wc-apidocs/
templateTheme: default
php: false
sourceCode: true
tree: true
deprecated: true
todo: true
download: false

View File

@ -1,226 +0,0 @@
<?php
/**
* Generate documentation for hooks in WC
*/
class WC_HookFinder {
private static $current_file = '';
private static $files_to_scan = array();
private static $pattern_custom_actions = '/do_action(.*?);/i';
private static $pattern_custom_filters = '/apply_filters(.*?);/i';
private static $found_files = array();
private static $custom_hooks_found = '';
private static function get_files( $pattern, $flags = 0, $path = '' ) {
if ( ! $path && ( $dir = dirname( $pattern ) ) != '.' ) {
if ( '\\' == $dir || '/' == $dir ) {
$dir = '';
}
return self::get_files( basename( $pattern ), $flags, $dir . '/' );
} // End IF Statement
$paths = glob( $path . '*', GLOB_ONLYDIR | GLOB_NOSORT );
$files = glob( $path . $pattern, $flags );
if ( is_array( $paths ) ) {
foreach ( $paths as $p ) {
$found_files = array();
$retrieved_files = (array) self::get_files( $pattern, $flags, $p . '/' );
foreach ( $retrieved_files as $file ) {
if ( ! in_array( $file, self::$found_files ) ) {
$found_files[] = $file;
}
}
self::$found_files = array_merge( self::$found_files, $found_files );
if ( is_array( $files ) && is_array( $found_files ) ) {
$files = array_merge( $files, $found_files );
}
} // End FOREACH Loop
}
return $files;
}
private static function get_hook_link( $hook, $details = array() ) {
if ( ! empty( $details['class'] ) ) {
$link = 'http://docs.woocommerce.com/wc-apidocs/source-class-' . $details['class'] . '.html#' . $details['line'];
} elseif ( ! empty( $details['function'] ) ) {
$link = 'http://docs.woocommerce.com/wc-apidocs/source-function-' . $details['function'] . '.html#' . $details['line'];
} else {
$link = 'https://github.com/woocommerce/woocommerce/search?utf8=%E2%9C%93&q=' . $hook;
}
return '<a href="' . $link . '">' . $hook . '</a>';
}
public static function process_hooks() {
self::$files_to_scan = array();
self::$files_to_scan['Template Files'] = self::get_files( '*.php', GLOB_MARK, '../templates/' );
self::$files_to_scan['Template Functions'] = array( '../includes/wc-template-functions.php', '../includes/wc-template-hooks.php' );
self::$files_to_scan['Shortcodes'] = self::get_files( '*.php', GLOB_MARK, '../includes/shortcodes/' );
self::$files_to_scan['Widgets'] = self::get_files( '*.php', GLOB_MARK, '../includes/widgets/' );
self::$files_to_scan['Data Stores'] = self::get_files( '*.php', GLOB_MARK, '../includes/data-stores' );
self::$files_to_scan['Core Classes'] = array_merge(
self::get_files( '*.php', GLOB_MARK, '../includes/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/abstracts/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/customizer/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/emails/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/export/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/gateways/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/import/' ),
self::get_files( '*.php', GLOB_MARK, '../includes/shipping/' )
);
self::$files_to_scan = array_filter( self::$files_to_scan );
$scanned = array();
ob_start();
$index = array();
foreach ( self::$files_to_scan as $heading => $files ) {
$index[] = '<a href="#hooks-' . str_replace( ' ', '-', strtolower( $heading ) ) . '">' . $heading . '</a>';
}
echo '<div id="content">';
echo '<h1>Action and Filter Hook Reference</h1>';
echo '<div class="description">
<p>This is simply a list of action and filter hooks found within WooCommerce files. View the source to see supported params and usage.</p>
<p>' . implode( ', ', $index ) . '</p>
</div>';
foreach ( self::$files_to_scan as $heading => $files ) {
self::$custom_hooks_found = array();
foreach ( $files as $f ) {
self::$current_file = basename( $f );
$tokens = token_get_all( file_get_contents( $f ) );
$token_type = false;
$current_class = '';
$current_function = '';
if ( in_array( self::$current_file, $scanned ) ) {
continue;
}
$scanned[] = self::$current_file;
foreach ( $tokens as $index => $token ) {
if ( is_array( $token ) ) {
$trimmed_token_1 = trim( $token[1] );
if ( T_CLASS == $token[0] ) {
$token_type = 'class';
} elseif ( T_FUNCTION == $token[0] ) {
$token_type = 'function';
} elseif ( 'do_action' === $token[1] ) {
$token_type = 'action';
} elseif ( 'apply_filters' === $token[1] ) {
$token_type = 'filter';
} elseif ( $token_type && ! empty( $trimmed_token_1 ) ) {
switch ( $token_type ) {
case 'class' :
$current_class = $token[1];
break;
case 'function' :
$current_function = $token[1];
break;
case 'filter' :
case 'action' :
$hook = trim( $token[1], "'" );
$hook = str_replace( '_FUNCTION_', strtoupper( $current_function ), $hook );
$hook = str_replace( '_CLASS_', strtoupper( $current_class ), $hook );
$hook = str_replace( '$this', strtoupper( $current_class ), $hook );
$hook = str_replace( array( '.', '{', '}', '"', "'", ' ', ')', '(' ), '', $hook );
$loop = 0;
// Keep adding to hook until we find a comma or colon
while ( 1 ) {
$loop ++;
$prev_hook = is_string( $tokens[ $index + $loop - 1 ] ) ? $tokens[ $index + $loop - 1 ] : $tokens[ $index + $loop - 1 ][1];
$next_hook = is_string( $tokens[ $index + $loop ] ) ? $tokens[ $index + $loop ] : $tokens[ $index + $loop ][1];
if ( in_array( $next_hook, array( '.', '{', '}', '"', "'", ' ', ')', '(' ) ) ) {
continue;
}
if ( in_array( $next_hook, array( ',', ';' ) ) ) {
break;
}
$hook_first = substr( $next_hook, 0, 1 );
$hook_last = substr( $next_hook, -1, 1 );
if ( '{' === $hook_first || '}' === $hook_last || '$' === $hook_first || ')' === $hook_last || '>' === substr( $prev_hook, -1, 1 ) ) {
$next_hook = strtoupper( $next_hook );
}
$next_hook = str_replace( array( '.', '{', '}', '"', "'", ' ', ')', '(' ), '', $next_hook );
$hook .= $next_hook;
}
if ( isset( self::$custom_hooks_found[ $hook ] ) ) {
self::$custom_hooks_found[ $hook ]['file'][] = self::$current_file;
} else {
self::$custom_hooks_found[ $hook ] = array(
'line' => $token[2],
'class' => $current_class,
'function' => $current_function,
'file' => array( self::$current_file ),
'type' => $token_type,
);
}
break;
}
$token_type = false;
}
}
}
}
foreach ( self::$custom_hooks_found as $hook => $details ) {
if ( ! strstr( $hook, 'woocommerce' ) && ! strstr( $hook, 'product' ) && ! strstr( $hook, 'wc_' ) ) {
//unset( self::$custom_hooks_found[ $hook ] );
}
}
ksort( self::$custom_hooks_found );
if ( ! empty( self::$custom_hooks_found ) ) {
echo '<div class="panel panel-default"><div class="panel-heading"><h2 id="hooks-' . str_replace( ' ', '-', strtolower( $heading ) ) . '">' . $heading . '</h2></div>';
echo '<table class="summary table table-bordered table-striped"><thead><tr><th>Hook</th><th>Type</th><th>File(s)</th></tr></thead><tbody>';
foreach ( self::$custom_hooks_found as $hook => $details ) {
echo '<tr>
<td>' . self::get_hook_link( $hook, $details ) . '</td>
<td>' . $details['type'] . '</td>
<td>' . implode( ', ', array_unique( $details['file'] ) ) . '</td>
</tr>' . "\n";
}
echo '</tbody></table></div>';
}
}
echo '</div><div id="footer">';
$html = file_get_contents( '../wc-apidocs/tree.html' );
$header = explode( '<div id="content">', $html );
$header = str_replace( '<li class="active">', '<li>', current( $header ) );
$header = str_replace( '<li class="hooks">', '<li class="active">', $header );
$header = str_replace( 'Tree | ', 'Hook Reference | ', $header );
$footer = explode( '<div id="footer">', $html );
file_put_contents( '../wc-apidocs/hook-docs.html', $header . ob_get_clean() . end( $footer ) );
echo "Hook docs generated :)\n";
}
}
WC_HookFinder::process_hooks();

View File

@ -1,13 +0,0 @@
{layout '@layout.latte'}
{var $robots = false}
{block title}Page not found{/block}
{block content}
<div id="content">
<h1>{include title}</h1>
<p>The requested page could not be found.</p>
<p>You have probably clicked on a link that is outdated and points to a page that does not exist any more or you have made an typing error in the address.</p>
<p>To continue please try to find requested page in the menu,{if $config->tree} take a look at <a href="tree.html">the tree view</a> of the whole project{/if} or use search field on the top.</p>
</div>
{/block}

View File

@ -1,60 +0,0 @@
{define elements}
<tr n:foreach="$elements as $element">
<td class="name"><a href="{$element|elementUrl}" n:class="$element->deprecated ? deprecated, !$element->valid ? invalid">{if $namespace}{$element->shortName}{else}{$element->name}{/if}</a></td>
<td>{$element|shortDescription|noescape}</td>
</tr>
{/define}
{if $classes}
<div class="panel panel-default">
<div class="panel-heading"><h2>Classes summary</h2></div>
<table class="summary table table-bordered table-striped" id="classes">
{include elements, elements => $classes}
</table>
</div>
{/if}
{if $interfaces}
<div class="panel panel-default">
<div class="panel-heading"><h2>Interfaces summary</h2></div>
<table class="summary table table-bordered table-striped" id="interfaces">
{include elements, elements => $interfaces}
</table>
</div>
{/if}
{if $traits}
<div class="panel panel-default">
<div class="panel-heading"><h2>Traits summary</h2></div>
<table class="summary table table-bordered table-striped" id="traits">
{include elements, elements => $traits}
</table>
</div>
{/if}
{if $exceptions}
<div class="panel panel-default">
<div class="panel-heading"><h2>Exceptions summary</h2></div>
<table class="summary table table-bordered table-striped" id="exceptions">
{include elements, elements => $exceptions}
</table>
</div>
{/if}
{if $constants}
<div class="panel panel-default">
<div class="panel-heading"><h2>Constants summary</h2></div>
<table class="summary table table-bordered table-striped" id="constants">
{include elements, elements => $constants}
</table>
</div>
{/if}
{if $functions}
<div class="panel panel-default">
<div class="panel-heading"><h2>Functions summary</h2></div>
<table class="summary table table-bordered table-striped" id="functions">
{include elements, elements => $functions}
</table>
</div>
{/if}

View File

@ -1,185 +0,0 @@
{default $robots = true}
{default $active = ''}
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="robots" content="noindex" n:if="!$robots">
<title>{include title}{if 'overview' !== $active && $config->title} | {$config->title}{/if}</title>
<link rel="stylesheet" href="{='resources/bootstrap.min.css'|staticFile}">
<link rel="stylesheet" href="{='resources/style.css'|staticFile}">
<link n:if="$config->googleCseId" rel="search" type="application/opensearchdescription+xml" title="{$config->title}" href="{$config->baseUrl}/opensearch.xml">
<script n:if="$config->googleAnalytics">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', {$config->googleAnalytics}]);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</head>
<body>
<nav id="navigation" class="navbar navbar-default navbar-fixed-top">
<div class="container-fluid">
<div class="navbar-header">
<a href="index.html" class="navbar-brand">{if $config->title}{$config->title}{else}Overview{/if}</a>
</div>
<div class="collapse navbar-collapse">
<form{if $config->googleCseId} action="http://www.google.com/cse"{/if} id="search" class="navbar-form navbar-left" role="search">
<input type="hidden" name="cx" value="{$config->googleCseId}">
<input type="hidden" name="ie" value="UTF-8">
<div class="form-group">
<input type="text" name="q" class="search-query form-control" placeholder="Search"{if 'overview' === $active} autofocus{/if}>
</div>
</form>
<ul class="nav navbar-nav">
<li n:class="'package' === $active ? active" n:if="$packages">
<a n:tag-if="'package' !== $active && $package" href="{$package|packageUrl}" title="Summary of {$package}"><span>Package</span></a>
</li>
<li n:class="'namespace' === $active ? active" n:if="$namespaces">
<a n:tag-if="'namespace' !== $active && $namespace" href="{$namespace|namespaceUrl}" title="Summary of {$namespace}"><span>Namespace</span></a>
</li>
<li n:class="'class' === $active ? active" n:if="!$function && !$constant">
<a n:tag-if="'class' !== $active && $class" href="{$class|classUrl}" title="Summary of {$class->name}"><span>Class</span></a>
</li>
<li n:class="'function' === $active ? active" n:if="$function">
<a n:tag-if="'function' !== $active" href="{$function|functionUrl}" title="Summary of {$function->name}"><span>Function</span></a>
</li>
<li n:class="'constant' === $active ? active" n:if="$constant">
<a n:tag-if="'constant' !== $active" href="{$constant|constantUrl}" title="Summary of {$constant->name}"><span>Constant</span></a>
</li>
<li class="divider-vertical" n:if="$config->tree || $config->deprecated || $config->todo"></li>
<li n:class="'tree' === $active ? active" n:if="$config->tree">
<a n:tag-if="'tree' !== $active" href="tree.html" title="Tree view of classes, interfaces, traits and exceptions"><span>Tree</span></a>
</li>
{foreach $annotationGroups as $annotation}
<li n:class="$active === 'annotation-group-' . $annotation ? active">
<a n:tag-if="$active !== 'annotation-group-' . $annotation" href="annotation-group-{$annotation}.html" title="List of elements with {$annotation} annotation">
<span>{$annotation|firstUpper}</span>
</a>
</li>
{/foreach}
<li class="divider-vertical"></li>
<li class="hooks">
<a href="hook-docs.html" title="Hooks"><span>Hook Reference</span></a>
</li>
<li class="woocommerce-com-docs">
<a href="https://docs.woocommerce.com/"><span>WooCommerce Docs</span></a>
</li>
<li class="api">
<a href="https://woocommerce.github.io/woocommerce-rest-api-docs/"><span>REST API Docs</span></a>
</li>
<li class="divider-vertical" n:if="$config->download"></li>
<li n:if="$config->download">
<a href="{$archive}" title="Download documentation as ZIP archive"><span>Download</span></a>
</li>
</ul>
</div>
</div>
</nav>
<div id="left">
<div id="menu">
{define group}
<ul>
{foreach $groups as $group}
{var $nextLevel = substr_count($iterator->nextValue, '\\') > substr_count($group, '\\')}
<li n:class="$actualGroup === $group || 0 === strpos($actualGroup, $group . '\\') ? active, $config->main && 0 === strpos($group, $config->main) ? main">
<a href="{if $groupBy === 'package'}{$group|packageUrl}{else}{$group|namespaceUrl}{/if}">
{$group|subgroupName}<span n:tag-if="$nextLevel"></span>
</a>
{if $nextLevel}
<ul>
{else}
</li>
{if substr_count($iterator->nextValue, '\\') < substr_count($group, '\\')}
{='</ul></li>'|repeat:substr_count($group, '\\') - substr_count($iterator->nextValue, '\\')|noescape}
{/if}
{/if}
{/foreach}
</ul>
{/define}
<div id="groups">
{if $namespaces}
<h3>Namespaces</h3>
{include group, groups => $namespaces, actualGroup => $namespace, groupBy => 'namespace'}
{elseif $packages}
<h3>Packages</h3>
{include group, groups => $packages, actualGroup => $package, groupBy => 'package'}
{/if}
</div>
{define elements}
<ul>
<li n:foreach="$elements as $element" n:class="$activeElement === $element ? active"><a n:class="$element->deprecated ? deprecated, !$element->valid ? invalid" href="{$element|elementUrl}">{if $namespace}{$element->shortName}{else}{$element->name}{/if}</a></li>
</ul>
{/define}
<div id="elements">
{if $classes}
<h3>Classes</h3>
{include elements, elements => $classes, activeElement => $class}
{/if}
{if $interfaces}
<h3>Interfaces</h3>
{include elements, elements => $interfaces, activeElement => $class}
{/if}
{if $traits}
<h3>Traits</h3>
{include elements, elements => $traits, activeElement => $class}
{/if}
{if $exceptions}
<h3>Exceptions</h3>
{include elements, elements => $exceptions, activeElement => $class}
{/if}
{if $constants}
<h3>Constants</h3>
{include elements, elements => $constants, activeElement => $constant}
{/if}
{if $functions}
<h3>Functions</h3>
{include elements, elements => $functions, activeElement => $function}
{/if}
</div>
</div>
</div>
<div id="splitter"></div>
<div id="right">
<div id="rightInner">
{include content}
</div>
<div id="footer">
{$config->title} API documentation generated by <a href="http://apigen.org">ApiGen</a>
</div>
</div>
<script src="{='resources/combined.js'|staticFile}"></script>
<script src="{='elementlist.js'|staticFile}"></script>
</body>
</html>

View File

@ -1,149 +0,0 @@
{layout '@layout.latte'}
{var $active = 'annotation-group-' . $annotation}
{block title}{$annotation|firstUpper}{/block}
{block content}
<div id="content">
<h1>{include title}</h1>
{if $hasElements}
{if $annotationClasses}
<div class="panel panel-default">
<div class="panel-heading"><h2>Classes summary</h2></div>
<table class="summary table table-bordered table-striped" id="classes">
{include classes, items => $annotationClasses}
</table>
</div>
{/if}
{if $annotationInterfaces}
<div class="panel panel-default">
<div class="panel-heading"><h2>Interfaces summary</h2></div>
<table class="summary table table-bordered table-striped" id="interfaces">
{include classes, items => $annotationInterfaces}
</table>
</div>
{/if}
{if $annotationTraits}
<div class="panel panel-default">
<div class="panel-heading"><h2>Traits summary</h2></div>
<table class="summary table table-bordered table-striped" id="traits">
{include classes, items => $annotationTraits}
</table>
</div>
{/if}
{if $annotationExceptions}
<div class="panel panel-default">
<div class="panel-heading"><h2>Exceptions summary</h2></div>
<table class="summary table table-bordered table-striped" id="exceptions">
{include classes, items => $annotationExceptions}
</table>
</div>
{/if}
{if $annotationMethods}
<div class="panel panel-default">
<div class="panel-heading"><h2>Methods summary</h2></div>
<table class="summary table table-bordered table-striped" id="methods">
<tr n:foreach="$annotationMethods as $method">
<td class="name"><a href="{$method->declaringClassName|classUrl}">{$method->declaringClassName}</a></td>
<td class="name"><code><a href="{$method|methodUrl}">{$method->name}()</a></code></td>
<td>
{if $method->hasAnnotation($annotation)}
{foreach $method->annotations[$annotation] as $description}
{if $description}
{$description|annotation:$annotation:$method|noescape}<br>
{/if}
{/foreach}
{/if}
</td>
</tr>
</table>
</div>
{/if}
{if $annotationConstants}
<div class="panel panel-default">
<div class="panel-heading"><h2>Constants summary</h2></div>
<table class="summary table table-bordered table-striped" id="constants">
<tr n:foreach="$annotationConstants as $constant">
{if $constant->declaringClassName}
<td class="name"><a href="{$constant->declaringClassName|classUrl}">{$constant->declaringClassName}</a></td>
<td class="name"><code><a href="{$constant|constantUrl}"><b>{$constant->name}</b></a></code></td>
{else}
<td class="name" n:if="$namespaces || $classes || $interfaces || $traits || $exceptions"><a n:if="$constant->namespaceName" href="{$constant->namespaceName|namespaceUrl}">{$constant->namespaceName}</a></td>
<td n:class="name"><code><a href="{$constant|constantUrl}"><b>{$constant->shortName}</b></a></code></td>
{/if}
<td>
{foreach $constant->annotations[$annotation] as $description}
{if $description}
{$description|annotation:$annotation:$constant|noescape}<br>
{/if}
{/foreach}
</td>
</tr>
</table>
</div>
{/if}
{if $annotationProperties}
<div class="panel panel-default">
<div class="panel-heading"><h2>Properties summary</h2></div>
<table class="summary table table-bordered table-striped" id="properties">
<tr n:foreach="$annotationProperties as $property">
<td class="name"><a href="{$property->declaringClassName|classUrl}">{$property->declaringClassName}</a></td>
<td class="name"><a href="{$property|propertyUrl}"><var>${$property->name}</var></a></td>
<td>
{foreach $property->annotations[$annotation] as $description}
{if $description}
{$description|annotation:$annotation:$property|noescape}<br>
{/if}
{/foreach}
</td>
</tr>
</table>
</div>
{/if}
{if $annotationFunctions}
<div class="panel panel-default">
<div class="panel-heading"><h2>Functions summary</h2></div>
<table class="summary table table-bordered table-striped" id="functions">
<tr n:foreach="$annotationFunctions as $function">
<td class="name" n:if="$namespaces"><a n:if="$function->namespaceName" href="{$function->namespaceName|namespaceUrl}">{$function->namespaceName}</a></td>
<td class="name"><code><a href="{$function|functionUrl}">{$function->shortName}</a></code></td>
<td>
{foreach $function->annotations[$annotation] as $description}
{if $description}
{$description|annotation:$annotation:$function|noescape}<br>
{/if}
{/foreach}
</td>
</tr>
</table>
</div>
{/if}
{else}
<p>No elements with <code>@{$annotation}</code> annotation found.</p>
{/if}
</div>
{/block}
{define classes}
<tr n:foreach="$items as $class">
<td class="name"><a href="{$class|classUrl}">{$class->name}</a></td>
<td>
{foreach $class->annotations[$annotation] as $description}
{if $description}
{$description|annotation:$annotation:$class|noescape}<br>
{/if}
{/foreach}
</td>
</tr>
{/define}

View File

@ -1,462 +0,0 @@
{layout '@layout.latte'}
{var $active = 'class'}
{block title}{if $class->deprecated}Deprecated {/if}{if $class->interface}Interface{elseif $class->trait}Trait{else}Class{/if} {$class->name}{/block}
{block content}
<div id="content" class="class">
<h1 n:class="$class->deprecated ? deprecated">{if $class->interface}Interface{elseif $class->trait}Trait{else}Class{/if} {$class->shortName}</h1>
{if $class->valid}
<div class="description" n:if="$template->longDescription($class)">
{$class|longDescription|noescape}
</div>
<dl class="tree well" n:if="$class->parentClass || $class->ownInterfaces || $class->ownTraits">
<dd n:foreach="$tree as $item" style="padding-left:{($iterator->counter - 1) * 30}px">
<img src="resources/inherit.png" alt="Extended by" n:if="$iterator->counter > 1">
{if $item->documented}
<a href="{$item|classUrl}" n:tag-if="!$iterator->last">{last}<b>{/last}<span n:class="$item->deprecated ? deprecated, !$item->valid ? invalid">{$item->name}</span>{last}</b>{/last}</a>
{else}{$item->name}{/if}
{var $itemOwnInterfaces = $item->ownInterfaces}
{if $itemOwnInterfaces} implements {foreach $itemOwnInterfaces as $interface}
<a href="{$interface|classUrl}" n:tag-if="$interface->documented"><span n:class="$interface->deprecated ? deprecated, !$interface->valid ? invalid">{$interface->name}</span></a>{sep}, {/sep}
{/foreach}{/if}
{var $itemOwnTraits = $item->ownTraits}
{if $itemOwnTraits} uses {foreach $itemOwnTraits as $trait}
{if is_string($trait)}
{$trait} (not available)
{else}
<a href="{$trait|classUrl}" n:tag-if="$trait->documented"><span n:class="$trait->deprecated ? deprecated, !$trait->valid ? invalid">{$trait->name}</span></a>{sep}, {/sep}
{/}
{/foreach}{/if}
</dd>
</dl>
{define children}
<p class="elementList">
{foreach $children as $child}
<code><a href="{$child|classUrl}" n:tag-if="$child->documented"><span n:tag-if="$child->deprecated" class="deprecated">{$child->name}</span></a></code>{sep}, {/sep}
{/foreach}
</p>
{/define}
<div n:if="$directSubClasses">
<h3>Direct known subclasses</h3>
{include children, children => $directSubClasses}
</div>
<div n:if="$indirectSubClasses">
<h3>Indirect known subclasses</h3>
{include children, children => $indirectSubClasses}
</div>
<div n:if="$directImplementers">
<h3>Direct known implementers</h3>
{include children, children => $directImplementers}
</div>
<div n:if="$indirectImplementers">
<h3>Indirect known implementers</h3>
{include children, children => $indirectImplementers}
</div>
<div n:if="$directUsers">
<h3>Direct Known Users</h3>
{include children, children => $directUsers}
</div>
<div n:if="$indirectUsers">
<h3>Indirect Known Users</h3>
{include children, children => $indirectUsers}
</div>
<div class="alert alert-info">
{if !$class->interface && !$class->trait && ($class->abstract || $class->final)}<b>{if $class->abstract}Abstract{else}Final{/if}</b><br>{/if}
{if $class->internal}<b>PHP Extension:</b> <a href="{$class->extension|manualUrl}" title="Go to PHP documentation">{$class->extension->name|firstUpper}</a><br>{/if}
{if $class->inNamespace()}<b>Namespace:</b> {$class->namespaceName|namespaceLinks|noescape}<br>{/if}
{if $class->inPackage()}<b>Package:</b> {$class->packageName|packageLinks|noescape}<br>{/if}
{foreach $template->annotationSort($template->annotationFilter($class->annotations)) as $annotation => $values}
{foreach $values as $value}
<b>{$annotation|annotationBeautify}{if $value}:{/if}</b>
{$value|annotation:$annotation:$class|noescape}<br>
{/foreach}
{/foreach}
{if $class->internal}
<b>Documented at</b> <a href="{$class|manualUrl}" title="Go to PHP documentation">php.net</a>
{else}
<b>Located at</b> <a n:tag-if="$config->sourceCode" href="{$class|sourceUrl}" title="Go to source code">{$class->fileName|relativePath}</a>
{/if}
<br>
</div>
{var $ownMethods = $class->ownMethods}
{var $inheritedMethods = $class->inheritedMethods}
{var $usedMethods = $class->usedMethods}
{var $ownMagicMethods = $class->ownMagicMethods}
{var $inheritedMagicMethods = $class->inheritedMagicMethods}
{var $usedMagicMethods = $class->usedMagicMethods}
{if $ownMethods || $inheritedMethods || $usedMethods || $ownMagicMethods || $usedMagicMethods}
{define method}
<tr data-order="{$method->name}" id="{if $method->magic}m{/if}_{$method->name}">
{var $annotations = $method->annotations}
<td class="attributes"><code>
{if !$class->interface && $method->abstract}abstract{elseif $method->final}final{/if} {if $method->protected}protected{elseif $method->private}private{else}public{/if} {if $method->static}static{/if}
{ifset $annotations['return']}{$annotations['return'][0]|typeLinks:$method|noescape}{/ifset}
{if $method->returnsReference()}&amp;{/if}
</code>
</td>
<td class="name"><div>
<a class="anchor" href="#{if $method->magic}m{/if}_{$method->name}">#</a>
<code n:class="$method->deprecated ? deprecated">{block|strip}
{if $class->internal}
<a href="{$method|manualUrl}" title="Go to PHP documentation">{$method->name}</a>(
{else}
<a n:tag-if="$config->sourceCode" href="{$method|sourceUrl}" title="Go to source code">{$method->name}</a>(
{/if}
{foreach $method->parameters as $parameter}
<span>{$parameter->typeHint|typeLinks:$method|noescape}
<var>{if $parameter->passedByReference}&amp; {/if}${$parameter->name}</var>{if $parameter->defaultValueAvailable} = {$parameter->defaultValueDefinition|highlightPHP:$class|noescape}{elseif $parameter->unlimited},…{/if}</span>{sep}, {/sep}
{/foreach}
){/block}</code>
{if $config->template['options']['elementDetailsCollapsed']}
<div class="description short">
{$method|shortDescription:true|noescape}
</div>
{/if}
<div n:class="description, detailed, $config->template['options']['elementDetailsCollapsed'] ? hidden">
{$method|longDescription|noescape}
{if !$class->deprecated && $method->deprecated}
<h4>Deprecated</h4>
{ifset $annotations['deprecated']}
<div class="list">
{foreach $annotations['deprecated'] as $description}
{if $description}
{$description|annotation:'deprecated':$method|noescape}<br>
{/if}
{/foreach}
</div>
{/ifset}
{/if}
{if $method->parameters && isset($annotations['param'])}
<h4>Parameters</h4>
<div class="list"><dl>
{foreach $method->parameters as $parameter}
<dt><var>${$parameter->name}</var>{if $parameter->unlimited},…{/if}</dt>
<dd>{$parameter->description|description:$method|noescape}</dd>
{/foreach}
</dl></div>
{/if}
{if isset($annotations['return']) && 'void' !== $annotations['return'][0]}
<h4>Returns</h4>
<div class="list">
{foreach $annotations['return'] as $description}
{$description|annotation:'return':$method|noescape}{sep}<br>{/}
{/foreach}
</div>
{/if}
{ifset $annotations['throws']}
<h4>Throws</h4>
<div class="list">
{foreach $annotations['throws'] as $description}
{$description|annotation:'throws':$method|noescape}{sep}<br>{/}
{/foreach}
</div>
{/ifset}
{foreach $template->annotationSort($template->annotationFilter($annotations, array('deprecated', 'param', 'return', 'throws'))) as $annotation => $descriptions}
<h4>{$annotation|annotationBeautify}</h4>
<div class="list">
{foreach $descriptions as $description}
{if $description}
{$description|annotation:$annotation:$method|noescape}<br>
{/if}
{/foreach}
</div>
{/foreach}
{var $overriddenMethod = $method->overriddenMethod}
{if $overriddenMethod}
<h4>Overrides</h4>
<div class="list"><code><a n:tag-if="$template->getClass($overriddenMethod->declaringClassName)" href="{$overriddenMethod|methodUrl}">{$overriddenMethod->declaringClassName}::{$overriddenMethod->name}</a></code></div>
{/if}
{var $implementedMethod = $method->implementedMethod}
{if $implementedMethod}
<h4>Implementation of</h4>
<div class="list"><code><a n:tag-if="$template->getClass($implementedMethod->declaringClassName)" href="{$implementedMethod|methodUrl}">{$implementedMethod->prettyName}</a></code></div>
{/if}
</div>
</div></td>
</tr>
{/define}
<div class="panel panel-default">
<div class="panel-heading"><h2>Methods summary</h2></div>
<table class="summary table table-bordered table-striped methods" id="methods" n:if="$ownMethods">
{foreach $ownMethods as $method}
{include method, method => $method}
{/foreach}
</table>
</div>
{foreach $inheritedMethods as $parentName => $methods}
<div class="panel panel-default">
<div class="panel-heading"><h3>Methods inherited from <a href="{$parentName|classUrl}#methods" n:tag-if="$template->getClass($parentName)">{$parentName}</a></h3></div>
<p class="elementList">
{foreach $methods as $method}
<code><a href="{$method|methodUrl}" n:tag-if="$template->getClass($parentName)"><span n:tag-if="$method->deprecated" class="deprecated">{$method->name}()</span></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{foreach $usedMethods as $traitName => $methods}
<div class="panel panel-default">
<div class="panel-heading"><h3>Methods used from <a href="{$traitName|classUrl}#methods" n:tag-if="$template->getClass($traitName)">{$traitName}</a></h3></div>
<p class="elementList">
{foreach $methods as $data}
<code><a href="{$data['method']|methodUrl:$data['method']->declaringTrait}" n:tag-if="$template->getClass($traitName)"><span n:tag-if="$data['method']->deprecated" class="deprecated">{$data['method']->name}()</span></a>{if $data['aliases']}(as {foreach $data['aliases'] as $alias}<span n:tag-if="$data['method']->deprecated" class="deprecated">{$alias->name}()</span>{sep}, {/sep}{/foreach}){/if}</code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{if $ownMagicMethods}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic methods summary</h3></div>
<table class="summary table table-bordered table-striped methods" id="magicMethods" n:if="$ownMagicMethods">
{foreach $ownMagicMethods as $method}
{include method, method => $method}
{/foreach}
</table>
</div>
{/if}
{foreach $inheritedMagicMethods as $parentName => $methods}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic methods inherited from <a href="{$parentName|classUrl}#methods" n:tag-if="$template->getClass($parentName)">{$parentName}</a></h3></div>
<p class="elementList">
{foreach $methods as $method}
<code><a href="{$method|methodUrl}" n:tag-if="$template->getClass($parentName)"><span n:tag-if="$method->deprecated" class="deprecated">{$method->name}()</span></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{foreach $usedMagicMethods as $traitName => $methods}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic methods used from <a href="{$traitName|classUrl}#methods" n:tag-if="$template->getClass($traitName)">{$traitName}</a></h3></div>
<p class="elementList">
{foreach $methods as $data}
<code><a href="{$data['method']|methodUrl:$data['method']->declaringTrait}" n:tag-if="$template->getClass($traitName)"><span n:tag-if="$data['method']->deprecated" class="deprecated">{$data['method']->name}()</span></a>{if $data['aliases']}(as {foreach $data['aliases'] as $alias}<span n:tag-if="$data['method']->deprecated" class="deprecated">{$alias->name}()</span>{sep}, {/sep}{/foreach}){/if}</code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{/if}
{var $ownConstants = $class->ownConstants}
{var $inheritedConstants = $class->inheritedConstants}
{if $ownConstants || $inheritedConstants}
<div class="panel panel-default">
<div class="panel-heading"><h2>Constants summary</h2></div>
<table class="summary table table-bordered table-striped constants" id="constants" n:if="$ownConstants">
<tr n:foreach="$ownConstants as $constant" data-order="{$constant->name}" id="{$constant->name}">
{var $annotations = $constant->annotations}
<td class="attributes"><code>{$constant->typeHint|typeLinks:$constant|noescape}</code></td>
<td class="name">
<code>
{if $class->internal}
<a href="{$constant|manualUrl}" title="Go to PHP documentation"><b>{$constant->name}</b></a>
{else}
<a n:tag-if="$config->sourceCode" href="{$constant|sourceUrl}" title="Go to source code"><b>{$constant->name}</b></a>
{/if}
</code>
<div n:if="$config->template['options']['elementDetailsCollapsed']" class="description short">
{$constant|shortDescription:true|noescape}
</div>
<div n:class="description, detailed, $config->template['options']['elementDetailsCollapsed'] ? hidden">
{$constant|longDescription|noescape}
{foreach $template->annotationSort($template->annotationFilter($annotations, array('var'))) as $annotation => $descriptions}
<h4>{$annotation|annotationBeautify}</h4>
<div class="list">
{foreach $descriptions as $description}
{if $description}
{$description|annotation:$annotation:$constant|noescape}<br>
{/if}
{/foreach}
</div>
{/foreach}
</div>
</td>
<td class="value">
<div>
<a href="#{$constant->name}" class="anchor">#</a>
<code>{$constant->valueDefinition|highlightValue:$class|noescape}</code>
</div>
</td>
</tr>
</table>
</div>
{foreach $inheritedConstants as $parentName => $constants}
<div class="panel panel-default">
<div class="panel-heading"><h3>Constants inherited from <a href="{$parentName|classUrl}#constants" n:tag-if="$template->getClass($parentName)">{$parentName}</a></h3></div>
<p class="elementList">
{foreach $constants as $constant}
<code><a href="{$constant|constantUrl}" n:tag-if="$template->getClass($parentName)"><b><span n:tag-if="$constant->deprecated" class"deprecated">{$constant->name}</span></b></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{/if}
{var $ownProperties = $class->ownProperties}
{var $inheritedProperties = $class->inheritedProperties}
{var $usedProperties = $class->usedProperties}
{var $ownMagicProperties = $class->ownMagicProperties}
{var $inheritedMagicProperties = $class->inheritedMagicProperties}
{var $usedMagicProperties = $class->usedMagicProperties}
{if $ownProperties || $inheritedProperties || $usedProperties || $ownMagicProperties || $inheritedMagicProperties || $usedMagicProperties}
{define property}
<tr data-order="{$property->name}" id="{if $property->magic}m{/if}${$property->name}">
<td class="attributes"><code>
{if $property->protected}protected{elseif $property->private}private{else}public{/if} {if $property->static}static{/if} {if $property->readOnly}read-only{elseif $property->writeOnly}write-only{/if}
{$property->typeHint|typeLinks:$property|noescape}
</code></td>
<td class="name">
{if $class->internal}
<a href="{$property|manualUrl}" title="Go to PHP documentation"><var>${$property->name}</var></a>
{else}
<a n:tag-if="$config->sourceCode" href="{$property|sourceUrl}" title="Go to source code"><var>${$property->name}</var></a>
{/if}
<div n:if="$config->template['options']['elementDetailsCollapsed']" class="description short">
{$property|shortDescription:true|noescape}
</div>
<div n:class="description, detailed, $config->template['options']['elementDetailsCollapsed'] ? hidden">
{$property|longDescription|noescape}
{foreach $template->annotationSort($template->annotationFilter($property->annotations, array('var'))) as $annotation => $descriptions}
<h4>{$annotation|annotationBeautify}</h4>
<div class="list">
{foreach $descriptions as $description}
{if $description}
{$description|annotation:$annotation:$property|noescape}<br>
{/if}
{/foreach}
</div>
{/foreach}
</div>
</td>
<td n:if="!$property->magic" class="value">
<div>
<a href="#{if $property->magic}m{/if}${$property->name}" class="anchor">#</a>
<code>{$property->defaultValueDefinition|highlightValue:$class|noescape}</code>
</div>
</td>
</tr>
{/define}
<div class="panel panel-default">
<div class="panel-heading"><h2>Properties summary</h2></div>
<table class="summary table table-bordered table-striped properties" id="properties" n:if="$ownProperties">
{foreach $ownProperties as $property}
{include property, property => $property}
{/foreach}
</table>
</div>
{foreach $inheritedProperties as $parentName => $properties}
<div class="panel panel-default">
<div class="panel-heading"><h3>Properties inherited from <a href="{$parentName|classUrl}#properties" n:tag-if="$template->getClass($parentName)">{$parentName}</a></h3></div>
<p class="elementList">
{foreach $properties as $property}
<code><a href="{$property|propertyUrl}" n:tag-if="$template->getClass($parentName)"><var><span n:tag-if="$property->deprecated" class="deprecated">${$property->name}</span></var></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{foreach $usedProperties as $traitName => $properties}
<div class="panel panel-default">
<div class="panel-heading"><h3>Properties used from <a href="{$traitName|classUrl}#properties" n:tag-if="$template->getClass($traitName)">{$traitName}</a></h3></div>
<p class="elementList">
{foreach $properties as $property}
<code><a href="{$property|propertyUrl:$property->declaringTrait}" n:tag-if="$template->getClass($traitName)"><var><span n:tag-if="$property->deprecated" class="deprecated">${$property->name}</span></var></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{if $ownMagicProperties}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic properties</h3></div>
<table class="summary table table-bordered table-striped properties" id="magicProperties">
{foreach $ownMagicProperties as $property}
{include property, property => $property}
{/foreach}
</table>
</div>
{/if}
{foreach $inheritedMagicProperties as $parentName => $properties}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic properties inherited from <a href="{$parentName|classUrl}#properties" n:tag-if="$template->getClass($parentName)">{$parentName}</a></h3></div>
<p class="elementList">
{foreach $properties as $property}
<code><a href="{$property|propertyUrl}" n:tag-if="$template->getClass($parentName)"><var><span n:tag-if="$property->deprecated" class="deprecated">${$property->name}</span></var></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{foreach $usedMagicProperties as $traitName => $properties}
<div class="panel panel-default">
<div class="panel-heading"><h3>Magic properties used from <a href="{$traitName|classUrl}#properties" n:tag-if="$template->getClass($traitName)">{$traitName}</a></h3></div>
<p class="elementList">
{foreach $properties as $property}
<code><a href="{$property|propertyUrl:$property->declaringTrait}" n:tag-if="$template->getClass($traitName)"><var><span n:tag-if="$property->deprecated" class="deprecated">${$property->name}</span></var></a></code>{sep}, {/sep}
{/foreach}
</p>
</div>
{/foreach}
{/if}
{else}
<div class="alert alert-error">
<p>
Documentation of this class could not be generated.
</p>
<p>
Class was originally declared in {$class->fileName|relativePath} and is invalid because of:
</p>
<ul>
<li n:foreach="$class->reasons as $reason">Class was redeclared in {$reason->getSender()->getFileName()|relativePath}.</li>
</ul>
</div>
{/if}
</div>
{/block}

View File

@ -1,10 +0,0 @@
{contentType javascript}
var ApiGen = ApiGen || {};
ApiGen.config = {$config->template};
{var $scripts = ['jquery.min.js', 'jquery.cookie.js', 'jquery.sprintf.js', 'jquery.autocomplete.js', 'jquery.sortElements.js', 'main.js']}
{foreach $scripts as $script}
{file_get_contents("$basePath/js/$script")|noescape}
{/foreach}

View File

@ -1 +0,0 @@
name: "Twitter Bootstrap theme"

View File

@ -1,60 +0,0 @@
{layout '@layout.latte'}
{var $active = 'constant'}
{block title}{if $constant->deprecated}Deprecated {/if}Constant {$constant->name}{/block}
{block content}
<div id="content" class="constant">
<h1 n:class="$constant->deprecated ? deprecated">Constant {$constant->shortName}</h1>
{if $constant->valid}
<div class="description" n:if="$template->longDescription($constant)">
{$constant|longDescription|noescape}
</div>
<div class="alert alert-info">
{if $constant->inNamespace()}<b>Namespace:</b> {$constant->namespaceName|namespaceLinks|noescape}<br>{/if}
{if $constant->inPackage()}<b>Package:</b> {$constant->packageName|packageLinks|noescape}<br>{/if}
{foreach $template->annotationSort($template->annotationFilter($constant->annotations, array('var'))) as $annotation => $values}
{foreach $values as $value}
<b>{$annotation|annotationBeautify}{if $value}:{/if}</b>
{$value|annotation:$annotation:$constant|noescape}<br>
{/foreach}
{/foreach}
<b>Located at</b>
<a n:tag-if="$config->sourceCode" href="{$constant|sourceUrl}" title="Go to source code">
{$constant->fileName|relativePath}
</a><br>
</div>
{var $annotations = $constant->annotations}
<div class="panel panel-default">
<div class="panel-heading"><h2>Value summary</h2></div>
<table class="summary table table-bordered table-striped" id="vars">
<tr>
<td class="name"><code>{$constant->typeHint|typeLinks:$constant|noescape}</code></td>
<td class="value">{block|strip}
{var $element = $template->resolveElement($constant->valueDefinition, $constant)}
{if $element}<a href="{$element|constantUrl}">{$constant->valueDefinition}</a>{else}<code>{$constant->valueDefinition|highlightValue:$constant|noescape}</code>{/if}
{/block}</td>
</tr>
</table>
</div>
{else}
<div class="alert alert-error">
<p>
Documentation of this constant could not be generated.
</p>
<p>
Constant was originally declared in {$constant->fileName|relativePath} and is invalid because of:
</p>
<ul>
<li n:foreach="$constant->reasons as $reason">Constant was redeclared in {$reason->getSender()->getFileName()|relativePath}.</li>
</ul>
</div>
{/if}
</div>
{/block}

View File

@ -1,4 +0,0 @@
{contentType javascript}
var ApiGen = ApiGen || {};
ApiGen.elements = {$elements};

View File

@ -1,94 +0,0 @@
{layout '@layout.latte'}
{var $active = 'function'}
{block title}{if $function->deprecated}Deprecated {/if}Function {$function->name}{/block}
{block content}
<div id="content" class="function">
<h1 n:class="$function->deprecated ? deprecated">Function {$function->shortName}</h1>
{if $function->valid}
<div class="description" n:if="$template->longDescription($function)">
{$function|longDescription|noescape}
</div>
<div class="alert alert-info">
{if $function->inNamespace()}<b>Namespace:</b> {$function->namespaceName|namespaceLinks|noescape}<br>{/if}
{if $function->inPackage()}<b>Package:</b> {$function->packageName|packageLinks|noescape}<br>{/if}
{foreach $template->annotationSort($template->annotationFilter($function->annotations, array('param', 'return', 'throws'))) as $annotation => $values}
{foreach $values as $value}
<b>{$annotation|annotationBeautify}{if $value}:{/if}</b>
{$value|annotation:$annotation:$function|noescape}<br>
{/foreach}
{/foreach}
<b>Located at</b>
<a n:tag-if="$config->sourceCode" href="{$function|sourceUrl}" title="Go to source code">
{$function->fileName|relativePath}
</a><br>
</div>
{var $annotations = $function->annotations}
{if count($function->parameters)}
<div class="panel panel-default">
<div class="panel-heading"><h2>Parameters summary</h2></div>
<table class="summary table table-bordered table-striped" id="parameters">
<tr n:foreach="$function->parameters as $parameter" id="${$parameter->name}">
<td class="name"><code>{$parameter->typeHint|typeLinks:$function|noescape}</code></td>
<td class="value"><code>{block|strip}
<var>{if $parameter->passedByReference}&amp; {/if}${$parameter->name}</var>{if $parameter->defaultValueAvailable} = {$parameter->defaultValueDefinition|highlightPHP:$function|noescape}{elseif $parameter->unlimited},…{/if}
{/block}</code></td>
<td>{$parameter->description|description:$function}</td>
</tr>
</table>
</div>
{/if}
{if isset($annotations['return']) && 'void' !== $annotations['return'][0]}
<div class="panel panel-default">
<div class="panel-heading"><h2>Return value summary</h2></div>
<table class="summary table table-bordered table-striped" id="returns">
<tr>
<td class="name"><code>
{$annotations['return'][0]|typeLinks:$function|noescape}
</code></td>
<td>
{$annotations['return'][0]|description:$function|noescape}
</td>
</tr>
</table>
</div>
{/if}
{if isset($annotations['throws'])}
<div class="panel panel-default">
<div class="panel-heading"><h2>Thrown exceptions summary</h2></div>
<table class="summary table table-bordered table-striped" id="throws">
<tr n:foreach="$annotations['throws'] as $throws">
<td class="name"><code>
{$throws|typeLinks:$function|noescape}
</code></td>
<td>
{$throws|description:$function|noescape}
</td>
</tr>
</table>
</div>
{/if}
{else}
<div class="alert alert-error">
<p>
Documentation of this function could not be generated.
</p>
<p>
Function was originally declared in {$function->fileName|relativePath} and is invalid because of:
</p>
<ul>
<li n:foreach="$function->reasons as $reason">Function was redeclared in {$reason->getSender()->getFileName()|relativePath}.</li>
</ul>
</div>
{/if}
</div>
{/block}

View File

@ -1,841 +0,0 @@
/*
* jQuery Autocomplete plugin 1.2.3
*
* Copyright (c) 2009 Jörn Zaefferer
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*
* With small modifications by Alfonso Gómez-Arzola.
* See changelog for details.
*
*/
;(function($) {
'use strict';
$.fn.extend({
autocomplete: function(urlOrData, options) {
var isUrl = typeof urlOrData == "string";
options = $.extend({}, $.Autocompleter.defaults, {
url: isUrl ? urlOrData : null,
data: isUrl ? null : urlOrData,
delay: isUrl ? $.Autocompleter.defaults.delay : 10,
max: options && !options.scroll ? 10 : 150,
noRecord: "No Records."
}, options);
// if highlight is set to false, replace it with a do-nothing function
options.highlight = options.highlight || function(value) { return value; };
// if the formatMatch option is not specified, then use formatItem for backwards compatibility
options.formatMatch = options.formatMatch || options.formatItem;
return this.each(function() {
new $.Autocompleter(this, options);
});
},
result: function(handler) {
return this.bind("result", handler);
},
search: function(handler) {
return this.trigger("search", [handler]);
},
flushCache: function() {
return this.trigger("flushCache");
},
setOptions: function(options){
return this.trigger("setOptions", [options]);
},
unautocomplete: function() {
return this.trigger("unautocomplete");
}
});
$.Autocompleter = function(input, options) {
var KEY = {
UP: 38,
DOWN: 40,
DEL: 46,
TAB: 9,
RETURN: 13,
ESC: 27,
COMMA: 188,
PAGEUP: 33,
PAGEDOWN: 34,
BACKSPACE: 8
};
var globalFailure = null;
if(options.failure != null && typeof options.failure == "function") {
globalFailure = options.failure;
}
// Create $ object for input element
var $input = $(input).attr("autocomplete", "off").addClass(options.inputClass);
var timeout;
var previousValue = "";
var cache = $.Autocompleter.Cache(options);
var hasFocus = 0;
var lastKeyPressCode;
var config = {
mouseDownOnSelect: false
};
var select = $.Autocompleter.Select(options, input, selectCurrent, config);
var blockSubmit;
// prevent form submit in opera when selecting with return key
navigator.userAgent.indexOf("Opera") != -1 && $(input.form).bind("submit.autocomplete", function() {
if (blockSubmit) {
blockSubmit = false;
return false;
}
});
// older versions of opera don't trigger keydown multiple times while pressed, others don't work with keypress at all
$input.bind((navigator.userAgent.indexOf("Opera") != -1 && !'KeyboardEvent' in window ? "keypress" : "keydown") + ".autocomplete", function(event) {
// a keypress means the input has focus
// avoids issue where input had focus before the autocomplete was applied
hasFocus = 1;
// track last key pressed
lastKeyPressCode = event.keyCode;
switch(event.keyCode) {
case KEY.UP:
if ( select.visible() ) {
event.preventDefault();
select.prev();
} else {
onChange(0, true);
}
break;
case KEY.DOWN:
if ( select.visible() ) {
event.preventDefault();
select.next();
} else {
onChange(0, true);
}
break;
case KEY.PAGEUP:
if ( select.visible() ) {
event.preventDefault();
select.pageUp();
} else {
onChange(0, true);
}
break;
case KEY.PAGEDOWN:
if ( select.visible() ) {
event.preventDefault();
select.pageDown();
} else {
onChange(0, true);
}
break;
// matches also semicolon
case options.multiple && $.trim(options.multipleSeparator) == "," && KEY.COMMA:
case KEY.TAB:
case KEY.RETURN:
if( selectCurrent() ) {
// stop default to prevent a form submit, Opera needs special handling
event.preventDefault();
blockSubmit = true;
return false;
}
break;
case KEY.ESC:
select.hide();
break;
default:
clearTimeout(timeout);
timeout = setTimeout(onChange, options.delay);
break;
}
}).focus(function(){
// track whether the field has focus, we shouldn't process any
// results if the field no longer has focus
hasFocus++;
}).blur(function() {
hasFocus = 0;
if (!config.mouseDownOnSelect) {
hideResults();
}
}).click(function() {
// show select when clicking in a focused field
// but if clickFire is true, don't require field
// to be focused to begin with; just show select
if( options.clickFire ) {
if ( !select.visible() ) {
onChange(0, true);
}
} else {
if ( hasFocus++ > 1 && !select.visible() ) {
onChange(0, true);
}
}
}).bind("search", function() {
var fn = (arguments.length > 1) ? arguments[1] : null;
function findValueCallback(q, data) {
var result;
if( data && data.length ) {
for (var i=0; i < data.length; i++) {
if( data[i].result.toLowerCase() == q.toLowerCase() ) {
result = data[i];
break;
}
}
}
if( typeof fn == "function" ) fn(result);
else $input.trigger("result", result && [result.data, result.value]);
}
$.each(trimWords($input.val()), function(i, value) {
request(value, findValueCallback, findValueCallback);
});
}).bind("flushCache", function() {
cache.flush();
}).bind("setOptions", function() {
$.extend(true, options, arguments[1]);
// if we've updated the data, repopulate
if ( "data" in arguments[1] )
cache.populate();
}).bind("unautocomplete", function() {
select.unbind();
$input.unbind();
$(input.form).unbind(".autocomplete");
});
function selectCurrent() {
var selected = select.selected();
if( !selected )
return false;
var v = selected.result;
previousValue = v;
if ( options.multiple ) {
var words = trimWords($input.val());
if ( words.length > 1 ) {
var seperator = options.multipleSeparator.length;
var cursorAt = $(input).selection().start;
var wordAt, progress = 0;
$.each(words, function(i, word) {
progress += word.length;
if (cursorAt <= progress) {
wordAt = i;
return false;
}
progress += seperator;
});
words[wordAt] = v;
//$.Autocompleter.Selection(input, progress + seperator, progress + seperator);
v = words.join( options.multipleSeparator );
}
v += options.multipleSeparator;
}
$input.val(v);
hideResultsNow();
$input.trigger("result", [selected.data, selected.value]);
return true;
}
function onChange(crap, skipPrevCheck) {
if( lastKeyPressCode == KEY.DEL ) {
select.hide();
return;
}
var currentValue = $input.val();
if ( !skipPrevCheck && currentValue == previousValue )
return;
previousValue = currentValue;
currentValue = lastWord(currentValue);
if ( currentValue.length >= options.minChars) {
$input.addClass(options.loadingClass);
if (!options.matchCase)
currentValue = currentValue.toLowerCase();
request(currentValue, receiveData, hideResultsNow);
} else {
stopLoading();
select.hide();
}
};
function trimWords(value) {
if (!value)
return [""];
if (!options.multiple)
return [$.trim(value)];
return $.map(value.split(options.multipleSeparator), function(word) {
return $.trim(value).length ? $.trim(word) : null;
});
}
function lastWord(value) {
if ( !options.multiple )
return value;
var words = trimWords(value);
if (words.length == 1)
return words[0];
var cursorAt = $(input).selection().start;
if (cursorAt == value.length) {
words = trimWords(value)
} else {
words = trimWords(value.replace(value.substring(cursorAt), ""));
}
return words[words.length - 1];
}
// fills in the input box w/the first match (assumed to be the best match)
// q: the term entered
// sValue: the first matching result
function autoFill(q, sValue){
// autofill in the complete box w/the first match as long as the user hasn't entered in more data
// if the last user key pressed was backspace, don't autofill
if( options.autoFill && (lastWord($input.val()).toLowerCase() == q.toLowerCase()) && lastKeyPressCode != KEY.BACKSPACE ) {
// fill in the value (keep the case the user has typed)
$input.val($input.val() + sValue.substring(lastWord(previousValue).length));
// select the portion of the value not typed by the user (so the next character will erase)
$(input).selection(previousValue.length, previousValue.length + sValue.length);
}
};
function hideResults() {
clearTimeout(timeout);
timeout = setTimeout(hideResultsNow, 200);
};
function hideResultsNow() {
var wasVisible = select.visible();
select.hide();
clearTimeout(timeout);
stopLoading();
if (options.mustMatch) {
// call search and run callback
$input.search(
function (result){
// if no value found, clear the input box
if( !result ) {
if (options.multiple) {
var words = trimWords($input.val()).slice(0, -1);
$input.val( words.join(options.multipleSeparator) + (words.length ? options.multipleSeparator : "") );
}
else {
$input.val( "" );
$input.trigger("result", null);
}
}
}
);
}
};
function receiveData(q, data) {
if ( data && data.length && hasFocus ) {
stopLoading();
select.display(data, q);
autoFill(q, data[0].value);
select.show();
} else {
hideResultsNow();
}
};
function request(term, success, failure) {
if (!options.matchCase)
term = term.toLowerCase();
var data = cache.load(term);
// recieve the cached data
if (data) {
if(data.length) {
success(term, data);
}
else{
var parsed = options.parse && options.parse(options.noRecord) || parse(options.noRecord);
success(term,parsed);
}
// if an AJAX url has been supplied, try loading the data now
} else if( (typeof options.url == "string") && (options.url.length > 0) ){
var extraParams = {
timestamp: +new Date()
};
$.each(options.extraParams, function(key, param) {
extraParams[key] = typeof param == "function" ? param() : param;
});
$.ajax({
// try to leverage ajaxQueue plugin to abort previous requests
mode: "abort",
// limit abortion to this input
port: "autocomplete" + input.name,
dataType: options.dataType,
url: options.url,
data: $.extend({
q: lastWord(term),
limit: options.max
}, extraParams),
success: function(data) {
var parsed = options.parse && options.parse(data) || parse(data);
cache.add(term, parsed);
success(term, parsed);
}
});
} else {
// if we have a failure, we need to empty the list -- this prevents the the [TAB] key from selecting the last successful match
select.emptyList();
if(globalFailure != null) {
globalFailure();
}
else {
failure(term);
}
}
};
function parse(data) {
var parsed = [];
var rows = data.split("\n");
for (var i=0; i < rows.length; i++) {
var row = $.trim(rows[i]);
if (row) {
row = row.split("|");
parsed[parsed.length] = {
data: row,
value: row[0],
result: options.formatResult && options.formatResult(row, row[0]) || row[0]
};
}
}
return parsed;
};
function stopLoading() {
$input.removeClass(options.loadingClass);
};
};
$.Autocompleter.defaults = {
inputClass: "ac_input",
resultsClass: "ac_results",
loadingClass: "ac_loading",
minChars: 1,
delay: 400,
matchCase: false,
matchSubset: true,
matchContains: false,
cacheLength: 100,
max: 1000,
mustMatch: false,
extraParams: {},
selectFirst: true,
formatItem: function(row) { return row[0]; },
formatMatch: null,
autoFill: false,
width: 0,
multiple: false,
multipleSeparator: " ",
inputFocus: true,
clickFire: false,
highlight: function(value, term) {
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term.replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1") + ")(?![^<>]*>)(?![^&;]+;)", "gi"), "<strong>$1</strong>");
},
scroll: true,
scrollHeight: 180,
scrollJumpPosition: true
};
$.Autocompleter.Cache = function(options) {
var data = {};
var length = 0;
function matchSubset(s, sub) {
return (new RegExp(sub.toUpperCase().replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1").replace(/[A-Z0-9]/g, function(m, offset) {
return offset === 0 ? '(?:' + m + '|^' + m.toLowerCase() + ')' : '(?:.*' + m + '|' + m.toLowerCase() + ')';
}))).test(s); // find by initials
};
function add(q, value) {
if (length > options.cacheLength){
flush();
}
if (!data[q]){
length++;
}
data[q] = value;
}
function populate(){
if( !options.data ) return false;
// track the matches
var stMatchSets = {},
nullData = 0;
// no url was specified, we need to adjust the cache length to make sure it fits the local data store
if( !options.url ) options.cacheLength = 1;
// track all options for minChars = 0
stMatchSets[""] = [];
// loop through the array and create a lookup structure
for ( var i = 0, ol = options.data.length; i < ol; i++ ) {
var rawValue = options.data[i];
// if rawValue is a string, make an array otherwise just reference the array
rawValue = (typeof rawValue == "string") ? [rawValue] : rawValue;
var value = options.formatMatch(rawValue, i+1, options.data.length);
if ( typeof(value) === 'undefined' || value === false )
continue;
var firstChar = value.charAt(0).toLowerCase();
// if no lookup array for this character exists, look it up now
if( !stMatchSets[firstChar] )
stMatchSets[firstChar] = [];
// if the match is a string
var row = {
value: value,
data: rawValue,
result: options.formatResult && options.formatResult(rawValue) || value
};
// push the current match into the set list
stMatchSets[firstChar].push(row);
// keep track of minChars zero items
if ( nullData++ < options.max ) {
stMatchSets[""].push(row);
}
};
// add the data items to the cache
$.each(stMatchSets, function(i, value) {
// increase the cache size
options.cacheLength++;
// add to the cache
add(i, value);
});
}
// populate any existing data
setTimeout(populate, 25);
function flush(){
data = {};
length = 0;
}
return {
flush: flush,
add: add,
populate: populate,
load: function(q) {
if (!options.cacheLength || !length)
return null;
/*
* if dealing w/local data and matchContains than we must make sure
* to loop through all the data collections looking for matches
*/
if( !options.url && options.matchContains ){
// track all matches
var csub = [];
// loop through all the data grids for matches
for( var k in data ){
// don't search through the stMatchSets[""] (minChars: 0) cache
// this prevents duplicates
if( k.length > 0 ){
var c = data[k];
$.each(c, function(i, x) {
// if we've got a match, add it to the array
if (matchSubset(x.value, q)) {
csub.push(x);
}
});
}
}
return csub;
} else
// if the exact item exists, use it
if (data[q]){
return data[q];
} else
if (options.matchSubset) {
for (var i = q.length - 1; i >= options.minChars; i--) {
var c = data[q.substr(0, i)];
if (c) {
var csub = [];
$.each(c, function(i, x) {
if (matchSubset(x.value, q)) {
csub[csub.length] = x;
}
});
return csub;
}
}
}
return null;
}
};
};
$.Autocompleter.Select = function (options, input, select, config) {
var CLASSES = {
ACTIVE: "ac_over"
};
var listItems,
active = -1,
data,
term = "",
needsInit = true,
element,
list;
// Create results
function init() {
if (!needsInit)
return;
element = $("<div/>")
.hide()
.addClass(options.resultsClass)
.css("position", "absolute")
.appendTo(document.body)
.hover(function(event) {
// Browsers except FF do not fire mouseup event on scrollbars, resulting in mouseDownOnSelect remaining true, and results list not always hiding.
if($(this).is(":visible")) {
input.focus();
}
config.mouseDownOnSelect = false;
});
list = $("<ul/>").appendTo(element).mouseover( function(event) {
if(target(event).nodeName && target(event).nodeName.toUpperCase() == 'LI') {
active = $("li", list).removeClass(CLASSES.ACTIVE).index(target(event));
$(target(event)).addClass(CLASSES.ACTIVE);
}
}).click(function(event) {
$(target(event)).addClass(CLASSES.ACTIVE);
select();
if( options.inputFocus )
input.focus();
return false;
}).mousedown(function() {
config.mouseDownOnSelect = true;
}).mouseup(function() {
config.mouseDownOnSelect = false;
});
if( options.width > 0 )
element.css("width", options.width);
needsInit = false;
}
function target(event) {
var element = event.target;
while(element && element.tagName != "LI")
element = element.parentNode;
// more fun with IE, sometimes event.target is empty, just ignore it then
if(!element)
return [];
return element;
}
function moveSelect(step) {
listItems.slice(active, active + 1).removeClass(CLASSES.ACTIVE);
movePosition(step);
var activeItem = listItems.slice(active, active + 1).addClass(CLASSES.ACTIVE);
if(options.scroll) {
var offset = 0;
listItems.slice(0, active).each(function() {
offset += this.offsetHeight;
});
if((offset + activeItem[0].offsetHeight - list.scrollTop()) > list[0].clientHeight) {
list.scrollTop(offset + activeItem[0].offsetHeight - list.innerHeight());
} else if(offset < list.scrollTop()) {
list.scrollTop(offset);
}
}
};
function movePosition(step) {
if (options.scrollJumpPosition || (!options.scrollJumpPosition && !((step < 0 && active == 0) || (step > 0 && active == listItems.length - 1)) )) {
active += step;
if (active < 0) {
active = listItems.length - 1;
} else if (active >= listItems.length) {
active = 0;
}
}
}
function limitNumberOfItems(available) {
return options.max && options.max < available
? options.max
: available;
}
function fillList() {
list.empty();
var max = limitNumberOfItems(data.length);
for (var i=0; i < max; i++) {
if (!data[i])
continue;
var formatted = options.formatItem(data[i].data, i+1, max, data[i].value, term);
if ( formatted === false )
continue;
var li = $("<li/>").html( options.highlight(formatted, term) ).addClass(i%2 == 0 ? "ac_even" : "ac_odd").appendTo(list)[0];
$.data(li, "ac_data", data[i]);
}
listItems = list.find("li");
if ( options.selectFirst ) {
listItems.slice(0, 1).addClass(CLASSES.ACTIVE);
active = 0;
}
// apply bgiframe if available
if ( $.fn.bgiframe )
list.bgiframe();
}
return {
display: function(d, q) {
init();
data = d;
term = q;
fillList();
},
next: function() {
moveSelect(1);
},
prev: function() {
moveSelect(-1);
},
pageUp: function() {
if (active != 0 && active - 8 < 0) {
moveSelect( -active );
} else {
moveSelect(-8);
}
},
pageDown: function() {
if (active != listItems.length - 1 && active + 8 > listItems.length) {
moveSelect( listItems.length - 1 - active );
} else {
moveSelect(8);
}
},
hide: function() {
element && element.hide();
listItems && listItems.removeClass(CLASSES.ACTIVE);
active = -1;
},
visible : function() {
return element && element.is(":visible");
},
current: function() {
return this.visible() && (listItems.filter("." + CLASSES.ACTIVE)[0] || options.selectFirst && listItems[0]);
},
show: function() {
var offset = $(input).offset();
element.css({
width: typeof options.width == "string" || options.width > 0 ? options.width : $(input).width(),
top: offset.top + input.offsetHeight,
left: offset.left
}).show();
if(options.scroll) {
list.scrollTop(0);
list.css({
maxHeight: options.scrollHeight,
overflow: 'auto'
});
if(navigator.userAgent.indexOf("MSIE") != -1 && typeof document.body.style.maxHeight === "undefined") {
var listHeight = 0;
listItems.each(function() {
listHeight += this.offsetHeight;
});
var scrollbarsVisible = listHeight > options.scrollHeight;
list.css('height', scrollbarsVisible ? options.scrollHeight : listHeight );
if (!scrollbarsVisible) {
// IE doesn't recalculate width when scrollbar disappears
listItems.width( list.width() - parseInt(listItems.css("padding-left")) - parseInt(listItems.css("padding-right")) );
}
}
}
},
selected: function() {
var selected = listItems && listItems.filter("." + CLASSES.ACTIVE).removeClass(CLASSES.ACTIVE);
return selected && selected.length && $.data(selected[0], "ac_data");
},
emptyList: function (){
list && list.empty();
},
unbind: function() {
element && element.remove();
}
};
};
$.fn.selection = function(start, end) {
if (start !== undefined) {
return this.each(function() {
if( this.createTextRange ){
var selRange = this.createTextRange();
if (end === undefined || start == end) {
selRange.move("character", start);
selRange.select();
} else {
selRange.collapse(true);
selRange.moveStart("character", start);
selRange.moveEnd("character", end);
selRange.select();
}
} else if( this.setSelectionRange ){
this.setSelectionRange(start, end);
} else if( this.selectionStart ){
this.selectionStart = start;
this.selectionEnd = end;
}
});
}
var field = this[0];
if ( field.createTextRange ) {
var range = document.selection.createRange(),
orig = field.value,
teststring = "<->",
textLength = range.text.length;
range.text = teststring;
var caretAt = field.value.indexOf(teststring);
field.value = orig;
this.selection(caretAt, caretAt + textLength);
return {
start: caretAt,
end: caretAt + textLength
}
} else if( field.selectionStart !== undefined ){
return {
start: field.selectionStart,
end: field.selectionEnd
}
}
};
})(jQuery);

View File

@ -1,114 +0,0 @@
/*!
* jQuery Cookie Plugin v1.4.1
* https://github.com/carhartl/jquery-cookie
*
* Copyright 2006, 2014 Klaus Hartl
* Released under the MIT license
*/
(function (factory) {
if (typeof define === 'function' && define.amd) {
// AMD (Register as an anonymous module)
define(['jquery'], factory);
} else if (typeof exports === 'object') {
// Node/CommonJS
module.exports = factory(require('jquery'));
} else {
// Browser globals
factory(jQuery);
}
}(function ($) {
var pluses = /\+/g;
function encode(s) {
return config.raw ? s : encodeURIComponent(s);
}
function decode(s) {
return config.raw ? s : decodeURIComponent(s);
}
function stringifyCookieValue(value) {
return encode(config.json ? JSON.stringify(value) : String(value));
}
function parseCookieValue(s) {
if (s.indexOf('"') === 0) {
// This is a quoted cookie as according to RFC2068, unescape...
s = s.slice(1, -1).replace(/\\"/g, '"').replace(/\\\\/g, '\\');
}
try {
// Replace server-side written pluses with spaces.
// If we can't decode the cookie, ignore it, it's unusable.
// If we can't parse the cookie, ignore it, it's unusable.
s = decodeURIComponent(s.replace(pluses, ' '));
return config.json ? JSON.parse(s) : s;
} catch(e) {}
}
function read(s, converter) {
var value = config.raw ? s : parseCookieValue(s);
return $.isFunction(converter) ? converter(value) : value;
}
var config = $.cookie = function (key, value, options) {
// Write
if (arguments.length > 1 && !$.isFunction(value)) {
options = $.extend({}, config.defaults, options);
if (typeof options.expires === 'number') {
var days = options.expires, t = options.expires = new Date();
t.setMilliseconds(t.getMilliseconds() + days * 864e+5);
}
return (document.cookie = [
encode(key), '=', stringifyCookieValue(value),
options.expires ? '; expires=' + options.expires.toUTCString() : '', // use expires attribute, max-age is not supported by IE
options.path ? '; path=' + options.path : '',
options.domain ? '; domain=' + options.domain : '',
options.secure ? '; secure' : ''
].join(''));
}
// Read
var result = key ? undefined : {},
// To prevent the for loop in the first place assign an empty array
// in case there are no cookies at all. Also prevents odd result when
// calling $.cookie().
cookies = document.cookie ? document.cookie.split('; ') : [],
i = 0,
l = cookies.length;
for (; i < l; i++) {
var parts = cookies[i].split('='),
name = decode(parts.shift()),
cookie = parts.join('=');
if (key === name) {
// If second argument (value) is a function it's a converter...
result = read(cookie, value);
break;
}
// Prevent storing a cookie that we couldn't decode.
if (!key && (cookie = read(cookie)) !== undefined) {
result[name] = cookie;
}
}
return result;
};
config.defaults = {};
$.removeCookie = function (key, options) {
// Must not alter options, thus extending a fresh object...
$.cookie(key, '', $.extend({}, options, { expires: -1 }));
return !$.cookie(key);
};
}));

File diff suppressed because one or more lines are too long

View File

@ -1,69 +0,0 @@
/**
* jQuery.fn.sortElements
* --------------
* @author James Padolsey (http://james.padolsey.com)
* @version 0.11
* @updated 18-MAR-2010
* --------------
* @param Function comparator:
* Exactly the same behaviour as [1,2,3].sort(comparator)
*
* @param Function getSortable
* A function that should return the element that is
* to be sorted. The comparator will run on the
* current collection, but you may want the actual
* resulting sort to occur on a parent or another
* associated element.
*
* E.g. $('td').sortElements(comparator, function(){
* return this.parentNode;
* })
*
* The <td>'s parent (<tr>) will be sorted instead
* of the <td> itself.
*/
jQuery.fn.sortElements = (function(){
var sort = [].sort;
return function(comparator, getSortable) {
getSortable = getSortable || function(){return this;};
var placements = this.map(function(){
var sortElement = getSortable.call(this),
parentNode = sortElement.parentNode,
// Since the element itself will change position, we have
// to have some way of storing it's original position in
// the DOM. The easiest way is to have a 'flag' node:
nextSibling = parentNode.insertBefore(
document.createTextNode(''),
sortElement.nextSibling
);
return function() {
if (parentNode === this) {
throw new Error(
"You can't sort elements if any one is a descendant of another."
);
}
// Insert before flag:
parentNode.insertBefore(this, nextSibling);
// Remove flag:
parentNode.removeChild(nextSibling);
};
});
return sort.call(this, comparator).each(function(i){
placements[i].call(getSortable.call(this));
});
};
})();

View File

@ -1,8 +0,0 @@
/*!
* sprintf and vsprintf for jQuery
* somewhat based on http://jan.moesen.nu/code/javascript/sprintf-and-printf-in-javascript/
* Copyright (c) 2008 Sabin Iacob (m0n5t3r) <iacobs@m0n5t3r.info>
* @license http://www.gnu.org/licenses/gpl.html
* @project jquery.sprintf
*/
(function(d){var a={b:function(e){return parseInt(e,10).toString(2)},c:function(e){return String.fromCharCode(parseInt(e,10))},d:function(e){return parseInt(e,10)},u:function(e){return Math.abs(e)},f:function(f,e){e=parseInt(e,10);f=parseFloat(f);if(isNaN(e&&f)){return NaN}return e&&f.toFixed(e)||f},o:function(e){return parseInt(e,10).toString(8)},s:function(e){return e},x:function(e){return(""+parseInt(e,10).toString(16)).toLowerCase()},X:function(e){return(""+parseInt(e,10).toString(16)).toUpperCase()}};var c=/%(?:(\d+)?(?:\.(\d+))?|\(([^)]+)\))([%bcdufosxX])/g;var b=function(f){if(f.length==1&&typeof f[0]=="object"){f=f[0];return function(i,h,k,j,g,m,l){return a[g](f[j])}}else{var e=0;return function(i,h,k,j,g,m,l){if(g=="%"){return"%"}return a[g](f[e++],k)}}};d.extend({sprintf:function(f){var e=Array.apply(null,arguments).slice(1);return f.replace(c,b(e))},vsprintf:function(f,e){return f.replace(c,b(e))}})})(jQuery);

View File

@ -1,308 +0,0 @@
$(window).load(function() {
var $document = $(document);
var $navigation = $('#navigation');
var navigationHeight = $navigation.height();
var $left = $('#left');
var $right = $('#right');
var $rightInner = $('#rightInner');
var $splitter = $('#splitter');
var $groups = $('#groups');
var $content = $('#content');
// Menu
// Hide deep packages and namespaces
$('ul span', $groups).click(function(event) {
event.preventDefault();
event.stopPropagation();
$(this)
.toggleClass('collapsed')
.parent()
.next('ul')
.toggleClass('collapsed');
}).click();
$active = $('ul li.active', $groups);
if ($active.length > 0) {
// Open active
$('> a > span', $active).click();
} else {
$main = $('> ul > li.main', $groups);
if ($main.length > 0) {
// Open first level of the main project
$('> a > span', $main).click();
} else {
// Open first level of all
$('> ul > li > a > span', $groups).click();
}
}
// Content
// Search autocompletion
var autocompleteFound = false;
var autocompleteFiles = {'c': 'class', 'co': 'constant', 'f': 'function', 'm': 'class', 'mm': 'class', 'p': 'class', 'mp': 'class', 'cc': 'class'};
var $search = $('#search input[name=q]');
$search
.autocomplete(ApiGen.elements, {
matchContains: true,
scrollHeight: 200,
max: 20,
width: 300,
noRecord: '',
highlight: function(value, term) {
var term = term.toUpperCase().replace(/([\^\$\(\)\[\]\{\}\*\.\+\?\|\\])/gi, "\\$1").replace(/[A-Z0-9]/g, function(m, offset) {
return offset === 0 ? '(?:' + m + '|^' + m.toLowerCase() + ')' : '(?:(?:[^<>]|<[^<>]*>)*' + m + '|' + m.toLowerCase() + ')';
});
return value.replace(new RegExp("(?![^&;]+;)(?!<[^<>]*)(" + term + ")(?![^<>]*>)(?![^&;]+;)"), "<strong>$1</strong>");
},
formatItem: function(data) {
return data.length > 1 ? data[1].replace(/^(.+\\)(.+)$/, '<span><small>$1</small>$2</span>') : data[0];
},
formatMatch: function(data) {
return data[1];
},
formatResult: function(data) {
return data[1];
},
show: function($list) {
var $items = $('li span', $list);
var maxWidth = Math.max.apply(null, $items.map(function() {
return $(this).width();
}));
// 10px padding
$list.width(Math.max(maxWidth + 10, $search.innerWidth()));
}
}).result(function(event, data) {
autocompleteFound = true;
var location = window.location.href.split('/');
location.pop();
var parts = data[1].split(/::|$/);
var file = $.sprintf(ApiGen.config.templates[autocompleteFiles[data[0]]].filename, parts[0].replace(/\(\)/, '').replace(/[^\w]/g, '.'));
if (parts[1]) {
file += '#' + ('mm' === data[0] || 'mp' === data[0] ? 'm' : '') + parts[1].replace(/([\w]+)\(\)/, '_$1');
}
location.push(file);
window.location = location.join('/');
// Workaround for Opera bug
$(this).closest('form').attr('action', location.join('/'));
}).closest('form')
.submit(function() {
var query = $search.val();
if ('' === query) {
return false;
}
return !autocompleteFound && '' !== $('#search input[name=cx]').val();
});
// Save natural order
$('table.summary tr[data-order]', $content).each(function(index) {
do {
index = '0' + index;
} while (index.length < 3);
$(this).attr('data-order-natural', index);
});
// Switch between natural and alphabetical order
var $caption = $('table.summary', $content)
.filter(':has(tr[data-order])')
.prev('h2');
$caption
.click(function() {
var $this = $(this);
var order = $this.data('order') || 'natural';
order = 'natural' === order ? 'alphabetical' : 'natural';
$this.data('order', order);
$.cookie('order', order, {expires: 365});
var attr = 'alphabetical' === order ? 'data-order' : 'data-order-natural';
$this
.next('table')
.find('tr').sortElements(function(a, b) {
return $(a).attr(attr) > $(b).attr(attr) ? 1 : -1;
});
return false;
})
.addClass('switchable')
.attr('title', 'Switch between natural and alphabetical order');
if ((null === $.cookie('order') && 'alphabetical' === ApiGen.config.options.elementsOrder) || 'alphabetical' === $.cookie('order')) {
$caption.click();
}
// Open details
if (ApiGen.config.options.elementDetailsCollapsed) {
$(document.body).on('click', 'tr', function(ev) {
var short = this.querySelector('.short')
, detailed = this.querySelector('.detailed')
if (!short || !detailed) return
$(short).toggleClass('hidden')
$(detailed).toggleClass('hidden')
})
}
// Splitter
var splitterWidth = $splitter.width();
var splitterPosition = $.cookie('splitter') ? parseInt($.cookie('splitter')) : null;
var splitterPositionBackup = $.cookie('splitterBackup') ? parseInt($.cookie('splitterBackup')) : null;
function setSplitterPosition(position)
{
splitterPosition = position;
$left.width(position);
$right.css('margin-left', position + splitterWidth);
$splitter.css('left', position);
}
function setNavigationPosition()
{
var height = $(window).height() - navigationHeight;
$left.height(height);
$splitter.height(height);
$right.height(height);
}
function setContentWidth()
{
var width = $rightInner.width();
$rightInner
.toggleClass('medium', width <= 960)
.toggleClass('small', width <= 650);
}
$splitter.mousedown(function() {
$splitter.addClass('active');
$document.mousemove(function(event) {
if (event.pageX >= 230 && $document.width() - event.pageX >= 600 + splitterWidth) {
setSplitterPosition(event.pageX);
setContentWidth();
}
});
$()
.add($splitter)
.add($document)
.mouseup(function() {
$splitter
.removeClass('active')
.unbind('mouseup');
$document
.unbind('mousemove')
.unbind('mouseup');
$.cookie('splitter', splitterPosition, {expires: 365});
});
return false;
});
$splitter.dblclick(function() {
if (splitterPosition) {
splitterPositionBackup = $left.width();
setSplitterPosition(0);
} else {
setSplitterPosition(splitterPositionBackup);
splitterPositionBackup = null;
}
setContentWidth();
$.cookie('splitter', splitterPosition, {expires: 365});
$.cookie('splitterBackup', splitterPositionBackup, {expires: 365});
});
if (null !== splitterPosition) {
setSplitterPosition(splitterPosition);
}
setNavigationPosition();
setContentWidth();
$(window)
.resize(setNavigationPosition)
.resize(setContentWidth);
// Select selected lines
var matches = window.location.hash.substr(1).match(/^\d+(?:-\d+)?(?:,\d+(?:-\d+)?)*$/);
if (null !== matches) {
var lists = matches[0].split(',');
for (var i = 0; i < lists.length; i++) {
var lines = lists[i].split('-');
lines[0] = parseInt(lines[0]);
lines[1] = parseInt(lines[1] || lines[0]);
for (var j = lines[0]; j <= lines[1]; j++) {
$('#' + j).addClass('selected');
}
}
var $firstLine = $('#' + parseInt(matches[0]));
if ($firstLine.length > 0) {
$right.scrollTop($firstLine.position().top);
}
}
// Save selected lines
var lastLine;
$('.l a').click(function(event) {
event.preventDefault();
var selectedLine = $(this).parent().index() + 1;
var $selectedLine = $('pre.code .l').eq(selectedLine - 1);
if (event.shiftKey) {
if (lastLine) {
for (var i = Math.min(selectedLine, lastLine); i <= Math.max(selectedLine, lastLine); i++) {
$('#' + i).addClass('selected');
}
} else {
$selectedLine.addClass('selected');
}
} else if (event.ctrlKey) {
$selectedLine.toggleClass('selected');
} else {
var $selected = $('.l.selected')
.not($selectedLine)
.removeClass('selected');
if ($selected.length > 0) {
$selectedLine.addClass('selected');
} else {
$selectedLine.toggleClass('selected');
}
}
lastLine = $selectedLine.hasClass('selected') ? selectedLine : null;
// Update hash
var lines = $('.l.selected')
.map(function() {
return parseInt($(this).attr('id'));
})
.get()
.sort(function(a, b) {
return a - b;
});
var hash = [];
var list = [];
for (var j = 0; j < lines.length; j++) {
if (0 === j && j + 1 === lines.length) {
hash.push(lines[j]);
} else if (0 === j) {
list[0] = lines[j];
} else if (lines[j - 1] + 1 !== lines[j] && j + 1 === lines.length) {
hash.push(list.join('-'));
hash.push(lines[j]);
} else if (lines[j - 1] + 1 !== lines[j]) {
hash.push(list.join('-'));
list = [lines[j]];
} else if (j + 1 === lines.length) {
list[1] = lines[j];
hash.push(list.join('-'));
} else {
list[1] = lines[j];
}
}
hash = hash.join(',');
$backup = $('#' + hash).removeAttr('id');
window.location.hash = hash;
$backup.attr('id', hash);
});
});

View File

@ -1,23 +0,0 @@
{layout '@layout.latte'}
{var $active = 'namespace'}
{block title}{if $namespace != 'None'}Namespace {$namespace}{else}No namespace{/if}{/block}
{block content}
<div id="content" class="namespace">
<h1>{if $namespace != 'None'}Namespace {$namespace|namespaceLinks:false|noescape}{else}No namespace{/if}</h1>
{if $subnamespaces}
<div class="panel panel-default">
<div class="panel-heading"><h2>Namespaces summary</h2></div>
<table class="summary table table-bordered table-striped" id="namespaces">
<tr n:foreach="$subnamespaces as $namespace">
<td class="name"><a href="{$namespace|namespaceUrl}">{$namespace}</a></td>
</tr>
</table>
</div>
{/if}
{include '@elementlist.latte'}
</div>
{/block}

View File

@ -1,11 +0,0 @@
{contentType xml}
<?xml version="1.0" encoding="UTF-8"?>
<OpenSearchDescription xmlns="http://a9.com/-/spec/opensearch/1.1/">
<ShortName>{$config->title}</ShortName>
<Description>{$config->title} Documentation</Description>
<Url type="text/html" method="GET" template="http://www.google.com/cse?cx={$config->googleCseId|url}&amp;ie=UTF-8&amp;q={l}searchTerms{r}"/>
<Image width="16" height="16">{$config->baseUrl}/favicon.ico</Image>
<SyndicationRight>open</SyndicationRight>
<InputEncoding>UTF-8</InputEncoding>
<OutputEncoding>UTF-8</OutputEncoding>
</OpenSearchDescription>

View File

@ -1,48 +0,0 @@
{layout '@layout.latte'}
{var $active = 'overview'}
{block title}{$config->title ?: 'Overview'}{/block}
{block content}
<div id="content">
<h1>{include title}</h1>
{var $group = false}
{if count($namespaces)}
<div class="panel panel-default">
<div class="panel-heading"><h2>Namespaces summary</h2></div>
<table class="summary table table-bordered table-striped" id="namespaces">
{foreach $namespaces as $namespace}
{continueIf $config->main && 0 !== strpos($namespace, $config->main)}
<tr>
{var $group = true}
<td class="name"><a href="{$namespace|namespaceUrl}">{$namespace}</a></td>
</tr>
{/foreach}
</table>
</div>
{/if}
{if count($packages)}
<div class="panel panel-default">
<div class="panel-heading"><h2>Packages summary</h2></div>
<table class="summary table table-bordered table-striped" id="packages">
{foreach $packages as $package}
{continueIf $config->main && 0 !== strpos($package, $config->main)}
<tr>
{var $group = true}
<td class="name">
<a href="{$package|packageUrl}">{$package}</a>
</td>
</tr>
{/foreach}
</table>
</div>
{/if}
{if ! $group}
{include '@elementlist.latte'}
{/if}
</div>
{/block}

View File

@ -1,23 +0,0 @@
{layout '@layout.latte'}
{var $active = 'package'}
{block title}{if $package != 'None'}Package {$package}{else}No package{/if}{/block}
{block content}
<div id="content" class="package">
<h1>{if $package != 'None'}Package {$package|packageLinks:false|noescape}{else}No package{/if}</h1>
{if $subpackages}
<div class="panel panel-default">
<div class="panel-heading"><h2>Packages summary</h2></div>
<table class="summary table table-bordered table-striped" id="packages">
<tr n:foreach="$subpackages as $package">
<td class="name"><a href="{$package|packageUrl}">{$package}</a></td>
</tr>
</table>
</div>
{/if}
{include '@elementlist.latte'}
</div>
{/block}

File diff suppressed because one or more lines are too long

Binary file not shown.

Before

Width:  |  Height:  |  Size: 288 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 152 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 216 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 171 B

View File

@ -1,569 +0,0 @@
/* Normal styles */
body {
padding: 50px 0 0 0;
}
h1 {
font-size: 2em;
margin: 0.67em 0;
}
h2 {
font-size: 1.5em;
margin: 0.83em 0;
}
h3 {
font-size: 1.17em;
margin: 1em 0 0.2em 0;
}
h4 {
font-size: 100%;
margin: 0;
padding: 0;
}
.panel-heading h2,
.panel-heading h3 {
margin-top: 0;
margin-bottom: 0;
}
.panel > p {
margin: 10px;
}
ul, ol {
margin-bottom: 0;
}
a, a:hover {
text-decoration: none;
}
var {
font-weight: bold;
font-style: normal;
color: #c09853;
}
code {
color: #000;
white-space: nowrap;
border: none;
background: transparent;
padding: 0
}
code:empty {
display: none;
}
code a b {
color: #000;
}
pre code {
white-space: pre;
}
.deprecated {
text-decoration: line-through;
opacity: .5;
}
.invalid {
color: #dd1144;
}
.hidden {
display: none;
}
/* Left side */
#left {
overflow: auto;
width: 270px;
height: 100%;
position: fixed;
}
/* Menu */
#menu {
padding: 10px;
overflow-x: hidden;
}
#menu h3 {
border-bottom: 1px solid #E7E7E7;
margin-left: -10px;
margin-right: -10px;
padding: 0 10px 5px 10px;
}
#menu ul {
list-style: none;
padding: 0;
margin: 0;
}
#menu ul ul {
padding-left: 10px;
}
#menu li {
white-space: nowrap;
position: relative;
}
#menu a {
display: block;
padding: 3px;
border-radius: 3px;
width: 100%;
overflow: hidden;
text-overflow: ellipsis;
}
#menu a:hover {
background-color: #a46497;
color: #fff !important;
}
#menu .active > a {
font-weight: bold;
color: #000;
}
#menu .active > a.invalid {
color: #dd1144;
}
#menu #groups span {
position: absolute;
top: 6px;
right: 3px;
cursor: pointer;
display: block;
width: 12px;
height: 12px;
background: url('collapsed.png') transparent 0 0 no-repeat;
}
#menu #groups span:hover {
background-position: -12px 0;
}
#menu #groups span.collapsed {
background-position: 0 -12px;
}
#menu #groups span.collapsed:hover {
background-position: -12px -12px;
}
#menu #groups ul.collapsed {
display: none;
}
/* Autocomplete */
.ac_results {
border-radius: 4px;
margin-top: 2px;
background-color: #fff;
border: 1px solid #E7E7E7;
box-shadow: 0 5px 10px rgba(0, 0, 0, 0.2);
overflow: hidden;
z-index: 99999;
}
.ac_results ul {
display: block;
list-style: none;
padding: 0;
margin: 0;
}
.ac_results li {
margin: 0;
padding: 0 5px;
line-height: 2;
cursor: default;
display: block;
overflow: hidden;
white-space: nowrap;
text-overflow: ellipsis;
}
.ac_results li strong {
color: #000;
}
.ac_over {
background-color: #a46497;
color: #fff;
}
.ac_results li.ac_over strong {
color: #fff;
}
/* Right side */
#right {
overflow: auto;
margin-left: 275px;
height: 100%;
position: relative;
left: 0;
right: 0;
}
#rightInner {
max-width: 1000px;
min-width: 350px;
}
/* Navigation */
#navigation {
margin-bottom: 0;
}
.navbar .nav > li > span {
position: relative;
display: block;
color: #777;
line-height: 20px;
padding: 15px;
}
.navbar .nav > li.active > span {
background-color: #E7E7E7;
color: #555;
}
/* Content */
#content {
clear: both;
padding: 5px 15px;
}
#content > .description {
margin: 1.2em 0;
}
#content .alert-info {
margin-top: 18px;
}
dl.tree {
margin: 1.2em 0;
padding: 10px;
}
dl.tree dd {
margin: 0;
padding: 0;
line-height: 18px;
}
.elementList {
line-height: 24px;
}
h2.switchable {
background: transparent url('sort.png') no-repeat center right;
cursor: pointer;
}
.summary td:first-child {
text-align: right;
}
.summary td hr {
margin: 8px -8px;
}
#packages.summary td:first-child, #namespaces.summary td:first-child, .inherited.summary td:first-child, .used.summary td:first-child {
text-align: left;
}
.summary tr:hover td {
background: #f6f6f4;
}
.summary .description p {
margin: 0;
}
.class #methods.summary .description p:first-child, .summary .description.detailed h4:first-child {
margin-top: 8px;
}
.summary .description p + p, .summary .description ul, .summary .description pre, .summary .description.detailed h4 {
margin-top: 4px;
}
.summary dl {
margin: 0;
}
.summary dd {
margin: 0 0 0 25px;
}
.summary dt, dd {
line-height: 24px;
}
.name, .attributes {
white-space: nowrap;
}
.value code {
white-space: pre-wrap;
}
td.name, td.attributes {
width: 1%;
}
.class .methods .name, .class .properties .name, .class .constants .name {
width: auto;
white-space: normal;
}
.class .methods .name > div > code {
white-space: pre-wrap;
}
.class .methods .name > div > code span, .function .value > code {
white-space: nowrap;
display: inline-block;
}
.class .methods td.name > div, .class td.value > div {
position: relative;
padding-right: 1em;
}
.attributes code, .name code, dd code {
color: #468847;
}
.anchor {
position: absolute;
top: 0;
right: 0;
line-height: 1;
font-size: 85%;
margin: 0;
color: #a46497 !important;
}
.list {
margin: 0 0 5px 25px;
line-height: 24px;
}
/* Splitter */
#splitter {
position: fixed;
height: 100%;
width: 5px;
left: 270px;
background: #E7E7E7 url('resize.png') left center no-repeat;
cursor: e-resize;
}
#splitter.active {
opacity: .5;
}
/* Footer */
#footer {
border-top: 1px solid #e5e5e5;
clear: both;
color: #808080;
text-align: right;
padding: 2em 1em;
margin: 3em 0 40px 0;
}
/* Tree */
div.tree ul {
list-style: none;
background: url('tree-vertical.png') left repeat-y;
padding: 0;
margin-left: 20px;
}
div.tree li {
margin: 0;
padding: 0;
}
div.tree div {
padding-left: 30px;
}
div.tree div.notlast {
background: url('tree-hasnext.png') left 10px no-repeat;
}
div.tree div.last {
background: url('tree-last.png') left -240px no-repeat;
}
div.tree li.last {
background: url('tree-cleaner.png') left center repeat-y;
}
div.tree span.padding {
padding-left: 15px;
}
/* Source code */
#source {
margin: 1em 0 1em 1em;
border: 1px solid #ccc;
border-radius: 4px;
overflow: auto;
}
#source pre {
padding: 0;
border: none;
overflow: visible;
}
#source .numbers {
float: left;
background-color: transparent;
}
#source .code {
}
.php-keyword1 {
color: #468847;
font-weight: bold;
}
.php-keyword2 {
font-weight: bold;
}
.php-var {
color: #c09853;
font-weight: bold;
}
.php-num {
color: #006dcc;
}
.php-quote {
color: #006dcc;
}
.php-comment {
color: #929292;
}
.xlang {
color: #468847;
font-weight: bold;
}
span.l {
display: block;
}
span.l.selected {
background: #f9f2d2;
}
span.l a {
color: #333333;
}
span.l a:hover, span.l a:active, span.l a:focus {
background: transparent;
color: #333333 !important;
}
span.l .php-var a {
color: #c09853;
}
span.l .php-var a:hover, span.l .php-var a:active, span.l .php-var a:focus {
color: #c09853 !important;
}
span.l a.l {
background: #fbfbfc;
margin-right: 8px;
padding: 2px 2px 2px 8px;
color: #c0c0c0;
}
span.l a.l:hover, span.l a.l:active, span.l a.l:focus {
background: #fbfbfc;
color: #c0c0c0 !important;
}
/* Small screens */
#rightInner.medium .name, #rightInner.medium .attributes {
white-space: normal;
}
/* global style */
.left, .summary td.left {
text-align: left;
}
.right, .summary td.right {
text-align: right;
}
/* Custom styles for Woo */
.navbar-header {
padding: 10px;
}
.navbar-brand {
background: url(woocommerce_logo_white.png) no-repeat left top;
background-size: 149px 30px;
width: 159px;
padding: 30px 0 0 0;
overflow: hidden;
height: 0;
}
#navigation {
background: #3c3c3c;
color: #fff;
}
#navigation a {
color: #fff;
}
.navbar .nav > li > span {
color: #999;
}
.navbar .nav > li > a:hover > span {
color: #a46497;
}
.navbar .nav > li.active > span, .navbar .nav > li.active > a {
background: #a46497;
color: #fff;
}
a {
color: #a46497;
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 126 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 128 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 172 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 127 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 5.8 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 6.1 KiB

View File

@ -1,4 +0,0 @@
{contentType text}
User-agent: *
Disallow:
Sitemap: {$config->baseUrl}/sitemap.xml

View File

@ -1,26 +0,0 @@
{contentType xml}
<?xml version="1.0" encoding="UTF-8"?>
<urlset xmlns="http://www.sitemaps.org/schemas/sitemap/0.9">
<url>
<loc>{$config->baseUrl}/index.html</loc>
</url>
<url n:foreach="$namespaces as $namespace">
<loc>{$config->baseUrl}/{$namespace|namespaceUrl}</loc>
</url>
<url n:foreach="$packages as $package">
<loc>{$config->baseUrl}/{$package|packageUrl}</loc>
</url>
{define elements}
<url n:foreach="$elements as $element">
<loc>{$config->baseUrl}/{$element|elementUrl}</loc>
</url>
{/define}
{include elements, elements => $classes}
{include elements, elements => $interfaces}
{include elements, elements => $traits}
{include elements, elements => $exceptions}
{include elements, elements => $constants}
{include elements, elements => $functions}
</urlset>

View File

@ -1,12 +0,0 @@
{layout '@layout.latte'}
{var $robots = false}
{block title}File {$fileName}{/block}
{block content}
<div id="source">
{var $lineRegex = '~<span class="line">(\s*)(\d+):(\s*)</span>([^\\n]*(?:\\n|$))~'}
<pre class="numbers"><code>{$source|replaceRE:$lineRegex,'<span class="l"><a href="#$2">$1$2$3</a></span>'|noescape}</code></pre>
<pre class="code"><code>{$source|replaceRE:$lineRegex,'<span id="$2" class="l">$4</span>'|noescape}</code></pre>
</div>
{/block}

View File

@ -1,67 +0,0 @@
{layout '@layout.latte'}
{var $active = 'tree'}
{block title}Tree{/block}
{define tree}
<div class="tree">
<ul>
{var $level = -1}
{foreach $tree as $reflectionName => $reflection|noiterator}
{if $level === $tree->getDepth()}
</li>
{elseif $level > $tree->getDepth()}
{='</ul></li>'|repeat:$level - $tree->getDepth()|noescape}
{elseif -1 !== $level}
<ul>
{/if}
<li n:class="!$tree->hasSibling() ? last"><div class="{if $tree->hasSibling()}not{/if}last"><a href="{$reflectionName|classUrl}" n:tag-if="$reflection->documented"><span n:class="$reflection->deprecated ? deprecated, !$reflection->valid ? invalid">{$reflectionName}</span></a>
{var $interfaces = $reflection->ownInterfaces}
{if $interfaces} implements {foreach $interfaces as $interface}
<a href="{$interface|classUrl}" n:tag-if="$interface->documented"><span n:class="$interface->deprecated ? deprecated, !$interface->valid ? invalid">{$interface->name}</span></a>{sep}, {/sep}
{/foreach}{/if}
{var $traits = $reflection->ownTraits}
{if $traits}{if $interfaces}<br><span class="padding"></span>{/if} uses {foreach $traits as $trait}
{if is_string($trait)}
{$trait} (not available)
{else}
<a href="{$trait|classUrl}" n:tag-if="$trait->documented"><span n:class="$trait->deprecated ? deprecated, !$trait->valid ? invalid">{$trait->name}</span></a>{sep}, {/sep}
{/}
{/foreach}{/if}
</div>
{var $level = $tree->getDepth()}
{/foreach}
</li>
{='</ul></li>'|repeat:$level|noescape}
</ul>
</div>
{/define}
{block content}
<div id="content">
<h1>{include title}</h1>
{if $classTree->valid()}
<h2>Classes</h2>
{include tree, tree => $classTree}
{/if}
{if $interfaceTree->valid()}
<h2>Interfaces</h2>
{include tree, tree => $interfaceTree}
{/if}
{if $traitTree->valid()}
<h2>Traits</h2>
{include tree, tree => $traitTree}
{/if}
{if $exceptionTree->valid()}
<h2>Exceptions</h2>
{include tree, tree => $exceptionTree}
{/if}
</div>
{/block}

View File

@ -66,34 +66,3 @@ p.woocommerce-actions,
.woocommerce-about-text {
margin-bottom: 1em !important;
}
div.woocommerce-legacy-shipping-notice,
div.woocommerce-no-shipping-methods-notice {
overflow: hidden;
padding: 1px 12px;
p {
position: relative;
z-index: 1;
line-height: 1.5em;
margin: 12px 0;
&.main {
font-size: 1.1em;
}
}
&::before {
content: "\e01b";
font-family: "WooCommerce";
text-align: center;
line-height: 1;
color: #f7f1f6;
display: block;
width: 1em;
font-size: 20em;
top: 36px;
right: 12px;
position: absolute;
}
}

View File

@ -2263,7 +2263,8 @@ ul.wc_coupon_list_block {
&::before {
content: "";
background: url("../images/wpspin.gif") no-repeat center top;
background: url("../images/wpspin-2x.gif") no-repeat center top;
background-size: 71%;
}
}
}
@ -3270,6 +3271,10 @@ table.wc_shipping {
margin-top: 0;
}
.wc-shipping-zone-settings tbody {
display: inherit;
}
table {
tr,
@ -4568,6 +4573,7 @@ img.help_tip {
}
}
.woocommerce_attribute,
.woocommerce_variation {
h3 .sort {
@ -4956,6 +4962,7 @@ img.help_tip {
}
}
&.woocommerce_attribute h3,
&.woocommerce_variation h3 {
cursor: pointer;
padding: 0.5em 0.75em 0.5em 1em !important;

View File

@ -6,9 +6,9 @@
/**
* Imports
*/
@import 'mixins';
@import 'variables';
@import 'fonts';
@import "mixins";
@import "variables";
@import "fonts";
/**
* Styling begins
@ -37,7 +37,7 @@ ul.woocommerce_stats {
}
strong {
font-family: Georgia, 'Times New Roman', 'Bitstream Charter', Times, serif;
font-family: Georgia, "Times New Roman", "Bitstream Charter", Times, serif;
font-size: 4em;
line-height: 1.2em;
font-weight: normal;
@ -47,13 +47,16 @@ ul.woocommerce_stats {
}
#woocommerce_dashboard_status {
.inside {
padding: 0;
margin: 0;
}
.best-seller-this-month {
a {
strong {
margin-right: 48px;
}
@ -111,6 +114,7 @@ ul.woocommerce_stats {
}
&::before {
@include icon();
font-size: 2em;
position: relative;
@ -132,8 +136,8 @@ ul.woocommerce_stats {
width: 100%;
a::before {
font-family: 'Dashicons';
content: '\f185';
font-family: "Dashicons";
content: "\f185";
}
}
@ -141,7 +145,7 @@ ul.woocommerce_stats {
width: 100%;
a::before {
content: '\e006';
content: "\e006";
}
}
@ -149,14 +153,15 @@ ul.woocommerce_stats {
border-right: 1px solid #ececec;
a::before {
content: '\e011';
content: "\e011";
color: $green;
}
}
li.on-hold-orders {
a::before {
content: '\e033';
content: "\e033";
color: #999;
}
}
@ -165,14 +170,15 @@ ul.woocommerce_stats {
border-right: 1px solid #ececec;
a::before {
content: '\e016';
content: "\e016";
color: $orange;
}
}
li.out-of-stock {
a::before {
content: '\e013';
content: "\e013";
color: $red;
}
}
@ -180,6 +186,7 @@ ul.woocommerce_stats {
}
#woocommerce_dashboard_recent_reviews {
li {
line-height: 1.5em;
margin-bottom: 12px;
@ -210,11 +217,11 @@ ul.woocommerce_stats {
line-height: 1.5;
margin-left: 0.5em;
width: 5.4em;
font-family: 'WooCommerce' !important;
font-family: "WooCommerce" !important;
&::before {
content: '\e021\e021\e021\e021\e021';
color: darken( #ccc, 10% );
content: "\e021\e021\e021\e021\e021";
color: darken(#ccc, 10%);
float: left;
top: 0;
left: 0;
@ -233,7 +240,7 @@ ul.woocommerce_stats {
}
span::before {
content: '\e020\e020\e020\e020\e020';
content: "\e020\e020\e020\e020\e020";
top: 0;
position: absolute;
left: 0;
@ -245,6 +252,6 @@ ul.woocommerce_stats {
}
#dash-right-now li.product-count a::before {
font-family: 'WooCommerce';
content: '\e01d';
font-family: "WooCommerce";
content: "\e01d";
}

View File

@ -32,6 +32,7 @@ a.suggestion-dismiss::before {
a::before {
@include iconbeforedashicons( "\f106" );
@media only screen and (max-width: 900px) {

File diff suppressed because it is too large Load Diff

View File

@ -733,7 +733,7 @@ p.demo_store,
}
&:hover {
background-color: darken( $secondary, 5% );
background-color: darken($secondary, 5%);
text-decoration: none;
background-image: none;
color: $secondarytext;
@ -745,7 +745,7 @@ p.demo_store,
-webkit-font-smoothing: antialiased;
&:hover {
background-color: darken( $primary, 5% );
background-color: darken($primary, 5%);
color: $primarytext;
}
@ -1101,6 +1101,10 @@ p.demo_store,
small {
font-weight: normal;
}
del {
font-weight: normal;
}
}
tbody:first-child tr:first-child {
@ -1674,7 +1678,7 @@ p.demo_store,
.price_slider_wrapper .ui-widget-content {
border-radius: 1em;
background-color: darken( $primary, 30% );
background-color: darken($primary, 30%);
border: 0;
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 17 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 31.5 27.78"><defs><style>.cls-1,.cls-2{fill:#fff;}.cls-2{stroke:#fff;stroke-linecap:round;stroke-miterlimit:10;stroke-width:1.5px;}</style></defs><title>Asset 5</title><g id="Layer_2" data-name="Layer 2"><g id="Layer_1-2" data-name="Layer 1"><path class="cls-1" d="M4.8,16.57H6.61a2,2,0,0,1,2,2v8.55a0,0,0,0,1,0,0H2.8a0,0,0,0,1,0,0V18.57A2,2,0,0,1,4.8,16.57Z"/><path class="cls-1" d="M14.85,7.53h1.81a2,2,0,0,1,2,2V27.12a0,0,0,0,1,0,0H12.85a0,0,0,0,1,0,0V9.53A2,2,0,0,1,14.85,7.53Z"/><path class="cls-1" d="M24.89,0H26.7a2,2,0,0,1,2,2V27.12a0,0,0,0,1,0,0H22.89a0,0,0,0,1,0,0V2A2,2,0,0,1,24.89,0Z"/><line class="cls-2" x1="0.75" y1="27.03" x2="30.75" y2="27.03"/></g></g></svg>

After

Width:  |  Height:  |  Size: 729 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 21 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.0 KiB

View File

@ -21,6 +21,12 @@ jQuery(function( $ ) {
// Get value
var select_val = $( this ).val();
if ( 'percent' === select_val ) {
$( '#coupon_amount' ).removeClass( 'wc_input_price' ).addClass( 'wc_input_decimal' );
} else {
$( '#coupon_amount' ).removeClass( 'wc_input_decimal' ).addClass( 'wc_input_price' );
}
if ( select_val !== 'fixed_cart' ) {
$( '.limit_usage_to_x_items_field' ).show();
} else {

View File

@ -83,7 +83,7 @@ jQuery( function ( $ ) {
.prop( 'name', input_name )
.prop( 'placeholder', placeholder )
.addClass( 'js_field-state' )
.val( value );
.val( '' );
$state.replaceWith( $newstate );
}
@ -400,15 +400,17 @@ jQuery( function ( $ ) {
if ( value != null ) {
wc_meta_boxes_order_items.block();
var user_id = $( '#customer_user' ).val();
var user_id = $( '#customer_user' ).val();
var user_email = $( '#_billing_email' ).val();
var data = $.extend( {}, wc_meta_boxes_order_items.get_taxable_address(), {
action : 'woocommerce_add_coupon_discount',
dataType : 'json',
order_id : woocommerce_admin_meta_boxes.post_id,
security : woocommerce_admin_meta_boxes.order_item_nonce,
coupon : value,
user_id : user_id
action : 'woocommerce_add_coupon_discount',
dataType : 'json',
order_id : woocommerce_admin_meta_boxes.post_id,
security : woocommerce_admin_meta_boxes.order_item_nonce,
coupon : value,
user_id : user_id,
user_email : user_email
} );
$.post( woocommerce_admin_meta_boxes.ajax_url, data, function( response ) {

View File

@ -118,11 +118,12 @@ jQuery( function( $ ) {
// Init TipTip
$( '#tiptip_holder' ).removeAttr( 'style' );
$( '#tiptip_arrow' ).removeAttr( 'style' );
$( '.woocommerce_variations .tips, .woocommerce_variations .help_tip, .woocommerce_variations .woocommerce-help-tip', wrapper ).tipTip({
'attribute': 'data-tip',
'fadeIn': 50,
'fadeOut': 50,
'delay': 200
$( '.woocommerce_variations .tips, .woocommerce_variations .help_tip, .woocommerce_variations .woocommerce-help-tip', wrapper )
.tipTip({
'attribute': 'data-tip',
'fadeIn': 50,
'fadeOut': 50,
'delay': 200
});
// Datepicker fields
@ -195,7 +196,10 @@ jQuery( function( $ ) {
offset = parseInt( ( current_page - 1 ) * woocommerce_admin_meta_boxes_variations.variations_per_page, 10 );
$( '.woocommerce_variations .woocommerce_variation' ).each( function ( index, el ) {
$( '.variation_menu_order', el ).val( parseInt( $( el ).index( '.woocommerce_variations .woocommerce_variation' ), 10 ) + 1 + offset ).change();
$( '.variation_menu_order', el )
.val( parseInt( $( el )
.index( '.woocommerce_variations .woocommerce_variation' ), 10 ) + 1 + offset )
.change();
});
}
};
@ -259,14 +263,16 @@ jQuery( function( $ ) {
if ( $button.is( '.remove' ) ) {
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( '' ).change();
wc_meta_boxes_product_variations_media.setting_variation_image.find( 'img' ).eq( 0 ).attr( 'src', woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src );
wc_meta_boxes_product_variations_media.setting_variation_image.find( 'img' ).eq( 0 )
.attr( 'src', woocommerce_admin_meta_boxes_variations.woocommerce_placeholder_img_src );
wc_meta_boxes_product_variations_media.setting_variation_image.find( '.upload_image_button' ).removeClass( 'remove' );
} else {
// If the media frame already exists, reopen it.
if ( wc_meta_boxes_product_variations_media.variable_image_frame ) {
wc_meta_boxes_product_variations_media.variable_image_frame.uploader.uploader.param( 'post_id', wc_meta_boxes_product_variations_media.setting_variation_image_id );
wc_meta_boxes_product_variations_media.variable_image_frame.uploader.uploader
.param( 'post_id', wc_meta_boxes_product_variations_media.setting_variation_image_id );
wc_meta_boxes_product_variations_media.variable_image_frame.open();
return;
} else {
@ -291,7 +297,8 @@ jQuery( function( $ ) {
// When an image is selected, run a callback.
wc_meta_boxes_product_variations_media.variable_image_frame.on( 'select', function () {
var attachment = wc_meta_boxes_product_variations_media.variable_image_frame.state().get( 'selection' ).first().toJSON(),
var attachment = wc_meta_boxes_product_variations_media.variable_image_frame.state()
.get( 'selection' ).first().toJSON(),
url = attachment.sizes && attachment.sizes.thumbnail ? attachment.sizes.thumbnail.url : attachment.url;
$( '.upload_image_id', wc_meta_boxes_product_variations_media.setting_variation_image ).val( attachment.id ).change();
@ -328,7 +335,8 @@ jQuery( function( $ ) {
$( '#variable_product_options' )
.on( 'click', 'button.save-variation-changes', this.save_variations )
.on( 'click', 'button.cancel-variation-changes', this.cancel_variations )
.on( 'click', '.remove_variation', this.remove_variation );
.on( 'click', '.remove_variation', this.remove_variation )
.on( 'click','.downloadable_files a.delete', this.input_changed );
$( document.body )
.on( 'change', '#variable_product_options .woocommerce_variations :input', this.input_changed )
@ -553,7 +561,8 @@ jQuery( function( $ ) {
cancel_variations: function() {
var current = parseInt( $( '#variable_product_options' ).find( '.woocommerce_variations' ).attr( 'data-page' ), 10 );
$( '#variable_product_options' ).find( '.woocommerce_variations .variation-needs-update' ).removeClass( 'variation-needs-update' );
$( '#variable_product_options' ).find( '.woocommerce_variations .variation-needs-update' )
.removeClass( 'variation-needs-update' );
$( '.variations-defaults select' ).each( function() {
$( this ).val( $( this ).attr( 'data-current' ) );
});
@ -582,6 +591,7 @@ jQuery( function( $ ) {
var variation = $( response );
variation.addClass( 'variation-needs-update' );
$( '.woocommerce-notice-invalid-variation' ).remove();
$( '#variable_product_options' ).find( '.woocommerce_variations' ).prepend( variation );
$( 'button.cancel-variation-changes, button.save-variation-changes' ).removeAttr( 'disabled' );
$( '#variable_product_options' ).trigger( 'woocommerce_variations_added', 1 );
@ -617,7 +627,9 @@ jQuery( function( $ ) {
$.post( woocommerce_admin_meta_boxes_variations.ajax_url, data, function() {
var wrapper = $( '#variable_product_options' ).find( '.woocommerce_variations' ),
current_page = parseInt( wrapper.attr( 'data-page' ), 10 ),
total_pages = Math.ceil( ( parseInt( wrapper.attr( 'data-total' ), 10 ) - 1 ) / woocommerce_admin_meta_boxes_variations.variations_per_page ),
total_pages = Math.ceil( (
parseInt( wrapper.attr( 'data-total' ), 10 ) - 1
) / woocommerce_admin_meta_boxes_variations.variations_per_page ),
page = 1;
$( '#woocommerce-product-data' ).trigger( 'woocommerce_variations_removed' );
@ -726,7 +738,8 @@ jQuery( function( $ ) {
if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_delete_all_variations ) ) {
if ( window.confirm( woocommerce_admin_meta_boxes_variations.i18n_last_warning ) ) {
data.allowed = true;
changes = parseInt( $( '#variable_product_options' ).find( '.woocommerce_variations' ).attr( 'data-total' ), 10 ) * -1;
changes = parseInt( $( '#variable_product_options' ).find( '.woocommerce_variations' )
.attr( 'data-total' ), 10 ) * -1;
}
}
break;

View File

@ -138,7 +138,7 @@ jQuery(function( $ ) {
var groupby = $( this ) .data( 'groupby' );
var index_type = $( this ).data( 'index_type' );
var export_format = $( this ).data( 'export' );
var csv_data = 'data:text/csv;charset=utf-8,\uFEFF';
var csv_data = '';
var s, series_data, d;
if ( 'table' === export_format ) {
@ -243,8 +243,9 @@ jQuery(function( $ ) {
} );
}
csv_data = 'data:text/csv;charset=utf-8,\uFEFF' + encodeURIComponent( csv_data );
// Set data as href and return
$( this ).attr( 'href', encodeURI( csv_data ) );
$( this ).attr( 'href', csv_data );
return true;
});
});

View File

@ -161,12 +161,28 @@
lastRow = $( this ).find( 'tbody tr:last' ),
firstRow = $( this ).find( 'tbody tr:first' );
table.find( '.wc-item-reorder-nav .wc-move-disabled' ).removeClass( 'wc-move-disabled' ).attr( { 'tabindex': '0', 'aria-hidden': 'false' } );
firstRow.find( '.wc-item-reorder-nav .wc-move-up' ).addClass( 'wc-move-disabled' ).attr( { 'tabindex': '-1', 'aria-hidden': 'true' } );
lastRow.find( '.wc-item-reorder-nav .wc-move-down' ).addClass( 'wc-move-disabled' ).attr( { 'tabindex': '-1', 'aria-hidden': 'true' } );
table.find( '.wc-item-reorder-nav .wc-move-disabled' ).removeClass( 'wc-move-disabled' )
.attr( { 'tabindex': '0', 'aria-hidden': 'false' } );
firstRow.find( '.wc-item-reorder-nav .wc-move-up' ).addClass( 'wc-move-disabled' )
.attr( { 'tabindex': '-1', 'aria-hidden': 'true' } );
lastRow.find( '.wc-item-reorder-nav .wc-move-down' ).addClass( 'wc-move-disabled' )
.attr( { 'tabindex': '-1', 'aria-hidden': 'true' } );
} );
$( '.wc-item-reorder-nav').closest( 'table' ).trigger( 'updateMoveButtons' );
$( '.submit button' ).on( 'click', function() {
if (
$( 'select#woocommerce_allowed_countries' ).val() === 'specific' &&
! $( '[name="woocommerce_specific_allowed_countries[]"]' ).val()
) {
if ( window.confirm( woocommerce_settings_params.i18n_no_specific_countries_selected ) ) {
return true;
}
return false;
}
} );
});
})( jQuery, woocommerce_settings_params, wp );

View File

@ -11,7 +11,12 @@
*/
init: function() {
$( document.body )
.on( 'keyup change', 'form.register #reg_password, form.checkout #account_password, form.edit-account #password_1, form.lost_reset_password #password_1', this.strengthMeter );
.on(
'keyup change',
'form.register #reg_password, form.checkout #account_password, ' +
'form.edit-account #password_1, form.lost_reset_password #password_1',
this.strengthMeter
);
$( 'form.checkout #createaccount' ).change();
},
@ -19,17 +24,28 @@
* Strength Meter.
*/
strengthMeter: function() {
var wrapper = $( 'form.register, form.checkout, form.edit-account, form.lost_reset_password' ),
submit = $( 'button[type="submit"]', wrapper ),
field = $( '#reg_password, #account_password, #password_1', wrapper ),
strength = 1,
fieldValue = field.val();
var wrapper = $( 'form.register, form.checkout, form.edit-account, form.lost_reset_password' ),
submit = $( 'button[type="submit"]', wrapper ),
field = $( '#reg_password, #account_password, #password_1', wrapper ),
strength = 1,
fieldValue = field.val(),
stop_checkout = ! wrapper.is( 'form.checkout' ); // By default is disabled on checkout.
wc_password_strength_meter.includeMeter( wrapper, field );
strength = wc_password_strength_meter.checkPasswordStrength( wrapper, field );
if ( fieldValue.length > 0 && strength < wc_password_strength_meter_params.min_password_strength && ! wrapper.is( 'form.checkout' ) && -1 !== strength ) {
// Allow password strength meter stop checkout.
if ( wc_password_strength_meter_params.stop_checkout ) {
stop_checkout = true;
}
if (
fieldValue.length > 0 &&
strength < wc_password_strength_meter_params.min_password_strength &&
-1 !== strength &&
stop_checkout
) {
submit.attr( 'disabled', 'disabled' ).addClass( 'disabled' );
} else {
submit.removeAttr( 'disabled', 'disabled' ).removeClass( 'disabled' );

View File

@ -10,8 +10,7 @@
"composer/installers": "1.6.0"
},
"require-dev": {
"apigen/apigen": "4.1.2",
"nette/utils": "2.5.3",
"myclabs/deep-copy": "1.7.0",
"phpunit/phpunit": "6.5.14",
"woocommerce/woocommerce-sniffs": "0.0.6"
},

2201
composer.lock generated

File diff suppressed because it is too large Load Diff

View File

@ -17,17 +17,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'AU',
'state' => '',
'rate' => '10.0000',
'name' => 'GST',
'shipping' => true,
),
),
),
),
'BD' => array(
'currency_code' => 'BDT',
@ -37,17 +26,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'in',
'tax_rates' => array(
'' => array(
array(
'country' => 'BD',
'state' => '',
'rate' => '15.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'BE' => array(
'currency_code' => 'EUR',
@ -57,17 +35,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'BE',
'state' => '',
'rate' => '21.0000',
'name' => 'BTW',
'shipping' => true,
),
),
),
),
'BR' => array(
'currency_code' => 'BRL',
@ -77,7 +44,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(),
),
'CA' => array(
'currency_code' => 'CAD',
@ -87,141 +53,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'BC' => array(
array(
'country' => 'CA',
'state' => 'BC',
'rate' => '7.0000',
'name' => _x( 'PST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => false,
'priority' => 2,
),
),
'SK' => array(
array(
'country' => 'CA',
'state' => 'SK',
'rate' => '5.0000',
'name' => _x( 'PST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => false,
'priority' => 2,
),
),
'MB' => array(
array(
'country' => 'CA',
'state' => 'MB',
'rate' => '8.0000',
'name' => _x( 'PST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => false,
'priority' => 2,
),
),
'QC' => array(
array(
'country' => 'CA',
'state' => 'QC',
'rate' => '9.975',
'name' => _x( 'QST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => false,
'priority' => 2,
),
),
'*' => array(
array(
'country' => 'CA',
'state' => 'ON',
'rate' => '13.0000',
'name' => _x( 'HST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'NL',
'rate' => '13.0000',
'name' => _x( 'HST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'NB',
'rate' => '13.0000',
'name' => _x( 'HST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'PE',
'rate' => '14.0000',
'name' => _x( 'HST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'NS',
'rate' => '15.0000',
'name' => _x( 'HST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'AB',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'BC',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'NT',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'NU',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'YT',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'SK',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'MB',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
array(
'country' => 'CA',
'state' => 'QC',
'rate' => '5.0000',
'name' => _x( 'GST', 'Canadian Tax Rates', 'woocommerce' ),
'shipping' => true,
),
),
),
),
'DE' => array(
'currency_code' => 'EUR',
@ -231,17 +62,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'DE',
'state' => '',
'rate' => '19.0000',
'name' => 'Mwst.',
'shipping' => true,
),
),
),
),
'DK' => array(
'currency_code' => 'DKK',
@ -251,17 +71,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => '*',
'state' => '',
'rate' => '25.0000',
'name' => 'Moms',
'shipping' => true,
),
),
),
),
'ES' => array(
'currency_code' => 'EUR',
@ -271,17 +80,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'ES',
'state' => '',
'rate' => '21.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'FI' => array(
'currency_code' => 'EUR',
@ -291,17 +89,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'FI',
'state' => '',
'rate' => '24.0000',
'name' => 'ALV',
'shipping' => true,
),
),
),
),
'FR' => array(
'currency_code' => 'EUR',
@ -311,17 +98,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'FR',
'state' => '',
'rate' => '20.0000',
'name' => 'TVA',
'shipping' => true,
),
),
),
),
'GB' => array(
'currency_code' => 'GBP',
@ -331,17 +107,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'GB',
'state' => '',
'rate' => '20.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'HU' => array(
'currency_code' => 'HUF',
@ -351,17 +116,6 @@ return array(
'num_decimals' => 0,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'HU',
'state' => '',
'rate' => '27.0000',
'name' => 'ÁFA',
'shipping' => true,
),
),
),
),
'IT' => array(
'currency_code' => 'EUR',
@ -371,17 +125,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'IT',
'state' => '',
'rate' => '22.0000',
'name' => 'IVA',
'shipping' => true,
),
),
),
),
'JP' => array(
'currency_code' => 'JPY',
@ -391,17 +134,6 @@ return array(
'num_decimals' => 0,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'JP',
'state' => '',
'rate' => '8.0000',
'name' => __( 'Consumption tax', 'woocommerce' ),
'shipping' => true,
),
),
),
),
'MD' => array(
'currency_code' => 'MDL',
@ -411,17 +143,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'MD',
'state' => '',
'rate' => '20.0000',
'name' => 'TVA',
'shipping' => true,
),
),
),
),
'NL' => array(
'currency_code' => 'EUR',
@ -431,17 +152,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'NL',
'state' => '',
'rate' => '21.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'NO' => array(
'currency_code' => 'Kr',
@ -451,17 +161,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'NO',
'state' => '',
'rate' => '25.0000',
'name' => 'MVA',
'shipping' => true,
),
),
),
),
'NP' => array(
'currency_code' => 'NPR',
@ -471,17 +170,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'NP',
'state' => '',
'rate' => '13.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'PL' => array(
'currency_code' => 'PLN',
@ -491,17 +179,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'PL',
'state' => '',
'rate' => '23.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'PY' => array(
'currency_code' => 'PYG',
@ -511,17 +188,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'PY',
'state' => '',
'rate' => '10.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'RO' => array(
'currency_code' => 'RON',
@ -531,17 +197,16 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'RO',
'state' => '',
'rate' => '19.0000',
'name' => 'TVA',
'shipping' => true,
),
),
),
),
'RS' => array(
'currency_code' => 'RSD',
'currency_pos' => 'right_space',
'thousand_sep' => '.',
'decimal_sep' => ',',
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(),
),
'TH' => array(
'currency_code' => 'THB',
@ -551,17 +216,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'TH',
'state' => '',
'rate' => '7.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
'TR' => array(
'currency_code' => 'TRY',
@ -571,17 +225,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'TR',
'state' => '',
'rate' => '18.0000',
'name' => 'KDV',
'shipping' => true,
),
),
),
),
'US' => array(
'currency_code' => 'USD',
@ -591,440 +234,6 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'oz',
'dimension_unit' => 'in',
'tax_rates' => array(
'AL' => array(
array(
'country' => 'US',
'state' => 'AL',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'AZ' => array(
array(
'country' => 'US',
'state' => 'AZ',
'rate' => '5.6000',
'name' => 'State Tax',
'shipping' => false,
),
),
'AR' => array(
array(
'country' => 'US',
'state' => 'AR',
'rate' => '6.5000',
'name' => 'State Tax',
'shipping' => true,
),
),
'CA' => array(
array(
'country' => 'US',
'state' => 'CA',
'rate' => '7.5000',
'name' => 'State Tax',
'shipping' => false,
),
),
'CO' => array(
array(
'country' => 'US',
'state' => 'CO',
'rate' => '2.9000',
'name' => 'State Tax',
'shipping' => false,
),
),
'CT' => array(
array(
'country' => 'US',
'state' => 'CT',
'rate' => '6.3500',
'name' => 'State Tax',
'shipping' => true,
),
),
'DC' => array(
array(
'country' => 'US',
'state' => 'DC',
'rate' => '5.7500',
'name' => 'State Tax',
'shipping' => true,
),
),
'FL' => array(
array(
'country' => 'US',
'state' => 'FL',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'GA' => array(
array(
'country' => 'US',
'state' => 'GA',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'GU' => array(
array(
'country' => 'US',
'state' => 'GU',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'HI' => array(
array(
'country' => 'US',
'state' => 'HI',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'ID' => array(
array(
'country' => 'US',
'state' => 'ID',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'IL' => array(
array(
'country' => 'US',
'state' => 'IL',
'rate' => '6.2500',
'name' => 'State Tax',
'shipping' => false,
),
),
'IN' => array(
array(
'country' => 'US',
'state' => 'IN',
'rate' => '7.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'IA' => array(
array(
'country' => 'US',
'state' => 'IA',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'KS' => array(
array(
'country' => 'US',
'state' => 'KS',
'rate' => '6.1500',
'name' => 'State Tax',
'shipping' => true,
),
),
'KY' => array(
array(
'country' => 'US',
'state' => 'KY',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'LA' => array(
array(
'country' => 'US',
'state' => 'LA',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'ME' => array(
array(
'country' => 'US',
'state' => 'ME',
'rate' => '5.5000',
'name' => 'State Tax',
'shipping' => false,
),
),
'MD' => array(
array(
'country' => 'US',
'state' => 'MD',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'MA' => array(
array(
'country' => 'US',
'state' => 'MA',
'rate' => '6.2500',
'name' => 'State Tax',
'shipping' => false,
),
),
'MI' => array(
array(
'country' => 'US',
'state' => 'MI',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'MN' => array(
array(
'country' => 'US',
'state' => 'MN',
'rate' => '6.8750',
'name' => 'State Tax',
'shipping' => true,
),
),
'MS' => array(
array(
'country' => 'US',
'state' => 'MS',
'rate' => '7.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'MO' => array(
array(
'country' => 'US',
'state' => 'MO',
'rate' => '4.225',
'name' => 'State Tax',
'shipping' => false,
),
),
'NE' => array(
array(
'country' => 'US',
'state' => 'NE',
'rate' => '5.5000',
'name' => 'State Tax',
'shipping' => true,
),
),
'NV' => array(
array(
'country' => 'US',
'state' => 'NV',
'rate' => '6.8500',
'name' => 'State Tax',
'shipping' => false,
),
),
'NJ' => array(
array(
'country' => 'US',
'state' => 'NJ',
'rate' => '6.8750',
'name' => 'State Tax',
'shipping' => true,
),
),
'NM' => array(
array(
'country' => 'US',
'state' => 'NM',
'rate' => '5.1250',
'name' => 'State Tax',
'shipping' => true,
),
),
'NY' => array(
array(
'country' => 'US',
'state' => 'NY',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'NC' => array(
array(
'country' => 'US',
'state' => 'NC',
'rate' => '4.7500',
'name' => 'State Tax',
'shipping' => true,
),
),
'ND' => array(
array(
'country' => 'US',
'state' => 'ND',
'rate' => '5.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'OH' => array(
array(
'country' => 'US',
'state' => 'OH',
'rate' => '5.7500',
'name' => 'State Tax',
'shipping' => true,
),
),
'OK' => array(
array(
'country' => 'US',
'state' => 'OK',
'rate' => '4.5000',
'name' => 'State Tax',
'shipping' => false,
),
),
'PA' => array(
array(
'country' => 'US',
'state' => 'PA',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'PR' => array(
array(
'country' => 'US',
'state' => 'PR',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'RI' => array(
array(
'country' => 'US',
'state' => 'RI',
'rate' => '7.0000',
'name' => 'State Tax',
'shipping' => false,
),
),
'SC' => array(
array(
'country' => 'US',
'state' => 'SC',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'SD' => array(
array(
'country' => 'US',
'state' => 'SD',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'TN' => array(
array(
'country' => 'US',
'state' => 'TN',
'rate' => '7.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'TX' => array(
array(
'country' => 'US',
'state' => 'TX',
'rate' => '6.2500',
'name' => 'State Tax',
'shipping' => true,
),
),
'UT' => array(
array(
'country' => 'US',
'state' => 'UT',
'rate' => '5.9500',
'name' => 'State Tax',
'shipping' => false,
),
),
'VT' => array(
array(
'country' => 'US',
'state' => 'VT',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'VA' => array(
array(
'country' => 'US',
'state' => 'VA',
'rate' => '5.3000',
'name' => 'State Tax',
'shipping' => false,
),
),
'WA' => array(
array(
'country' => 'US',
'state' => 'WA',
'rate' => '6.5000',
'name' => 'State Tax',
'shipping' => true,
),
),
'WV' => array(
array(
'country' => 'US',
'state' => 'WV',
'rate' => '6.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'WI' => array(
array(
'country' => 'US',
'state' => 'WI',
'rate' => '5.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
'WY' => array(
array(
'country' => 'US',
'state' => 'WY',
'rate' => '4.0000',
'name' => 'State Tax',
'shipping' => true,
),
),
),
),
'ZA' => array(
'currency_code' => 'ZAR',
@ -1034,16 +243,5 @@ return array(
'num_decimals' => 2,
'weight_unit' => 'kg',
'dimension_unit' => 'cm',
'tax_rates' => array(
'' => array(
array(
'country' => 'ZA',
'state' => '',
'rate' => '15.0000',
'name' => 'VAT',
'shipping' => true,
),
),
),
),
);

View File

@ -1077,6 +1077,7 @@ return array(
'VS' => __( 'Vaslui', 'woocommerce' ),
'VN' => __( 'Vrancea', 'woocommerce' ),
),
'RS' => array(),
'SG' => array(),
'SK' => array(),
'SI' => array(),

144
i18n/states/UG.php Normal file
View File

@ -0,0 +1,144 @@
<?php
/**
* Uganda Districts
*
* Based on English names published at https://en.wikipedia.org/wiki/ISO_3166-2:UG
*
* @package WooCommerce\i18n
* @version 3.7.0
*/
global $states;
defined( 'ABSPATH' ) || exit;
$states['UG'] = array(
'UG314' => __( 'Abim', 'woocommerce' ),
'UG301' => __( 'Adjumani', 'woocommerce' ),
'UG322' => __( 'Agago', 'woocommerce' ),
'UG323' => __( 'Alebtong', 'woocommerce' ),
'UG315' => __( 'Amolatar', 'woocommerce' ),
'UG324' => __( 'Amudat', 'woocommerce' ),
'UG216' => __( 'Amuria', 'woocommerce' ),
'UG316' => __( 'Amuru', 'woocommerce' ),
'UG302' => __( 'Apac', 'woocommerce' ),
'UG303' => __( 'Arua', 'woocommerce' ),
'UG217' => __( 'Budaka', 'woocommerce' ),
'UG218' => __( 'Bududa', 'woocommerce' ),
'UG201' => __( 'Bugiri', 'woocommerce' ),
'UG235' => __( 'Bugweri', 'woocommerce' ),
'UG420' => __( 'Buhweju', 'woocommerce' ),
'UG117' => __( 'Buikwe', 'woocommerce' ),
'UG219' => __( 'Bukedea', 'woocommerce' ),
'UG118' => __( 'Bukomansimbi', 'woocommerce' ),
'UG220' => __( 'Bukwa', 'woocommerce' ),
'UG225' => __( 'Bulambuli', 'woocommerce' ),
'UG416' => __( 'Buliisa', 'woocommerce' ),
'UG401' => __( 'Bundibugyo', 'woocommerce' ),
'UG430' => __( 'Bunyangabu', 'woocommerce' ),
'UG402' => __( 'Bushenyi', 'woocommerce' ),
'UG202' => __( 'Busia', 'woocommerce' ),
'UG221' => __( 'Butaleja', 'woocommerce' ),
'UG119' => __( 'Butambala', 'woocommerce' ),
'UG233' => __( 'Butebo', 'woocommerce' ),
'UG120' => __( 'Buvuma', 'woocommerce' ),
'UG226' => __( 'Buyende', 'woocommerce' ),
'UG317' => __( 'Dokolo', 'woocommerce' ),
'UG121' => __( 'Gomba', 'woocommerce' ),
'UG304' => __( 'Gulu', 'woocommerce' ),
'UG403' => __( 'Hoima', 'woocommerce' ),
'UG417' => __( 'Ibanda', 'woocommerce' ),
'UG203' => __( 'Iganga', 'woocommerce' ),
'UG418' => __( 'Isingiro', 'woocommerce' ),
'UG204' => __( 'Jinja', 'woocommerce' ),
'UG318' => __( 'Kaabong', 'woocommerce' ),
'UG404' => __( 'Kabale', 'woocommerce' ),
'UG405' => __( 'Kabarole', 'woocommerce' ),
'UG213' => __( 'Kaberamaido', 'woocommerce' ),
'UG427' => __( 'Kagadi', 'woocommerce' ),
'UG428' => __( 'Kakumiro', 'woocommerce' ),
'UG101' => __( 'Kalangala', 'woocommerce' ),
'UG222' => __( 'Kaliro', 'woocommerce' ),
'UG122' => __( 'Kalungu', 'woocommerce' ),
'UG102' => __( 'Kampala', 'woocommerce' ),
'UG205' => __( 'Kamuli', 'woocommerce' ),
'UG413' => __( 'Kamwenge', 'woocommerce' ),
'UG414' => __( 'Kanungu', 'woocommerce' ),
'UG206' => __( 'Kapchorwa', 'woocommerce' ),
'UG236' => __( 'Kapelebyong', 'woocommerce' ),
'UG126' => __( 'Kasanda', 'woocommerce' ),
'UG406' => __( 'Kasese', 'woocommerce' ),
'UG207' => __( 'Katakwi', 'woocommerce' ),
'UG112' => __( 'Kayunga', 'woocommerce' ),
'UG407' => __( 'Kibaale', 'woocommerce' ),
'UG103' => __( 'Kiboga', 'woocommerce' ),
'UG227' => __( 'Kibuku', 'woocommerce' ),
'UG432' => __( 'Kikuube', 'woocommerce' ),
'UG419' => __( 'Kiruhura', 'woocommerce' ),
'UG421' => __( 'Kiryandongo', 'woocommerce' ),
'UG408' => __( 'Kisoro', 'woocommerce' ),
'UG305' => __( 'Kitgum', 'woocommerce' ),
'UG319' => __( 'Koboko', 'woocommerce' ),
'UG325' => __( 'Kole', 'woocommerce' ),
'UG306' => __( 'Kotido', 'woocommerce' ),
'UG208' => __( 'Kumi', 'woocommerce' ),
'UG333' => __( 'Kwania', 'woocommerce' ),
'UG228' => __( 'Kween', 'woocommerce' ),
'UG123' => __( 'Kyankwanzi', 'woocommerce' ),
'UG422' => __( 'Kyegegwa', 'woocommerce' ),
'UG415' => __( 'Kyenjojo', 'woocommerce' ),
'UG125' => __( 'Kyotera', 'woocommerce' ),
'UG326' => __( 'Lamwo', 'woocommerce' ),
'UG307' => __( 'Lira', 'woocommerce' ),
'UG229' => __( 'Luuka', 'woocommerce' ),
'UG104' => __( 'Luwero', 'woocommerce' ),
'UG124' => __( 'Lwengo', 'woocommerce' ),
'UG114' => __( 'Lyantonde', 'woocommerce' ),
'UG223' => __( 'Manafwa', 'woocommerce' ),
'UG320' => __( 'Maracha', 'woocommerce' ),
'UG105' => __( 'Masaka', 'woocommerce' ),
'UG409' => __( 'Masindi', 'woocommerce' ),
'UG214' => __( 'Mayuge', 'woocommerce' ),
'UG209' => __( 'Mbale', 'woocommerce' ),
'UG410' => __( 'Mbarara', 'woocommerce' ),
'UG423' => __( 'Mitooma', 'woocommerce' ),
'UG115' => __( 'Mityana', 'woocommerce' ),
'UG308' => __( 'Moroto', 'woocommerce' ),
'UG309' => __( 'Moyo', 'woocommerce' ),
'UG106' => __( 'Mpigi', 'woocommerce' ),
'UG107' => __( 'Mubende', 'woocommerce' ),
'UG108' => __( 'Mukono', 'woocommerce' ),
'UG334' => __( 'Nabilatuk', 'woocommerce' ),
'UG311' => __( 'Nakapiripirit', 'woocommerce' ),
'UG116' => __( 'Nakaseke', 'woocommerce' ),
'UG109' => __( 'Nakasongola', 'woocommerce' ),
'UG230' => __( 'Namayingo', 'woocommerce' ),
'UG234' => __( 'Namisindwa', 'woocommerce' ),
'UG224' => __( 'Namutumba', 'woocommerce' ),
'UG327' => __( 'Napak', 'woocommerce' ),
'UG310' => __( 'Nebbi', 'woocommerce' ),
'UG231' => __( 'Ngora', 'woocommerce' ),
'UG424' => __( 'Ntoroko', 'woocommerce' ),
'UG411' => __( 'Ntungamo', 'woocommerce' ),
'UG328' => __( 'Nwoya', 'woocommerce' ),
'UG331' => __( 'Omoro', 'woocommerce' ),
'UG329' => __( 'Otuke', 'woocommerce' ),
'UG321' => __( 'Oyam', 'woocommerce' ),
'UG312' => __( 'Pader', 'woocommerce' ),
'UG332' => __( 'Pakwach', 'woocommerce' ),
'UG210' => __( 'Pallisa', 'woocommerce' ),
'UG110' => __( 'Rakai', 'woocommerce' ),
'UG429' => __( 'Rubanda', 'woocommerce' ),
'UG425' => __( 'Rubirizi', 'woocommerce' ),
'UG431' => __( 'Rukiga', 'woocommerce' ),
'UG412' => __( 'Rukungiri', 'woocommerce' ),
'UG111' => __( 'Sembabule', 'woocommerce' ),
'UG232' => __( 'Serere', 'woocommerce' ),
'UG426' => __( 'Sheema', 'woocommerce' ),
'UG215' => __( 'Sironko', 'woocommerce' ),
'UG211' => __( 'Soroti', 'woocommerce' ),
'UG212' => __( 'Tororo', 'woocommerce' ),
'UG113' => __( 'Wakiso', 'woocommerce' ),
'UG313' => __( 'Yumbe', 'woocommerce' ),
'UG330' => __( 'Zombo', 'woocommerce' ),
);

View File

@ -200,16 +200,32 @@ abstract class WC_Data {
* @return int
*/
public function save() {
if ( $this->data_store ) {
// Trigger action before saving to the DB. Allows you to adjust object props before save.
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
if ( ! $this->data_store ) {
return $this->get_id();
}
/**
* Trigger action before saving to the DB. Allows you to adjust object props before save.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
/**
* Trigger action after saving to the DB.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_after_' . $this->object_type . '_object_save', $this, $this->data_store );
return $this->get_id();
}

View File

@ -165,8 +165,17 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
* @return int order ID
*/
public function save() {
if ( $this->data_store ) {
// Trigger action before saving to the DB. Allows you to adjust object props before save.
if ( ! $this->data_store ) {
return $this->get_id();
}
try {
/**
* Trigger action before saving to the DB. Allows you to adjust object props before save.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
@ -174,11 +183,41 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
} else {
$this->data_store->create( $this );
}
$this->save_items();
/**
* Trigger action after saving to the DB.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_after_' . $this->object_type . '_object_save', $this, $this->data_store );
} catch ( Exception $e ) {
$this->handle_exception( $e, __( 'Error saving order.', 'woocommerce' ) );
}
$this->save_items();
return $this->get_id();
}
/**
* Log an error about this order is exception is encountered.
*
* @param Exception $e Exception object.
* @param string $message Message regarding exception thrown.
* @since 3.7.0
*/
protected function handle_exception( $e, $message = 'Error' ) {
wc_get_logger()->error(
$message,
array(
'order' => $this,
'error' => $e,
)
);
}
/**
* Save all order items which are part of this order.
*/
@ -730,6 +769,16 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
return apply_filters( 'woocommerce_order_get_items', $items, $this, $types );
}
/**
* Return an array of coupons within this order.
*
* @since 3.7.0
* @return WC_Order_Item_Coupon[]
*/
public function get_coupons() {
return $this->get_items( 'coupon' );
}
/**
* Return an array of fees within this order.
*
@ -771,11 +820,12 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
}
/**
* Get coupon codes only.
* Get used coupon codes only.
*
* @since 3.7.0
* @return array
*/
public function get_used_coupons() {
public function get_coupon_codes() {
$coupon_codes = array();
$coupons = $this->get_items( 'coupon' );
@ -954,6 +1004,22 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
return $applied;
}
$data_store = $coupon->get_data_store();
// Check specific for guest checkouts here as well since WC_Cart handles that seperately in check_customer_coupons.
if ( $data_store && 0 === $this->get_customer_id() ) {
$usage_count = $data_store->get_usage_by_email( $coupon, $this->get_billing_email() );
if ( 0 < $coupon->get_usage_limit_per_user() && $usage_count >= $coupon->get_usage_limit_per_user() ) {
return new WP_Error(
'invalid_coupon',
$coupon->get_coupon_error( 106 ),
array(
'status' => 400,
)
);
}
}
$this->set_coupon_discount_amounts( $discounts );
$this->save();
@ -1316,11 +1382,10 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
// Default to base.
if ( 'base' === $tax_based_on || empty( $args['country'] ) ) {
$default = wc_get_base_location();
$args['country'] = $default['country'];
$args['state'] = $default['state'];
$args['postcode'] = '';
$args['city'] = '';
$args['country'] = WC()->countries->get_base_country();
$args['state'] = WC()->countries->get_base_state();
$args['postcode'] = WC()->countries->get_base_postcode();
$args['city'] = WC()->countries->get_base_city();
}
return $args;
@ -1631,7 +1696,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
/**
* Gets line subtotal - formatted for display.
*
* @param array $item Item to get total from.
* @param object $item Item to get total from.
* @param string $tax_display Incl or excl tax display mode.
* @return string
*/
@ -1848,7 +1913,7 @@ abstract class WC_Abstract_Order extends WC_Abstract_Legacy_Order {
*/
protected function add_order_item_totals_tax_rows( &$total_rows, $tax_display ) {
// Tax for tax exclusive prices.
if ( 'excl' === $tax_display ) {
if ( 'excl' === $tax_display && wc_tax_enabled() ) {
if ( 'itemized' === get_option( 'woocommerce_tax_total_display' ) ) {
foreach ( $this->get_tax_totals() as $code => $tax ) {
$total_rows[ sanitize_title( $code ) ] = array(

View File

@ -1360,19 +1360,36 @@ class WC_Product extends WC_Abstract_Legacy_Product {
public function save() {
$this->validate_props();
if ( $this->data_store ) {
// Trigger action before saving to the DB. Use a pointer to adjust object props before save.
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
if ( $this->get_parent_id() ) {
wc_deferred_product_sync( $this->get_parent_id() );
}
if ( ! $this->data_store ) {
return $this->get_id();
}
/**
* Trigger action before saving to the DB. Allows you to adjust object props before save.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_before_' . $this->object_type . '_object_save', $this, $this->data_store );
if ( $this->get_id() ) {
$this->data_store->update( $this );
} else {
$this->data_store->create( $this );
}
if ( $this->get_parent_id() ) {
wc_deferred_product_sync( $this->get_parent_id() );
}
/**
* Trigger action after saving to the DB.
*
* @param WC_Data $this The object being saved.
* @param WC_Data_Store_WP $data_store THe data store persisting the data.
*/
do_action( 'woocommerce_after_' . $this->object_type . '_object_save', $this, $this->data_store );
return $this->get_id();
}

View File

@ -132,6 +132,7 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
// Get the request params.
$items = array_filter( $request->get_params() );
$query = $request->get_query_params();
$response = array();
// Check batch limit.
@ -156,6 +157,10 @@ abstract class WC_REST_Controller extends WP_REST_Controller {
// Set request parameters.
$_item->set_body_params( $item );
// Set query (GET) parameters.
$_item->set_query_params( $query );
$_response = $this->create_item( $_item );
if ( is_wp_error( $_response ) ) {

View File

@ -196,6 +196,15 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
try {
$this->update_additional_fields_for_object( $object, $request );
/**
* Fires after a single object is created or updated via the REST API.
*
* @param WC_Data $object Inserted object.
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating object, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true );
} catch ( WC_Data_Exception $e ) {
$object->delete();
return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() );
@ -204,15 +213,6 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
/**
* Fires after a single object is created or updated via the REST API.
*
* @param WC_Data $object Inserted object.
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating object, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, true );
$request->set_param( 'context', 'edit' );
$response = $this->prepare_object_for_response( $object, $request );
$response = rest_ensure_response( $response );
@ -243,21 +243,21 @@ abstract class WC_REST_CRUD_Controller extends WC_REST_Posts_Controller {
try {
$this->update_additional_fields_for_object( $object, $request );
/**
* Fires after a single object is created or updated via the REST API.
*
* @param WC_Data $object Inserted object.
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating object, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false );
} catch ( WC_Data_Exception $e ) {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), $e->getErrorData() );
} catch ( WC_REST_Exception $e ) {
return new WP_Error( $e->getErrorCode(), $e->getMessage(), array( 'status' => $e->getCode() ) );
}
/**
* Fires after a single object is created or updated via the REST API.
*
* @param WC_Data $object Inserted object.
* @param WP_REST_Request $request Request object.
* @param boolean $creating True when creating object, false when updating.
*/
do_action( "woocommerce_rest_insert_{$this->post_type}_object", $object, $request, false );
$request->set_param( 'context', 'edit' );
$response = $this->prepare_object_for_response( $object, $request );
return rest_ensure_response( $response );

View File

@ -36,6 +36,7 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
* Init dashboard widgets.
*/
public function init() {
// Reviews Widget.
if ( current_user_can( 'publish_shop_orders' ) && post_type_supports( 'product', 'comments' ) ) {
wp_add_dashboard_widget( 'woocommerce_dashboard_recent_reviews', __( 'WooCommerce Recent Reviews', 'woocommerce' ), array( $this, 'recent_reviews' ) );
}
@ -215,7 +216,12 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
if ( false === $lowinstock_count ) {
$lowinstock_count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT( product_id ) FROM {$wpdb->wc_product_meta_lookup} WHERE stock_quantity <= %d AND stock_quantity > %d",
"SELECT COUNT( product_id )
FROM {$wpdb->wc_product_meta_lookup} AS lookup
INNER JOIN {$wpdb->posts} as posts ON lookup.product_id = posts.ID
WHERE stock_quantity <= %d
AND stock_quantity > %d
AND posts.post_status = 'publish'",
$stock,
$nostock
)
@ -229,7 +235,11 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
if ( false === $outofstock_count ) {
$outofstock_count = (int) $wpdb->get_var(
$wpdb->prepare(
"SELECT COUNT( product_id ) FROM {$wpdb->wc_product_meta_lookup} WHERE stock_quantity <= %d",
"SELECT COUNT( product_id )
FROM {$wpdb->wc_product_meta_lookup} AS lookup
INNER JOIN {$wpdb->posts} as posts ON lookup.product_id = posts.ID
WHERE stock_quantity <= %d
AND posts.post_status = 'publish'",
$nostock
)
);
@ -378,7 +388,6 @@ if ( ! class_exists( 'WC_Admin_Dashboard', false ) ) :
</div>
<?php
}
}
endif;

View File

@ -66,7 +66,7 @@ class WC_Admin_Help {
'<h2>' . __( 'Found a bug?', 'woocommerce' ) . '</h2>' .
/* translators: 1: GitHub issues URL 2: GitHub contribution guide URL 3: System status report URL */
'<p>' . sprintf( __( 'If you find a bug within WooCommerce core you can create a ticket via <a href="%1$s">Github issues</a>. Ensure you read the <a href="%2$s">contribution guide</a> prior to submitting your report. To help us solve your issue, please be as descriptive as possible and include your <a href="%3$s">system status report</a>.', 'woocommerce' ), 'https://github.com/woocommerce/woocommerce/issues?state=open', 'https://github.com/woocommerce/woocommerce/blob/master/.github/CONTRIBUTING.md', admin_url( 'admin.php?page=wc-status' ) ) . '</p>' .
'<p><a href="https://github.com/woocommerce/woocommerce/issues?state=open" class="button button-primary">' . __( 'Report a bug', 'woocommerce' ) . '</a> <a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button">' . __( 'System status', 'woocommerce' ) . '</a></p>',
'<p><a href="https://github.com/woocommerce/woocommerce/issues/new?template=Bug_report.md" class="button button-primary">' . __( 'Report a bug', 'woocommerce' ) . '</a> <a href="' . admin_url( 'admin.php?page=wc-status' ) . '" class="button">' . __( 'System status', 'woocommerce' ) . '</a></p>',
)
);

View File

@ -278,7 +278,7 @@ class WC_Admin_Importers {
array(
'position' => 'done',
'percentage' => 100,
'url' => add_query_arg( array( 'nonce' => wp_create_nonce( 'product-csv' ) ), admin_url( 'edit.php?post_type=product&page=product_importer&step=done' ) ),
'url' => add_query_arg( array( '_wpnonce' => wp_create_nonce( 'woocommerce-csv-importer' ) ), admin_url( 'edit.php?post_type=product&page=product_importer&step=done' ) ),
'imported' => count( $results['imported'] ),
'failed' => count( $results['failed'] ),
'updated' => count( $results['updated'] ),

View File

@ -126,7 +126,7 @@ class WC_Admin_Log_Table_List extends WP_List_Table {
public function column_timestamp( $log ) {
return esc_html(
mysql2date(
get_option( 'date_format' ) . ' ' . get_option( 'time_format' ),
'Y-m-d H:i:s',
$log['timestamp']
)
);

View File

@ -4,15 +4,10 @@
*
* Sets up the write panels used by products and orders (custom post types).
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Meta Boxes
* @version 2.1.0
* @package WooCommerce/Admin/Meta Boxes
*/
if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly
}
defined( 'ABSPATH' ) || exit;
/**
* WC_Admin_Meta_Boxes.
@ -75,7 +70,7 @@ class WC_Admin_Meta_Boxes {
/**
* Add an error message.
*
* @param string $text
* @param string $text Error to add.
*/
public static function add_error( $text ) {
self::$meta_box_errors[] = $text;
@ -104,7 +99,7 @@ class WC_Admin_Meta_Boxes {
echo '</div>';
// Clear
// Clear.
delete_option( 'woocommerce_meta_box_errors' );
}
}
@ -124,10 +119,13 @@ class WC_Admin_Meta_Boxes {
// Orders.
foreach ( wc_get_order_types( 'order-meta-boxes' ) as $type ) {
$order_type_object = get_post_type_object( $type );
/* Translators: %s order type name. */
add_meta_box( 'woocommerce-order-data', sprintf( __( '%s data', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Data::output', $type, 'normal', 'high' );
add_meta_box( 'woocommerce-order-items', __( 'Items', 'woocommerce' ), 'WC_Meta_Box_Order_Items::output', $type, 'normal', 'high' );
/* Translators: %s order type name. */
add_meta_box( 'woocommerce-order-notes', sprintf( __( '%s notes', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Notes::output', $type, 'side', 'default' );
add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable product permissions', 'woocommerce' ) . wc_help_tip( __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) ), 'WC_Meta_Box_Order_Downloads::output', $type, 'normal', 'default' );
/* Translators: %s order type name. */
add_meta_box( 'woocommerce-order-actions', sprintf( __( '%s actions', 'woocommerce' ), $order_type_object->labels->singular_name ), 'WC_Meta_Box_Order_Actions::output', $type, 'side', 'high' );
}
@ -135,7 +133,7 @@ class WC_Admin_Meta_Boxes {
add_meta_box( 'woocommerce-coupon-data', __( 'Coupon data', 'woocommerce' ), 'WC_Meta_Box_Coupon_Data::output', 'shop_coupon', 'normal', 'high' );
// Comment rating.
if ( 'comment' === $screen_id && isset( $_GET['c'] ) && metadata_exists( 'comment', $_GET['c'], 'rating' ) ) {
if ( 'comment' === $screen_id && isset( $_GET['c'] ) && metadata_exists( 'comment', wc_clean( wp_unslash( $_GET['c'] ) ), 'rating' ) ) { // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
add_meta_box( 'woocommerce-rating', __( 'Rating', 'woocommerce' ), 'WC_Meta_Box_Product_Reviews::output', 'comment', 'normal', 'high' );
}
}
@ -168,8 +166,8 @@ class WC_Admin_Meta_Boxes {
public function rename_meta_boxes() {
global $post;
// Comments/Reviews
if ( isset( $post ) && ( 'publish' == $post->post_status || 'private' == $post->post_status ) && post_type_supports( 'product', 'comments' ) ) {
// Comments/Reviews.
if ( isset( $post ) && ( 'publish' === $post->post_status || 'private' === $post->post_status ) && post_type_supports( 'product', 'comments' ) ) {
remove_meta_box( 'commentsdiv', 'product', 'normal' );
add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' );
}
@ -178,31 +176,33 @@ class WC_Admin_Meta_Boxes {
/**
* Check if we're saving, the trigger an action based on the post type.
*
* @param int $post_id
* @param object $post
* @param int $post_id Post ID.
* @param object $post Post object.
*/
public function save_meta_boxes( $post_id, $post ) {
$post_id = absint( $post_id );
// $post_id and $post are required
if ( empty( $post_id ) || empty( $post ) || self::$saved_meta_boxes ) {
return;
}
// Dont' save meta boxes for revisions or autosaves
// Dont' save meta boxes for revisions or autosaves.
if ( ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) || is_int( wp_is_post_revision( $post ) ) || is_int( wp_is_post_autosave( $post ) ) ) {
return;
}
// Check the nonce
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) {
// Check the nonce.
if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( wp_unslash( $_POST['woocommerce_meta_nonce'] ), 'woocommerce_save_data' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
return;
}
// Check the post being saved == the $post_id to prevent triggering this call for other save_post events
if ( empty( $_POST['post_ID'] ) || $_POST['post_ID'] != $post_id ) {
// Check the post being saved == the $post_id to prevent triggering this call for other save_post events.
if ( empty( $_POST['post_ID'] ) || absint( $_POST['post_ID'] ) !== $post_id ) {
return;
}
// Check user has permission to edit
// Check user has permission to edit.
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return;
}
@ -210,13 +210,13 @@ class WC_Admin_Meta_Boxes {
// We need this save event to run once to avoid potential endless loops. This would have been perfect:
// remove_action( current_filter(), __METHOD__ );
// But cannot be used due to https://github.com/woocommerce/woocommerce/issues/6485
// When that is patched in core we can use the above. For now:
// When that is patched in core we can use the above.
self::$saved_meta_boxes = true;
// Check the post type
if ( in_array( $post->post_type, wc_get_order_types( 'order-meta-boxes' ) ) ) {
// Check the post type.
if ( in_array( $post->post_type, wc_get_order_types( 'order-meta-boxes' ), true ) ) {
do_action( 'woocommerce_process_shop_order_meta', $post_id, $post );
} elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon' ) ) ) {
} elseif ( in_array( $post->post_type, array( 'product', 'shop_coupon' ), true ) ) {
do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post );
}
}

View File

@ -34,6 +34,8 @@ class WC_Admin_Notices {
'regenerating_thumbnails' => 'regenerating_thumbnails_notice',
'regenerating_lookup_table' => 'regenerating_lookup_table_notice',
'no_secure_connection' => 'secure_connection_notice',
'wc_admin' => 'wc_admin_feature_plugin_notice',
'wp_php_min_requirements' => 'wp_php_min_requirements_notice',
);
/**
@ -82,7 +84,9 @@ class WC_Admin_Notices {
if ( ! self::is_ssl() ) {
self::add_notice( 'no_secure_connection' );
}
self::add_wc_admin_feature_plugin_notice();
self::add_notice( 'template_files' );
self::add_min_version_notice();
}
/**
@ -341,6 +345,89 @@ class WC_Admin_Notices {
include dirname( __FILE__ ) . '/views/html-notice-regenerating-lookup-table.php';
}
/**
* If on WordPress 5.0 or greater, inform users of WooCommerce Admin feature plugin.
*
* @since 3.6.4
* @todo Remove this notice and associated code once the feature plugin has been merged into core.
*/
public static function add_wc_admin_feature_plugin_notice() {
if ( version_compare( get_bloginfo( 'version' ), '5.0', '>=' ) ) {
self::add_notice( 'wc_admin' );
}
}
/**
* Notice to try WooCommerce Admin
*
* @since 3.6.4
* @todo Remove this notice and associated code once the feature plugin has been merged into core.
*/
public static function wc_admin_feature_plugin_notice() {
if ( get_user_meta( get_current_user_id(), 'dismissed_wc_admin_notice', true ) || self::is_plugin_active( 'woocommerce-admin/woocommerce-admin.php' ) ) {
self::remove_notice( 'wc_admin' );
return;
}
include dirname( __FILE__ ) . '/views/html-notice-wc-admin.php';
}
/**
* Add notice about minimum PHP and WordPress requirement.
*
* @since 3.6.5
*/
public static function add_min_version_notice() {
if ( version_compare( phpversion(), WC_NOTICE_MIN_PHP_VERSION, '<' ) || version_compare( get_bloginfo( 'version' ), WC_NOTICE_MIN_WP_VERSION, '<' ) ) {
self::add_notice( 'wp_php_min_requirements' );
}
}
/**
* Notice about WordPress and PHP minimum requirements.
*
* @since 3.6.5
* @return void
*/
public static function wp_php_min_requirements_notice() {
if ( apply_filters( 'woocommerce_hide_php_wp_nag', get_user_meta( get_current_user_id(), 'dismissed_wp_php_min_requirements_notice', true ) ) ) {
self::remove_notice( 'wp_php_min_requirements' );
return;
}
$old_php = version_compare( phpversion(), WC_NOTICE_MIN_PHP_VERSION, '<' );
$old_wp = version_compare( get_bloginfo( 'version' ), WC_NOTICE_MIN_WP_VERSION, '<' );
// Both PHP and WordPress up to date version => no notice.
if ( ! $old_php && ! $old_wp ) {
return;
}
if ( $old_php && $old_wp ) {
$msg = sprintf(
/* translators: 1: Minimum PHP version 2: Minimum WordPress version */
__( 'Update required: WooCommerce will soon require PHP version %1$s and WordPress version %2$s or newer.', 'woocommerce' ),
WC_NOTICE_MIN_PHP_VERSION,
WC_NOTICE_MIN_WP_VERSION
);
} elseif ( $old_php ) {
$msg = sprintf(
/* translators: %s: Minimum PHP version */
__( 'Update required: WooCommerce will soon require PHP version %s or newer.', 'woocommerce' ),
WC_NOTICE_MIN_PHP_VERSION
);
} elseif ( $old_wp ) {
$msg = sprintf(
/* translators: %s: Minimum WordPress version */
__( 'Update required: WooCommerce will soon require WordPress version %s or newer.', 'woocommerce' ),
WC_NOTICE_MIN_WP_VERSION
);
}
include dirname( __FILE__ ) . '/views/html-notice-wp-php-minimum-requirements.php';
}
/**
* Determine if the store is running SSL.
*

View File

@ -633,13 +633,13 @@ class WC_Admin_Post_Types {
$change_stock = absint( $_REQUEST['change_stock'] );
switch ( $change_stock ) {
case 2:
wc_update_product_stock( $product, $stock_amount, 'increase' );
wc_update_product_stock( $product, $stock_amount, 'increase', true );
break;
case 3:
wc_update_product_stock( $product, $stock_amount, 'decrease' );
wc_update_product_stock( $product, $stock_amount, 'decrease', true );
break;
default:
wc_update_product_stock( $product, $stock_amount, 'set' );
wc_update_product_stock( $product, $stock_amount, 'set', true );
break;
}
}

View File

@ -135,10 +135,13 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
wp_enqueue_script( 'woocommerce_settings', WC()->plugin_url() . '/assets/js/admin/settings' . $suffix . '.js', array( 'jquery', 'wp-util', 'jquery-ui-datepicker', 'jquery-ui-sortable', 'iris', 'selectWoo' ), WC()->version, true );
wp_localize_script(
'woocommerce_settings', 'woocommerce_settings_params', array(
'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'woocommerce' ),
'i18n_moved_up' => __( 'Item moved up', 'woocommerce' ),
'i18n_moved_down' => __( 'Item moved down', 'woocommerce' ),
'woocommerce_settings',
'woocommerce_settings_params',
array(
'i18n_nav_warning' => __( 'The changes you made will be lost if you navigate away from this page.', 'woocommerce' ),
'i18n_moved_up' => __( 'Item moved up', 'woocommerce' ),
'i18n_moved_down' => __( 'Item moved down', 'woocommerce' ),
'i18n_no_specific_countries_selected' => __( 'Selecting no country to sell to prevents from completing the checkout. Continue anyway?', 'woocommerce' ),
)
);
@ -156,6 +159,10 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
* @return mixed
*/
public static function get_option( $option_name, $default = '' ) {
if ( ! $option_name ) {
return $default;
}
// Array value.
if ( strstr( $option_name, '[' ) ) {
@ -227,6 +234,9 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
if ( ! isset( $value['suffix'] ) ) {
$value['suffix'] = '';
}
if ( ! isset( $value['value'] ) ) {
$value['value'] = self::get_option( $value['id'], $value['default'] );
}
// Custom attribute handling.
$custom_attributes = array();
@ -285,7 +295,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
case 'email':
case 'url':
case 'tel':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
?><tr valign="top">
<th scope="row" class="titledesc">
@ -309,7 +319,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Color picker.
case 'color':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
?>
<tr valign="top">
@ -337,7 +347,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Textarea.
case 'textarea':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
?>
<tr valign="top">
@ -363,7 +373,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Select boxes.
case 'select':
case 'multiselect':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
?>
<tr valign="top">
@ -391,7 +401,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
selected( $option_value, (string) $key );
}
?>
?>
><?php echo esc_html( $val ); ?></option>
<?php
}
@ -404,7 +414,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Radio inputs.
case 'radio':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
?>
<tr valign="top">
@ -441,7 +451,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Checkbox input.
case 'checkbox':
$option_value = self::get_option( $value['id'], $value['default'] );
$option_value = $value['value'];
$visibility_class = array();
if ( ! isset( $value['hide_if_checked'] ) ) {
@ -494,7 +504,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
<?php
if ( ! isset( $value['checkboxgroup'] ) || 'end' === $value['checkboxgroup'] ) {
?>
?>
</fieldset>
</td>
</tr>
@ -547,7 +557,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
'show_option_none' => ' ',
'class' => $value['class'],
'echo' => false,
'selected' => absint( self::get_option( $value['id'], $value['default'] ) ),
'selected' => absint( $value['value'] ),
'post_status' => 'publish,private,draft',
);
@ -569,7 +579,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Single country selects.
case 'single_select_country':
$country_setting = (string) self::get_option( $value['id'], $value['default'] );
$country_setting = (string) $value['value'];
if ( strstr( $country_setting, ':' ) ) {
$country_setting = explode( ':', $country_setting );
@ -594,7 +604,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Country multiselects.
case 'multi_select_countries':
$selections = (array) self::get_option( $value['id'], $value['default'] );
$selections = (array) $value['value'];
if ( ! empty( $value['options'] ) ) {
$countries = $value['options'];
@ -631,7 +641,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
'months' => __( 'Month(s)', 'woocommerce' ),
'years' => __( 'Year(s)', 'woocommerce' ),
);
$option_value = wc_parse_relative_date_option( self::get_option( $value['id'], $value['default'] ) );
$option_value = wc_parse_relative_date_option( $value['value'] );
?>
<tr valign="top">
<th scope="row" class="titledesc">
@ -734,7 +744,7 @@ if ( ! class_exists( 'WC_Admin_Settings', false ) ) :
// Loop options and get values to save.
foreach ( $options as $option ) {
if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) ) {
if ( ! isset( $option['id'] ) || ! isset( $option['type'] ) || ( isset( $option['is_option'] ) && false === $option['is_option'] ) ) {
continue;
}

View File

@ -144,6 +144,17 @@ class WC_Admin_Setup_Wizard {
return current_user_can( 'install_plugins' );
}
/**
* Should we show the WooCommerce Admin install option?
* True only if the user can install plugins,
* and up until the end date of the recommendation.
*
* @return boolean
*/
protected function should_show_wc_admin() {
return current_user_can( 'install_plugins' );
}
/**
* Should we display the 'Recommended' step?
* True if at least one of the recommendations will be displayed.
@ -154,7 +165,8 @@ class WC_Admin_Setup_Wizard {
return $this->should_show_theme()
|| $this->should_show_automated_tax()
|| $this->should_show_mailchimp()
|| $this->should_show_facebook();
|| $this->should_show_facebook()
|| $this->should_show_wc_admin();
}
/**
@ -1393,7 +1405,7 @@ class WC_Admin_Setup_Wizard {
'name' => __( 'WooCommerce PayPal Checkout Gateway', 'woocommerce' ),
'image' => WC()->plugin_url() . '/assets/images/paypal.png',
'description' => $paypal_checkout_description,
'enabled' => true,
'enabled' => false,
'class' => 'checked paypal-logo',
'repo-slug' => 'woocommerce-gateway-paypal-express-checkout',
'settings' => array(
@ -1432,7 +1444,7 @@ class WC_Admin_Setup_Wizard {
'klarna_checkout' => array(
'name' => __( 'Klarna Checkout for WooCommerce', 'woocommerce' ),
'description' => $klarna_checkout_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'image' => WC()->plugin_url() . '/assets/images/klarna-black.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-checkout-for-woocommerce',
@ -1440,7 +1452,7 @@ class WC_Admin_Setup_Wizard {
'klarna_payments' => array(
'name' => __( 'Klarna Payments for WooCommerce', 'woocommerce' ),
'description' => $klarna_payments_description,
'image' => WC()->plugin_url() . '/assets/images/klarna-white.png',
'image' => WC()->plugin_url() . '/assets/images/klarna-black.png',
'enabled' => true,
'class' => 'klarna-logo',
'repo-slug' => 'klarna-payments-for-woocommerce',
@ -1448,9 +1460,9 @@ class WC_Admin_Setup_Wizard {
'square' => array(
'name' => __( 'WooCommerce Square', 'woocommerce' ),
'description' => $square_description,
'image' => WC()->plugin_url() . '/assets/images/square-white.png',
'image' => WC()->plugin_url() . '/assets/images/square-black.png',
'class' => 'square-logo',
'enabled' => true,
'enabled' => false,
'repo-slug' => 'woocommerce-square',
),
'eway' => array(
@ -1492,38 +1504,14 @@ class WC_Admin_Setup_Wizard {
return $can_paypal ? array( 'paypal' => $gateways['paypal'] ) : array();
}
$spotlight = '';
$klarna_or_square = false;
if ( $this->is_klarna_checkout_supported_country( $country ) ) {
$spotlight = 'klarna_checkout';
$klarna_or_square = 'klarna_checkout';
} elseif ( $this->is_klarna_payments_supported_country( $country ) ) {
$spotlight = 'klarna_payments';
$klarna_or_square = 'klarna_payments';
} elseif ( $this->is_square_supported_country( $country ) && get_option( 'woocommerce_sell_in_person' ) ) {
$spotlight = 'square';
}
if ( $spotlight ) {
$offered_gateways = array(
$spotlight => $gateways[ $spotlight ],
);
if ( $can_paypal ) {
$offered_gateways += array( 'ppec_paypal' => $gateways['ppec_paypal'] );
}
if ( $can_stripe ) {
$offered_gateways += array( 'stripe' => $gateways['stripe'] );
}
if ( $can_eway ) {
$offered_gateways += array( 'eway' => $gateways['eway'] );
}
if ( $can_payfast ) {
$offered_gateways += array( 'payfast' => $gateways['payfast'] );
}
return $offered_gateways;
$klarna_or_square = 'square';
}
$offered_gateways = array();
@ -1532,6 +1520,22 @@ class WC_Admin_Setup_Wizard {
$gateways['stripe']['enabled'] = true;
$gateways['stripe']['featured'] = true;
$offered_gateways += array( 'stripe' => $gateways['stripe'] );
} elseif ( $can_paypal ) {
$gateways['ppec_paypal']['enabled'] = true;
}
if ( $klarna_or_square ) {
if ( in_array( $klarna_or_square, array( 'klarna_checkout', 'klarna_payments' ), true ) ) {
$gateways[ $klarna_or_square ]['enabled'] = true;
$gateways[ $klarna_or_square ]['featured'] = false;
$offered_gateways += array(
$klarna_or_square => $gateways[ $klarna_or_square ],
);
} else {
$offered_gateways += array(
$klarna_or_square => $gateways[ $klarna_or_square ],
);
}
}
if ( $can_paypal ) {
@ -1596,7 +1600,7 @@ class WC_Admin_Setup_Wizard {
// Show the user-saved state if it was previously saved.
// Otherwise, rely on the item info.
if ( is_array( $previously_saved_settings ) ) {
$should_enable_toggle = isset( $previously_saved_settings['enabled'] ) && 'yes' === $previously_saved_settings['enabled'];
$should_enable_toggle = ( isset( $previously_saved_settings['enabled'] ) && 'yes' === $previously_saved_settings['enabled'] ) ? true : ( isset( $item_info['enabled'] ) && $item_info['enabled'] );
} else {
$should_enable_toggle = isset( $item_info['enabled'] ) && $item_info['enabled'];
}
@ -1874,7 +1878,7 @@ class WC_Admin_Setup_Wizard {
?>
<h1><?php esc_html_e( 'Recommended for All WooCommerce Stores', 'woocommerce' ); ?></h1>
<p>
<?php esc_html_e( 'Enhance your store with these recommended features.', 'woocommerce' ); ?>
<?php esc_html_e( 'Enhance your store with these recommended free features.', 'woocommerce' ); ?>
</p>
<form method="post">
<ul class="recommended-step">
@ -1905,6 +1909,17 @@ class WC_Admin_Setup_Wizard {
) );
endif;
if ( $this->should_show_wc_admin() ) :
$this->display_recommended_item( array(
'type' => 'wc_admin',
'title' => __( 'WooCommerce Admin', 'woocommerce' ),
'description' => __( 'Manage your store\'s reports and monitor key metrics with a new and improved interface and dashboard.', 'woocommerce' ),
'img_url' => WC()->plugin_url() . '/assets/images/obw-woocommerce-admin-icon.svg',
'img_alt' => __( 'WooCommerce Admin icon', 'woocommerce' ),
'plugins' => array( array( 'name' => __( 'WooCommerce Admin', 'woocommerce' ), 'slug' => 'woocommerce-admin' ) ),
) );
endif;
if ( $this->should_show_mailchimp() ) :
$this->display_recommended_item( array(
'type' => 'mailchimp',
@ -1947,6 +1962,7 @@ class WC_Admin_Setup_Wizard {
$setup_automated_tax = isset( $_POST['setup_automated_taxes'] ) && 'yes' === $_POST['setup_automated_taxes'];
$setup_mailchimp = isset( $_POST['setup_mailchimp'] ) && 'yes' === $_POST['setup_mailchimp'];
$setup_facebook = isset( $_POST['setup_facebook'] ) && 'yes' === $_POST['setup_facebook'];
$setup_wc_admin = isset( $_POST['setup_wc_admin'] ) && 'yes' === $_POST['setup_wc_admin'];
update_option( 'woocommerce_calc_taxes', $setup_automated_tax ? 'yes' : 'no' );
update_option( 'woocommerce_setup_automated_taxes', $setup_automated_tax );
@ -1983,6 +1999,16 @@ class WC_Admin_Setup_Wizard {
);
}
if ( $setup_wc_admin ) {
$this->install_plugin(
'woocommerce-admin',
array(
'name' => __( 'WooCommerce Admin', 'woocommerce' ),
'repo-slug' => 'woocommerce-admin',
)
);
}
wp_redirect( esc_url_raw( $this->get_next_step_link() ) );
exit;
}

View File

@ -393,7 +393,7 @@ class WC_Admin_Taxonomies {
if ( $default_category_id !== $term->term_id && current_user_can( 'edit_term', $term->term_id ) ) {
$actions['make_default'] = sprintf(
'<a href="%s" aria-label="%s">%s</a>',
wp_nonce_url( 'edit-tags.php?action=make_default&amp;taxonomy=product_cat&amp;tag_ID=' . absint( $term->term_id ), 'make_default_' . absint( $term->term_id ) ),
wp_nonce_url( 'edit-tags.php?action=make_default&amp;taxonomy=product_cat&amp;post_type=product&amp;tag_ID=' . absint( $term->term_id ), 'make_default_' . absint( $term->term_id ) ),
/* translators: %s: taxonomy term name */
esc_attr( sprintf( __( 'Make &#8220;%s&#8221; the default category', 'woocommerce' ), $term->name ) ),
__( 'Make default', 'woocommerce' )

View File

@ -30,6 +30,9 @@ class WC_Admin {
add_filter( 'admin_footer_text', array( $this, 'admin_footer_text' ), 1 );
add_action( 'wp_ajax_setup_wizard_check_jetpack', array( $this, 'setup_wizard_check_jetpack' ) );
add_action( 'init', array( 'WC_Site_Tracking', 'init' ) );
// Disable WXR export of schedule action posts.
add_filter( 'action_scheduler_post_type_args', array( $this, 'disable_webhook_post_export' ) );
}
/**
@ -69,8 +72,8 @@ class WC_Admin {
}
// Setup/welcome.
if ( ! empty( $_GET['page'] ) ) {
switch ( $_GET['page'] ) {
if ( ! empty( $_GET['page'] ) ) { // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
switch ( $_GET['page'] ) { // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification
case 'wc-setup':
include_once dirname( __FILE__ ) . '/class-wc-admin-setup-wizard.php';
break;
@ -251,7 +254,7 @@ class WC_Admin {
$wc_pages = array_diff( $wc_pages, array( 'profile', 'user-edit' ) );
// Check to make sure we're on a WooCommerce admin page.
if ( isset( $current_screen->id ) && apply_filters( 'woocommerce_display_admin_footer_text', in_array( $current_screen->id, $wc_pages ) ) ) {
if ( isset( $current_screen->id ) && apply_filters( 'woocommerce_display_admin_footer_text', in_array( $current_screen->id, $wc_pages, true ) ) ) {
// Change the footer text.
if ( ! get_option( 'woocommerce_admin_footer_text_rated' ) ) {
$footer_text = sprintf(
@ -288,6 +291,20 @@ class WC_Admin {
)
);
}
/**
* Disable WXR export of scheduled action posts.
*
* @since 3.6.2
*
* @param array $args Scehduled action post type registration args.
*
* @return array
*/
public function disable_webhook_post_export( $args ) {
$args['can_export'] = false;
return $args;
}
}
return new WC_Admin();

View File

@ -407,7 +407,7 @@ class WC_Helper {
$valid_filters = array_keys( self::get_filters() );
if ( ! empty( $_GET['filter'] ) && in_array( wp_unslash( $_GET['filter'] ), $valid_filters ) ) {
$current_filter = wp_unslash( $_GET['filter'] );
$current_filter = wc_clean( wp_unslash( $_GET['filter'] ) );
}
return $current_filter;
@ -480,16 +480,17 @@ class WC_Helper {
* @return array Array pairs of message/type strings with notices.
*/
private static function _get_return_notices() {
$return_status = isset( $_GET['wc-helper-status'] ) ? wp_unslash( $_GET['wc-helper-status'] ) : null;
$return_status = isset( $_GET['wc-helper-status'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-status'] ) ) : null;
$notices = array();
switch ( $return_status ) {
case 'activate-success':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$notices[] = array(
'type' => 'updated',
/* translators: %s: product name */
'message' => sprintf(
/* translators: %s: product name */
__( '%s activated successfully. You will now receive updates for this product.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>'
),
@ -497,11 +498,12 @@ class WC_Helper {
break;
case 'activate-error':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$notices[] = array(
'type' => 'error',
/* translators: %s: product name */
'message' => sprintf(
/* translators: %s: product name */
__( 'An error has occurred when activating %s. Please try again later.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>'
),
@ -509,11 +511,12 @@ class WC_Helper {
break;
case 'deactivate-success':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$local = self::_get_local_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$local = self::_get_local_from_product_id( $product_id );
/* translators: %s: product name */
$message = sprintf(
/* translators: %s: product name */
__( 'Subscription for %s deactivated successfully. You will no longer receive updates for this product.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>'
);
@ -531,8 +534,8 @@ class WC_Helper {
admin_url( 'admin.php' )
);
/* translators: %1$s: product name, %2$s: deactivate url */
$message = sprintf(
/* translators: %1$s: product name, %2$s: deactivate url */
__( 'Subscription for %1$s deactivated successfully. You will no longer receive updates for this product. <a href="%2$s">Click here</a> if you wish to deactivate the plugin as well.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>',
esc_url( $deactivate_plugin_url )
@ -546,11 +549,12 @@ class WC_Helper {
break;
case 'deactivate-error':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$notices[] = array(
'type' => 'error',
/* translators: %s: product name */
'message' => sprintf(
/* translators: %s: product name */
__( 'An error has occurred when deactivating the subscription for %s. Please try again later.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>'
),
@ -558,11 +562,12 @@ class WC_Helper {
break;
case 'deactivate-plugin-success':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$notices[] = array(
'type' => 'updated',
/* translators: %s: product name */
'message' => sprintf(
/* translators: %s: product name */
__( 'The extension %s has been deactivated successfully.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>'
),
@ -570,11 +575,12 @@ class WC_Helper {
break;
case 'deactivate-plugin-error':
$subscription = self::_get_subscriptions_from_product_id( absint( $_GET['wc-helper-product-id'] ) );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$subscription = self::_get_subscriptions_from_product_id( $product_id );
$notices[] = array(
'type' => 'error',
/* translators: %1$s: product name, %2$s: plugins screen url */
'message' => sprintf(
/* translators: %1$s: product name, %2$s: plugins screen url */
__( 'An error has occurred when deactivating the extension %1$s. Please proceed to the <a href="%2$s">Plugins screen</a> to deactivate it manually.', 'woocommerce' ),
'<strong>' . esc_html( $subscription['product_name'] ) . '</strong>',
admin_url( 'plugins.php' )
@ -609,6 +615,8 @@ class WC_Helper {
/**
* Various early-phase actions with possible redirects.
*
* @param object $screen WP screen object.
*/
public static function current_screen( $screen ) {
$wc_screen_id = sanitize_title( __( 'WooCommerce', 'woocommerce' ) );
@ -654,7 +662,7 @@ class WC_Helper {
* Initiate a new OAuth connection.
*/
private static function _helper_auth_connect() {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'connect' ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'connect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_auth_connect' );
wp_die( 'Could not verify nonce' );
}
@ -714,7 +722,7 @@ class WC_Helper {
* Return from WooCommerce.com OAuth flow.
*/
private static function _helper_auth_return() {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'connect' ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'connect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_auth_return' );
wp_die( 'Something went wrong' );
}
@ -740,7 +748,7 @@ class WC_Helper {
'oauth/access_token',
array(
'body' => array(
'request_token' => $_GET['request_token'],
'request_token' => wp_unslash( $_GET['request_token'] ), // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
'home_url' => home_url(),
),
)
@ -808,7 +816,7 @@ class WC_Helper {
* Disconnect from WooCommerce.com, clear OAuth tokens.
*/
private static function _helper_auth_disconnect() {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'disconnect' ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'disconnect' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_auth_disconnect' );
wp_die( 'Could not verify nonce' );
}
@ -848,7 +856,7 @@ class WC_Helper {
* User hit the Refresh button, clear all caches.
*/
private static function _helper_auth_refresh() {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'refresh' ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'refresh' ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_auth_refresh' );
wp_die( 'Could not verify nonce' );
}
@ -880,15 +888,16 @@ class WC_Helper {
* Active a product subscription.
*/
private static function _helper_subscription_activate() {
$product_key = $_GET['wc-helper-product-key'];
$product_id = absint( $_GET['wc-helper-product-id'] );
$product_key = isset( $_GET['wc-helper-product-key'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-product-key'] ) ) : '';
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'activate:' . $product_key ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'activate:' . $product_key ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_subscription_activate' );
wp_die( 'Could not verify nonce' );
}
$request = WC_Helper_API::post(
// Activate subscription.
$activation_response = WC_Helper_API::post(
'activate',
array(
'authenticated' => true,
@ -900,12 +909,33 @@ class WC_Helper {
)
);
$activated = wp_remote_retrieve_response_code( $request ) === 200;
$body = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' == $body['code'] ) {
$activated = wp_remote_retrieve_response_code( $activation_response ) === 200;
$body = json_decode( wp_remote_retrieve_body( $activation_response ), true );
if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' === $body['code'] ) {
$activated = true;
}
if ( $activated ) {
/**
* Fires when the Helper activates a product successfully.
*
* @param int $product_id Product ID being activated.
* @param string $product_key Subscription product key.
* @param array $activation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response );
} else {
/**
* Fires when the Helper fails to activate a product.
*
* @param int $product_id Product ID being activated.
* @param string $product_key Subscription product key.
* @param array $activation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response );
}
// Attempt to activate this plugin.
$local = self::_get_local_from_product_id( $product_id );
if ( $local && 'plugin' == $local['_type'] && current_user_can( 'activate_plugins' ) && ! is_plugin_active( $local['_filename'] ) ) {
@ -934,15 +964,15 @@ class WC_Helper {
* Deactivate a product subscription.
*/
private static function _helper_subscription_deactivate() {
$product_key = $_GET['wc-helper-product-key'];
$product_id = absint( $_GET['wc-helper-product-id'] );
$product_key = isset( $_GET['wc-helper-product-key'] ) ? wc_clean( wp_unslash( $_GET['wc-helper-product-key'] ) ) : '';
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'deactivate:' . $product_key ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'deactivate:' . $product_key ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_subscription_deactivate' );
wp_die( 'Could not verify nonce' );
}
$request = WC_Helper_API::post(
$deactivation_response = WC_Helper_API::post(
'deactivate',
array(
'authenticated' => true,
@ -954,13 +984,33 @@ class WC_Helper {
)
);
$code = wp_remote_retrieve_response_code( $request );
$code = wp_remote_retrieve_response_code( $deactivation_response );
$deactivated = 200 === $code;
if ( ! $deactivated ) {
if ( $deactivated ) {
/**
* Fires when the Helper activates a product successfully.
*
* @param int $product_id Product ID being deactivated.
* @param string $product_key Subscription product key.
* @param array $deactivation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response );
} else {
self::log( sprintf( 'Deactivate API call returned a non-200 response code (%d)', $code ) );
/**
* Fires when the Helper fails to activate a product.
*
* @param int $product_id Product ID being deactivated.
* @param string $product_key Subscription product key.
* @param array $deactivation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response );
}
self::_flush_subscriptions_cache();
$redirect_uri = add_query_arg(
array(
'page' => 'wc-addons',
@ -980,10 +1030,10 @@ class WC_Helper {
* Deactivate a plugin.
*/
private static function _helper_plugin_deactivate() {
$product_id = absint( $_GET['wc-helper-product-id'] );
$product_id = isset( $_GET['wc-helper-product-id'] ) ? absint( $_GET['wc-helper-product-id'] ) : 0;
$deactivated = false;
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( $_GET['wc-helper-nonce'], 'deactivate-plugin:' . $product_id ) ) {
if ( empty( $_GET['wc-helper-nonce'] ) || ! wp_verify_nonce( wp_unslash( $_GET['wc-helper-nonce'] ), 'deactivate-plugin:' . $product_id ) ) { // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
self::log( 'Could not verify nonce in _helper_plugin_deactivate' );
wp_die( 'Could not verify nonce' );
}
@ -1125,7 +1175,7 @@ class WC_Helper {
foreach ( $themes as $theme ) {
$header = $theme->get( 'Woo' );
// Backwards compatibility for theme_info.txt
// Backwards compatibility for theme_info.txt.
if ( ! $header ) {
$txt = $theme->get_stylesheet_directory() . '/theme_info.txt';
if ( is_readable( $txt ) ) {
@ -1171,7 +1221,8 @@ class WC_Helper {
*/
public static function get_subscriptions() {
$cache_key = '_woocommerce_helper_subscriptions';
if ( false !== ( $data = get_transient( $cache_key ) ) ) {
$data = get_transient( $cache_key );
if ( false !== $data ) {
return $data;
}
@ -1209,7 +1260,7 @@ class WC_Helper {
public static function activated_plugin( $filename ) {
$plugins = self::get_local_woo_plugins();
// Not a local woo plugin
// Not a local woo plugin.
if ( empty( $plugins[ $filename ] ) ) {
return;
}
@ -1221,9 +1272,10 @@ class WC_Helper {
}
$plugin = $plugins[ $filename ];
$subscriptions = self::_get_subscriptions_from_product_id( $plugin['_product_id'], false );
$product_id = $plugin['_product_id'];
$subscriptions = self::_get_subscriptions_from_product_id( $product_id, false );
// No valid subscriptions for this product
// No valid subscriptions for this product.
if ( empty( $subscriptions ) ) {
return;
}
@ -1251,30 +1303,49 @@ class WC_Helper {
return;
}
$request = WC_Helper_API::post(
$product_key = $subscription['product_key'];
$activation_response = WC_Helper_API::post(
'activate',
array(
'authenticated' => true,
'body' => wp_json_encode(
array(
'product_key' => $subscription['product_key'],
'product_key' => $product_key,
)
),
)
);
$activated = wp_remote_retrieve_response_code( $request ) === 200;
$body = json_decode( wp_remote_retrieve_body( $request ), true );
if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' == $body['code'] ) {
$activated = wp_remote_retrieve_response_code( $activation_response ) === 200;
$body = json_decode( wp_remote_retrieve_body( $activation_response ), true );
if ( ! $activated && ! empty( $body['code'] ) && 'already_connected' === $body['code'] ) {
$activated = true;
}
if ( ! $activated ) {
if ( $activated ) {
self::log( 'Auto-activated a subscription for ' . $filename );
/**
* Fires when the Helper activates a product successfully.
*
* @param int $product_id Product ID being activated.
* @param string $product_key Subscription product key.
* @param array $activation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_activate_success', $product_id, $product_key, $activation_response );
} else {
self::log( 'Could not activate a subscription upon plugin activation: ' . $filename );
return;
/**
* Fires when the Helper fails to activate a product.
*
* @param int $product_id Product ID being activated.
* @param string $product_key Subscription product key.
* @param array $activation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_activate_error', $product_id, $product_key, $activation_response );
}
self::log( 'Auto-activated a subscription for ' . $filename );
self::_flush_subscriptions_cache();
self::_flush_updates_cache();
}
@ -1290,7 +1361,7 @@ class WC_Helper {
public static function deactivated_plugin( $filename ) {
$plugins = self::get_local_woo_plugins();
// Not a local woo plugin
// Not a local woo plugin.
if ( empty( $plugins[ $filename ] ) ) {
return;
}
@ -1302,10 +1373,11 @@ class WC_Helper {
}
$plugin = $plugins[ $filename ];
$subscriptions = self::_get_subscriptions_from_product_id( $plugin['_product_id'], false );
$product_id = $plugin['_product_id'];
$subscriptions = self::_get_subscriptions_from_product_id( $product_id, false );
$site_id = absint( $auth['site_id'] );
// No valid subscriptions for this product
// No valid subscriptions for this product.
if ( empty( $subscriptions ) ) {
return;
}
@ -1314,24 +1386,43 @@ class WC_Helper {
foreach ( $subscriptions as $subscription ) {
// Don't touch subscriptions that aren't activated on this site.
if ( ! in_array( $site_id, $subscription['connections'] ) ) {
if ( ! in_array( $site_id, $subscription['connections'], true ) ) {
continue;
}
$request = WC_Helper_API::post(
$product_key = $subscription['product_key'];
$deactivation_response = WC_Helper_API::post(
'deactivate',
array(
'authenticated' => true,
'body' => wp_json_encode(
array(
'product_key' => $subscription['product_key'],
'product_key' => $product_key,
)
),
)
);
if ( wp_remote_retrieve_response_code( $request ) === 200 ) {
if ( wp_remote_retrieve_response_code( $deactivation_response ) === 200 ) {
$deactivated++;
/**
* Fires when the Helper activates a product successfully.
*
* @param int $product_id Product ID being deactivated.
* @param string $product_key Subscription product key.
* @param array $deactivation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_deactivate_success', $product_id, $product_key, $deactivation_response );
} else {
/**
* Fires when the Helper fails to activate a product.
*
* @param int $product_id Product ID being deactivated.
* @param string $product_key Subscription product key.
* @param array $deactivation_response The response object from wp_safe_remote_request().
*/
do_action( 'woocommerce_helper_subscription_deactivate_error', $product_id, $product_key, $deactivation_response );
}
}
@ -1367,7 +1458,7 @@ class WC_Helper {
// Add a note about available extension updates if Woo core has an update available.
$notice = self::_get_extensions_update_notice();
if ( ! empty( $notice ) ) {
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>';
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>'; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
}
}
@ -1417,7 +1508,7 @@ class WC_Helper {
/* translators: %s: helper screen url */
$notice = __( '<a href="%s">Connect your store</a> to WooCommerce.com to receive extensions updates and support.', 'woocommerce' );
$notice = sprintf( $notice, admin_url( 'admin.php?page=wc-addons&section=helper' ) );
echo '<div class="updated woocommerce-message"><p>' . $notice . '</p></div>';
echo '<div class="updated woocommerce-message"><p>' . wp_kses_post( $notice ) . '</p></div>';
}
}
@ -1446,8 +1537,8 @@ class WC_Helper {
return;
}
/* translators: %1$s: helper url, %2$d: number of extensions */
return sprintf(
/* translators: %1$s: helper url, %2$d: number of extensions */
_n( 'Note: You currently have <a href="%1$s">%2$d paid extension</a> which should be updated first before updating WooCommerce.', 'Note: You currently have <a href="%1$s">%2$d paid extensions</a> which should be updated first before updating WooCommerce.', $available, 'woocommerce' ),
admin_url( 'admin.php?page=wc-addons&section=helper' ),
$available
@ -1486,8 +1577,6 @@ class WC_Helper {
/**
* Flush auth cache.
*
* @access private
*/
public static function _flush_authentication_cache() {
$request = WC_Helper_API::get(
@ -1527,8 +1616,8 @@ class WC_Helper {
/**
* Sort subscriptions by the product_name.
*
* @param array $a Subscription array
* @param array $b Subscription array
* @param array $a Subscription array.
* @param array $b Subscription array.
*
* @return int
*/
@ -1539,8 +1628,8 @@ class WC_Helper {
/**
* Sort subscriptions by the Name.
*
* @param array $a Product array
* @param array $b Product array
* @param array $a Product array.
* @param array $b Product array.
*
* @return int
*/
@ -1552,8 +1641,7 @@ class WC_Helper {
* Log a helper event.
*
* @param string $message Log message.
* @param string $level Optional, defaults to info, valid levels:
* emergency|alert|critical|error|warning|notice|info|debug
* @param string $level Optional, defaults to info, valid levels: emergency|alert|critical|error|warning|notice|info|debug.
*/
public static function log( $message, $level = 'info' ) {
if ( ! defined( 'WP_DEBUG' ) || ! WP_DEBUG ) {

View File

@ -19,7 +19,7 @@ defined( 'ABSPATH' ) || exit();
<img src="<?php echo esc_url( WC()->plugin_url() . '/assets/images/woocommerce_logo.png' ); ?>" alt="WooCommerce" style="width:180px;">
<?php if ( ! empty( $_GET['wc-helper-status'] ) && 'helper-disconnected' === $_GET['wc-helper-status'] ) : ?>
<p><strong><?php esc_html_e( 'Sorry to see you go.', 'woocommerce' ) . '</strong>' . esc_html_e( 'Feel free to reconnect again using the button below.', 'woocommerce' ); ?></p>
<p><strong><?php esc_html_e( 'Sorry to see you go.', 'woocommerce' ); ?></strong> <?php esc_html_e( 'Feel free to reconnect again using the button below.', 'woocommerce' ); ?></p>
<?php endif; ?>
<h2><?php esc_html_e( 'Manage your subscriptions, get important product notifications, and updates, all from the convenience of your WooCommerce dashboard', 'woocommerce' ); ?></h2>

View File

@ -86,6 +86,7 @@ class WC_Product_CSV_Importer_Controller {
/**
* Check whether a file is a valid CSV file.
*
* @todo Replace this method with wc_is_file_valid_csv() function.
* @param string $file File path.
* @param bool $check_path Whether to also check the file is located in a valid location (Default: true).
* @return bool
@ -156,6 +157,9 @@ class WC_Product_CSV_Importer_Controller {
$this->map_preferences = isset( $_REQUEST['map_preferences'] ) ? (bool) $_REQUEST['map_preferences'] : false;
// phpcs:enable
// Import mappings for CSV data.
include_once dirname( __FILE__ ) . '/mappings/mappings.php';
if ( $this->map_preferences ) {
add_filter( 'woocommerce_csv_product_import_mapped_columns', array( $this, 'auto_map_user_preferences' ), 9999 );
}
@ -366,6 +370,7 @@ class WC_Product_CSV_Importer_Controller {
* Mapping step.
*/
protected function mapping_form() {
check_admin_referer( 'woocommerce-csv-importer' );
$args = array(
'lines' => 1,
'delimiter' => $this->delimiter,
@ -399,6 +404,10 @@ class WC_Product_CSV_Importer_Controller {
* Import the file if it exists and is valid.
*/
public function import() {
// Displaying this page triggers Ajax action to run the import with a valid nonce,
// therefore this page needs to be nonce protected as well.
check_admin_referer( 'woocommerce-csv-importer' );
if ( ! self::is_file_valid_csv( $this->file ) ) {
$this->add_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) );
$this->output_errors();
@ -411,7 +420,6 @@ class WC_Product_CSV_Importer_Controller {
return;
}
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- Nonce already verified in WC_Admin_Importers::do_ajax_product_import()
if ( ! empty( $_POST['map_from'] ) && ! empty( $_POST['map_to'] ) ) {
$mapping_from = wc_clean( wp_unslash( $_POST['map_from'] ) );
$mapping_to = wc_clean( wp_unslash( $_POST['map_to'] ) );
@ -422,7 +430,6 @@ class WC_Product_CSV_Importer_Controller {
wp_redirect( esc_url_raw( $this->get_next_step_link( 'upload' ) ) );
exit;
}
// phpcs:enable
wp_localize_script(
'wc-product-import',
@ -447,13 +454,12 @@ class WC_Product_CSV_Importer_Controller {
* Done step.
*/
protected function done() {
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification
check_admin_referer( 'woocommerce-csv-importer' );
$imported = isset( $_GET['products-imported'] ) ? absint( $_GET['products-imported'] ) : 0;
$updated = isset( $_GET['products-updated'] ) ? absint( $_GET['products-updated'] ) : 0;
$failed = isset( $_GET['products-failed'] ) ? absint( $_GET['products-failed'] ) : 0;
$skipped = isset( $_GET['products-skipped'] ) ? absint( $_GET['products-skipped'] ) : 0;
$errors = array_filter( (array) get_user_option( 'product_import_error_log' ) );
// phpcs:enable
include_once dirname( __FILE__ ) . '/views/html-csv-import-done.php';
}
@ -485,8 +491,6 @@ class WC_Product_CSV_Importer_Controller {
$weight_unit = get_option( 'woocommerce_weight_unit' );
$dimension_unit = get_option( 'woocommerce_dimension_unit' );
include dirname( __FILE__ ) . '/mappings/mappings.php';
/*
* @hooked wc_importer_generic_mappings - 10
* @hooked wc_importer_wordpress_mappings - 10
@ -539,7 +543,8 @@ class WC_Product_CSV_Importer_Controller {
__( 'External URL', 'woocommerce' ) => 'product_url',
__( 'Button text', 'woocommerce' ) => 'button_text',
__( 'Position', 'woocommerce' ) => 'menu_order',
)
),
$raw_headers
)
);
@ -564,7 +569,8 @@ class WC_Product_CSV_Importer_Controller {
__( 'Download %d URL', 'woocommerce' ) => 'downloads:url',
/* translators: %d: Meta number */
__( 'Meta: %s', 'woocommerce' ) => 'meta:',
)
),
$raw_headers
)
)
);
@ -694,7 +700,8 @@ class WC_Product_CSV_Importer_Controller {
),
),
'category_ids' => __( 'Categories', 'woocommerce' ),
'tag_ids' => __( 'Tags', 'woocommerce' ),
'tag_ids' => __( 'Tags (comma separated)', 'woocommerce' ),
'tag_ids_spaces' => __( 'Tags (space separated)', 'woocommerce' ),
'shipping_class_id' => __( 'Shipping class', 'woocommerce' ),
'images' => __( 'Images', 'woocommerce' ),
'parent_id' => __( 'Parent', 'woocommerce' ),
@ -729,7 +736,7 @@ class WC_Product_CSV_Importer_Controller {
),
'reviews_allowed' => __( 'Allow customer reviews?', 'woocommerce' ),
'purchase_note' => __( 'Purchase note', 'woocommerce' ),
'meta:' . $meta => __( 'Import as meta', 'woocommerce' ),
'meta:' . $meta => __( 'Import as meta data', 'woocommerce' ),
'menu_order' => __( 'Position', 'woocommerce' ),
);

View File

@ -200,8 +200,7 @@ class WC_Tax_Rate_Importer extends WP_Importer {
* @return bool False if error uploading or invalid file, true otherwise
*/
public function handle_upload() {
// phpcs:disable WordPress.Security.NonceVerification.NoNonceVerification -- Nonce already verified in WC_Tax_Rate_Importer::dispatch()
$file_url = isset( $_POST['file_url'] ) ? wc_clean( wp_unslash( $_POST['file_url'] ) ) : '';
$file_url = isset( $_POST['file_url'] ) ? wc_clean( wp_unslash( $_POST['file_url'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.NoNonceVerification -- Nonce already verified in WC_Tax_Rate_Importer::dispatch()
if ( empty( $file_url ) ) {
$file = wp_import_handle_upload();
@ -210,13 +209,23 @@ class WC_Tax_Rate_Importer extends WP_Importer {
$this->import_error( $file['error'] );
}
if ( ! wc_is_file_valid_csv( $file['file'], false ) ) {
// Remove file if not valid.
wp_delete_attachment( $file['id'], true );
$this->import_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) );
}
$this->id = absint( $file['id'] );
} elseif ( file_exists( ABSPATH . $file_url ) ) {
if ( ! wc_is_file_valid_csv( ABSPATH . $file_url ) ) {
$this->import_error( __( 'Invalid file type. The importer supports CSV and TXT file formats.', 'woocommerce' ) );
}
$this->file_url = esc_attr( $file_url );
} else {
$this->import_error();
}
// phpcs:enable
return true;
}

View File

@ -11,4 +11,5 @@ if ( ! defined( 'ABSPATH' ) ) {
require dirname( __FILE__ ) . '/default.php';
require dirname( __FILE__ ) . '/generic.php';
require dirname( __FILE__ ) . '/shopify.php';
require dirname( __FILE__ ) . '/wordpress.php';

View File

@ -0,0 +1,90 @@
<?php
/**
* Shopify mappings
*
* @package WooCommerce\Admin\Importers
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Add Shopify mappings.
*
* @since 3.7.0
* @param array $mappings Importer columns mappings.
* @param array $raw_headers Raw headers from CSV being imported.
* @return array
*/
function wc_importer_shopify_mappings( $mappings, $raw_headers ) {
// Only map if this is looks like a Shopify export.
if ( 0 !== count( array_diff( array( 'Title', 'Body (HTML)', 'Type', 'Variant SKU' ), $raw_headers ) ) ) {
return $mappings;
}
$shopify_mappings = array(
'Variant SKU' => 'sku',
'Title' => 'name',
'Body (HTML)' => 'description',
'Quantity' => 'stock_quantity',
'Variant Inventory Qty' => 'stock_quantity',
'Image Src' => 'images',
'Variant Image' => 'images',
'Variant SKU' => 'sku',
'Variant Price' => 'sale_price',
'Variant Compare At Price' => 'regular_price',
'Type' => 'category_ids',
'Tags' => 'tag_ids_spaces',
'Variant Grams' => 'weight',
'Variant Requires Shipping' => 'meta:shopify_requires_shipping',
'Variant Taxable' => 'tax_status',
);
return array_merge( $mappings, $shopify_mappings );
}
add_filter( 'woocommerce_csv_product_import_mapping_default_columns', 'wc_importer_shopify_mappings', 10, 2 );
/**
* Add special wildcard Shopify mappings.
*
* @since 3.7.0
* @param array $mappings Importer columns mappings.
* @param array $raw_headers Raw headers from CSV being imported.
* @return array
*/
function wc_importer_shopify_special_mappings( $mappings, $raw_headers ) {
// Only map if this is looks like a Shopify export.
if ( 0 !== count( array_diff( array( 'Title', 'Body (HTML)', 'Type', 'Variant SKU' ), $raw_headers ) ) ) {
return $mappings;
}
$shopify_mappings = array(
'Option%d Name' => 'attributes:name',
'Option%d Value' => 'attributes:value',
);
return array_merge( $mappings, $shopify_mappings );
}
add_filter( 'woocommerce_csv_product_import_mapping_special_columns', 'wc_importer_shopify_special_mappings', 10, 2 );
/**
* Expand special Shopify columns to WC format.
*
* @since 3.7.0
* @param array $data Array of data.
* @return array Expanded data.
*/
function wc_importer_shopify_expand_data( $data ) {
if ( isset( $data['meta:shopify_requires_shipping'] ) ) {
$requires_shipping = wc_string_to_bool( $data['meta:shopify_requires_shipping'] );
if ( ! $requires_shipping ) {
if ( isset( $data['type'] ) ) {
$data['type'][] = 'virtual';
} else {
$data['type'] = array( 'virtual' );
}
}
unset( $data['meta:shopify_requires_shipping'] );
}
return $data;
}
add_filter( 'woocommerce_product_importer_pre_expand_data', 'wc_importer_shopify_expand_data' );

View File

@ -183,6 +183,15 @@ class WC_Admin_List_Table_Orders extends WC_Admin_List_Table {
$buyer = ucwords( $user->display_name );
}
/**
* Filter buyer name in list table orders.
*
* @since 3.7.0
* @param string $buyer Buyer name.
* @param WC_Order $order Order data.
*/
$buyer = apply_filters( 'woocommerce_admin_order_buyer_name', $buyer, $this->object );
if ( $this->object->get_status() === 'trash' ) {
echo '<strong>#' . esc_attr( $this->object->get_order_number() ) . ' ' . esc_html( $buyer ) . '</strong>';
} else {

View File

@ -40,7 +40,6 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
add_filter( 'views_edit-product', array( $this, 'product_views' ) );
add_filter( 'get_search_query', array( $this, 'search_label' ) );
add_filter( 'posts_clauses', array( $this, 'posts_clauses' ), 10, 2 );
add_filter( 'the_posts', array( $this, 'remove_ordering_args' ) );
}
/**
@ -451,6 +450,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
* @return array
*/
protected function query_filters( $query_vars ) {
$this->remove_ordering_args();
// Custom order by arguments.
if ( isset( $query_vars['orderby'] ) ) {
$orderby = strtolower( $query_vars['orderby'] );
@ -520,10 +520,10 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
/**
* Remove ordering queries.
*
* @param array $posts Posts from WP Query.
* @param array $posts Posts array, keeping this for backwards compatibility defaulting to empty array.
* @return array
*/
public function remove_ordering_args( $posts ) {
public function remove_ordering_args( $posts = array() ) {
remove_filter( 'posts_clauses', array( $this, 'order_by_price_asc_post_clauses' ) );
remove_filter( 'posts_clauses', array( $this, 'order_by_price_desc_post_clauses' ) );
remove_filter( 'posts_clauses', array( $this, 'order_by_sku_asc_post_clauses' ) );
@ -531,7 +531,7 @@ class WC_Admin_List_Table_Products extends WC_Admin_List_Table {
remove_filter( 'posts_clauses', array( $this, 'filter_downloadable_post_clauses' ) );
remove_filter( 'posts_clauses', array( $this, 'filter_virtual_post_clauses' ) );
remove_filter( 'posts_clauses', array( $this, 'filter_stock_status_post_clauses' ) );
return $posts;
return $posts; // Keeping this here for backward compatibility.
}
/**

View File

@ -90,7 +90,7 @@ class WC_Meta_Box_Coupon_Data {
'label' => __( 'Coupon amount', 'woocommerce' ),
'placeholder' => wc_format_localized_price( 0 ),
'description' => __( 'Value of the coupon.', 'woocommerce' ),
'data_type' => 'price',
'data_type' => 'percent' === $coupon->get_discount_type( 'edit' ) ? 'decimal' : 'price',
'desc_tip' => true,
'value' => $coupon->get_amount( 'edit' ),
)

View File

@ -49,13 +49,18 @@ class WC_Meta_Box_Product_Images {
$update_meta = true;
continue;
}
echo '<li class="image" data-attachment_id="' . esc_attr( $attachment_id ) . '">
' . $attachment . '
<ul class="actions">
<li><a href="#" class="delete tips" data-tip="' . esc_attr__( 'Delete image', 'woocommerce' ) . '">' . __( 'Delete', 'woocommerce' ) . '</a></li>
</ul>
</li>';
?>
<li class="image" data-attachment_id="<?php echo esc_attr( $attachment_id ); ?>">
<?php echo $attachment; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>
<ul class="actions">
<li><a href="#" class="delete tips" data-tip="<?php esc_attr_e( 'Delete image', 'woocommerce' ); ?>"><?php esc_html_e( 'Delete', 'woocommerce' ); ?></a></li>
</ul>
<?php
// Allow for extra info to be exposed or extra action to be executed for this attachment.
do_action( 'woocommerce_admin_after_product_gallery_item', $thepostid, $attachment_id );
?>
</li>
<?php
// rebuild ids to be saved.
$updated_gallery_ids[] = $attachment_id;

View File

@ -43,7 +43,9 @@ if ( wc_tax_enabled() ) {
<th class="line_tax tips" data-tip="<?php echo esc_attr( $column_tip ); ?>">
<?php echo esc_attr( $column_label ); ?>
<input type="hidden" class="order-tax-id" name="order_taxes[<?php echo esc_attr( $tax_id ); ?>]" value="<?php echo esc_attr( $tax_item['rate_id'] ); ?>">
<a class="delete-order-tax" href="#" data-rate_id="<?php echo esc_attr( $tax_id ); ?>"></a>
<?php if ( $order->is_editable() ) : ?>
<a class="delete-order-tax" href="#" data-rate_id="<?php echo esc_attr( $tax_id ); ?>"></a>
<?php endif; ?>
</th>
<?php
endforeach;

View File

@ -7,6 +7,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<h3>
<a href="#" class="remove_row delete"><?php esc_html_e( 'Remove', 'woocommerce' ); ?></a>
<div class="handlediv" title="<?php esc_attr_e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<div class="tips sort" data-tip="<?php esc_attr_e( 'Drag and drop to set admin attribute order', 'woocommerce' ); ?>"></div>
<strong class="attribute_name"><?php echo wc_attribute_label( $attribute->get_name() ); ?></strong>
</h3>
<div class="woocommerce_attribute_data wc-metabox-content hidden">
@ -40,7 +41,7 @@ if ( ! defined( 'ABSPATH' ) ) {
<select multiple="multiple" data-placeholder="<?php esc_attr_e( 'Select terms', 'woocommerce' ); ?>" class="multiselect attribute_values wc-enhanced-select" name="attribute_values[<?php echo esc_attr( $i ); ?>][]">
<?php
$args = array(
'orderby' => 'name',
'orderby' => ! empty( $attribute_taxonomy->attribute_orderby ) ? $attribute_taxonomy->attribute_orderby : 'name',
'hide_empty' => 0,
);
$all_terms = get_terms( $attribute->get_taxonomy(), apply_filters( 'woocommerce_product_attribute_terms', $args ) );

View File

@ -65,7 +65,7 @@ defined( 'ABSPATH' ) || exit;
<label for="_sale_price_dates_from">' . esc_html__( 'Sale price dates', 'woocommerce' ) . '</label>
<input type="text" class="short" name="_sale_price_dates_from" id="_sale_price_dates_from" value="' . esc_attr( $sale_price_dates_from ) . '" placeholder="' . esc_html( _x( 'From&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
<input type="text" class="short" name="_sale_price_dates_to" id="_sale_price_dates_to" value="' . esc_attr( $sale_price_dates_to ) . '" placeholder="' . esc_html( _x( 'To&hellip;', 'placeholder', 'woocommerce' ) ) . ' YYYY-MM-DD" maxlength="10" pattern="' . esc_attr( apply_filters( 'woocommerce_date_input_html_pattern', '[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])' ) ) . '" />
<a href="#" class="description cancel_sale_schedule">' . esc_html__( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will end at the beginning of the set date.', 'woocommerce' ) ) . '
<a href="#" class="description cancel_sale_schedule">' . esc_html__( 'Cancel', 'woocommerce' ) . '</a>' . wc_help_tip( __( 'The sale will start at 00:00:00 of "From" date and end at 23:59:59 of "To" date.', 'woocommerce' ) ) . '
</p>';
do_action( 'woocommerce_product_options_pricing' );

View File

@ -20,7 +20,7 @@ class WC_Admin_Report {
* @var array List of transients name that have been updated and need persisting.
*/
protected static $transients_to_update = array();
/**
* @var array The list of transients.
*/
@ -333,8 +333,8 @@ class WC_Admin_Report {
$query['limit'] = "LIMIT {$limit}";
}
$query = apply_filters( 'woocommerce_reports_get_order_report_query', $query );
$query = implode( ' ', $query );
$query = apply_filters( 'woocommerce_reports_get_order_report_query', $query );
$query = implode( ' ', $query );
if ( $debug ) {
echo '<pre>';
@ -348,7 +348,7 @@ class WC_Admin_Report {
$result = apply_filters( 'woocommerce_reports_get_order_report_data', $wpdb->$query_type( $query ), $data );
} else {
$query_hash = md5( $query_type . $query );
$result = $this->get_cached_query( $query_hash );
$result = $this->get_cached_query( $query_hash );
if ( $result === null ) {
self::enable_big_selects();
@ -368,7 +368,7 @@ class WC_Admin_Report {
add_action( 'shutdown', array( 'WC_Admin_Report', 'maybe_update_transients' ) );
}
}
/**
* Enables big mysql selects for reports, just once for this session.
*/
@ -392,11 +392,11 @@ class WC_Admin_Report {
*/
protected function get_cached_query( $query_hash ) {
$class = strtolower( get_class( $this ) );
if ( ! isset( self::$cached_results[ $class ] ) ) {
self::$cached_results[ $class ] = get_transient( strtolower( get_class( $this ) ) );
}
if ( isset( self::$cached_results[ $class ][ $query_hash ] ) ) {
return self::$cached_results[ $class ][ $query_hash ];
}
@ -412,13 +412,13 @@ class WC_Admin_Report {
*/
protected function set_cached_query( $query_hash, $data ) {
$class = strtolower( get_class( $this ) );
if ( ! isset( self::$cached_results[ $class ] ) ) {
self::$cached_results[ $class ] = get_transient( strtolower( get_class( $this ) ) );
}
self::add_update_transients_hook();
self::$transients_to_update[ $class ] = $class;
self::$cached_results[ $class ][ $query_hash ] = $data;
}
@ -593,7 +593,7 @@ class WC_Admin_Report {
$tooltip = sprintf( __( 'Sold %1$s worth in the last %2$d days', 'woocommerce' ), strip_tags( wc_price( $total ) ), $days );
} else {
/* translators: 1: total items sold 2: days */
$tooltip = sprintf( _n( 'Sold 1 item in the last %2$d days', 'Sold %1$d items in the last %2$d days', $total, 'woocommerce' ), $total, $days );
$tooltip = sprintf( _n( 'Sold %1$d item in the last %2$d days', 'Sold %1$d items in the last %2$d days', $total, 'woocommerce' ), $total, $days );
}
$sparkline_data = array_values( $this->prepare_chart_data( $data, 'post_date', 'sparkline_value', $days - 1, strtotime( 'midnight -' . ( $days - 1 ) . ' days', current_time( 'timestamp' ) ), 'day' ) );

View File

@ -78,7 +78,7 @@ class WC_Settings_Accounts extends WC_Settings_Page {
'autoload' => false,
),
array(
'desc' => __( 'When creating an account, automatically generate a username from the customer\'s email address', 'woocommerce' ),
'desc' => __( 'When creating an account, automatically generate an account username for the customer based on their name, surname or email', 'woocommerce' ),
'id' => 'woocommerce_registration_generate_username',
'default' => 'yes',
'type' => 'checkbox',

View File

@ -47,8 +47,8 @@ class WC_Settings_Emails extends WC_Settings_Page {
*/
public function get_settings() {
$settings = apply_filters(
'woocommerce_email_settings', array(
'woocommerce_email_settings',
array(
array(
'title' => __( 'Email notifications', 'woocommerce' ),
'desc' => __( 'Email notifications sent from WooCommerce are listed below. Click on an email to configure it.', 'woocommerce' ),
@ -80,7 +80,7 @@ class WC_Settings_Emails extends WC_Settings_Page {
'desc' => __( 'How the sender name appears in outgoing WooCommerce emails.', 'woocommerce' ),
'id' => 'woocommerce_email_from_name',
'type' => 'text',
'css' => 'min-width:300px;',
'css' => 'min-width:400px;',
'default' => esc_attr( get_bloginfo( 'name', 'display' ) ),
'autoload' => false,
'desc_tip' => true,
@ -94,7 +94,7 @@ class WC_Settings_Emails extends WC_Settings_Page {
'custom_attributes' => array(
'multiple' => 'multiple',
),
'css' => 'min-width:300px;',
'css' => 'min-width:400px;',
'default' => get_option( 'admin_email' ),
'autoload' => false,
'desc_tip' => true,
@ -118,7 +118,7 @@ class WC_Settings_Emails extends WC_Settings_Page {
'desc' => __( 'URL to an image you want to show in the email header. Upload images using the media uploader (Admin > Media).', 'woocommerce' ),
'id' => 'woocommerce_email_header_image',
'type' => 'text',
'css' => 'min-width:300px;',
'css' => 'min-width:400px;',
'placeholder' => __( 'N/A', 'woocommerce' ),
'default' => '',
'autoload' => false,
@ -128,12 +128,12 @@ class WC_Settings_Emails extends WC_Settings_Page {
array(
'title' => __( 'Footer text', 'woocommerce' ),
/* translators: %s: Available placeholders for use */
'desc' => __( 'The text to appear in the footer of WooCommerce emails.', 'woocommerce' ) . ' ' . sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '{site_title}' ),
'desc' => __( 'The text to appear in the footer of all WooCommerce emails.', 'woocommerce' ) . ' ' . sprintf( __( 'Available placeholders: %s', 'woocommerce' ), '{site_title} {site_address}' ),
'id' => 'woocommerce_email_footer_text',
'css' => 'width:300px; height: 75px;',
'css' => 'width:400px; height: 75px;',
'placeholder' => __( 'N/A', 'woocommerce' ),
'type' => 'textarea',
'default' => '{site_title}<br/>Built with <a href="https://woocommerce.com/">WooCommerce</a>',
'default' => '{site_title} &mdash; Built with {WooCommerce}',
'autoload' => false,
'desc_tip' => true,
),
@ -260,7 +260,8 @@ class WC_Settings_Emails extends WC_Settings_Page {
<tr>
<?php
$columns = apply_filters(
'woocommerce_email_setting_columns', array(
'woocommerce_email_setting_columns',
array(
'status' => '',
'name' => __( 'Email', 'woocommerce' ),
'email_type' => __( 'Content type', 'woocommerce' ),

Some files were not shown because too many files have changed in this diff Show More