Merge pull request #1 from woothemes/master

sync
This commit is contained in:
Yakir Sitbon 2012-12-04 05:13:39 -08:00
commit 75c37ed2ed
523 changed files with 301769 additions and 117622 deletions

6
.gitignore vendored Normal file
View File

@ -0,0 +1,6 @@
logs/
/nbproject/private/
project.xml
project.properties
.DS_Store
Thumbs.db

32
CONTRIBUTING.md Normal file
View File

@ -0,0 +1,32 @@
# How to contribute
Community made patches, localisations, bug reports and contributions are always welcome and are crucial to ensure WooCommerce remains the #1 eCommerce platform for WordPress ;)
When contributing please ensure you follow the guidelines below so that we can keep on top of things.
__note__ GitHub is for bug reports and contributions only - if you have a support question or a request for a customisation don't post here. Use [WooThemes Support](http://support.woothemes.com) and [WooJobs](http://jobs.woothemes.com) respectively.
## Getting Started
* Make sure you have a [GitHub account](https://github.com/signup/free)
* Submit a ticket for your issue, assuming one does not already exist.
* Clearly describe the issue including steps to reproduce when it is a bug.
* Make sure you fill in the earliest version that you know has the issue.
## Making Changes
* Fork the repository on GitHub
* Make the changes to your forked repository
* Ensure you stick to the [WordPress Coding Standards](http://codex.wordpress.org/WordPress_Coding_Standards)
* Ensure you use LF line endings - no crazy windows line endings :)
* When committing, reference your issue (#1234) and include a note about the fix
* Push the changes to your fork and submit a pull request on the master WooCommerce repository
At this point you're waiting on us to merge your pull request. We'll review all pull requests, and make suggestions and changes if necessary.
# Additional Resources
* [General GitHub documentation](http://help.github.com/)
* [GitHub pull request documentation](http://help.github.com/send-pull-requests/)
* [WooCommerce Docs](http://wcdocs.woothemes.com/)
* [WooThemes Support](http://support.woothemes.com)

View File

@ -0,0 +1,39 @@
<?php
/**
* Init/register importers for WooCommerce.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Importers
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
register_importer( 'woocommerce_tax_rate_csv', __( 'WooCommerce Tax Rates (CSV)', 'woocommerce' ), __( 'Import <strong>tax rates</strong> to your store via a csv file.', 'woocommerce'), 'woocommerce_tax_rates_importer' );
/**
* woocommerce_tax_rates_importer function.
*
* @access public
* @return void
*/
function woocommerce_tax_rates_importer() {
// Load Importer API
require_once ABSPATH . 'wp-admin/includes/import.php';
if ( ! class_exists( 'WP_Importer' ) ) {
$class_wp_importer = ABSPATH . 'wp-admin/includes/class-wp-importer.php';
if ( file_exists( $class_wp_importer ) )
require $class_wp_importer;
}
// includes
require dirname( __FILE__ ) . '/tax-rates-importer.php';
// Dispatch
$WC_CSV_Tax_Rates_Import = new WC_CSV_Tax_Rates_Import();
$WC_CSV_Tax_Rates_Import->dispatch();
}

View File

@ -0,0 +1,6 @@
Country Code,State Code,ZIP/Postcode,City,Rate %,Tax Name,Priority,Compound,Shipping,Tax Class
GB,*,*,*,20.0000,VAT,1,1,1,
GB,*,*,*,5.0000,VAT,1,1,1,reduced-rate
GB,*,*,*,0.0000,VAT,1,1,1,zero-rate
US,*,*,*,10.0000,US,1,1,1,
US,AL,12345; 123456,*,2.0000,US AL,2,1,1,
1 Country Code State Code ZIP/Postcode City Rate % Tax Name Priority Compound Shipping Tax Class
2 GB * * * 20.0000 VAT 1 1 1
3 GB * * * 5.0000 VAT 1 1 1 reduced-rate
4 GB * * * 0.0000 VAT 1 1 1 zero-rate
5 US * * * 10.0000 US 1 1 1
6 US AL 12345; 123456 * 2.0000 US AL 2 1 1

View File

@ -0,0 +1,338 @@
<?php
/**
* Tax Rates importer - import tax rates and local tax rates into WooCommerce.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Importers
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
if ( class_exists( 'WP_Importer' ) ) {
class WC_CSV_Tax_Rates_Import extends WP_Importer {
var $id;
var $file_url;
var $import_page;
var $delimiter;
var $posts = array();
var $imported;
var $skipped;
/**
* __construct function.
*
* @access public
* @return void
*/
public function __construct() {
$this->import_page = 'woocommerce_tax_rate_csv';
}
/**
* Registered callback function for the WordPress Importer
*
* Manages the three separate stages of the CSV import process
*/
function dispatch() {
$this->header();
if ( ! empty( $_POST['delimiter'] ) )
$this->delimiter = stripslashes( trim( $_POST['delimiter'] ) );
if ( ! $this->delimiter )
$this->delimiter = ',';
$step = empty( $_GET['step'] ) ? 0 : (int) $_GET['step'];
switch ( $step ) {
case 0:
$this->greet();
break;
case 1:
check_admin_referer( 'import-upload' );
if ( $this->handle_upload() ) {
if ( $this->id )
$file = get_attached_file( $this->id );
else
$file = ABSPATH . $this->file_url;
add_filter( 'http_request_timeout', array( &$this, 'bump_request_timeout' ) );
if ( function_exists( 'gc_enable' ) )
gc_enable();
@set_time_limit(0);
@ob_flush();
@flush();
$this->import( $file );
}
break;
}
$this->footer();
}
/**
* format_data_from_csv function.
*
* @access public
* @param mixed $data
* @param mixed $enc
* @return void
*/
function format_data_from_csv( $data, $enc ) {
return ( $enc == 'UTF-8' ) ? $data : utf8_encode( $data );
}
/**
* import function.
*
* @access public
* @param mixed $file
* @return void
*/
function import( $file ) {
global $woocommerce, $wpdb;
$this->imported = $this->skipped = 0;
if ( ! is_file($file) ) {
echo '<p><strong>' . __( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong><br />';
echo __( 'The file does not exist, please try again.', 'woocommerce' ) . '</p>';
$this->footer();
die();
}
$new_rates = array();
if ( ( $handle = fopen( $file, "r" ) ) !== FALSE ) {
$header = fgetcsv( $handle, 0, $this->delimiter );
if ( sizeof( $header ) == 10 ) {
$loop = 0;
while ( ( $row = fgetcsv( $handle, 0, $this->delimiter ) ) !== FALSE ) {
list( $country, $state, $postcode, $city, $rate, $name, $priority, $compound, $shipping, $class ) = $row;
$country = trim( strtoupper( $country ) );
$state = trim( strtoupper( $state ) );
if ( $country == '*' )
$country = '';
if ( $state == '*' )
$state = '';
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rates",
array(
'tax_rate_country' => $country,
'tax_rate_state' => $state,
'tax_rate' => number_format( $rate, 4, '.', '' ),
'tax_rate_name' => trim( $name ),
'tax_rate_priority' => absint( $priority ),
'tax_rate_compound' => $compound ? 1 : 0,
'tax_rate_shipping' => $shipping ? 1 : 0,
'tax_rate_order' => $loop,
'tax_rate_class' => sanitize_title( $class )
)
);
$tax_rate_id = $wpdb->insert_id;
$postcode = woocommerce_clean( $postcode );
$postcodes = explode( ';', $postcode );
$postcodes = array_map( 'strtoupper', array_map( 'woocommerce_clean', $postcodes ) );
foreach( $postcodes as $postcode ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $postcode,
'tax_rate_id' => $tax_rate_id,
'location_type' => 'postcode',
)
);
}
$city = woocommerce_clean( $city );
$cities = explode( ';', $city );
$cities = array_map( 'strtoupper', array_map( 'woocommerce_clean', $cities ) );
foreach( $cities as $city ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $city,
'tax_rate_id' => $tax_rate_id,
'location_type' => 'city',
)
);
}
$loop ++;
$this->imported++;
}
} else {
echo '<p><strong>' . __( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong><br />';
echo __( 'The CSV is invalid.', 'woocommerce' ) . '</p>';
$this->footer();
die();
}
fclose( $handle );
}
// Show Result
echo '<div class="updated settings-error below-h2"><p>
'.sprintf( __( 'Import complete - imported <strong>%s</strong> tax rates and skipped <strong>%s</strong>.', 'woocommerce' ), $this->imported, $this->skipped ).'
</p></div>';
$this->import_end();
}
/**
* Performs post-import cleanup of files and the cache
*/
function import_end() {
echo '<p>' . __( 'All done!', 'woocommerce' ) . ' <a href="' . admin_url('admin.php?page=woocommerce_settings&tab=tax') . '">' . __( 'View Tax Rates', 'woocommerce' ) . '</a>' . '</p>';
do_action( 'import_end' );
}
/**
* Handles the CSV upload and initial parsing of the file to prepare for
* displaying author import options
*
* @return bool False if error uploading or invalid file, true otherwise
*/
function handle_upload() {
if ( empty( $_POST['file_url'] ) ) {
$file = wp_import_handle_upload();
if ( isset( $file['error'] ) ) {
echo '<p><strong>' . __( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong><br />';
echo esc_html( $file['error'] ) . '</p>';
return false;
}
$this->id = (int) $file['id'];
} else {
if ( file_exists( ABSPATH . $_POST['file_url'] ) ) {
$this->file_url = esc_attr( $_POST['file_url'] );
} else {
echo '<p><strong>' . __( 'Sorry, there has been an error.', 'woocommerce' ) . '</strong></p>';
return false;
}
}
return true;
}
/**
* header function.
*
* @access public
* @return void
*/
function header() {
echo '<div class="wrap"><div class="icon32 icon32-woocommerce-importer" id="icon-woocommerce"><br></div>';
echo '<h2>' . __( 'Import Tax Rates', 'woocommerce' ) . '</h2>';
}
/**
* footer function.
*
* @access public
* @return void
*/
function footer() {
echo '</div>';
}
/**
* greet function.
*
* @access public
* @return void
*/
function greet() {
global $woocommerce;
echo '<div class="narrow">';
echo '<p>' . __( 'Hi there! Upload a CSV file containing tax rates to import the contents into your shop. Choose a .csv file to upload, then click "Upload file and import".', 'woocommerce' ).'</p>';
echo '<p>' . sprintf( __( 'Tax rates need to be defined with columns in a specific order (10 columns). <a href="%s">Click here to download a sample</a>.', 'woocommerce' ), $woocommerce->plugin_url() . '/admin/importers/samples/sample_tax_rates.csv' ) . '</p>';
$action = 'admin.php?import=woocommerce_tax_rate_csv&step=1';
$bytes = apply_filters( 'import_upload_size_limit', wp_max_upload_size() );
$size = wp_convert_bytes_to_hr( $bytes );
$upload_dir = wp_upload_dir();
if ( ! empty( $upload_dir['error'] ) ) :
?><div class="error"><p><?php _e('Before you can upload your import file, you will need to fix the following error:'); ?></p>
<p><strong><?php echo $upload_dir['error']; ?></strong></p></div><?php
else :
?>
<form enctype="multipart/form-data" id="import-upload-form" method="post" action="<?php echo esc_attr(wp_nonce_url($action, 'import-upload')); ?>">
<table class="form-table">
<tbody>
<tr>
<th>
<label for="upload"><?php _e( 'Choose a file from your computer:' ); ?></label>
</th>
<td>
<input type="file" id="upload" name="import" size="25" />
<input type="hidden" name="action" value="save" />
<input type="hidden" name="max_file_size" value="<?php echo $bytes; ?>" />
<small><?php printf( __('Maximum size: %s' ), $size ); ?></small>
</td>
</tr>
<tr>
<th>
<label for="file_url"><?php _e( 'OR enter path to file:', 'woocommerce' ); ?></label>
</th>
<td>
<?php echo ' ' . ABSPATH . ' '; ?><input type="text" id="file_url" name="file_url" size="25" />
</td>
</tr>
<tr>
<th><label><?php _e( 'Delimiter', 'woocommerce' ); ?></label><br/></th>
<td><input type="text" name="delimiter" placeholder="," size="2" /></td>
</tr>
</tbody>
</table>
<p class="submit">
<input type="submit" class="button" value="<?php esc_attr_e( 'Upload file and import' ); ?>" />
</p>
</form>
<?php
endif;
echo '</div>';
}
/**
* Added to http_request_timeout filter to force timeout at 60 seconds during import
* @return int 60
*/
function bump_request_timeout() {
return 60;
}
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,175 @@
<?php
/**
* Functions used to duplicate a product
*
* Based on 'Duplicate Post' (http://www.lopo.it/duplicate-post-plugin/) by Enrico Battocchi
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Duplicate a product action.
*
* @access public
* @return void
*/
function woocommerce_duplicate_product() {
if (! ( isset( $_GET['post']) || isset( $_POST['post']) || ( isset($_REQUEST['action']) && 'duplicate_post_save_as_new_page' == $_REQUEST['action'] ) ) ) {
wp_die(__( 'No product to duplicate has been supplied!', 'woocommerce' ));
}
// Get the original page
$id = (isset($_GET['post']) ? $_GET['post'] : $_POST['post']);
check_admin_referer( 'woocommerce-duplicate-product_' . $id );
$post = woocommerce_get_product_to_duplicate($id);
// Copy the page and insert it
if (isset($post) && $post!=null) {
$new_id = woocommerce_create_duplicate_from_product($post);
// If you have written a plugin which uses non-WP database tables to save
// information about a page you can hook this action to dupe that data.
do_action( 'woocommerce_duplicate_product', $new_id, $post );
// Redirect to the edit screen for the new draft page
wp_redirect( admin_url( 'post.php?action=edit&post=' . $new_id ) );
exit;
} else {
wp_die(__( 'Product creation failed, could not find original product:', 'woocommerce' ) . ' ' . $id);
}
}
/**
* Get a product from the database to duplicate
*
* @access public
* @param mixed $id
* @return void
*/
function woocommerce_get_product_to_duplicate($id) {
global $wpdb;
$post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
if (isset($post->post_type) && $post->post_type == "revision"){
$id = $post->post_parent;
$post = $wpdb->get_results("SELECT * FROM $wpdb->posts WHERE ID=$id");
}
return $post[0];
}
/**
* Function to create the duplicate of the product.
*
* @access public
* @param mixed $post
* @param int $parent (default: 0)
* @param string $post_status (default: '')
* @return void
*/
function woocommerce_create_duplicate_from_product( $post, $parent = 0, $post_status = '' ) {
global $wpdb;
$new_post_author = wp_get_current_user();
$new_post_date = current_time('mysql');
$new_post_date_gmt = get_gmt_from_date($new_post_date);
if ( $parent > 0 ) {
$post_parent = $parent;
$post_status = $post_status ? $post_status : 'publish';
$suffix = '';
} else {
$post_parent = $post->post_parent;
$post_status = $post_status ? $post_status : 'draft';
$suffix = ' ' . __( '(Copy)', 'woocommerce' );
}
$new_post_type = $post->post_type;
$post_content = str_replace("'", "''", $post->post_content);
$post_content_filtered = str_replace("'", "''", $post->post_content_filtered);
$post_excerpt = str_replace("'", "''", $post->post_excerpt);
$post_title = str_replace("'", "''", $post->post_title).$suffix;
$post_name = str_replace("'", "''", $post->post_name);
$comment_status = str_replace("'", "''", $post->comment_status);
$ping_status = str_replace("'", "''", $post->ping_status);
// Insert the new template in the post table
$wpdb->query(
"INSERT INTO $wpdb->posts
(post_author, post_date, post_date_gmt, post_content, post_content_filtered, post_title, post_excerpt, post_status, post_type, comment_status, ping_status, post_password, to_ping, pinged, post_modified, post_modified_gmt, post_parent, menu_order, post_mime_type)
VALUES
('$new_post_author->ID', '$new_post_date', '$new_post_date_gmt', '$post_content', '$post_content_filtered', '$post_title', '$post_excerpt', '$post_status', '$new_post_type', '$comment_status', '$ping_status', '$post->post_password', '$post->to_ping', '$post->pinged', '$new_post_date', '$new_post_date_gmt', '$post_parent', '$post->menu_order', '$post->post_mime_type')");
$new_post_id = $wpdb->insert_id;
// Copy the taxonomies
woocommerce_duplicate_post_taxonomies( $post->ID, $new_post_id, $post->post_type );
// Copy the meta information
woocommerce_duplicate_post_meta( $post->ID, $new_post_id );
// Copy the children (variations)
if ( $children_products =& get_children( 'post_parent='.$post->ID.'&post_type=product_variation' ) ) {
if ($children_products) foreach ($children_products as $child) {
woocommerce_create_duplicate_from_product( woocommerce_get_product_to_duplicate( $child->ID ), $new_post_id, $child->post_status );
}
}
return $new_post_id;
}
/**
* Copy the taxonomies of a post to another post
*
* @access public
* @param mixed $id
* @param mixed $new_id
* @param mixed $post_type
* @return void
*/
function woocommerce_duplicate_post_taxonomies($id, $new_id, $post_type) {
global $wpdb;
$taxonomies = get_object_taxonomies($post_type); //array("category", "post_tag");
foreach ($taxonomies as $taxonomy) {
$post_terms = wp_get_object_terms($id, $taxonomy);
$post_terms_count = sizeof( $post_terms );
for ($i=0; $i<$post_terms_count; $i++) {
wp_set_object_terms($new_id, $post_terms[$i]->slug, $taxonomy, true);
}
}
}
/**
* Copy the meta information of a post to another post
*
* @access public
* @param mixed $id
* @param mixed $new_id
* @return void
*/
function woocommerce_duplicate_post_meta($id, $new_id) {
global $wpdb;
$post_meta_infos = $wpdb->get_results("SELECT meta_key, meta_value FROM $wpdb->postmeta WHERE post_id=$id");
if (count($post_meta_infos)!=0) {
$sql_query = "INSERT INTO $wpdb->postmeta (post_id, meta_key, meta_value) ";
foreach ($post_meta_infos as $meta_info) {
$meta_key = $meta_info->meta_key;
$meta_value = addslashes($meta_info->meta_value);
$sql_query_sel[]= "SELECT $new_id, '$meta_key', '$meta_value'";
}
$sql_query.= implode(" UNION ALL ", $sql_query_sel);
$wpdb->query($sql_query);
}
}

View File

@ -0,0 +1,9 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div id="message" class="updated woocommerce-message wc-connect">
<div class="squeezer">
<h4><?php _e( '<strong>Welcome to WooCommerce</strong> &#8211; You\'re almost ready to start selling :)', 'woocommerce' ); ?></h4>
<p class="submit"><a href="<?php echo add_query_arg('install_woocommerce_pages', 'true', admin_url('admin.php?page=woocommerce_settings') ); ?>" class="button-primary"><?php _e( 'Install WooCommerce Pages', 'woocommerce' ); ?></a> <a class="skip button-primary" href="<?php echo add_query_arg('skip_install_woocommerce_pages', 'true', admin_url('admin.php?page=woocommerce_settings') ); ?>"><?php _e( 'Skip setup', 'woocommerce' ); ?></a></p>
</div>
</div>

View File

@ -0,0 +1,13 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div id="message" class="updated woocommerce-message wc-connect">
<div class="squeezer">
<h4><?php _e( '<strong>WooCommerce has been installed</strong> &#8211; You\'re ready to start selling :)', 'woocommerce' ); ?></h4>
<p class="submit"><a href="<?php echo admin_url('admin.php?page=woocommerce_settings'); ?>" class="button-primary"><?php _e( 'Settings', 'woocommerce' ); ?></a> <a class="docs button-primary" href="http://www.woothemes.com/woocommerce-docs/"><?php _e( 'Docs', 'woocommerce' ); ?></a></p>
<p><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://www.woothemes.com/woocommerce/" data-text="A open-source (free) #ecommerce plugin for #WordPress that helps you sell anything. Beautifully." data-via="WooThemes" data-size="large" data-hashtags="WooCommerce">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script></p>
</div>
</div>

View File

@ -0,0 +1,15 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div id="message" class="updated woocommerce-message wc-connect">
<div class="squeezer">
<h4><?php _e( '<strong>Data Update Required</strong> &#8211; We just need to update your install to the latest version', 'woocommerce' ); ?></h4>
<p class="submit"><a href="<?php echo add_query_arg( 'do_update_woocommerce', 'true', admin_url('admin.php?page=woocommerce_settings') ); ?>" class="wc-update-now button-primary"><?php _e( 'Run the updater', 'woocommerce' ); ?></a></p>
</div>
</div>
<script type="text/javascript">
jQuery('.wc-update-now').click('click', function(){
var answer = confirm( '<?php _e( 'It is strongly recommended that you backup your database before proceeding. Are you sure you wish to run the updater now?', 'woocommerce' ); ?>' );
return answer;
});
</script>

View File

@ -0,0 +1,13 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div id="message" class="updated woocommerce-message wc-connect">
<div class="squeezer">
<h4><?php _e( '<strong>WooCommerce has been updated</strong> &#8211; You\'re ready to continue selling :)', 'woocommerce' ); ?></h4>
<p class="submit"><a href="<?php echo admin_url('admin.php?page=woocommerce_settings'); ?>" class="button-primary"><?php _e( 'Settings', 'woocommerce' ); ?></a> <a class="docs button-primary" href="http://www.woothemes.com/woocommerce-docs/"><?php _e( 'Docs', 'woocommerce' ); ?></a></p>
<p><a href="https://twitter.com/share" class="twitter-share-button" data-url="http://www.woothemes.com/woocommerce/" data-text="A open-source (free) #ecommerce plugin for #WordPress that helps you sell anything. Beautifully." data-via="WooThemes" data-size="large" data-hashtags="WooCommerce">Tweet</a>
<script>!function(d,s,id){var js,fjs=d.getElementsByTagName(s)[0];if(!d.getElementById(id)){js=d.createElement(s);js.id=id;js.src="//platform.twitter.com/widgets.js";fjs.parentNode.insertBefore(js,fjs);}}(document,"script","twitter-wjs");</script></p>
</div>
</div>

View File

@ -0,0 +1,34 @@
<?php
/**
* Update WC to 1.4
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Updates
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $wpdb, $woocommerce;
// Upgrade from old downloadable/virtual product types
$downloadable_type = get_term_by( 'slug', 'downloadable', 'product_type' );
if ( $downloadable_type ) {
$products = get_objects_in_term( $downloadable_type->term_id, 'product_type' );
foreach ( $products as $product ) {
update_post_meta( $product, '_downloadable', 'yes' );
update_post_meta( $product, '_virtual', 'yes' );
wp_set_object_terms( $product, 'simple', 'product_type');
}
}
$virtual_type = get_term_by( 'slug', 'virtual', 'product_type' );
if ( $virtual_type ) {
$products = get_objects_in_term( $virtual_type->term_id, 'product_type' );
foreach ( $products as $product ) {
update_post_meta( $product, '_downloadable', 'no' );
update_post_meta( $product, '_virtual', 'yes' );
wp_set_object_terms( $product, 'simple', 'product_type');
}
}

View File

@ -0,0 +1,47 @@
<?php
/**
* Update WC to 1.5
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Updates
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $wpdb, $woocommerce;
// Update woocommerce_downloadable_product_permissions table to include order ID's as well as keys
$results = $wpdb->get_results( "SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = 0;" );
if ( $results ) foreach ( $results as $result ) {
if ( ! $result->order_key )
continue;
$order_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM {$wpdb->postmeta} WHERE meta_key = '_order_key' AND meta_value = '%s' LIMIT 1;", $result->order_key ) );
if ( $order_id ) {
$wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions", array(
'order_id' => $order_id,
), array(
'product_id' => $result->product_id,
'order_key' => $result->order_key
), array( '%s' ), array( '%s', '%s' ) );
}
}
// Upgrade old meta keys for product data
$meta = array( 'sku', 'downloadable', 'virtual', 'price', 'visibility', 'stock', 'stock_status', 'backorders', 'manage_stock', 'sale_price', 'regular_price', 'weight', 'length', 'width', 'height', 'tax_status', 'tax_class', 'upsell_ids', 'crosssell_ids', 'sale_price_dates_from', 'sale_price_dates_to', 'min_variation_price', 'max_variation_price', 'featured', 'product_attributes', 'file_path', 'download_limit', 'product_url', 'min_variation_price', 'max_variation_price' );
$wpdb->query( "
UPDATE {$wpdb->postmeta}
LEFT JOIN {$wpdb->posts} ON ( {$wpdb->postmeta}.post_id = {$wpdb->posts}.ID )
SET meta_key = CONCAT( '_', meta_key )
WHERE meta_key IN ( '" . implode( "', '", $meta ) . "' )
AND {$wpdb->posts}.post_type IN ('product', 'product_variation')
" );

View File

@ -0,0 +1,292 @@
<?php
/**
* Update WC to 2.0
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Updates
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
global $wpdb, $woocommerce;
// Upgrade old style files paths to support multiple file paths
$existing_file_paths = $wpdb->get_results( "SELECT * FROM {$wpdb->postmeta} WHERE meta_key = '_file_path'" );
if ( $existing_file_paths ) {
foreach( $existing_file_paths as $existing_file_path ) {
$existing_file_path->meta_value = trim( $existing_file_path->meta_value );
if ( $existing_file_path->meta_value )
$file_paths = maybe_serialize( array( md5( $existing_file_path->meta_value ) => $existing_file_path->meta_value ) );
else
$file_paths = '';
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->postmeta} SET meta_key = '_file_paths', meta_value = %s WHERE meta_id = %d", $file_paths, $existing_file_path->meta_id ) );
$wpdb->query( $wpdb->prepare( "UPDATE {$wpdb->prefix}woocommerce_downloadable_product_permissions SET download_id = %s WHERE product_id = %d", md5( $existing_file_path->meta_value ), $existing_file_path->post_id ) );
}
}
// Update table primary keys
$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions DROP PRIMARY KEY" );
$wpdb->query( "ALTER TABLE {$wpdb->prefix}woocommerce_downloadable_product_permissions ADD PRIMARY KEY ( `product_id` , `order_id` , `order_key` , `download_id` )" );
// Setup default permalinks if shop page is defined
$permalinks = get_option( 'woocommerce_permalinks' );
$shop_page_id = woocommerce_get_page_id( 'shop' );
if ( empty( $permalinks ) && $shop_page_id > 0 ) {
$base_slug = $shop_page_id > 0 && get_page( $shop_page_id ) ? get_page_uri( $shop_page_id ) : 'shop';
$category_base = get_option('woocommerce_prepend_shop_page_to_urls') == "yes" ? trailingslashit( $base_slug ) : '';
$category_slug = get_option('woocommerce_product_category_slug') ? get_option('woocommerce_product_category_slug') : _x( 'product-category', 'slug', 'woocommerce' );
$tag_slug = get_option('woocommerce_product_tag_slug') ? get_option('woocommerce_product_tag_slug') : _x( 'product-tag', 'slug', 'woocommerce' );
if ( 'yes' == get_option('woocommerce_prepend_shop_page_to_products') ) {
$product_base = trailingslashit( $base_slug );
} else {
if ( ( $product_slug = get_option('woocommerce_product_slug') ) !== false && ! empty( $product_slug ) ) {
$product_base = trailingslashit( $product_slug );
} else {
$product_base = trailingslashit( _x('product', 'slug', 'woocommerce') );
}
}
if ( get_option('woocommerce_prepend_category_to_products') == 'yes' )
$product_base .= trailingslashit('%product_cat%');
$permalinks = array(
'product_base' => untrailingslashit( $product_base ),
'category_base' => untrailingslashit( $category_base . $category_slug ),
'attribute_base' => untrailingslashit( $category_base ),
'tag_base' => untrailingslashit( $category_base . $tag_slug )
);
update_option( 'woocommerce_permalinks', $permalinks );
}
// Update subcat display settings
if ( get_option( 'woocommerce_shop_show_subcategories' ) == 'yes' ) {
if ( get_option( 'woocommerce_hide_products_when_showing_subcategories' ) == 'yes' ) {
update_option( 'woocommerce_shop_page_display', 'subcategories' );
} else {
update_option( 'woocommerce_shop_page_display', 'both' );
}
}
if ( get_option( 'woocommerce_show_subcategories' ) == 'yes' ) {
if ( get_option( 'woocommerce_hide_products_when_showing_subcategories' ) == 'yes' ) {
update_option( 'woocommerce_category_archive_display', 'subcategories' );
} else {
update_option( 'woocommerce_category_archive_display', 'both' );
}
}
// Update tax rates
$loop = 0;
$tax_rates = get_option( 'woocommerce_tax_rates' );
foreach ( $tax_rates as $tax_rate ) {
foreach ( $tax_rate['countries'] as $country => $states ) {
$states = array_reverse( $states );
foreach ( $states as $state ) {
if ( $state == '*' )
$state = '';
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rates",
array(
'tax_rate_country' => $country,
'tax_rate_state' => $state,
'tax_rate' => $tax_rate['rate'],
'tax_rate_name' => $tax_rate['label'],
'tax_rate_priority' => 1,
'tax_rate_compound' => $tax_rate['compound'] == 'yes' ? 1 : 0,
'tax_rate_shipping' => $tax_rate['shipping'] == 'yes' ? 1 : 0,
'tax_rate_order' => $loop,
'tax_rate_class' => $tax_rate['class']
)
);
$loop++;
}
}
}
$local_tax_rates = get_option( 'woocommerce_local_tax_rates' );
foreach ( $local_tax_rates as $tax_rate ) {
$location_type = $tax_rate['location_type'] == 'postcode' ? 'postcode' : 'city';
if ( $tax_rate['state'] == '*' )
$tax_rate['state'] = '';
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rates",
array(
'tax_rate_country' => $tax_rate['country'],
'tax_rate_state' => $tax_rate['state'],
'tax_rate' => $tax_rate['rate'],
'tax_rate_name' => $tax_rate['label'],
'tax_rate_priority' => 2,
'tax_rate_compound' => $tax_rate['compound'] == 'yes' ? 1 : 0,
'tax_rate_shipping' => $tax_rate['shipping'] == 'yes' ? 1 : 0,
'tax_rate_order' => $loop,
'tax_rate_class' => $tax_rate['class']
)
);
$tax_rate_id = $wpdb->insert_id;
foreach ( $tax_rate['locations'] as $location ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $location,
'tax_rate_id' => $tax_rate_id,
'location_type' => $location_type,
)
);
}
$loop++;
}
update_option( 'woocommerce_tax_rates_backup', $tax_rates );
update_option( 'woocommerce_local_tax_rates_backup', $local_tax_rates );
delete_option( 'woocommerce_tax_rates' );
delete_option( 'woocommerce_local_tax_rates' );
// Now its time for the massive update to line items - move them to the new DB tables
// Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_items' WHERE meta_key = '_order_items_old'
$order_item_rows = $wpdb->get_results( "
SELECT * FROM {$wpdb->postmeta}
WHERE meta_key = '_order_items'
" );
foreach ( $order_item_rows as $order_item_row ) {
$order_items = (array) maybe_unserialize( $order_item_row->meta_value );
foreach ( $order_items as $order_item ) {
if ( ! isset( $order_item['line_total'] ) && isset( $order_item['taxrate'] ) && isset( $order_item['cost'] ) ) {
$order_item['line_tax'] = number_format( ( $order_item['cost'] * $order_item['qty'] ) * ( $order_item['taxrate'] / 100 ), 2, '.', '' );
$order_item['line_total'] = $order_item['cost'] * $order_item['qty'];
$order_item['line_subtotal_tax'] = $order_item['line_tax'];
$order_item['line_subtotal'] = $order_item['line_total'];
}
$order_item['line_tax'] = isset( $order_item['line_tax'] ) ? $order_item['line_tax'] : 0;
$order_item['line_total'] = isset( $order_item['line_total'] ) ? $order_item['line_total'] : 0;
$order_item['line_subtotal_tax'] = isset( $order_item['line_subtotal_tax'] ) ? $order_item['line_subtotal_tax'] : 0;
$order_item['line_subtotal'] = isset( $order_item['line_subtotal'] ) ? $order_item['line_subtotal'] : 0;
$item_id = woocommerce_add_order_item( $order_item_row->post_id, array(
'order_item_name' => $order_item['name'],
'order_item_type' => 'line_item'
) );
// Add line item meta
if ( $item_id ) {
woocommerce_add_order_item_meta( $item_id, '_qty', absint( $order_item['qty'] ) );
woocommerce_add_order_item_meta( $item_id, '_tax_class', $order_item['tax_class'] );
woocommerce_add_order_item_meta( $item_id, '_product_id', $order_item['id'] );
woocommerce_add_order_item_meta( $item_id, '_variation_id', $order_item['variation_id'] );
woocommerce_add_order_item_meta( $item_id, '_line_subtotal', woocommerce_format_decimal( $order_item['line_subtotal'] ) );
woocommerce_add_order_item_meta( $item_id, '_line_subtotal_tax', woocommerce_format_decimal( $order_item['line_subtotal_tax'] ) );
woocommerce_add_order_item_meta( $item_id, '_line_total', woocommerce_format_decimal( $order_item['line_total'] ) );
woocommerce_add_order_item_meta( $item_id, '_line_tax', woocommerce_format_decimal( $order_item['line_tax'] ) );
$meta_rows = array();
// Insert meta
if ( ! empty( $order_item['item_meta'] ) ) {
foreach ( $order_item['item_meta'] as $key => $meta ) {
// Backwards compatibility
if ( is_array( $meta ) && isset( $meta['meta_name'] ) ) {
$meta_rows[] = '(' . $item_id . ',"' . $wpdb->escape( $meta['meta_name'] ) . '","' . $wpdb->escape( $meta['meta_value'] ) . '")';
} else {
$meta_rows[] = '(' . $item_id . ',"' . $wpdb->escape( $key ) . '","' . $wpdb->escape( $meta ) . '")';
}
}
}
// Insert meta rows at once
if ( sizeof( $meta_rows ) > 0 ) {
$wpdb->query( $wpdb->prepare( "
INSERT INTO {$wpdb->prefix}woocommerce_order_itemmeta ( order_item_id, meta_key, meta_value )
VALUES " . implode( ',', $meta_rows ) . ";
", $order_item_row->post_id ) );
}
// Delete from DB (rename)
$wpdb->query( $wpdb->prepare( "
UPDATE {$wpdb->postmeta}
SET meta_key = '_order_items_old'
WHERE meta_key = '_order_items'
AND post_id = %d
", $order_item_row->post_id ) );
}
unset( $meta_rows, $item_id, $order_item );
}
}
// Do the same kind of update for order_taxes - move to lines
// Reverse with UPDATE `wpwc_postmeta` SET meta_key = '_order_taxes' WHERE meta_key = '_order_taxes_old'
$order_tax_rows = $wpdb->get_results( "
SELECT * FROM {$wpdb->postmeta}
WHERE meta_key = '_order_taxes'
" );
foreach ( $order_tax_rows as $order_tax_row ) {
$order_taxes = (array) maybe_unserialize( $order_tax_row->meta_value );
if ( $order_taxes ) {
foreach( $order_taxes as $order_tax ) {
if ( ! isset( $order_tax['label'] ) || ! isset( $order_tax['cart_tax'] ) || ! isset( $order_tax['shipping_tax'] ) )
continue;
$item_id = woocommerce_add_order_item( $order_tax_row->post_id, array(
'order_item_name' => $order_tax['label'],
'order_item_type' => 'tax'
) );
// Add line item meta
if ( $item_id ) {
woocommerce_add_order_item_meta( $item_id, 'compound', absint( isset( $order_tax['compound'] ) ? $order_tax['compound'] : 0 ) );
woocommerce_add_order_item_meta( $item_id, 'tax_amount', woocommerce_clean( $order_tax['cart_tax'] ) );
woocommerce_add_order_item_meta( $item_id, 'shipping_tax_amount', woocommerce_clean( $order_tax['shipping_tax'] ) );
}
// Delete from DB (rename)
$wpdb->query( $wpdb->prepare( "
UPDATE {$wpdb->postmeta}
SET meta_key = '_order_taxes_old'
WHERE meta_key = '_order_taxes'
AND post_id = %d
", $order_tax_row->post_id ) );
unset( $tax_amount );
}
}
}

View File

@ -1,32 +0,0 @@
<?php
/**
* WooCommerce Post Types Init
*
* Load post types panels
*
* @author WooThemes
* @category Admin
* @package WooCommerce
*/
global $typenow;
include_once( 'writepanels/writepanels-init.php' );
if ($typenow=='post' && isset($_GET['post']) && !empty($_GET['post'])) :
$typenow = $post->post_type;
elseif (empty($typenow) && !empty($_GET['post'])) :
$post = get_post($_GET['post']);
$typenow = $post->post_type;
endif;
if ( $typenow=='product' ) :
include_once('product.php');
include_once('writepanels/writepanel-product_data.php');
elseif ( $typenow=='shop_coupon' ) :
include_once('shop_coupon.php');
include_once('writepanels/writepanel-coupon_data.php');
elseif ( $typenow=='shop_order' ) :
include_once('shop_order.php');
include_once('writepanels/writepanel-order_data.php');
include_once('writepanels/writepanel-order_notes.php');
endif;

File diff suppressed because it is too large Load Diff

View File

@ -1,68 +1,95 @@
<?php <?php
/** /**
* Admin functions for the shop_coupon post type * Admin functions for the shop_coupon post type.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Coupons
* @version 1.6.4
*/ */
/**
* Columns for Coupons page
**/
add_filter('manage_edit-shop_coupon_columns', 'woocommerce_edit_coupon_columns');
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Define Columns for the Coupons admin page.
*
* @access public
* @param mixed $columns
* @return array
*/
function woocommerce_edit_coupon_columns($columns){ function woocommerce_edit_coupon_columns($columns){
$columns = array(); $columns = array();
$columns["cb"] = "<input type=\"checkbox\" />"; $columns["cb"] = "<input type=\"checkbox\" />";
$columns["title"] = __("Code", 'woothemes'); $columns["title"] = __( 'Code', 'woocommerce' );
$columns["type"] = __("Coupon type", 'woothemes'); $columns["type"] = __( 'Coupon type', 'woocommerce' );
$columns["amount"] = __("Coupon amount", 'woothemes'); $columns["amount"] = __( 'Coupon amount', 'woocommerce' );
$columns["products"] = __("Product IDs", 'woothemes'); $columns["description"] = __( 'Description', 'woocommerce' );
$columns["usage_limit"] = __("Usage limit", 'woothemes'); $columns["products"] = __( 'Product IDs', 'woocommerce' );
$columns["usage_count"] = __("Usage count", 'woothemes'); $columns["usage"] = __( 'Usage / Limit', 'woocommerce' );
$columns["expiry_date"] = __("Expiry date", 'woothemes'); $columns["expiry_date"] = __( 'Expiry date', 'woocommerce' );
return $columns; return $columns;
} }
add_filter( 'manage_edit-shop_coupon_columns', 'woocommerce_edit_coupon_columns' );
/** /**
* Custom Columns for Coupons page * Values for Columns on the Coupons admin page.
**/ *
add_action('manage_shop_coupon_posts_custom_column', 'woocommerce_custom_coupon_columns', 2); * @access public
* @param mixed $column
function woocommerce_custom_coupon_columns($column) { * @return void
*/
function woocommerce_custom_coupon_columns( $column ) {
global $post, $woocommerce; global $post, $woocommerce;
$type = get_post_meta($post->ID, 'discount_type', true);
$amount = get_post_meta($post->ID, 'coupon_amount', true);
$individual_use = get_post_meta($post->ID, 'individual_use', true);
$product_ids = (get_post_meta($post->ID, 'product_ids', true)) ? explode(',', get_post_meta($post->ID, 'product_ids', true)) : array();
$usage_limit = get_post_meta($post->ID, 'usage_limit', true);
$usage_count = (int) get_post_meta($post->ID, 'usage_count', true);
$expiry_date = get_post_meta($post->ID, 'expiry_date', true);
switch ($column) { switch ( $column ) {
case "type" : case "type" :
echo $woocommerce->get_coupon_discount_type($type); echo esc_html( $woocommerce->get_coupon_discount_type( get_post_meta( $post->ID, 'discount_type', true ) ) );
break; break;
case "amount" : case "amount" :
echo $amount; echo esc_html( get_post_meta( $post->ID, 'coupon_amount', true ) );
break; break;
case "products" : case "products" :
if (sizeof($product_ids)>0) echo implode(', ', $product_ids); else echo '&ndash;'; $product_ids = get_post_meta( $post->ID, 'product_ids', true );
$product_ids = $product_ids ? array_map( 'absint', explode( ',', $product_ids ) ) : array();
if ( sizeof( $product_ids ) > 0 )
echo esc_html( implode( ', ', $product_ids ) );
else
echo '&ndash;';
break; break;
case "usage_limit" : case "usage_limit" :
if ($usage_limit) echo $usage_limit; else echo '&ndash;'; $usage_limit = get_post_meta( $post->ID, 'usage_limit', true );
if ( $usage_limit )
echo esc_html( $usage_limit );
else
echo '&ndash;';
break; break;
case "usage_count" : case "usage" :
echo $usage_count; $usage_count = absint( get_post_meta( $post->ID, 'usage_count', true ) );
$usage_limit = esc_html( get_post_meta($post->ID, 'usage_limit', true) );
if ( $usage_limit )
printf( __( '%s / %s', 'woocommerce' ), $usage_count, $usage_limit );
else
printf( __( '%s / &infin;', 'woocommerce' ), $usage_count );
break; break;
case "expiry_date" : case "expiry_date" :
if ($expiry_date) echo date('F j, Y', strtotime($expiry_date)); else echo '&ndash;'; $expiry_date = get_post_meta($post->ID, 'expiry_date', true);
if ( $expiry_date )
echo esc_html( date_i18n( 'F j, Y', strtotime( $expiry_date ) ) );
else
echo '&ndash;';
break;
case "description" :
echo wp_kses_post( $post->post_excerpt );
break; break;
} }
} }
add_action( 'manage_shop_coupon_posts_custom_column', 'woocommerce_custom_coupon_columns', 2 );

View File

@ -1,332 +1,461 @@
<?php <?php
/** /**
* Admin functions for the shop_order post type * Admin functions for the shop_order post type.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Orders
* @version 1.6.4
*/ */
/**
* Columns for order page
**/
add_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Disable the auto-save functionality for Orders.
*
* @access public
* @return void
*/
function woocommerce_disable_autosave_for_orders(){
global $post;
if ( $post && get_post_type( $post->ID ) === 'shop_order' ) {
wp_dequeue_script( 'autosave' );
}
}
add_action( 'admin_print_scripts', 'woocommerce_disable_autosave_for_orders' );
/**
* Define columns for the orders page.
*
* @access public
* @param mixed $columns
* @return array
*/
function woocommerce_edit_order_columns($columns){ function woocommerce_edit_order_columns($columns){
global $woocommerce;
$columns = array(); $columns = array();
$columns["cb"] = "<input type=\"checkbox\" />"; $columns["cb"] = "<input type=\"checkbox\" />";
$columns["order_status"] = __("Status", 'woothemes'); $columns["order_status"] = __( 'Status', 'woocommerce' );
$columns["order_title"] = __("Order", 'woothemes'); $columns["order_title"] = __( 'Order', 'woocommerce' );
$columns["billing_address"] = __("Billing", 'woothemes'); $columns["billing_address"] = __( 'Billing', 'woocommerce' );
$columns["shipping_address"] = __("Shipping", 'woothemes'); $columns["shipping_address"] = __( 'Shipping', 'woocommerce' );
$columns["total_cost"] = __("Order Total", 'woothemes'); $columns["total_cost"] = __( 'Order Total', 'woocommerce' );
$columns["order_date"] = __("Date", 'woothemes'); $columns["order_comments"] = '<img alt="' . esc_attr__( 'Order Notes', 'woocommerce' ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/order-notes_head.png" class="tips" data-tip="' . __( 'Order Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["order_actions"] = __("Actions", 'woothemes'); $columns["note"] = '<img src="' . $woocommerce->plugin_url() . '/assets/images/note_head.png" alt="' . __( 'Customer Notes', 'woocommerce' ) . '" class="tips" data-tip="' . __( 'Customer Notes', 'woocommerce' ) . '" width="12" height="12" />';
$columns["order_date"] = __( 'Date', 'woocommerce' );
$columns["order_actions"] = __( 'Actions', 'woocommerce' );
return $columns; return $columns;
} }
add_filter('manage_edit-shop_order_columns', 'woocommerce_edit_order_columns');
/** /**
* Custom Columns for order page * Values for the custom columns on the orders page.
**/ *
add_action('manage_shop_order_posts_custom_column', 'woocommerce_custom_order_columns', 2); * @access public
* @param mixed $column
* @return void
*/
function woocommerce_custom_order_columns( $column ) {
function woocommerce_custom_order_columns($column) { global $post, $woocommerce;
$order = new WC_Order( $post->ID );
global $post; switch ( $column ) {
$order = &new woocommerce_order( $post->ID );
switch ($column) {
case "order_status" : case "order_status" :
echo sprintf( __('<mark class="%s">%s</mark>', 'woothemes'), sanitize_title($order->status), __($order->status, 'woothemes') ); printf( '<mark class="%s">%s</mark>', sanitize_title( $order->status ), esc_html__( $order->status, 'woocommerce' ) );
break; break;
case "order_title" : case "order_title" :
if ($order->user_id) $user_info = get_userdata($order->user_id); if ( $order->user_id )
$user_info = get_userdata( $order->user_id );
if (isset($user_info) && $user_info) :
if ( ! empty( $user_info ) ) {
$user = '<a href="user-edit.php?user_id=' . esc_attr( $user_info->ID ) . '">';
$user = '<a href="user-edit.php?user_id=' . absint( $user_info->ID ) . '">';
if ($user_info->first_name || $user_info->last_name) $user .= $user_info->first_name.' '.$user_info->last_name;
else $user .= esc_html( $user_info->display_name ); if ( $user_info->first_name || $user_info->last_name )
$user .= esc_html( $user_info->first_name . ' ' . $user_info->last_name );
else
$user .= esc_html( $user_info->display_name );
$user .= '</a>'; $user .= '</a>';
else : } else {
$user = __('Guest', 'woothemes'); $user = __( 'Guest', 'woocommerce' );
endif; }
echo '<a href="'.admin_url('post.php?post='.$post->ID.'&action=edit').'"><strong>'.sprintf( __('Order #%s', 'woothemes'), $post->ID ).'</strong></a> ' . __('made by', 'woothemes') . ' ' . $user; echo '<a href="' . admin_url( 'post.php?post=' . absint( $post->ID ) . '&action=edit' ) . '"><strong>' . sprintf( __( 'Order %s', 'woocommerce' ), esc_attr( $order->get_order_number() ) ) . '</strong></a> ' . __( 'made by', 'woocommerce' ) . ' ' . $user;
if ($order->billing_email) : if ( $order->billing_email )
echo '<small class="meta">'.__('Email:', 'woothemes') . ' ' . '<a href="' . esc_url( 'mailto:'.$order->billing_email ).'">'.esc_html( $order->billing_email ).'</a></small>'; echo '<small class="meta">' . __( 'Email:', 'woocommerce' ) . ' ' . '<a href="' . esc_url( 'mailto:' . $order->billing_email ) . '">' . esc_html( $order->billing_email ) . '</a></small>';
endif;
if ($order->billing_phone) : if ( $order->billing_phone )
echo '<small class="meta">'.__('Tel:', 'woothemes') . ' ' . esc_html( $order->billing_phone ) . '</small>'; echo '<small class="meta">' . __( 'Tel:', 'woocommerce' ) . ' ' . esc_html( $order->billing_phone ) . '</small>';
endif;
break; break;
case "billing_address" : case "billing_address" :
if ($order->formatted_shipping_address) : if ( $order->get_formatted_billing_address() )
echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q=' . urlencode( $order->get_billing_address() ) . '&z=16' ) . '">' . esc_html( preg_replace( '#<br\s*/?>#i', ', ', $order->get_formatted_billing_address() ) ) .'</a>';
echo '<a target="_blank" href="' . esc_url( 'http://maps.google.co.uk/maps?&q='.urlencode( $order->billing_address_only ).'&z=16' ) . '">'. preg_replace('#<br\s*/?>#i', ', ', $order->formatted_billing_address) .'</a>'; else
else :
echo '&ndash;'; echo '&ndash;';
endif;
if ( $order->payment_method_title )
if ($order->payment_method_title) : echo '<small class="meta">' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->payment_method_title ) . '</small>';
echo '<small class="meta">' . __('Via', 'woothemes') . ' ' . esc_html( $order->payment_method_title ) . '</small>';
endif;
break; break;
case "shipping_address" : case "shipping_address" :
if ($order->formatted_shipping_address) : if ( $order->get_formatted_shipping_address() )
echo '<a target="_blank" href="' . esc_url( 'http://maps.google.com/maps?&q=' . urlencode( $order->get_shipping_address() ) . '&z=16' ) . '">'. esc_html( preg_replace('#<br\s*/?>#i', ', ', $order->get_formatted_shipping_address() ) ) .'</a>';
echo '<a target="_blank" href="' . esc_url( 'http://maps.google.co.uk/maps?&q='.urlencode( $order->shipping_address_only ).'&z=16' ) .'">'. preg_replace('#<br\s*/?>#i', ', ', $order->formatted_shipping_address) .'</a>'; else
else :
echo '&ndash;'; echo '&ndash;';
endif;
if ( $order->shipping_method_title )
if ($order->shipping_method_title) : echo '<small class="meta">' . __( 'Via', 'woocommerce' ) . ' ' . esc_html( $order->shipping_method_title ) . '</small>';
echo '<small class="meta">' . __('Via', 'woothemes') . ' ' . esc_html( $order->shipping_method_title ) . '</small>';
endif;
break; break;
case "total_cost" : case "total_cost" :
echo woocommerce_price($order->order_total); echo esc_html( strip_tags( $order->get_formatted_order_total() ) );
break; break;
case "order_date" : case "order_date" :
if ( '0000-00-00 00:00:00' == $post->post_date ) :
$t_time = $h_time = __( 'Unpublished', 'woothemes' );
$time_diff = 0;
else :
$t_time = get_the_time( __( 'Y/m/d g:i:s A', 'woothemes' ) );
$m_time = $post->post_date;
$time = get_post_time( 'G', true, $post );
$time_diff = time() - $time; if ( '0000-00-00 00:00:00' == $post->post_date ) {
$t_time = $h_time = __( 'Unpublished', 'woocommerce' );
} else {
$t_time = get_the_time( __( 'Y/m/d g:i:s A', 'woocommerce' ), $post );
$gmt_time = strtotime( $post->post_date_gmt );
$time_diff = current_time('timestamp', 1) - $gmt_time;
if ( $time_diff > 0 && $time_diff < 24*60*60 ) if ( $time_diff > 0 && $time_diff < 24*60*60 )
$h_time = sprintf( __( '%s ago', 'woothemes' ), human_time_diff( $time ) ); $h_time = sprintf( __( '%s ago', 'woocommerce' ), human_time_diff( $gmt_time, current_time('timestamp', 1) ) );
else else
$h_time = mysql2date( __( 'Y/m/d', 'woothemes' ), $m_time ); $h_time = get_the_time( __( 'Y/m/d', 'woocommerce' ), $post );
endif; }
echo '<abbr title="' . esc_attr( $t_time ) . '">' . esc_html( apply_filters( 'post_date_column_time', $h_time, $post ) ) . '</abbr>';
echo '<abbr title="' . $t_time . '">' . apply_filters( 'post_date_column_time', $h_time, $post ) . '</abbr>';
break; break;
case "order_actions" : case "order_actions" :
?><p> ?><p>
<?php if (in_array($order->status, array('pending', 'on-hold'))) : ?><a class="button" href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=woocommerce-mark-order-processing&order_id=' . $post->ID) ); ?>"><?php _e('Processing', 'woothemes'); ?></a><?php endif; ?> <?php
<?php if (in_array($order->status, array('pending', 'on-hold', 'processing'))) : ?><a class="button" href="<?php echo wp_nonce_url( admin_url('admin-ajax.php?action=woocommerce-mark-order-complete&order_id=' . $post->ID) ); ?>"><?php _e('Complete', 'woothemes'); ?></a><?php endif; ?> do_action( 'woocommerce_admin_order_actions_start', $order );
<a class="button" href="<?php echo admin_url('post.php?post='.$post->ID.'&action=edit'); ?>"><?php _e('View', 'woothemes'); ?></a>
$actions = array();
if ( in_array( $order->status, array( 'pending', 'on-hold' ) ) )
$actions[] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-processing&order_id=' . $post->ID ), 'woocommerce-mark-order-processing' ),
'name' => __( 'Processing', 'woocommerce' ),
'action' => "processing"
);
if ( in_array( $order->status, array( 'pending', 'on-hold', 'processing' ) ) )
$actions[] = array(
'url' => wp_nonce_url( admin_url( 'admin-ajax.php?action=woocommerce-mark-order-complete&order_id=' . $post->ID ), 'woocommerce-mark-order-complete' ),
'name' => __( 'Complete', 'woocommerce' ),
'action' => "complete"
);
$actions[] = array(
'url' => admin_url( 'post.php?post=' . $post->ID . '&action=edit' ),
'name' => __( 'View', 'woocommerce' ),
'action' => "view"
);
$actions = apply_filters( 'woocommerce_admin_order_actions', $actions, $order );
foreach ( $actions as $action ) {
$image = ( isset( $action['image_url'] ) ) ? $action['image_url'] : $woocommerce->plugin_url() . '/assets/images/icons/' . $action['action'] . '.png';
printf( '<a class="button tips" href="%s" data-tip="%s"><img src="%s" alt="%s" width="14" /></a>', esc_url( $action['url'] ), esc_attr( $action['name'] ), esc_attr( $image ), esc_attr( $action['name'] ) );
}
do_action( 'woocommerce_admin_order_actions_end', $order );
?>
</p><?php </p><?php
break;
case "note" :
if ( $order->customer_note )
echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note.png" alt="yes" class="tips" data-tip="' . __( 'Yes', 'woocommerce' ) . '" width="14" height="14" />';
else
echo '<img src="'.$woocommerce->plugin_url().'/assets/images/note-off.png" alt="no" class="tips" data-tip="' . __( 'No', 'woocommerce' ) . '" width="14" height="14" />';
break;
case "order_comments" :
echo '<div class="post-com-count-wrapper">
<a href="'. esc_url( admin_url('post.php?post=' . $post->ID . '&action=edit') ) .'" class="post-com-count"><span class="comment-count">'. $post->comment_count .'</span></a>
</div>';
break; break;
} }
} }
add_action( 'manage_shop_order_posts_custom_column', 'woocommerce_custom_order_columns', 2 );
/** /**
* Order page filters * Filters for the order page.
**/ *
add_filter('views_edit-shop_order', 'woocommerce_custom_order_views'); * @access public
* @param mixed $views
* @return array
*/
function woocommerce_custom_order_views( $views ) { function woocommerce_custom_order_views( $views ) {
unset($views['publish']); unset( $views['publish'] );
if (isset($views['trash'])) : if ( isset( $views['trash'] ) ) {
$trash = $views['trash']; $trash = $views['trash'];
unset($views['draft']); unset( $views['draft'] );
unset($views['trash']); unset( $views['trash'] );
$views['trash'] = $trash; $views['trash'] = $trash;
endif; }
return $views; return $views;
} }
add_filter( 'views_edit-shop_order', 'woocommerce_custom_order_views' );
/** /**
* Order page actions * Actions for the orders page.
**/ *
add_filter( 'post_row_actions', 'woocommerce_remove_row_actions', 10, 1 ); * @access public
* @param mixed $actions
* @return array
*/
function woocommerce_remove_row_actions( $actions ) { function woocommerce_remove_row_actions( $actions ) {
if( get_post_type() === 'shop_order' ) : if( get_post_type() === 'shop_order' ) {
unset( $actions['view'] ); unset( $actions['view'] );
unset( $actions['inline hide-if-no-js'] ); unset( $actions['inline hide-if-no-js'] );
endif; }
return $actions; return $actions;
} }
add_filter( 'post_row_actions', 'woocommerce_remove_row_actions', 10, 1 );
/** /**
* Order page bulk actions * Remove edit from the bulk actions.
**/ *
add_filter( 'bulk_actions-edit-shop_order', 'woocommerce_bulk_actions' ); * @access public
* @param mixed $actions
* @return array
*/
function woocommerce_bulk_actions( $actions ) { function woocommerce_bulk_actions( $actions ) {
if (isset($actions['edit'])) unset($actions['edit']); if ( isset( $actions['edit'] ) )
unset( $actions['edit'] );
return $actions; return $actions;
} }
/** add_filter( 'bulk_actions-edit-shop_order', 'woocommerce_bulk_actions' );
* Filter orders by status
**/
add_action('restrict_manage_posts','woocommerce_orders_by_status');
function woocommerce_orders_by_status() {
global $typenow, $wp_query; /**
if ($typenow=='shop_order') : * Show custom filters to filter orders by status/customer.
$terms = get_terms('shop_order_status'); *
$output = "<select name='shop_order_status' id='dropdown_shop_order_status'>"; * @access public
$output .= '<option value="">'.__('Show all statuses', 'woothemes').'</option>'; * @return void
foreach($terms as $term) : */
$output .="<option value='$term->slug' "; function woocommerce_restrict_manage_orders() {
if ( isset( $wp_query->query['shop_order_status'] ) ) $output .=selected($term->slug, $wp_query->query['shop_order_status'], false); global $woocommerce, $typenow, $wp_query;
$output .=">".__($term->name, 'woothemes')." ($term->count)</option>";
endforeach; if ( $typenow != 'shop_order' )
$output .="</select>"; return;
echo $output;
endif; // Status
?>
<select name='shop_order_status' id='dropdown_shop_order_status'>
<option value=""><?php _e( 'Show all statuses', 'woocommerce' ); ?></option>
<?php
$terms = get_terms('shop_order_status');
foreach ( $terms as $term ) {
echo '<option value="' . esc_attr( $term->slug ) . '"';
if ( isset( $wp_query->query['shop_order_status'] ) )
selected( $term->slug, $wp_query->query['shop_order_status'] );
echo '>' . esc_html__( $term->name, 'woocommerce' ) . ' (' . absint( $term->count ) . ')</option>';
}
?>
</select>
<?php
// Customers
?>
<select id="dropdown_customers" name="_customer_user">
<option value=""><?php _e( 'Show all customers', 'woocommerce' ) ?></option>
<?php
if ( ! empty( $_GET['_customer_user'] ) ) {
$user = get_user_by( 'id', absint( $_GET['_customer_user'] ) );
echo '<option value="' . absint( $user->ID ) . '" ';
selected( 1, 1 );
echo '>' . esc_html( $user->display_name ) . ' (#' . absint( $user->ID ) . ' &ndash; ' . esc_html( $user->user_email ) . ')</option>';
}
?>
</select>
<?php
$woocommerce->add_inline_js( "
jQuery('select#dropdown_shop_order_status, select[name=m]').css('width', '150px').chosen();
jQuery('select#dropdown_customers').css('width', '250px').ajaxChosen({
method: 'GET',
url: '" . admin_url('admin-ajax.php') . "',
dataType: 'json',
afterTypeDelay: 100,
minTermLength: 1,
data: {
action: 'woocommerce_json_search_customers',
security: '" . wp_create_nonce("search-customers") . "',
default: '" . __( 'Show all customers', 'woocommerce' ) . "'
}
}, function (data) {
var terms = {};
$.each(data, function (i, val) {
terms[i] = val;
});
return terms;
});
" );
} }
/** add_action( 'restrict_manage_posts', 'woocommerce_restrict_manage_orders' );
* Filter orders by customer
**/
add_action('restrict_manage_posts', 'woocommerce_orders_by_customer');
function woocommerce_orders_by_customer() {
global $typenow, $wp_query;
if ($typenow=='shop_order') :
$users_query = new WP_User_Query( array(
'fields' => 'all',
//'role' => 'customer',
'orderby' => 'display_name'
) );
$users = $users_query->get_results();
if ($users) :
$output = "<select name='_customer_user' id='dropdown_customers'>";
$output .= '<option value="">'.__('Show all customers', 'woothemes').'</option>';
foreach($users as $user) :
$output .="<option value='$user->ID' ";
if ( isset( $_GET['_customer_user'] ) ) $output .=selected($user->ID, $_GET['_customer_user'], false);
$output .=">$user->display_name</option>";
endforeach;
$output .="</select>";
echo $output;
endif;
endif;
}
/** /**
* Filter orders by customer query * Filter the orders by the posted customer.
**/ *
add_filter( 'request', 'woocommerce_orders_by_customer_query' ); * @access public
* @param mixed $vars
* @return array
*/
function woocommerce_orders_by_customer_query( $vars ) { function woocommerce_orders_by_customer_query( $vars ) {
global $typenow, $wp_query; global $typenow, $wp_query;
if ($typenow=='shop_order' && isset( $_GET['_customer_user'] ) && $_GET['_customer_user']>0) : if ( $typenow == 'shop_order' && isset( $_GET['_customer_user'] ) && $_GET['_customer_user'] > 0 ) {
$vars['meta_key'] = '_customer_user'; $vars['meta_key'] = '_customer_user';
$vars['meta_value'] = (int) $_GET['_customer_user']; $vars['meta_value'] = (int) $_GET['_customer_user'];
endif; }
return $vars; return $vars;
} }
/** add_filter( 'request', 'woocommerce_orders_by_customer_query' );
* Make order columns sortable
* https://gist.github.com/906872
**/
add_filter("manage_edit-shop_order_sortable_columns", 'woocommerce_custom_shop_order_sort');
function woocommerce_custom_shop_order_sort($columns) {
/**
* Make order columns sortable.
*
*
* https://gist.github.com/906872
*
* @access public
* @param mixed $columns
* @return array
*/
function woocommerce_custom_shop_order_sort( $columns ) {
$custom = array( $custom = array(
'order_title' => 'ID', 'order_title' => 'ID',
'order_total' => 'order_total', 'order_total' => 'order_total',
'order_date' => 'date' 'order_date' => 'date'
); );
return wp_parse_args($custom, $columns); unset( $columns['comments'] );
return wp_parse_args( $custom, $columns );
} }
add_filter( "manage_edit-shop_order_sortable_columns", 'woocommerce_custom_shop_order_sort' );
/** /**
* Order column orderby/request * Order column orderby/request.
**/ *
add_filter( 'request', 'woocommerce_custom_shop_order_orderby' ); * @access public
* @param mixed $vars
* @return array
*/
function woocommerce_custom_shop_order_orderby( $vars ) { function woocommerce_custom_shop_order_orderby( $vars ) {
global $typenow, $wp_query; global $typenow, $wp_query;
if ($typenow!='shop_order') return $vars; if ( $typenow != 'shop_order' )
return $vars;
// Sorting // Sorting
if (isset( $vars['orderby'] )) : if ( isset( $vars['orderby'] ) ) {
if ( 'order_total' == $vars['orderby'] ) : if ( 'order_total' == $vars['orderby'] ) {
$vars = array_merge( $vars, array( $vars = array_merge( $vars, array(
'meta_key' => '_order_total', 'meta_key' => '_order_total',
'orderby' => 'meta_value_num' 'orderby' => 'meta_value_num'
) ); ) );
endif; }
endif; }
return $vars; return $vars;
} }
/** add_filter( 'request', 'woocommerce_custom_shop_order_orderby' );
* Order custom field search
**/
if (is_admin()) :
add_filter( 'parse_query', 'woocommerce_shop_order_search_custom_fields' );
add_filter( 'get_search_query', 'woocommerce_shop_order_search_label' );
endif;
/**
* Search custom fields as well as content.
*
* @access public
* @param mixed $wp
* @return void
*/
function woocommerce_shop_order_search_custom_fields( $wp ) { function woocommerce_shop_order_search_custom_fields( $wp ) {
global $pagenow, $wpdb; global $pagenow, $wpdb;
if( 'edit.php' != $pagenow ) return $wp; if ( 'edit.php' != $pagenow ) return $wp;
if( !isset( $wp->query_vars['s'] ) || !$wp->query_vars['s'] ) return $wp; if ( ! isset( $wp->query_vars['s'] ) || ! $wp->query_vars['s'] ) return $wp;
if ($wp->query_vars['post_type']!='shop_order') return $wp; if ( $wp->query_vars['post_type'] != 'shop_order' ) return $wp;
$search_fields = array( $search_fields = array_map( 'esc_attr', apply_filters( 'woocommerce_shop_order_search_fields', array(
'_order_key', '_order_key',
'_billing_first_name', '_billing_first_name',
'_billing_last_name', '_billing_last_name',
'_billing_company', '_billing_company',
'_billing_address_1', '_billing_address_1',
'_billing_address_2', '_billing_address_2',
'_billing_city', '_billing_city',
'_billing_postcode', '_billing_postcode',
'_billing_country', '_billing_country',
'_billing_state', '_billing_state',
'_billing_email', '_billing_email',
'_order_items',
'_billing_phone' '_billing_phone'
); ) ) );
// Query matching custom fields - this seems faster than meta_query // Query matching custom fields - this seems faster than meta_query
$post_ids = $wpdb->get_col($wpdb->prepare('SELECT post_id FROM '.$wpdb->postmeta.' WHERE meta_key IN ('.'"'.implode('","', $search_fields).'"'.') AND meta_value LIKE "%%%s%%"', esc_attr($_GET['s']) )); $post_ids = $wpdb->get_col(
$wpdb->prepare(
"SELECT post_id FROM " . $wpdb->postmeta . " WHERE meta_key IN ('" . implode( "','", $search_fields ) . "') AND meta_value LIKE '%%%s%%'", esc_attr( $_GET['s'] )
)
);
// Query matching excerpts and titles // Query matching excerpts and titles
$post_ids = array_merge($post_ids, $wpdb->get_col($wpdb->prepare(' $post_ids = array_merge( $post_ids, $wpdb->get_col( $wpdb->prepare('
SELECT '.$wpdb->posts.'.ID SELECT ' . $wpdb->posts . '.ID
FROM '.$wpdb->posts.' FROM ' . $wpdb->posts . '
LEFT JOIN '.$wpdb->postmeta.' ON '.$wpdb->posts.'.ID = '.$wpdb->postmeta.'.post_id LEFT JOIN ' . $wpdb->postmeta . ' ON ' . $wpdb->posts . '.ID = ' . $wpdb->postmeta . '.post_id
LEFT JOIN '.$wpdb->users.' ON '.$wpdb->postmeta.'.meta_value = '.$wpdb->users.'.ID LEFT JOIN ' . $wpdb->users . ' ON ' . $wpdb->postmeta . '.meta_value = ' . $wpdb->users . '.ID
WHERE WHERE
post_excerpt LIKE "%%%1$s%%" OR post_excerpt LIKE "%%%1$s%%" OR
post_title LIKE "%%%1$s%%" OR post_title LIKE "%%%1$s%%" OR
( (
@ -338,44 +467,63 @@ function woocommerce_shop_order_search_custom_fields( $wp ) {
display_name LIKE "%%%1$s%%" display_name LIKE "%%%1$s%%"
) )
) )
', ',
esc_attr($_GET['s']) esc_attr($_GET['s'])
))); ) ) );
// Add ID // Add ID
$search_order_id = str_replace('Order #', '', $_GET['s']); $search_order_id = str_replace( 'Order #', '', $_GET['s'] );
if (is_numeric($search_order_id)) $post_ids[] = $search_order_id; if ( is_numeric( $search_order_id ) )
$post_ids[] = $search_order_id;
// Add blank ID so not all results are returned if the search finds nothing // Add blank ID so not all results are returned if the search finds nothing
$post_ids[] = 0; $post_ids[] = 0;
// Remove s - we don't want to search order name // Remove s - we don't want to search order name
unset( $wp->query_vars['s'] ); unset( $wp->query_vars['s'] );
// so we know we're doing this // so we know we're doing this
$wp->query_vars['shop_order_search'] = true; $wp->query_vars['shop_order_search'] = true;
// Search by found posts // Search by found posts
$wp->query_vars['post__in'] = $post_ids; $wp->query_vars['post__in'] = $post_ids;
} }
/**
* Change the label when searching orders.
*
* @access public
* @param mixed $query
* @return string
*/
function woocommerce_shop_order_search_label($query) { function woocommerce_shop_order_search_label($query) {
global $pagenow, $typenow; global $pagenow, $typenow;
if( 'edit.php' != $pagenow ) return $query; if ( 'edit.php' != $pagenow ) return $query;
if ( $typenow!='shop_order' ) return $query; if ( $typenow != 'shop_order' ) return $query;
if ( !get_query_var('shop_order_search')) return $query; if ( ! get_query_var( 'shop_order_search' ) ) return $query;
return $_GET['s']; return $_GET['s'];
} }
/** if ( is_admin() ) {
* Query vars for custom searches add_filter( 'parse_query', 'woocommerce_shop_order_search_custom_fields' );
**/ add_filter( 'get_search_query', 'woocommerce_shop_order_search_label' );
add_filter('query_vars', 'woocommerce_add_custom_query_var'); }
/**
* Query vars for custom searches.
*
* @access public
* @param mixed $public_query_vars
* @return array
*/
function woocommerce_add_custom_query_var($public_query_vars) { function woocommerce_add_custom_query_var($public_query_vars) {
$public_query_vars[] = 'sku'; $public_query_vars[] = 'sku';
$public_query_vars[] = 'shop_order_search'; $public_query_vars[] = 'shop_order_search';
return $public_query_vars; return $public_query_vars;
} }
add_filter('query_vars', 'woocommerce_add_custom_query_var');

View File

@ -0,0 +1,28 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div class="wc-metabox closed">
<h3 class="fixed">
<button type="button" rel="<?php echo absint( $download->product_id ) . ',' . esc_attr( $download->download_id ); ?>" class="revoke_access button"><?php _e( 'Revoke Access', 'woocommerce' ); ?></button>
<div class="handlediv" title="<?php _e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong>
<?php echo '#' . absint( $product->id ) . ' &mdash; ' . apply_filters( 'woocommerce_admin_download_permissions_title', $product->get_title(), $download->product_id, $download->order_id, $download->order_key, $download->download_id ) . ' &mdash; ' . sprintf( __( 'File %d: %s', 'woocommerce' ), $file_count, basename( $product->get_file_download_path( $download->download_id ) ) ) . ' &mdash; ' . sprintf( _n('Downloaded %s time', 'Downloaded %s times', absint( $download->download_count ), 'woocommerce'), absint( $download->download_count ) ); ?>
</strong>
</h3>
<table cellpadding="0" cellspacing="0" class="wc-metabox-content">
<tbody>
<tr>
<td>
<label><?php _e( 'Downloads Remaining', 'woocommerce' ); ?>:</label>
<input type="hidden" name="product_id[<?php echo $loop; ?>]" value="<?php echo absint( $download->product_id ); ?>" />
<input type="hidden" name="download_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->download_id ); ?>" />
<input type="number" step="1" min="0" class="short" name="downloads_remaining[<?php echo $loop; ?>]" value="<?php echo esc_attr( $download->downloads_remaining ); ?>" placeholder="<?php _e( 'Unlimited', 'woocommerce' ); ?>" />
</td>
<td>
<label><?php _e( 'Access Expires', 'woocommerce' ); ?>:</label>
<input type="text" class="short date-picker" name="access_expires[<?php echo $loop; ?>]" value="<?php echo $download->access_expires > 0 ? date_i18n( 'Y-m-d', strtotime( $download->access_expires ) ) : ''; ?>" maxlength="10" placeholder="<?php _e( 'Never', 'woocommerce' ); ?>" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -0,0 +1,46 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<tr class="fee" data-order_item_id="<?php echo $item_id; ?>">
<td class="check-column"><input type="checkbox" /></td>
<td class="thumb"></td>
<td class="name">
<input type="text" placeholder="<?php _e( 'Fee Name', 'woocommerce' ); ?>" name="order_item_name[<?php echo absint( $item_id ); ?>]" value="<?php if ( isset( $item['name'] ) ) echo esc_attr( $item['name'] ); ?>" />
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
</td>
<td class="tax_class" width="1%">
<select class="tax_class" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" title="<?php _e( 'Tax class', 'woocommerce' ); ?>">
<?php $tax_class = isset( $item['tax_class'] ) ? sanitize_title( $item['tax_class'] ) : ''; ?>
<option value="0" <?php selected( 0, $tax_class ) ?>><?php _e( 'N/A', 'woocommerce' ); ?></option>
<optgroup label="<?php _e( 'Taxable', 'woocommerce' ); ?>">
<?php
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('woocommerce_tax_classes' ) ) ) );
$classes_options = array();
$classes_options[''] = __( 'Standard', 'woocommerce' );
if ( $tax_classes )
foreach ( $tax_classes as $class )
$classes_options[ sanitize_title( $class ) ] = $class;
foreach ( $classes_options as $value => $name )
echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $tax_class, false ) . '>'. esc_html( $name ) . '</option>';
?>
</optgroup>
</select>
</td>
<td class="quantity" width="1%">1</td>
<td class="line_cost" width="1%">
<label><?php _e( 'Total', 'woocommerce' ); ?>: <input type="text" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_total'] ) ) echo esc_attr( $item['line_total'] ); ?>" class="line_total" /></label>
</td>
<td class="line_tax" width="1%">
<input type="text" name="line_tax[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_tax'] ) ) echo esc_attr( $item['line_tax'] ); ?>" class="line_tax" />
</td>
</tr>

View File

@ -0,0 +1,117 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<tr class="item <?php if ( ! empty( $class ) ) echo $class; ?>" data-order_item_id="<?php echo $item_id; ?>">
<td class="check-column"><input type="checkbox" /></td>
<td class="thumb">
<a href="<?php echo esc_url( admin_url( 'post.php?post=' . absint( $_product->id ) . '&action=edit' ) ); ?>" class="tips" data-tip="<?php
echo '<strong>' . __( 'Product ID:', 'woocommerce' ) . '</strong> ' . absint( $item['product_id'] );
if ( $item['variation_id'] )
echo '<br/><strong>' . __( 'Variation ID:', 'woocommerce' ) . '</strong> ' . absint( $item['variation_id'] );
if ( $_product->get_sku() )
echo '<br/><strong>' . __( 'Product SKU:', 'woocommerce' ).'</strong> ' . esc_html( $_product->get_sku() );
?>"><?php echo $_product->get_image( 'shop_thumbnail', array( 'title' => '' ) ); ?></a>
</td>
<td class="name">
<?php if ( $_product->get_sku() ) echo esc_html( $_product->get_sku() ) . ' &ndash; '; ?>
<a target="_blank" href="<?php echo esc_url( admin_url( 'post.php?post='. absint( $_product->id ) .'&action=edit' ) ); ?>"><?php echo esc_html( $item['name'] ); ?></a>
<input type="hidden" class="order_item_id" name="order_item_id[]" value="<?php echo esc_attr( $item_id ); ?>" />
<?php
if ( isset( $_product->variation_data ) )
echo '<br/>' . woocommerce_get_formatted_variation( $_product->variation_data, true );
?>
<table class="meta" cellspacing="0">
<tfoot>
<tr>
<td colspan="4"><button class="add_order_item_meta button"><?php _e( 'Add&nbsp;meta', 'woocommerce' ); ?></button></td>
</tr>
</tfoot>
<tbody class="meta_items">
<?php
if ( $metadata = $order->has_meta( $item_id )) {
foreach ( $metadata as $meta ) {
// Skip hidden core fields
if ( in_array( $meta['meta_key'], apply_filters( 'woocommerce_hidden_order_itemmeta', array(
'_qty',
'_tax_class',
'_product_id',
'_variation_id',
'_line_subtotal',
'_line_subtotal_tax',
'_line_total',
'_line_tax'
) ) ) ) continue;
// Handle serialised fields
if ( is_serialized( $meta['meta_value'] ) ) {
if ( is_serialized_string( $meta['meta_value'] ) ) {
// this is a serialized string, so we should display it
$meta['meta_value'] = maybe_unserialize( $meta['meta_value'] );
} else {
continue;
}
}
$meta['meta_key'] = esc_attr( $meta['meta_key'] );
$meta['meta_value'] = esc_textarea( $meta['meta_value'] ); // using a <textarea />
$meta['meta_id'] = (int) $meta['meta_id'];
echo '<tr data-meta_id="' . $meta['meta_id'] . '">
<td><input type="text" name="meta_key[' . $meta['meta_id'] . ']" value="' . $meta['meta_key'] . '" /></td>
<td><input type="text" name="meta_value[' . $meta['meta_id'] . ']" value="' . $meta['meta_value'] . '" /></td>
<td width="1%"><button class="remove_order_item_meta button">&times;</button></td>
</tr>';
}
}
?>
</tbody>
</table>
</td>
<?php do_action( 'woocommerce_admin_order_item_values', $_product, $item, absint( $item_id ) ); ?>
<td class="tax_class" width="1%">
<select class="tax_class" name="order_item_tax_class[<?php echo absint( $item_id ); ?>]" title="<?php _e( 'Tax class', 'woocommerce' ); ?>">
<?php
$item_value = isset( $item['tax_class'] ) ? sanitize_title( $item['tax_class'] ) : '';
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('woocommerce_tax_classes' ) ) ) );
$classes_options = array();
$classes_options[''] = __( 'Standard', 'woocommerce' );
if ( $tax_classes )
foreach ( $tax_classes as $class )
$classes_options[ sanitize_title( $class ) ] = $class;
foreach ( $classes_options as $value => $name )
echo '<option value="' . esc_attr( $value ) . '" ' . selected( $value, $item_value, false ) . '>'. esc_html( $name ) . '</option>';
?>
</select>
</td>
<td class="quantity" width="1%">
<input type="number" step="<?php echo apply_filters( 'woocommerce_quantity_input_step', '1', $_product ); ?>" min="0" autocomplete="off" name="order_item_qty[<?php echo absint( $item_id ); ?>]" placeholder="0" value="<?php echo esc_attr( $item['qty'] ); ?>" size="4" class="quantity" />
</td>
<td class="line_cost" width="1%">
<label><?php _e( 'Total', 'woocommerce' ); ?>: <input type="number" step="any" min="0" name="line_total[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_total'] ) ) echo esc_attr( $item['line_total'] ); ?>" class="line_total" /></label>
<span class="subtotal"><label><?php _e( 'Subtotal', 'woocommerce' ); ?>: <input type="number" step="any" min="0" name="line_subtotal[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_subtotal'] ) ) echo esc_attr( $item['line_subtotal'] ); ?>" class="line_subtotal" /></label></span>
</td>
<td class="line_tax" width="1%">
<input type="number" step="any" min="0" name="line_tax[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_tax'] ) ) echo esc_attr( $item['line_tax'] ); ?>" class="line_tax" />
<span class="subtotal"><input type="number" step="any" min="0" name="line_subtotal_tax[<?php echo absint( $item_id ); ?>]" placeholder="0.00" value="<?php if ( isset( $item['line_subtotal_tax'] ) ) echo esc_attr( $item['line_subtotal_tax'] ); ?>" class="line_subtotal_tax" /></span>
</td>
</tr>

View File

@ -0,0 +1,24 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div class="tax_row" data-order_item_id="<?php echo $item_id; ?>">
<p class="first">
<label><?php _e( 'Tax Label:', 'woocommerce' ) ?></label>
<input type="text" name="order_taxes_label[<?php echo $item_id; ?>]" placeholder="<?php echo $woocommerce->countries->tax_or_vat(); ?>" value="<?php if ( isset( $item['name'] ) ) echo esc_attr( $item['name'] ); ?>" />
<input type="hidden" name="order_taxes_id[<?php echo $item_id; ?>]" value="<?php echo esc_attr( $item_id ); ?>" />
</p>
<p class="last">
<label><?php _e( 'Compound:', 'woocommerce' ) ?>
<input type="checkbox" name="order_taxes_compound[<?php echo $item_id; ?>]" <?php if ( isset( $item['compound'] ) ) checked( $item['compound'], 1 ); ?> /></label>
</p>
<p class="first">
<label><?php _e( 'Sales Tax:', 'woocommerce' ) ?></label>
<input type="number" step="any" min="0" name="order_taxes_amount[<?php echo $item_id; ?>]" placeholder="0.00" value="<?php if ( isset( $item['tax_amount'] ) ) echo esc_attr( $item['tax_amount'] ); ?>" />
</p>
<p class="last">
<label><?php _e( 'Shipping Tax:', 'woocommerce' ) ?></label>
<input type="number" step="any" min="0" name="order_taxes_shipping_amount[<?php echo $item_id; ?>]" placeholder="0.00" value="<?php if ( isset( $item['shipping_tax_amount'] ) ) echo esc_attr( $item['shipping_tax_amount'] ); ?>" />
</p>
<a href="#" class="delete_tax_row">&times;</a>
<div class="clear"></div>
</div>

View File

@ -0,0 +1,173 @@
<?php
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
?>
<div class="woocommerce_variation wc-metabox closed">
<h3>
<button type="button" class="remove_variation button" rel="<?php echo esc_attr( $variation_id ); ?>"><?php _e( 'Remove', 'woocommerce' ); ?></button>
<div class="handlediv" title="<?php _e( 'Click to toggle', 'woocommerce' ); ?>"></div>
<strong>#<?php echo esc_html( $variation_id ); ?> &mdash; </strong>
<?php
foreach ( $parent_data['attributes'] as $attribute ) {
// Only deal with attributes that are variations
if ( ! $attribute['is_variation'] )
continue;
// Get current value for variation (if set)
$variation_selected_value = isset( $variation_data[ 'attribute_' . sanitize_title( $attribute['name'] ) ][0] ) ? $variation_data[ 'attribute_' . sanitize_title( $attribute['name'] ) ][0] : '';
// Name will be something like attribute_pa_color
echo '<select name="attribute_' . sanitize_title( $attribute['name'] ) . '[' . $loop . ']"><option value="">' . __( 'Any', 'woocommerce' ) . ' ' . esc_html( $woocommerce->attribute_label( $attribute['name'] ) ) . '&hellip;</option>';
// Get terms for attribute taxonomy or value if its a custom attribute
if ( $attribute['is_taxonomy'] ) {
$post_terms = wp_get_post_terms( $parent_data['id'], $attribute['name'] );
foreach ( $post_terms as $term ) {
echo '<option ' . selected( $variation_selected_value, $term->slug, false ) . ' value="' . esc_attr( $term->slug ) . '">' . apply_filters( 'woocommerce_variation_option_name', esc_html( $term->name ) ) . '</option>';
}
} else {
$options = explode( '|', $attribute['value'] );
foreach ( $options as $option ) {
echo '<option ' . selected( $variation_selected_value, $option, false ) . ' value="' . esc_attr( $option ) . '">' . ucfirst( apply_filters( 'woocommerce_variation_option_name', esc_html( $option ) ) ) . '</option>';
}
}
echo '</select>';
}
?>
<input type="hidden" name="variable_post_id[<?php echo $loop; ?>]" value="<?php echo esc_attr( $variation_id ); ?>" />
<input type="hidden" class="variation_menu_order" name="variation_menu_order[<?php echo $loop; ?>]" value="<?php echo $loop; ?>" />
</h3>
<table cellpadding="0" cellspacing="0" class="woocommerce_variable_attributes wc-metabox-content">
<tbody>
<tr>
<td class="sku" colspan="2">
<?php if ( get_option( 'woocommerce_enable_sku', true ) !== 'no' ) : ?>
<label><?php _e( 'SKU', 'woocommerce' ); ?>: <a class="tips" data-tip="<?php _e( 'Enter a SKU for this variation or leave blank to use the parent product SKU.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="text" size="5" name="variable_sku[<?php echo $loop; ?>]" value="<?php if ( isset( $_sku ) ) echo esc_attr( $_sku ); ?>" placeholder="<?php echo esc_attr( $parent_data['sku'] ); ?>" />
<?php else : ?>
<input type="hidden" name="variable_sku[<?php echo $loop; ?>]" value="<?php if ( isset( $_sku ) ) echo esc_attr( $_sku ); ?>" />
<?php endif; ?>
</td>
<td class="data" rowspan="2">
<table cellspacing="0" cellpadding="0">
<?php if ( get_option( 'woocommerce_manage_stock' ) == 'yes' ) : ?>
<tr>
<td>
<label><?php _e( 'Stock Qty:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enter a quantity to enable stock management for this variation, or leave blank to use the variable product stock options.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="number" size="5" name="variable_stock[<?php echo $loop; ?>]" value="<?php if ( isset( $_stock ) ) echo esc_attr( $_stock ); ?>" step="any" />
</td>
<td>&nbsp;</td>
</tr>
<?php endif; ?>
<tr>
<td>
<label><?php _e( 'Price:', 'woocommerce' ); ?></label>
<input type="number" size="5" name="variable_regular_price[<?php echo $loop; ?>]" value="<?php if ( isset( $_regular_price ) ) echo esc_attr( $_regular_price ); ?>" step="any" min="0" />
</td>
<td>
<label><?php _e( 'Sale Price:', 'woocommerce' ); ?> <a href="#" class="sale_schedule"><?php _e( 'Schedule', 'woocommerce' ); ?></a><a href="#" class="cancel_sale_schedule" style="display:none"><?php _e( 'Cancel schedule', 'woocommerce' ); ?></a></label>
<input type="number" size="5" name="variable_sale_price[<?php echo $loop; ?>]" value="<?php if ( isset( $_sale_price ) ) echo esc_attr( $_sale_price ); ?>" step="any" min="0" />
</td>
</tr>
<tr class="sale_price_dates_fields" style="display:none">
<td>
<label><?php _e( 'Sale start date:', 'woocommerce' ) ?></label>
<input type="text" class="sale_price_dates_from" name="variable_sale_price_dates_from[<?php echo $loop; ?>]" value="<?php echo ! empty( $_sale_price_dates_from ) ? date_i18n( 'Y-m-d', $_sale_price_dates_from ) : ''; ?>" placeholder="<?php echo _x( 'From&hellip;', 'placeholder', 'woocommerce' ) ?> YYYY-MM-DD" maxlength="10" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />
</td>
<td>
<label><?php _e( 'Sale end date:', 'woocommerce' ) ?></label>
<input type="text" name="variable_sale_price_dates_to[<?php echo $loop; ?>]" value="<?php echo ! empty( $_sale_price_dates_to ) ? date_i18n( 'Y-m-d', $_sale_price_dates_to ) : ''; ?>" placeholder="<?php echo _x('To&hellip;', 'placeholder', 'woocommerce') ?> YYYY-MM-DD" maxlength="10" pattern="[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" />
</td>
</tr>
<?php if ( get_option( 'woocommerce_enable_weight', true ) !== 'no' || get_option( 'woocommerce_enable_dimensions', true ) !== 'no' ) : ?>
<tr>
<?php if ( get_option( 'woocommerce_enable_weight', true ) !== 'no' ) : ?>
<td class="hide_if_variation_virtual">
<label><?php _e( 'Weight', 'woocommerce' ) . ' (' . esc_html( get_option( 'woocommerce_weight_unit' ) ) . '):'; ?> <a class="tips" data-tip="<?php _e( 'Enter a weight for this variation or leave blank to use the parent product weight.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="number" size="5" name="variable_weight[<?php echo $loop; ?>]" value="<?php if ( isset( $_weight ) ) echo esc_attr( $_weight ); ?>" placeholder="<?php echo esc_attr( $parent_data['weight'] ); ?>" step="any" min="0" />
</td>
<?php else : ?>
<td>&nbsp;</td>
<?php endif; ?>
<?php if ( get_option( 'woocommerce_enable_dimensions', true ) !== 'no' ) : ?>
<td class="dimensions_field hide_if_variation_virtual">
<label for"product_length"><?php echo __( 'Dimensions (L&times;W&times;H)', 'woocommerce' ); ?></label>
<input id="product_length" class="input-text" size="6" type="number" step="any" min="0" name="variable_length[<?php echo $loop; ?>]" value="<?php if ( isset( $_length ) ) echo esc_attr( $_length ); ?>" placeholder="<?php echo esc_attr( $parent_data['length'] ); ?>" />
<input class="input-text" size="6" type="number" step="any" min="0" name="variable_width[<?php echo $loop; ?>]" value="<?php if ( isset( $_width ) ) echo esc_attr( $_width ); ?>" placeholder="<?php echo esc_attr( $parent_data['width'] ); ?>" />
<input class="input-text last" size="6" type="number" step="any" min="0" name="variable_height[<?php echo $loop; ?>]" value="<?php if ( isset( $_height ) ) echo esc_attr( $_height ); ?>" placeholder="<?php echo esc_attr( $parent_data['height'] ); ?>" />
</td>
<?php else : ?>
<td>&nbsp;</td>
<?php endif; ?>
</tr>
<?php endif; ?>
<tr>
<td><label><?php _e( 'Shipping class:', 'woocommerce' ); ?></label> <?php
$args = array(
'taxonomy' => 'product_shipping_class',
'hide_empty' => 0,
'show_option_all' => __( 'Same as parent', 'woocommerce' ),
'name' => 'variable_shipping_class[' . $loop . ']',
'id' => '',
'selected' => isset( $shipping_class ) ? esc_attr( $shipping_class ) : '',
'echo' => 0
);
echo wp_dropdown_categories( $args );
?></td>
<td>
<label><?php _e( 'Tax class:', 'woocommerce' ); ?></label>
<select name="variable_tax_class[<?php echo $loop; ?>]"><?php
foreach ( $parent_data['tax_class_options'] as $key => $value )
echo '<option value="' . esc_attr( $key ) . '" ' . selected( $key, $_tax_class, false ) . '>' . esc_html( $value ) . '</option>';
?></select>
</td>
</tr>
<tr class="show_if_variation_downloadable">
<td rowspan="2">
<div class="file_path_field">
<label><?php _e( 'File paths:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enter one or more File Paths, one per line, to make this variation a downloadable product, or leave blank.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<textarea style="float:left;" class="short file_paths" cols="20" rows="2" placeholder="<?php _e( 'File paths/URLs, one per line', 'woocommerce' ); ?>" name="variable_file_paths[<?php echo $loop; ?>]" wrap="off"><?php if ( isset( $_file_paths ) ) echo esc_textarea( $_file_paths ); ?></textarea>
<input type="button" class="upload_file_button button" value="<?php _e( 'Upload a file', 'woocommerce' ); ?>" title="<?php _e( 'Upload', 'woocommerce' ); ?>" />
</div>
</td>
<td>
<div>
<label><?php _e( 'Download Limit:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Leave blank for unlimited re-downloads.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="number" size="5" name="variable_download_limit[<?php echo $loop; ?>]" value="<?php if ( isset( $_download_limit ) ) echo esc_attr( $_download_limit ); ?>" placeholder="<?php _e( 'Unlimited', 'woocommerce' ); ?>" step="1" min="0" />
</div>
</td>
</tr>
<tr class="show_if_variation_downloadable">
<td>
<div>
<label><?php _e( 'Download Expiry:', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enter the number of days before a download link expires, or leave blank.', 'woocommerce' ); ?>" href="#">[?]</a></label>
<input type="number" size="5" name="variable_download_expiry[<?php echo $loop; ?>]" value="<?php if ( isset( $_download_expiry ) ) echo esc_attr( $_download_expiry ); ?>" placeholder="<?php _e( 'Unlimited', 'woocommerce' ); ?>" step="1" min="0" />
</div>
</td>
</tr>
<?php do_action( 'woocommerce_product_after_variable_attributes', $loop, $variation_data ); ?>
</table>
</td>
</tr>
<tr>
<td class="upload_image">
<a href="#" class="upload_image_button <?php if ( $image_id > 0 ) echo 'remove'; ?>" rel="<?php echo esc_attr( $variation_id ); ?>"><img src="<?php if ( ! empty( $image ) ) echo esc_attr( $image ); else echo esc_attr( woocommerce_placeholder_img_src() ); ?>" /><input type="hidden" name="upload_image_id[<?php echo $loop; ?>]" class="upload_image_id" value="<?php echo esc_attr( $image_id ); ?>" /><span class="overlay"></span></a>
</td>
<td class="options">
<label><input type="checkbox" class="checkbox" name="variable_enabled[<?php echo $loop; ?>]" <?php checked( $variation_post_status, 'publish' ); ?> /> <?php _e( 'Enabled', 'woocommerce' ); ?></label>
<label><input type="checkbox" class="checkbox variable_is_downloadable" name="variable_is_downloadable[<?php echo $loop; ?>]" <?php checked( isset( $_downloadable ) ? $_downloadable : '', 'yes' ); ?> /> <?php _e( 'Downloadable', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enable this option if access is given to a downloadable file upon purchase of a product', 'woocommerce' ); ?>" href="#">[?]</a></label>
<label><input type="checkbox" class="checkbox variable_is_virtual" name="variable_is_virtual[<?php echo $loop; ?>]" <?php checked( isset( $_virtual ) ? $_virtual : '', 'yes' ); ?> /> <?php _e( 'Virtual', 'woocommerce' ); ?> <a class="tips" data-tip="<?php _e( 'Enable this option if a product is not shipped or there is no shipping cost', 'woocommerce' ); ?>" href="#">[?]</a></label>
<?php do_action( 'woocommerce_variation_options', $loop, $variation_data ); ?>
</td>
</tr>
</tbody>
</table>
</div>

View File

@ -1,101 +1,248 @@
<?php <?php
/** /**
* Coupon Data * Coupon Data
* *
* Functions for displaying the coupon data meta box * Functions for displaying the coupon data meta box.
* *
* @author WooThemes * @author WooThemes
* @category Admin Write Panels * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/WritePanels
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Coupon data meta box * Displays the coupon data meta box.
* *
* Displays the meta box * @access public
* @param mixed $post
* @return void
*/ */
function woocommerce_coupon_data_meta_box($post) { function woocommerce_coupon_data_meta_box( $post ) {
global $woocommerce; global $woocommerce;
wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' ); wp_nonce_field( 'woocommerce_save_data', 'woocommerce_meta_nonce' );
?> ?>
<style type="text/css"> <style type="text/css">
#edit-slug-box { display:none } #edit-slug-box, #minor-publishing-actions { display:none }
</style> </style>
<div id="coupon_options" class="panel woocommerce_options_panel"> <div id="coupon_options" class="panel woocommerce_options_panel">
<?php <?php
echo '<div class="options_group">';
// Description
woocommerce_wp_text_input( array( 'id' => 'coupon_description', 'label' => __( 'Coupon description', 'woocommerce' ), 'description' => __( 'Optionally enter a description for this coupon for your reference.', 'woocommerce' ), 'value' => $post->post_excerpt, 'name' => 'excerpt' ) );
echo '</div><div class="options_group">';
// Type // Type
woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __('Discount type', 'woothemes'), 'options' => $woocommerce->get_coupon_discount_types() ) ); woocommerce_wp_select( array( 'id' => 'discount_type', 'label' => __( 'Discount type', 'woocommerce' ), 'options' => $woocommerce->get_coupon_discount_types() ) );
// Amount // Amount
woocommerce_wp_text_input( array( 'id' => 'coupon_amount', 'label' => __('Coupon amount', 'woothemes'), 'placeholder' => __('0.00', 'woothemes'), 'description' => __('Enter an amount e.g. 2.99', 'woothemes') ) ); woocommerce_wp_text_input( array( 'id' => 'coupon_amount', 'label' => __( 'Coupon amount', 'woocommerce' ), 'placeholder' => '0.00', 'description' => __( 'Enter an amount e.g. 2.99', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
'step' => 'any',
// Individual use 'min' => '0'
woocommerce_wp_checkbox( array( 'id' => 'individual_use', 'label' => __('Individual use', 'woothemes'), 'description' => __('Check this box if the coupon cannot be used in conjunction with other coupons', 'woothemes') ) ); ) ) );
// Apply before tax
woocommerce_wp_checkbox( array( 'id' => 'apply_before_tax', 'label' => __('Apply before tax', 'woothemes'), 'description' => __('Check this box if the coupon should be applied before calculating cart tax', 'woothemes') ) );
// Free Shipping // Free Shipping
woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __('Enable free shipping', 'woothemes'), 'description' => sprintf(__('Check this box if the coupon enables free shipping (see <a href="%s">Free Shipping</a>)', 'woothemes'), admin_url('admin.php?page=woocommerce&tab=shipping_methods&subtab=shipping-free_shipping')) ) ); woocommerce_wp_checkbox( array( 'id' => 'free_shipping', 'label' => __( 'Enable free shipping', 'woocommerce' ), 'description' => sprintf(__( 'Check this box if the coupon grants free shipping. The <a href="%s">free shipping method</a> must be enabled with the "must use coupon" setting checked.', 'woocommerce' ), admin_url('admin.php?page=woocommerce_settings&tab=shipping&section=WC_Free_Shipping')) ) );
// Individual use
woocommerce_wp_checkbox( array( 'id' => 'individual_use', 'label' => __( 'Individual use', 'woocommerce' ), 'description' => __( 'Check this box if the coupon cannot be used in conjunction with other coupons.', 'woocommerce' ) ) );
// Apply before tax
woocommerce_wp_checkbox( array( 'id' => 'apply_before_tax', 'label' => __( 'Apply before tax', 'woocommerce' ), 'description' => __( 'Check this box if the coupon should be applied before calculating cart tax.', 'woocommerce' ) ) );
echo '</div><div class="options_group">';
// minimum spend
woocommerce_wp_text_input( array( 'id' => 'minimum_amount', 'label' => __( 'Minimum amount', 'woocommerce' ), 'placeholder' => __( 'No minimum', 'woocommerce' ), 'description' => __( 'This field allows you to set the minimum subtotal needed to use the coupon.', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
'step' => 'any',
'min' => '0'
) ) );
echo '</div><div class="options_group">';
// Product ids // Product ids
woocommerce_wp_text_input( array( 'id' => 'product_ids', 'label' => __('Product IDs', 'woothemes'), 'placeholder' => __('N/A', 'woothemes'), 'description' => __('(optional) Comma separate IDs which need to be in the cart to use this coupon or, for "Product Discounts", which products are discounted.', 'woothemes') ) ); ?>
<p class="form-field"><label for="product_ids"><?php _e( 'Products', 'woocommerce' ) ?></label>
<select id="product_ids" name="product_ids[]" class="ajax_chosen_select_products_and_variations" multiple="multiple" data-placeholder="<?php _e( 'Search for a product&hellip;', 'woocommerce' ); ?>">
<?php
$product_ids = get_post_meta( $post->ID, 'product_ids', true );
if ( $product_ids ) {
$product_ids = array_map( 'absint', explode( ',', $product_ids ) );
foreach ( $product_ids as $product_id ) {
$title = get_the_title( $product_id );
$sku = get_post_meta( $product_id, '_sku', true );
if ( ! $title )
continue;
if ( ! empty( $sku ) )
$sku = ' (SKU: ' . $sku . ')';
echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . esc_html( $title . $sku ) . '</option>';
}
}
?>
</select> <img class="help_tip" data-tip='<?php _e( 'Products which need to be in the cart to use this coupon or, for "Product Discounts", which products are discounted.', 'woocommerce' ) ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
<?php
// Exclude Product ids // Exclude Product ids
woocommerce_wp_text_input( array( 'id' => 'exclude_product_ids', 'label' => __('Exclude Product IDs', 'woothemes'), 'placeholder' => __('N/A', 'woothemes'), 'description' => __('(optional) Comma separate IDs which must not be in the cart to use this coupon or, for "Product Discounts", which products are not discounted.', 'woothemes') ) ); ?>
<p class="form-field"><label for="exclude_product_ids"><?php _e( 'Exclude products', 'woocommerce' ) ?></label>
<select id="exclude_product_ids" name="exclude_product_ids[]" class="ajax_chosen_select_products_and_variations" multiple="multiple" data-placeholder="<?php _e( 'Search for a product…', 'woocommerce' ); ?>">
<?php
$product_ids = get_post_meta( $post->ID, 'exclude_product_ids', true );
if ( $product_ids ) {
$product_ids = array_map( 'absint', explode( ',', $product_ids ) );
foreach ( $product_ids as $product_id ) {
$title = get_the_title( $product_id );
$sku = get_post_meta( $product_id, '_sku', true );
if ( ! $title )
continue;
if ( ! empty( $sku ) )
$sku = ' (SKU: ' . $sku . ')';
echo '<option value="' . esc_attr( $product_id ) . '" selected="selected">' . esc_html( $title . $sku ) . '</option>';
}
}
?>
</select> <img class="help_tip" data-tip='<?php _e( 'Products which must not be in the cart to use this coupon or, for "Product Discounts", which products are not discounted.', 'woocommerce' ) ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
<?php
echo '</div><div class="options_group">';
// Categories
?>
<p class="form-field"><label for="product_ids"><?php _e( 'Product categories', 'woocommerce' ) ?></label>
<select id="product_categories" name="product_categories[]" class="chosen_select" multiple="multiple" data-placeholder="<?php _e( 'Any category', 'woocommerce' ); ?>">
<?php
$category_ids = (array) get_post_meta( $post->ID, 'product_categories', true );
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
if ( $categories ) foreach ( $categories as $cat )
echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
?>
</select> <img class="help_tip" data-tip='<?php _e( 'A product must be in this category for the coupon to remain valid or, for "Product Discounts", products in these categories will be discounted.', 'woocommerce' ) ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
<?php
// Exclude Categories
?>
<p class="form-field"><label for="exclude_product_categories"><?php _e( 'Exclude categories', 'woocommerce' ) ?></label>
<select id="exclude_product_categories" name="exclude_product_categories[]" class="chosen_select" multiple="multiple" data-placeholder="<?php _e( 'No categories', 'woocommerce' ); ?>">
<?php
$category_ids = (array) get_post_meta( $post->ID, 'exclude_product_categories', true );
$categories = get_terms( 'product_cat', 'orderby=name&hide_empty=0' );
if ( $categories ) foreach ( $categories as $cat )
echo '<option value="' . esc_attr( $cat->term_id ) . '"' . selected( in_array( $cat->term_id, $category_ids ), true, false ) . '>' . esc_html( $cat->name ) . '</option>';
?>
</select> <img class="help_tip" data-tip='<?php _e( 'Product must not be in this category for the coupon to remain valid or, for "Product Discounts", products in these categories will not be discounted.', 'woocommerce' ) ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></p>
<?php
echo '</div><div class="options_group">';
// Customers
woocommerce_wp_text_input( array( 'id' => 'customer_email', 'label' => __( 'Customer emails', 'woocommerce' ), 'placeholder' => __( 'Any customer', 'woocommerce' ), 'description' => __( 'Comma separate email addresses to restrict this coupon to specific billing and user emails.', 'woocommerce' ), 'value' => implode(', ', (array) get_post_meta( $post->ID, 'customer_email', true ) ), 'type' => 'email', 'custom_attributes' => array(
'multiple' => 'multiple'
) ) );
echo '</div><div class="options_group">';
// Usage limit // Usage limit
woocommerce_wp_text_input( array( 'id' => 'usage_limit', 'label' => __('Usage limit', 'woothemes'), 'placeholder' => __('Unlimited usage', 'woothemes'), 'description' => __('(optional) How many times this coupon can be used before it is void', 'woothemes') ) ); woocommerce_wp_text_input( array( 'id' => 'usage_limit', 'label' => __( 'Usage limit', 'woocommerce' ), 'placeholder' => _x('Unlimited usage', 'placeholder', 'woocommerce'), 'description' => __( 'How many times this coupon can be used before it is void.', 'woocommerce' ), 'type' => 'number', 'custom_attributes' => array(
'step' => '1',
'min' => '0'
) ) );
// Expiry date // Expiry date
woocommerce_wp_text_input( array( 'id' => 'expiry_date', 'label' => __('Expiry date', 'woothemes'), 'placeholder' => __('Never expire', 'woothemes'), 'description' => __('(optional) The date this coupon will expire, <code>YYYY-MM-DD</code>', 'woothemes'), 'class' => 'short date-picker' ) ); woocommerce_wp_text_input( array( 'id' => 'expiry_date', 'label' => __( 'Expiry date', 'woocommerce' ), 'placeholder' => _x('Never expire', 'placeholder', 'woocommerce'), 'description' => __( 'The date this coupon will expire, <code>YYYY-MM-DD</code>.', 'woocommerce' ), 'class' => 'short date-picker', 'custom_attributes' => array( 'pattern' => "[0-9]{4}-(0[1-9]|1[012])-(0[1-9]|1[0-9]|2[0-9]|3[01])" ) ) );
do_action('woocommerce_coupon_options'); echo '</div>';
do_action( 'woocommerce_coupon_options' );
?> ?>
</div> </div>
<?php <?php
} }
/**
* Coupon Data Save
*
* Function for processing and storing all coupon data.
*/
add_action('woocommerce_process_shop_coupon_meta', 'woocommerce_process_shop_coupon_meta', 1, 2);
/**
* Save the coupon data meta box.
*
* @access public
* @param mixed $post_id
* @param mixed $post
* @return void
*/
function woocommerce_process_shop_coupon_meta( $post_id, $post ) { function woocommerce_process_shop_coupon_meta( $post_id, $post ) {
global $wpdb; global $wpdb, $woocommerce_errors;
$woocommerce_errors = array(); // Ensure coupon code is correctly formatted
$post->post_title = apply_filters( 'woocommerce_coupon_code', $post->post_title );
$wpdb->update( $wpdb->posts, array( 'post_title' => $post->post_title ), array( 'ID' => $post_id ) );
// Check for dupe coupons
$coupon_found = $wpdb->get_var( $wpdb->prepare( "
SELECT $wpdb->posts.ID
FROM $wpdb->posts
WHERE $wpdb->posts.post_type = 'shop_coupon'
AND $wpdb->posts.post_status = 'publish'
AND $wpdb->posts.post_title = '%s'
AND $wpdb->posts.ID != %s
", $post->post_title, $post_id ) );
if ( $coupon_found )
$woocommerce_errors[] = __( 'Coupon code already exists - customers will use the latest coupon with this code.', 'woocommerce' );
// Add/Replace data to array // Add/Replace data to array
$type = strip_tags(stripslashes( $_POST['discount_type'] )); $type = woocommerce_clean( $_POST['discount_type'] );
$amount = strip_tags(stripslashes( $_POST['coupon_amount'] )); $amount = woocommerce_clean( $_POST['coupon_amount'] );
$product_ids = strip_tags(stripslashes( $_POST['product_ids'] )); $usage_limit = empty( $_POST['usage_limit'] ) ? '' : absint( $_POST['usage_limit'] );
$exclude_product_ids = strip_tags(stripslashes( $_POST['exclude_product_ids'] )); $individual_use = isset( $_POST['individual_use'] ) ? 'yes' : 'no';
$usage_limit = (isset($_POST['usage_limit']) && $_POST['usage_limit']>0) ? (int) $_POST['usage_limit'] : ''; $expiry_date = woocommerce_clean( $_POST['expiry_date'] );
$individual_use = isset($_POST['individual_use']) ? 'yes' : 'no'; $apply_before_tax = isset( $_POST['apply_before_tax'] ) ? 'yes' : 'no';
$expiry_date = strip_tags(stripslashes( $_POST['expiry_date'] )); $free_shipping = isset( $_POST['free_shipping'] ) ? 'yes' : 'no';
$apply_before_tax = isset($_POST['apply_before_tax']) ? 'yes' : 'no'; $minimum_amount = woocommerce_clean( $_POST['minimum_amount'] );
$free_shipping = isset($_POST['free_shipping']) ? 'yes' : 'no'; $customer_email = array_filter( array_map( 'trim', explode( ',', woocommerce_clean( $_POST['customer_email'] ) ) ) );
if ( isset( $_POST['product_ids'] ) ) {
$product_ids = implode( ',', array_filter( array_map( 'intval', (array) $_POST['product_ids'] ) ) );
} else {
$product_ids = '';
}
if ( isset( $_POST['exclude_product_ids'] ) ) {
$exclude_product_ids = implode( ',', array_filter( array_map( 'intval', (array) $_POST['exclude_product_ids'] ) ) );
} else {
$exclude_product_ids = '';
}
$product_categories = isset( $_POST['product_categories'] ) ? array_map( 'intval', $_POST['product_categories'] ) : array();
$exclude_product_categories = isset( $_POST['exclude_product_categories'] ) ? array_map( 'intval', $_POST['exclude_product_categories'] ) : array();
// Save // Save
update_post_meta( $post_id, 'discount_type', $type ); update_post_meta( $post_id, 'discount_type', $type );
update_post_meta( $post_id, 'coupon_amount', $amount ); update_post_meta( $post_id, 'coupon_amount', $amount );
update_post_meta( $post_id, 'individual_use', $individual_use ); update_post_meta( $post_id, 'individual_use', $individual_use );
update_post_meta( $post_id, 'product_ids', $product_ids ); update_post_meta( $post_id, 'product_ids', $product_ids );
update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids ); update_post_meta( $post_id, 'exclude_product_ids', $exclude_product_ids );
update_post_meta( $post_id, 'usage_limit', $usage_limit ); update_post_meta( $post_id, 'usage_limit', $usage_limit );
update_post_meta( $post_id, 'expiry_date', $expiry_date ); update_post_meta( $post_id, 'expiry_date', $expiry_date );
update_post_meta( $post_id, 'apply_before_tax', $apply_before_tax ); update_post_meta( $post_id, 'apply_before_tax', $apply_before_tax );
update_post_meta( $post_id, 'free_shipping', $free_shipping ); update_post_meta( $post_id, 'free_shipping', $free_shipping );
update_post_meta( $post_id, 'product_categories', $product_categories );
do_action('woocommerce_coupon_options'); update_post_meta( $post_id, 'exclude_product_categories', $exclude_product_categories );
update_post_meta( $post_id, 'minimum_amount', $minimum_amount );
// Error Handling update_post_meta( $post_id, 'customer_email', $customer_email );
if (sizeof($woocommerce_errors)>0) update_option('woocommerce_errors', $woocommerce_errors);
} do_action( 'woocommerce_coupon_options' );
}
add_action( 'woocommerce_process_shop_coupon_meta', 'woocommerce_process_shop_coupon_meta', 1, 2 );

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,250 @@
<?php
/**
* Order Downloads
*
* Functions for displaying order download permissions in admin.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/WritePanels
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Displays the order downloads meta box.
*
* @access public
* @return void
*/
function woocommerce_order_downloads_meta_box() {
global $woocommerce, $post, $wpdb;
?>
<div class="order_download_permissions wc-metaboxes-wrapper">
<div class="wc-metaboxes">
<?php
$download_permissions = $wpdb->get_results( $wpdb->prepare( "
SELECT * FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions
WHERE order_id = %d ORDER BY product_id
", $post->ID ) );
$product = null;
if ( $download_permissions && sizeof( $download_permissions ) > 0 ) foreach ( $download_permissions as $download ) {
if ( ! $product || $product->id != $download->product_id ) {
$product = get_product( absint( $download->product_id ) );
$file_count = $loop = 0;
}
// don't show permissions to files that have since been removed
if ( ! $product->exists() || ! $product->has_file( $download->download_id ) )
continue;
$loop++;
$file_count++;
include( 'order-download-permission-html.php' );
}
?>
</div>
<div class="toolbar">
<p class="buttons">
<select name="grant_access_id" class="grant_access_id chosen_select_nostd" data-placeholder="<?php _e( 'Choose a downloadable product&hellip;', 'woocommerce' ) ?>">
<?php
echo '<option value=""></option>';
$args = array(
'post_type' => array( 'product', 'product_variation' ),
'posts_per_page' => -1,
'post_status' => 'publish',
'order' => 'ASC',
'orderby' => 'parent title',
'meta_query' => array(
array(
'key' => '_downloadable',
'value' => 'yes'
)
)
);
$products = get_posts( $args );
if ( $products ) foreach ( $products as $product ) {
$sku = get_post_meta( $product->ID, '_sku', true );
if ( $sku )
$sku = ' SKU: ' . $sku;
echo '<option value="' . esc_attr( $product->ID ) . '">' . esc_html( $product->post_title . ' (#' . $product->ID . '' . $sku . ')' ) . '</option>';
}
?>
</select>
<button type="button" class="button grant_access"><?php _e( 'Grant Access', 'woocommerce' ); ?></button>
</p>
<div class="clear"></div>
</div>
</div>
<?php
/**
* Javascript
*/
ob_start();
?>
jQuery(function(){
jQuery('.order_download_permissions').on('click', 'button.grant_access', function(){
var product = jQuery('select.grant_access_id').val();
if (!product) return;
jQuery('.order_download_permissions').block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
var data = {
action: 'woocommerce_grant_access_to_download',
product_id: product,
loop: jQuery('.order_download_permissions .wc-metabox').size(),
order_id: '<?php echo $post->ID; ?>',
security: '<?php echo wp_create_nonce("grant-access"); ?>'
};
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function( response ) {
if ( response ) {
jQuery('.order_download_permissions .wc-metaboxes').append( response );
} else {
alert('<?php _e( 'Could not grant access - the user may already have permission for this file.', 'woocommerce' ); ?>');
}
jQuery( ".date-picker" ).datepicker({
dateFormat: "yy-mm-dd",
numberOfMonths: 1,
showButtonPanel: true,
showOn: "button",
buttonImage: woocommerce_writepanel_params.calendar_image,
buttonImageOnly: true
});
jQuery('.order_download_permissions').unblock();
});
return false;
});
jQuery('.order_download_permissions').on('click', 'button.revoke_access', function(e){
e.preventDefault();
var answer = confirm('<?php _e( 'Are you sure you want to revoke access to this download?', 'woocommerce' ); ?>');
if (answer){
var el = jQuery(this).parent().parent();
var product = jQuery(this).attr('rel').split(",")[0];
var file = jQuery(this).attr('rel').split(",")[1];
if (product>0) {
jQuery(el).block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
var data = {
action: 'woocommerce_revoke_access_to_download',
product_id: product,
download_id: file,
order_id: '<?php echo $post->ID; ?>',
security: '<?php echo wp_create_nonce("revoke-access"); ?>'
};
jQuery.post('<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
// Success
jQuery(el).fadeOut('300', function(){
jQuery(el).remove();
});
});
} else {
jQuery(el).fadeOut('300', function(){
jQuery(el).remove();
});
}
}
return false;
});
});
<?php
$javascript = ob_get_clean();
$woocommerce->add_inline_js( $javascript );
}
/**
* Save the order downloads meta box.
*
* @access public
* @param mixed $post_id
* @param mixed $post
* @return void
*/
function woocommerce_order_downloads_save( $post_id, $post ) {
global $wpdb, $woocommerce;
if ( isset( $_POST['download_id'] ) ) {
// Download data
$download_ids = $_POST['download_id'];
$product_ids = $_POST['product_id'];
$downloads_remaining = $_POST['downloads_remaining'];
$access_expires = $_POST['access_expires'];
// Order data
$order_key = get_post_meta( $post->ID, '_order_key', true );
$customer_email = get_post_meta( $post->ID, '_billing_email', true );
$customer_user = get_post_meta( $post->ID, '_customer_user', true );
$product_ids_count = sizeof( $product_ids );
for ( $i = 0; $i < $product_ids_count; $i ++ ) {
$data = array(
'user_id' => absint( $customer_user ),
'user_email' => woocommerce_clean( $customer_email ),
'downloads_remaining' => woocommerce_clean( $downloads_remaining[$i] )
);
$format = array( '%d', '%s', '%s' );
$expiry = ( array_key_exists( $i, $access_expires ) && $access_expires[ $i ] != '' ) ? date_i18n( 'Y-m-d', strtotime( $access_expires[ $i ] ) ) : null;
if ( ! is_null( $expiry ) ) {
$data['access_expires'] = $expiry;
$format[] = '%s';
}
$wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions",
$data,
array(
'order_id' => $post_id,
'product_id' => absint( $product_ids[$i] ),
'download_id' => woocommerce_clean( $download_ids[$i] )
),
$format, array( '%d', '%d', '%s' )
);
}
}
}
add_action( 'woocommerce_process_shop_order_meta', 'woocommerce_order_downloads_save', 5, 2 );

View File

@ -1,92 +1,104 @@
<?php <?php
/** /**
* Order Notes * Order Notes
* *
* Functions for displaying order comments in admin * Functions for displaying order comments in admin.
* *
* @author WooThemes * @author WooThemes
* @category Admin Write Panels * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/WritePanels
* @version 2.0.0
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Order notes meta box * Display the order notes meta box.
*
* @access public
* @return void
*/ */
function woocommerce_order_notes_meta_box() { function woocommerce_order_notes_meta_box() {
global $woocommerce, $post; global $woocommerce, $post;
$args = array( $args = array(
'post_id' => $post->ID, 'post_id' => $post->ID,
'approve' => 'approve', 'approve' => 'approve',
'type' => '' 'type' => 'order_note'
); );
$notes = get_comments( $args ); $notes = get_comments( $args );
echo '<ul class="order_notes">'; echo '<ul class="order_notes">';
if ($notes) : if ( $notes ) {
foreach($notes as $note) : foreach( $notes as $note ) {
$note_classes = get_comment_meta( $note->comment_ID, 'is_customer_note', true ) ? array( 'customer-note', 'note' ) : array( 'note' );
?>
<li rel="<?php echo absint( $note->comment_ID ) ; ?>" class="<?php echo implode( ' ', $note_classes ); ?>">
<div class="note_content">
<?php echo wpautop( wptexturize( wp_kses_post( $note->comment_content ) ) ); ?>
</div>
<p class="meta">
<?php printf( __( 'added %s ago', 'woocommerce' ), human_time_diff( strtotime( $note->comment_date_gmt ), current_time( 'timestamp', 1 ) ) ); ?> <a href="#" class="delete_note"><?php _e( 'Delete note', 'woocommerce' ); ?></a>
</p>
</li>
<?php
}
} else {
echo '<li>' . __( 'There are no notes for this order yet.', 'woocommerce' ) . '</li>';
}
$customer_note = get_comment_meta($note->comment_ID, 'is_customer_note', true);
echo '<li rel="'.$note->comment_ID.'" class="note ';
if ($customer_note) echo 'customer-note';
echo '"><div class="note_content">';
echo wpautop(wptexturize($note->comment_content));
echo '</div><p class="meta">'. sprintf(__('added %s ago', 'woothemes'), human_time_diff(strtotime($note->comment_date), current_time('timestamp'))) .' - <a href="#" class="delete_note">'.__('Delete note', 'woothemes').'</a></p>';
echo '</li>';
endforeach;
else :
echo '<li>' . __('There are no notes for this order yet.', 'woothemes') . '</li>';
endif;
echo '</ul>'; echo '</ul>';
?> ?>
<div class="add_note"> <div class="add_note">
<h4><?php _e('Add note', 'woothemes'); ?></h4> <h4><?php _e( 'Add note', 'woocommerce' ); ?> <img class="help_tip" data-tip='<?php esc_attr_e( 'Add a note for your reference, or add a customer note (the user will be notified).', 'woocommerce' ); ?>' src="<?php echo $woocommerce->plugin_url(); ?>/assets/images/help.png" height="16" width="16" /></h4>
<p><?php _e('Add a note for your reference, or add a customer note (the user will be notified).', 'woothemes'); ?></p> <p>
<p><input type="text" name="order_note" id="add_order_note" class="input-text" /> <textarea type="text" name="order_note" id="add_order_note" class="input-text" cols="20" rows="5"></textarea>
<select name="order_note_type" id="order_note_type"> </p>
<option value="customer"><?php _e('Customer note', 'woothemes'); ?></option> <p>
<option value=""><?php _e('Private note', 'woothemes'); ?></option> <select name="order_note_type" id="order_note_type">
</select></p> <option value="customer"><?php _e( 'Customer note', 'woocommerce' ); ?></option>
<a href="#" class="add_note button"><?php _e('Add', 'woothemes'); ?></a> <option value=""><?php _e( 'Private note', 'woocommerce' ); ?></option>
</select>
<a href="#" class="add_note button"><?php _e( 'Add', 'woocommerce' ); ?></a>
</p>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
jQuery('a.add_note').click(function(){ jQuery('a.add_note').click(function(){
if (!jQuery('input#add_order_note').val()) return; if (!jQuery('textarea#add_order_note').val()) return;
jQuery('#woocommerce-order-notes').block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } }); jQuery('#woocommerce-order-notes').block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
var data = { var data = {
action: 'woocommerce_add_order_note', action: 'woocommerce_add_order_note',
post_id: '<?php echo $post->ID; ?>', post_id: '<?php echo $post->ID; ?>',
note: jQuery('input#add_order_note').val(), note: jQuery('textarea#add_order_note').val(),
note_type: jQuery('select#order_note_type').val(), note_type: jQuery('select#order_note_type').val(),
security: '<?php echo wp_create_nonce("add-order-note"); ?>' security: '<?php echo wp_create_nonce("add-order-note"); ?>'
}; };
jQuery.post( '<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) { jQuery.post( '<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
jQuery('ul.order_notes').prepend( response ); jQuery('ul.order_notes').prepend( response );
jQuery('#woocommerce-order-notes').unblock(); jQuery('#woocommerce-order-notes').unblock();
jQuery('#add_order_note').val(''); jQuery('#add_order_note').val('');
}); });
return false; return false;
}); });
jQuery('a.delete_note').live('click', function(){ jQuery('a.delete_note').live('click', function(){
var note = jQuery(this).closest('li.note'); var note = jQuery(this).closest('li.note');
jQuery(note).block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } }); jQuery(note).block({ message: null, overlayCSS: { background: '#fff url(<?php echo $woocommerce->plugin_url(); ?>/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
var data = { var data = {
action: 'woocommerce_delete_order_note', action: 'woocommerce_delete_order_note',
note_id: jQuery(note).attr('rel'), note_id: jQuery(note).attr('rel'),
@ -94,15 +106,15 @@ function woocommerce_order_notes_meta_box() {
}; };
jQuery.post( '<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) { jQuery.post( '<?php echo admin_url('admin-ajax.php'); ?>', data, function(response) {
jQuery(note).remove(); jQuery(note).remove();
}); });
return false; return false;
}); });
</script> </script>
<?php <?php
} }

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,285 @@
<?php
/**
* Product Images
*
* Function for displaying the product images meta box.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/WritePanels
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Display the product images meta box.
*
* @access public
* @return void
*/
function woocommerce_product_images_box() {
global $post;
?>
<div id="product_images_container">
<ul class="product_images">
<?php
$thumbnail_id = get_post_thumbnail_id( $post->ID );
if ( $thumbnail_id )
echo '<li class="image" data-post_id="' . $thumbnail_id . '">
' . wp_get_attachment_image( $thumbnail_id, 'full' ) . '
<span class="loading"></span>
<ul class="actions">
<li><a href="#" class="delete">' . __( 'Delete', 'woocommerce' ) . '</a></li>
<li><a href="' . admin_url( 'media-upload.php?post_id=' . $post->ID . '&attachment_id=' . $thumbnail_id . '&tab=library&width=640&height=553&TB_iframe=1' ) . '" class="view thickbox" onclick="return false;">' . __( 'View', 'woocommerce' ) . '</a></li>
</ul>
</li>';
$attachments =& get_children( 'post_parent=' . $post->ID . '&numberposts=-1&post_type=attachment&orderby=menu_order&order=ASC&post_mime_type=image' );
foreach ( $attachments as $attachment_id => $attachment ) {
if ( $thumbnail_id == $attachment_id )
continue;
$exclude_class = get_post_meta( $attachment_id, '_woocommerce_exclude_image', true ) == 1 ? 'excluded' : '';
echo '<li class="image ' . $exclude_class . '" data-post_id="' . $attachment_id . '">
' . wp_get_attachment_image( $attachment_id, 'full' ) . '
<span class="loading"></span>
<ul class="actions">
<li><a href="#" class="delete">' . __( 'Delete', 'woocommerce' ) . '</a></li>
<li><a href="' . admin_url( 'media-upload.php?post_id=' . $post->ID . '&attachment_id=' . $attachment_id . '&tab=library&width=640&height=553&TB_iframe=1' ) . '" class="view thickbox" onclick="return false;">' . __( 'View', 'woocommerce' ) . '</a></li>
</ul>
</li>';
}
?>
</ul>
</div>
<!-- Uploader section -->
<div id="plupload-upload-ui" class="hide-if-no-js">
<div id="drag-drop-area">
<p class="drag-drop-info"><?php _e('Drop files here'); ?></p>
<p><?php _ex('or', 'Uploader: Drop files here - or - Select Files'); ?></p>
<p class="drag-drop-buttons"><input id="plupload-browse-button" type="button" value="<?php esc_attr_e('Select Files'); ?>" class="button" /></p>
</div>
</div>
<?php
// Drag and drop code adapted from Drag & Drop Featured Image by Jonathan Lundström
$plupload_init = array(
'runtimes' => 'html5,silverlight,flash,html4',
'browse_button' => 'plupload-browse-button',
'container' => 'plupload-upload-ui',
'drop_element' => 'drag-drop-area',
'file_data_name' => 'async-upload',
'multiple_queues' => true,
'max_file_size' => wp_max_upload_size() . 'b',
'url' => admin_url('admin-ajax.php'),
'flash_swf_url' => includes_url('js/plupload/plupload.flash.swf'),
'silverlight_xap_url' => includes_url('js/plupload/plupload.silverlight.xap'),
'filters' => array( array( 'title' => __( 'Allowed Files' ), 'extensions' => '*') ),
'multipart' => true,
'urlstream_upload' => true,
'multipart_params' => array(
'_ajax_nonce' => wp_create_nonce( 'product-images-box-upload' ),
'action' => 'woocommerce_product_images_box_upload',
'post_id' => $post->ID
)
);
// Apply filters to initiate plupload:
$plupload_init = apply_filters( 'plupload_init', $plupload_init );
?>
<script type="text/javascript">
jQuery(document).ready(function($){
function product_images_container_init() {
// Attribute ordering
$('#product_images_container ul.product_images').sortable({
items: 'li.image',
cursor: 'move',
scrollSensitivity:40,
forcePlaceholderSize: true,
forceHelperSize: false,
helper: 'clone',
opacity: 0.65,
placeholder: 'wc-metabox-sortable-placeholder',
start:function(event,ui){
ui.item.css('background-color','#f6f6f6');
},
stop:function(event,ui){
ui.item.removeAttr('style');
},
update: function(event, ui) {
$('#product_images_container ul li.image').css('cursor','default');
$('#product_images_container ul.product_images').sortable('disable');
var post_id = <?php echo $post->ID; ?>;
var attachment_id = ui.item.attr( 'data-post_id' );
var prev_attachment_id = ui.item.prev().attr( 'data-post_id' );
var next_attachment_id = ui.item.next().attr( 'data-post_id' );
// show spinner
ui.item.addClass('loading');
// go do the sorting stuff via ajax
jQuery.post( ajaxurl, {
action: 'woocommerce_product_image_ordering',
post_id: post_id,
attachment_id: attachment_id,
prev_attachment_id: prev_attachment_id,
next_attachment_id: next_attachment_id,
_ajax_nonce: '<?php echo wp_create_nonce( 'product-image-ordering' ); ?>'
}, function( response ) {
ui.item.removeClass('loading');
$('#product_images_container ul li.image').css('cursor','move');
$('#product_images_container ul.product_images').sortable('enable');
}
);
}
});
}
product_images_container_init();
// Delete images
$('#product_images_container').on( 'click', 'a.delete', function() {
$image = $(this).closest('li.image');
var attachment_id = $image.attr('data-post_id');
if ( attachment_id ) {
$image.addClass('loading');
var answer = confirm('<?php _e( 'Are you sure you want to remove this attachment?', 'woocommerce' ); ?>');
if ( answer ) {
jQuery.post( ajaxurl, {
action: 'woocommerce_product_image_delete',
post_id: <?php echo $post->ID; ?>,
attachment_id: attachment_id,
_ajax_nonce: '<?php echo wp_create_nonce( 'product-image-delete' ); ?>'
}, function( response ) {
$image.remove();
}
);
} else {
$image.removeClass('loading');
}
}
return false;
} );
// Drag and drop uploading of images
var uploader = new plupload.Uploader(<?php echo json_encode( $plupload_init ); ?>);
// Check for drag'n'drop functionality:
uploader.bind('Init', function(up){
var uploaddiv = $('#plupload-upload-ui');
// Add classes and bind actions:
if(up.features.dragdrop){
uploaddiv.addClass('drag-drop');
$('#drag-drop-area')
.bind('dragover.wp-uploader', function() { uploaddiv.addClass('drag-over'); })
.bind('dragleave.wp-uploader, drop.wp-uploader', function(){ uploaddiv.removeClass('drag-over'); });
} else{
uploaddiv.removeClass('drag-drop');
$('#drag-drop-area').unbind('.wp-uploader');
}
});
// Initiate uploading script:
uploader.init();
// File queue handler
uploader.bind('FilesAdded', function(up, files){
var hundredmb = 100 * 1024 * 1024, max = parseInt(up.settings.max_file_size, 10);
// Loop through files:
plupload.each(files, function(file){
if ( max > hundredmb && file.size > hundredmb && up.runtime != 'html5' ) {
alert( "<?php _e( 'The file you selected exceeds the maximum filesize specified in this installation.', 'woocommerce' ); ?>" );
}
});
// Refresh and start:
up.refresh();
up.start();
// Block the UI
$('#product_images_container').block({ message: null, overlayCSS: { background: '#fff url(' + woocommerce_writepanel_params.plugin_url + '/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
});
// Handle new uploads
uploader.bind( 'FileUploaded', function( up, file, response ) {
response = $.parseJSON( response.response );
if ( response.error ) {
alert( response.error );
} else {
$('#product_images_container ul').append('<li class="image" data-post_id="' + response.post_id + '">\
<img src="' + response.src + '" />\
<span class="loading"></span>\
<ul class="actions">\
<li><a href="#" class="delete"><?php _e( 'Delete', 'woocommerce' ) ?></a></li>\
<li><a href="' + response.edit_url + '" class="view thickbox" onclick="return false;"><?php _e( 'View', 'woocommerce' ) ?></a></li>\
</ul>\
</li>');
}
$('#product_images_container').unblock();
});
// Refresh images when a thickbox (images) closes
var loading_product_images = false;
jQuery(document).bind( 'tb_unload', function() {
if ( loading_product_images )
return;
loading_product_images = true;
// Block
$('#product_images_container').block({ message: null, overlayCSS: { background: '#fff url(' + woocommerce_writepanel_params.plugin_url + '/assets/images/ajax-loader.gif) no-repeat center', opacity: 0.6 } });
// Re-load images
jQuery.post( ajaxurl, {
action: 'woocommerce_product_image_refresh',
post_id: <?php echo $post->ID; ?>,
_ajax_nonce: '<?php echo wp_create_nonce( 'product-image-refresh' ); ?>'
}, function( response ) {
if ( response ) {
$("#product_images_container").html(response);
}
// Re-init
product_images_container_init();
// Unblock
$('#product_images_container').unblock();
loading_product_images = false;
}
);
} );
});
</script>
<?php
}

View File

@ -1,86 +1,203 @@
<?php <?php
/** /**
* WooCommerce Write Panels * WooCommerce Write Panels
* *
* Sets up the write panels used by products and orders (custom post types) * Sets up the write panels used by products and orders (custom post types)
* *
* @author WooThemes * @author WooThemes
* @category Admin Write Panels * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/WritePanels
* @version 2.0.0
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** Product data writepanel */
include_once('writepanel-product_data.php');
/** Product images writepanel */
include_once('writepanel-product_images.php');
/** Coupon data writepanel */
include_once('writepanel-coupon_data.php');
/** Order data writepanel */
include_once('writepanel-order_data.php');
/** Order notes writepanel */
include_once('writepanel-order_notes.php');
/** Order downloads writepanel */
include_once('writepanel-order_downloads.php');
/** /**
* Init the meta boxes * Init the meta boxes.
* *
* Inits the write panels for both products and orders. Also removes unused default write panels. * Inits the write panels for both products and orders. Also removes unused default write panels.
*
* @access public
* @return void
*/ */
add_action( 'add_meta_boxes', 'woocommerce_meta_boxes' );
function woocommerce_meta_boxes() { function woocommerce_meta_boxes() {
global $post;
// Products // Products
add_meta_box( 'woocommerce-product-type', __('Product Type &amp; Visibility', 'woothemes'), 'woocommerce_product_type_box', 'product', 'normal', 'high' ); add_meta_box( 'woocommerce-product-data', __( 'Product Data', 'woocommerce' ), 'woocommerce_product_data_box', 'product', 'normal', 'high' );
add_meta_box( 'woocommerce-product-data', __('Product Data', 'woothemes'), 'woocommerce_product_data_box', 'product', 'normal', 'high' ); add_meta_box( 'woocommerce-product-images', __( 'Product Images', 'woocommerce' ), 'woocommerce_product_images_box', 'product', 'side' );
remove_meta_box( 'product_shipping_classdiv', 'product', 'side' );
remove_meta_box( 'pageparentdiv', 'product', 'side' );
remove_meta_box( 'postimagediv', 'product', 'side' );
// Excerpt
if ( function_exists('wp_editor') ) {
remove_meta_box( 'postexcerpt', 'product', 'normal' );
add_meta_box( 'postexcerpt', __( 'Product Short Description', 'woocommerce' ), 'woocommerce_product_short_description_meta_box', 'product', 'normal' );
}
// Comments/Reviews
remove_meta_box( 'commentstatusdiv', 'product', 'normal' );
remove_meta_box( 'commentstatusdiv', 'product', 'side' );
if ( ('publish' == $post->post_status || 'private' == $post->post_status) ) {
remove_meta_box( 'commentsdiv', 'product', 'normal' );
add_meta_box( 'commentsdiv', __( 'Reviews', 'woocommerce' ), 'post_comment_meta_box', 'product', 'normal' );
}
// Orders // Orders
add_meta_box( 'woocommerce-order-data', __('Order Data', 'woothemes'), 'woocommerce_order_data_meta_box', 'shop_order', 'normal', 'high' ); add_meta_box( 'woocommerce-order-data', __( 'Order Data', 'woocommerce' ), 'woocommerce_order_data_meta_box', 'shop_order', 'normal', 'high' );
add_meta_box( 'woocommerce-order-items', __('Order Items <small>&ndash; Note: if you edit quantities or remove items from the order you will need to manually change the item\'s stock levels.</small>', 'woothemes'), 'woocommerce_order_items_meta_box', 'shop_order', 'normal', 'high'); add_meta_box( 'woocommerce-order-items', __( 'Order Items', 'woocommerce' ) . ' <span class="tips" data-tip="' . __( 'Note: if you edit quantities or remove items from the order you will need to manually update stock levels.', 'woocommerce' ) . '">[?]</span>', 'woocommerce_order_items_meta_box', 'shop_order', 'normal', 'high');
add_meta_box( 'woocommerce-order-totals', __('Order Totals', 'woothemes'), 'woocommerce_order_totals_meta_box', 'shop_order', 'side', 'default'); add_meta_box( 'woocommerce-order-totals', __( 'Order Totals', 'woocommerce' ), 'woocommerce_order_totals_meta_box', 'shop_order', 'side', 'default');
add_meta_box( 'woocommerce-order-notes', __('Order Notes', 'woothemes'), 'woocommerce_order_notes_meta_box', 'shop_order', 'side', 'default'); add_meta_box( 'woocommerce-order-notes', __( 'Order Notes', 'woocommerce' ), 'woocommerce_order_notes_meta_box', 'shop_order', 'side', 'default');
add_meta_box( 'woocommerce-order-actions', __('Order Actions', 'woothemes'), 'woocommerce_order_actions_meta_box', 'shop_order', 'side', 'high'); add_meta_box( 'woocommerce-order-downloads', __( 'Downloadable Product Permissions', 'woocommerce' ) . ' <span class="tips" data-tip="' . __( 'Note: Permissions for order items will automatically be granted when the order status changes to processing/completed.', 'woocommerce' ) . '">[?]</span>', 'woocommerce_order_downloads_meta_box', 'shop_order', 'normal', 'default');
add_meta_box( 'woocommerce-order-actions', __( 'Order Actions', 'woocommerce' ), 'woocommerce_order_actions_meta_box', 'shop_order', 'side', 'high');
remove_meta_box( 'commentsdiv', 'shop_order' , 'normal' ); remove_meta_box( 'commentsdiv', 'shop_order' , 'normal' );
remove_meta_box( 'woothemes-settings', 'shop_order' , 'normal' ); remove_meta_box( 'woothemes-settings', 'shop_order' , 'normal' );
remove_meta_box( 'commentstatusdiv', 'shop_order' , 'normal' ); remove_meta_box( 'commentstatusdiv', 'shop_order' , 'normal' );
remove_meta_box( 'slugdiv', 'shop_order' , 'normal' ); remove_meta_box( 'slugdiv', 'shop_order' , 'normal' );
// Coupons // Coupons
add_meta_box( 'woocommerce-coupon-data', __('Coupon Data', 'woothemes'), 'woocommerce_coupon_data_meta_box', 'shop_coupon', 'normal', 'high'); add_meta_box( 'woocommerce-coupon-data', __( 'Coupon Data', 'woocommerce' ), 'woocommerce_coupon_data_meta_box', 'shop_coupon', 'normal', 'high');
remove_meta_box( 'woothemes-settings', 'shop_coupon' , 'normal' ); remove_meta_box( 'woothemes-settings', 'shop_coupon' , 'normal' );
remove_meta_box( 'commentstatusdiv', 'shop_coupon' , 'normal' ); remove_meta_box( 'commentstatusdiv', 'shop_coupon' , 'normal' );
remove_meta_box( 'slugdiv', 'shop_coupon' , 'normal' ); remove_meta_box( 'slugdiv', 'shop_coupon' , 'normal' );
} }
/** add_action( 'add_meta_boxes', 'woocommerce_meta_boxes' );
* Title boxes
*/
add_filter('enter_title_here', 'woocommerce_enter_title_here', 1, 2);
/**
* Change title boxes in admin.
*
* @access public
* @param mixed $text
* @param mixed $post
* @return string
*/
function woocommerce_enter_title_here( $text, $post ) { function woocommerce_enter_title_here( $text, $post ) {
if ($post->post_type=='shop_coupon') return __('Coupon code', 'woothemes'); if ( $post->post_type == 'shop_coupon' ) return __( 'Coupon code', 'woocommerce' );
if ($post->post_type=='product') return __('Product name', 'woothemes'); if ( $post->post_type == 'product' ) return __( 'Product name', 'woocommerce' );
return $text; return $text;
} }
add_filter('enter_title_here', 'woocommerce_enter_title_here', 1, 2);
/** /**
* Save meta boxes * Save meta boxes
* *
* Runs when a post is saved and does an action which the write panel save scripts can hook into. * Runs when a post is saved and does an action which the write panel save scripts can hook into.
*
* @access public
* @param mixed $post_id
* @param mixed $post
* @return void
*/ */
add_action( 'save_post', 'woocommerce_meta_boxes_save', 1, 2 );
function woocommerce_meta_boxes_save( $post_id, $post ) { function woocommerce_meta_boxes_save( $post_id, $post ) {
global $wpdb; if ( empty( $post_id ) || empty( $post ) ) return;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
if ( !$_POST ) return $post_id; if ( is_int( wp_is_post_revision( $post ) ) ) return;
if ( is_int( wp_is_post_revision( $post_id ) ) ) return; if ( is_int( wp_is_post_autosave( $post ) ) ) return;
if( is_int( wp_is_post_autosave( $post_id ) ) ) return; if ( empty( $_POST['woocommerce_meta_nonce'] ) || ! wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ) ) return;
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) return $post_id; if ( !current_user_can( 'edit_post', $post_id )) return;
if ( !isset($_POST['woocommerce_meta_nonce']) || (isset($_POST['woocommerce_meta_nonce']) && !wp_verify_nonce( $_POST['woocommerce_meta_nonce'], 'woocommerce_save_data' ))) return $post_id; if ( $post->post_type != 'product' && $post->post_type != 'shop_order' && $post->post_type != 'shop_coupon' ) return;
if ( !current_user_can( 'edit_post', $post_id )) return $post_id;
if ( $post->post_type != 'product' && $post->post_type != 'shop_order' && $post->post_type != 'shop_coupon' ) return $post_id; do_action( 'woocommerce_process_' . $post->post_type . '_meta', $post_id, $post );
do_action( 'woocommerce_process_'.$post->post_type.'_meta', $post_id, $post ); woocommerce_meta_boxes_save_errors();
} }
/** add_action( 'save_post', 'woocommerce_meta_boxes_save', 1, 2 );
* Product data
*
* Forces certain product data based on the product's type, e.g. grouped products cannot have a parent.
*/
add_filter('wp_insert_post_data', 'woocommerce_product_data');
/**
* Some functions, like the term recount, require the visibility to be set prior. Lets save that here.
*
* @access public
* @param mixed $post_id
* @return void
*/
function woocommerce_pre_post_update( $post_id ) {
if ( isset( $_POST['_visibility'] ) )
update_post_meta( $post_id, '_visibility', stripslashes( $_POST['_visibility'] ) );
if ( isset( $_POST['_stock_status'] ) )
update_post_meta( $post_id, '_stock_status', stripslashes( $_POST['_stock_status'] ) );
}
add_action( 'pre_post_update', 'woocommerce_pre_post_update' );
/**
* Product Short Description.
*
* Replaces excerpt with a visual editor.
*
* @access public
* @param mixed $post
* @return void
*/
function woocommerce_product_short_description_meta_box( $post ) {
$settings = array(
'quicktags' => array( 'buttons' => 'em,strong,link' ),
'textarea_name' => 'excerpt',
'quicktags' => true,
'tinymce' => true,
'editor_css' => '<style>#wp-excerpt-editor-container .wp-editor-area{height:175px; width:100%;}</style>'
);
wp_editor( htmlspecialchars_decode( $post->post_excerpt ), 'excerpt', $settings );
}
/**
* Change the comment box to be a review box.
*
* @access public
* @param mixed $post
* @return void
*/
function woocommerce_product_review_status_meta_box( $post ) {
?>
<input name="advanced_view" type="hidden" value="1" />
<p class="meta-options">
<label for="comment_status" class="selectit"><input name="comment_status" type="checkbox" id="comment_status" value="open" <?php checked($post->comment_status, 'open'); ?> /> <?php _e( 'Allow reviews.', 'woocommerce' ) ?></label><br />
<label for="ping_status" class="selectit"><input name="ping_status" type="checkbox" id="ping_status" value="open" <?php checked($post->ping_status, 'open'); ?> /> <?php printf( __( 'Allow <a href="%s" target="_blank">trackbacks and pingbacks</a> on this page.' ), __( 'http://codex.wordpress.org/Introduction_to_Blogging#Managing_Comments' ) ); ?></label>
<?php do_action('post_comment_status_meta_box-options', $post); ?>
</p>
<?php
}
/**
* Forces certain product data based on the product's type, e.g. grouped products cannot have a parent.
*
* @access public
* @param mixed $data
* @return array
*/
function woocommerce_product_data( $data ) { function woocommerce_product_data( $data ) {
global $post; global $post;
if ($data['post_type']=='product' && isset($_POST['product-type'])) { if ($data['post_type']=='product' && isset($_POST['product-type'])) {
@ -95,102 +212,257 @@ function woocommerce_product_data( $data ) {
return $data; return $data;
} }
/** add_filter('wp_insert_post_data', 'woocommerce_product_data');
* Order data
*
* Forces the order posts to have a title in a certain format (containing the date)
*/
add_filter('wp_insert_post_data', 'woocommerce_order_data');
/**
* Forces the order posts to have a title in a certain format (containing the date)
*
* @access public
* @param mixed $data
* @return array
*/
function woocommerce_order_data( $data ) { function woocommerce_order_data( $data ) {
global $post; global $post;
if ($data['post_type']=='shop_order' && isset($data['post_date'])) { if ($data['post_type']=='shop_order' && isset($data['post_date'])) {
$order_title = 'Order'; $order_title = 'Order';
if ($data['post_date']) $order_title.= ' &ndash; '.date('F j, Y @ h:i A', strtotime($data['post_date'])); if ($data['post_date']) $order_title.= ' &ndash; ' . date_i18n( 'F j, Y @ h:i A', strtotime( $data['post_date'] ) );
$data['post_title'] = $order_title; $data['post_title'] = $order_title;
} }
return $data; return $data;
} }
add_filter('wp_insert_post_data', 'woocommerce_order_data');
/** /**
* Save errors * Grant downloadable file access to any newly added files on any existing
* * orders for this product that have previously been granted downloadable file access
* Stores error messages in a variable so they can be displayed on the edit post screen after saving. *
* @access public
* @param int $product_id product identifier
* @param int $variation_id optional product variation identifier
* @param array $file_paths newly set file paths
*/ */
add_action( 'admin_notices', 'woocommerce_meta_boxes_save_errors' ); function woocommerce_process_product_file_download_paths( $product_id, $variation_id, $file_paths ) {
global $wpdb;
function woocommerce_meta_boxes_save_errors() { if ( $variation_id )
$woocommerce_errors = maybe_unserialize(get_option('woocommerce_errors')); $product_id = $variation_id;
if ($woocommerce_errors && sizeof($woocommerce_errors)>0) :
echo '<div id="woocommerce_errors" class="error fade">'; // determine whether any new files have been added
foreach ($woocommerce_errors as $error) : $existing_file_paths = apply_filters( 'woocommerce_file_download_paths', get_post_meta( $product_id, '_file_paths', true ), $product_id, null, null );
echo '<p>'.$error.'</p>'; if ( ! $existing_file_paths ) $existing_file_paths = array();
endforeach; $new_download_ids = array_diff( array_keys( $file_paths ), array_keys( $existing_file_paths ) );
echo '</div>';
update_option('woocommerce_errors', ''); if ( $new_download_ids ) {
endif; // determine whether downloadable file access has been granted (either via the typical order completion, or via the admin ajax method)
$existing_permissions = $wpdb->get_results( $wpdb->prepare( "SELECT * from {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE product_id = %d GROUP BY order_id", $product_id ) );
foreach ( $existing_permissions as $existing_permission ) {
$order = new WC_Order( $existing_permission->order_id );
if ( $order->id ) {
foreach ( $new_download_ids as $new_download_id ) {
// grant permission if it doesn't already exist
if ( ! $wpdb->get_var( $wpdb->prepare( "SELECT true FROM {$wpdb->prefix}woocommerce_downloadable_product_permissions WHERE order_id = %d AND product_id = %d AND download_id = %s", $order->id, $product_id, $new_download_id ) ) ) {
woocommerce_downloadable_file_permission( $new_download_id, $product_id, $order );
}
}
}
}
}
} }
add_action( 'woocommerce_process_product_file_download_paths', 'woocommerce_process_product_file_download_paths', 10, 3 );
/** /**
* Output write panel form elements * Stores error messages in a variable so they can be displayed on the edit post screen after saving.
*
* @access public
* @return void
*/
function woocommerce_meta_boxes_save_errors() {
global $woocommerce_errors;
update_option( 'woocommerce_errors', $woocommerce_errors );
}
add_action( 'admin_footer', 'woocommerce_meta_boxes_save_errors' );
/**
* Show any stored error messages.
*
* @access public
* @return void
*/
function woocommerce_meta_boxes_show_errors() {
global $woocommerce_errors;
$woocommerce_errors = maybe_unserialize( get_option( 'woocommerce_errors' ) );
if ( ! empty( $woocommerce_errors ) ) {
echo '<div id="woocommerce_errors" class="error fade">';
foreach ( $woocommerce_errors as $error )
echo '<p>' . esc_html( $error ) . '</p>';
echo '</div>';
// Clear
update_option( 'woocommerce_errors', '' );
$woocommerce_errors = array();
}
}
add_action( 'admin_notices', 'woocommerce_meta_boxes_show_errors' );
/**
* Output a text input box.
*
* @access public
* @param array $field
* @return void
*/ */
function woocommerce_wp_text_input( $field ) { function woocommerce_wp_text_input( $field ) {
global $thepostid, $post; global $thepostid, $post, $woocommerce;
if (!$thepostid) $thepostid = $post->ID; $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
if (!isset($field['placeholder'])) $field['placeholder'] = ''; $field['placeholder'] = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
if (!isset($field['class'])) $field['class'] = 'short'; $field['class'] = isset( $field['class'] ) ? $field['class'] : 'short';
if (!isset($field['value'])) $field['value'] = get_post_meta($thepostid, $field['id'], true); $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
$field['name'] = isset( $field['name'] ) ? $field['name'] : $field['id'];
echo '<p class="form-field '.$field['id'].'_field"><label for="'.$field['id'].'">'.$field['label'].'</label><input type="text" class="'.$field['class'].'" name="'.$field['id'].'" id="'.$field['id'].'" value="'.esc_attr( $field['value'] ).'" placeholder="'.$field['placeholder'].'" /> '; $field['type'] = isset( $field['type'] ) ? $field['type'] : 'text';
if (isset($field['description'])) echo '<span class="description">' .$field['description'] . '</span>'; // Custom attribute handling
$custom_attributes = array();
if ( ! empty( $field['custom_attributes'] ) && is_array( $field['custom_attributes'] ) )
foreach ( $field['custom_attributes'] as $attribute => $value )
$custom_attributes[] = esc_attr( $attribute ) . '="' . esc_attr( $value ) . '"';
echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><input type="' . esc_attr( $field['type'] ) . '" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['name'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['value'] ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" ' . implode( ' ', $custom_attributes ) . ' /> ';
if ( ! empty( $field['description'] ) ) {
if ( isset( $field['desc_tip'] ) ) {
echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" height="16" width="16" />';
} else {
echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
}
}
echo '</p>'; echo '</p>';
} }
/**
* Output a hidden input box.
*
* @access public
* @param array $field
* @return void
*/
function woocommerce_wp_hidden_input( $field ) {
global $thepostid, $post;
$thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
$field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
$field['class'] = isset( $field['class'] ) ? $field['class'] : '';
echo '<input type="hidden" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['value'] ) . '" /> ';
}
/**
* Output a textarea input box.
*
* @access public
* @param array $field
* @return void
*/
function woocommerce_wp_textarea_input( $field ) {
global $thepostid, $post, $woocommerce;
$thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
$field['placeholder'] = isset( $field['placeholder'] ) ? $field['placeholder'] : '';
$field['class'] = isset( $field['class'] ) ? $field['class'] : 'short';
$field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><textarea class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" placeholder="' . esc_attr( $field['placeholder'] ) . '" rows="2" cols="20">' . esc_textarea( $field['value'] ) . '</textarea> ';
if ( ! empty( $field['description'] ) ) {
if ( isset( $field['desc_tip'] ) ) {
echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" height="16" width="16" />';
} else {
echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
}
}
echo '</p>';
}
/**
* Output a checkbox input box.
*
* @access public
* @param array $field
* @return void
*/
function woocommerce_wp_checkbox( $field ) { function woocommerce_wp_checkbox( $field ) {
global $thepostid, $post; global $thepostid, $post;
if (!$thepostid) $thepostid = $post->ID; $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
if (!isset($field['class'])) $field['class'] = 'checkbox'; $field['class'] = isset( $field['class'] ) ? $field['class'] : 'checkbox';
if (!isset($field['wrapper_class'])) $field['wrapper_class'] = ''; $field['wrapper_class'] = isset( $field['wrapper_class'] ) ? $field['wrapper_class'] : '';
if (!isset($field['value'])) $field['value'] = get_post_meta($thepostid, $field['id'], true); $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
$field['cbvalue'] = isset( $field['cbvalue'] ) ? $field['cbvalue'] : 'yes';
echo '<p class="form-field '.$field['id'].'_field '.$field['wrapper_class'].'"><label for="'.$field['id'].'">'.$field['label'].'</label><input type="checkbox" class="'.$field['class'].'" name="'.$field['id'].'" id="'.$field['id'].'" ';
echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field ' . esc_attr( $field['wrapper_class'] ) . '"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><input type="checkbox" class="' . esc_attr( $field['class'] ) . '" name="' . esc_attr( $field['id'] ) . '" id="' . esc_attr( $field['id'] ) . '" value="' . esc_attr( $field['cbvalue'] ) . '" ' . checked( $field['value'], $field['cbvalue'], false ) . ' /> ';
checked($field['value'], 'yes');
if ( ! empty( $field['description'] ) ) echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
echo ' /> ';
if (isset($field['description'])) echo '<span class="description">' .$field['description'] . '</span>';
echo '</p>'; echo '</p>';
} }
/**
* Output a select input box.
*
* @access public
* @param array $field
* @return void
*/
function woocommerce_wp_select( $field ) { function woocommerce_wp_select( $field ) {
global $thepostid, $post; global $thepostid, $post, $woocommerce;
if (!$thepostid) $thepostid = $post->ID; $thepostid = empty( $thepostid ) ? $post->ID : $thepostid;
if (!isset($field['class'])) $field['class'] = 'select short'; $field['class'] = isset( $field['class'] ) ? $field['class'] : 'select short';
if (!isset($field['value'])) $field['value'] = get_post_meta($thepostid, $field['id'], true); $field['value'] = isset( $field['value'] ) ? $field['value'] : get_post_meta( $thepostid, $field['id'], true );
echo '<p class="form-field '.$field['id'].'_field"><label for="'.$field['id'].'">'.$field['label'].'</label><select id="'.$field['id'].'" name="'.$field['id'].'" class="'.$field['class'].'">'; echo '<p class="form-field ' . esc_attr( $field['id'] ) . '_field"><label for="' . esc_attr( $field['id'] ) . '">' . wp_kses_post( $field['label'] ) . '</label><select id="' . esc_attr( $field['id'] ) . '" name="' . esc_attr( $field['id'] ) . '" class="' . esc_attr( $field['class'] ) . '">';
foreach ($field['options'] as $key => $value) : foreach ( $field['options'] as $key => $value ) {
echo '<option value="'.$key.'" '; echo '<option value="' . esc_attr( $key ) . '" ' . selected( esc_attr( $field['value'] ), esc_attr( $key ), false ) . '>' . esc_html( $value ) . '</option>';
selected($field['value'], $key);
echo '>'.$value.'</option>'; }
endforeach;
echo '</select> '; echo '</select> ';
if (isset($field['description'])) echo '<span class="description">' .$field['description'] . '</span>'; if ( ! empty( $field['description'] ) ) {
if ( isset( $field['desc_tip'] ) ) {
echo '<img class="help_tip" data-tip="' . esc_attr( $field['description'] ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" height="16" width="16" />';
} else {
echo '<span class="description">' . wp_kses_post( $field['description'] ) . '</span>';
}
}
echo '</p>'; echo '</p>';
} }

View File

@ -0,0 +1,89 @@
<?php
/**
* Frontend styles/color picker settings.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Settings
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Output the frontend styles settings.
*
* @access public
* @return void
*/
function woocommerce_frontend_styles_setting() {
global $woocommerce;
?><tr valign="top" class="woocommerce_frontend_css_colors">
<th scope="row" class="titledesc">
<label><?php _e( 'Styles', 'woocommerce' ); ?></label>
</th>
<td class="forminp"><?php
$base_file = $woocommerce->plugin_path() . '/assets/css/woocommerce-base.less';
$css_file = $woocommerce->plugin_path() . '/assets/css/woocommerce.css';
if ( is_writable( $base_file ) && is_writable( $css_file ) ) {
// Get settings
$colors = array_map( 'esc_attr', (array) get_option( 'woocommerce_frontend_css_colors' ) );
// Defaults
if ( empty( $colors['primary'] ) ) $colors['primary'] = '#ad74a2';
if ( empty( $colors['secondary'] ) ) $colors['secondary'] = '#f7f6f7';
if ( empty( $colors['highlight'] ) ) $colors['highlight'] = '#85ad74';
if ( empty( $colors['content_bg'] ) ) $colors['content_bg'] = '#ffffff';
if ( empty( $colors['subtext'] ) ) $colors['subtext'] = '#777777';
// Show inputs
woocommerce_frontend_css_color_picker( __( 'Primary', 'woocommerce' ), 'woocommerce_frontend_css_primary', $colors['primary'], __( 'Call to action buttons/price slider/layered nav UI', 'woocommerce' ) );
woocommerce_frontend_css_color_picker( __( 'Secondary', 'woocommerce' ), 'woocommerce_frontend_css_secondary', $colors['secondary'], __( 'Buttons and tabs', 'woocommerce' ) );
woocommerce_frontend_css_color_picker( __( 'Highlight', 'woocommerce' ), 'woocommerce_frontend_css_highlight', $colors['highlight'], __( 'Price labels and Sale Flashes', 'woocommerce' ) );
woocommerce_frontend_css_color_picker( __( 'Content', 'woocommerce' ), 'woocommerce_frontend_css_content_bg', $colors['content_bg'], __( 'Your themes page background - used for tab active states', 'woocommerce' ) );
woocommerce_frontend_css_color_picker( __( 'Subtext', 'woocommerce' ), 'woocommerce_frontend_css_subtext', $colors['subtext'], __( 'Used for certain text and asides - breadcrumbs, small text etc.', 'woocommerce' ) );
} else {
echo '<span class="description">' . __( 'To edit colours <code>woocommerce/assets/css/woocommerce-base.less</code> and <code>woocommerce.css</code> need to be writable. See <a href="http://codex.wordpress.org/Changing_File_Permissions">the Codex</a> for more information.', 'woocommerce' ) . '</span>';
}
?></td>
</tr>
<script type="text/javascript">
jQuery('input#woocommerce_frontend_css').change(function() {
if (jQuery(this).is(':checked')) {
jQuery('tr.woocommerce_frontend_css_colors').show();
} else {
jQuery('tr.woocommerce_frontend_css_colors').hide();
}
}).change();
</script>
<?php
}
add_action( 'woocommerce_admin_field_frontend_styles', 'woocommerce_frontend_styles_setting' );
/**
* Output a colour picker input box.
*
* @access public
* @param mixed $name
* @param mixed $id
* @param mixed $value
* @param string $desc (default: '')
* @return void
*/
function woocommerce_frontend_css_color_picker( $name, $id, $value, $desc = '' ) {
global $woocommerce;
echo '<div class="color_box"><strong><img class="help_tip" data-tip="' . esc_attr( $desc ) . '" src="' . $woocommerce->plugin_url() . '/assets/images/help.png" height="16" width="16" /> ' . esc_html( $name ) . '</strong>
<input name="' . esc_attr( $id ). '" id="' . esc_attr( $id ) . '" type="text" value="' . esc_attr( $value ) . '" class="colorpick" /> <div id="colorPickerDiv_' . esc_attr( $id ) . '" class="colorpickdiv"></div>
</div>';
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,66 @@
<?php
/**
* Additional payment gateway settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Settings
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Output payment gateway settings.
*
* @access public
* @return void
*/
function woocommerce_payment_gateways_setting() {
global $woocommerce;
?>
<tr valign="top">
<td class="forminp" colspan="2">
<table class="wc_gateways widefat" cellspacing="0">
<thead>
<tr>
<th width="1%"><?php _e( 'Default', 'woocommerce' ); ?></th>
<th><?php _e( 'Gateway', 'woocommerce' ); ?></th>
<th><?php _e( 'Status', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ( $woocommerce->payment_gateways->payment_gateways() as $gateway ) :
$default_gateway = get_option('woocommerce_default_gateway');
echo '<tr>
<td width="1%" class="radio">
<input type="radio" name="default_gateway" value="' . esc_attr( $gateway->id ) . '" ' . checked( $default_gateway, esc_attr( $gateway->id ), false ) . ' />
<input type="hidden" name="gateway_order[]" value="' . esc_attr( $gateway->id ) . '" />
</td>
<td>
<p><strong>' . $gateway->get_title() . '</strong><br/>
<small>' . __( 'Gateway ID', 'woocommerce' ) . ': ' . esc_html( $gateway->id ) . '</small></p>
</td>
<td>';
if ( $gateway->enabled == 'yes' )
echo '<img src="' . $woocommerce->plugin_url() . '/assets/images/success.png" width="16" height="14" alt="yes" />';
else
echo '<img src="' . $woocommerce->plugin_url() . '/assets/images/success-off.png" width="16" height="14" alt="no" />';
echo '</td>
</tr>';
endforeach;
?>
</tbody>
</table>
</td>
</tr>
<?php
}
add_action( 'woocommerce_admin_field_payment_gateways', 'woocommerce_payment_gateways_setting' );

View File

@ -0,0 +1,172 @@
<?php
/**
* Update options
*
* Updates the options on the woocommerce settings pages. Returns true if saved.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Settings
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Update all settings which are passed.
*
* @access public
* @param array $options
* @return void
*/
function woocommerce_update_options( $options ) {
if ( empty( $_POST ) )
return false;
// Options to update will be stored here
$update_options = array();
// Loop options and get values to save
foreach ( $options as $value ) {
if ( ! isset( $value['id'] ) )
continue;
$type = isset( $value['type'] ) ? sanitize_title( $value['type'] ) : '';
// Get the option name
$option_value = null;
switch ( $type ) {
// Standard types
case "checkbox" :
if ( isset( $_POST[$value['id']] ) ) {
$option_value = 'yes';
} else {
$option_value = 'no';
}
break;
case "textarea" :
if ( isset( $_POST[$value['id']] ) ) {
$option_value = wp_kses_post( $_POST[ $value['id'] ] );
} else {
$option_value = '';
}
break;
case "text" :
case 'email':
case 'number':
case "select" :
case "color" :
case "single_select_page" :
case "single_select_country" :
case 'radio' :
if ( $value['id'] == 'woocommerce_price_thousand_sep' || $value['id'] == 'woocommerce_price_decimal_sep' ) {
// price separators get a special treatment as they should allow a spaces (don't trim)
if ( isset( $_POST[ $value['id'] ] ) ) {
$option_value = esc_attr( $_POST[ $value['id'] ] );
} else {
$option_value = '';
}
} else {
if ( isset( $_POST[$value['id']] ) ) {
$option_value = woocommerce_clean( $_POST[ $value['id'] ] );
} else {
$option_value = '';
}
}
break;
// Special types
case "multi_select_countries" :
// Get countries array
if ( isset( $_POST[ $value['id'] ] ) )
$selected_countries = array_map( 'woocommerce_clean', (array) $_POST[ $value['id'] ] );
else
$selected_countries = array();
$option_value = $selected_countries;
break;
case "image_width" :
if ( isset( $_POST[$value['id'] ]['width'] ) ) {
$update_options[ $value['id'] ]['width'] = woocommerce_clean( $_POST[$value['id'] ]['width'] );
$update_options[ $value['id'] ]['height'] = woocommerce_clean( $_POST[$value['id'] ]['height'] );
if ( isset( $_POST[ $value['id'] ]['crop'] ) )
$update_options[ $value['id'] ]['crop'] = 1;
else
$update_options[ $value['id'] ]['crop'] = 0;
} else {
$update_options[ $value['id'] ]['width'] = $value['default']['width'];
$update_options[ $value['id'] ]['height'] = $value['default']['height'];
$update_options[ $value['id'] ]['crop'] = $value['default']['crop'];
}
break;
// Custom handling
default :
do_action( 'woocommerce_update_option_' . $type, $value );
break;
}
if ( ! is_null( $option_value ) ) {
// Check if option is an array
if ( strstr( $value['id'], '[' ) ) {
parse_str( $value['id'], $option_array );
// Option name is first key
$option_name = current( array_keys( $option_array ) );
// Get old option value
if ( ! isset( $update_options[ $option_name ] ) )
$update_options[ $option_name ] = get_option( $option_name, array() );
if ( ! is_array( $update_options[ $option_name ] ) )
$update_options[ $option_name ] = array();
// Set keys and value
$key = key( $option_array[ $option_name ] );
$update_options[ $option_name ][ $key ] = $option_value;
// Single value
} else {
$update_options[ $value['id'] ] = $option_value;
}
}
// Custom handling
do_action( 'woocommerce_update_option', $value );
}
// Now save the options
foreach( $update_options as $name => $value )
update_option( $name, $value, true );
return true;
}

View File

@ -0,0 +1,67 @@
<?php
/**
* Additional shipping settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Settings
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Output shipping method settings.
*
* @access public
* @return void
*/
function woocommerce_shipping_methods_setting() {
global $woocommerce;
?>
<tr valign="top">
<th scope="row" class="titledesc"><?php _e( 'Shipping Methods', 'woocommerce' ) ?></th>
<td class="forminp">
<p class="description" style="margin-top: 0;"><?php _e( 'Drag and drop methods to control their display order.', 'woocommerce' ); ?></p>
<table class="wc_shipping widefat" cellspacing="0">
<thead>
<tr>
<th><?php _e( 'Default', 'woocommerce' ); ?></th>
<th><?php _e( 'Shipping Method', 'woocommerce' ); ?></th>
<th><?php _e( 'Status', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
foreach ( $woocommerce->shipping->load_shipping_methods() as $method ) {
$default_shipping_method = esc_attr( get_option('woocommerce_default_shipping_method') );
echo '<tr>
<td width="1%" class="radio">
<input type="radio" name="default_shipping_method" value="' . $method->id . '" ' . checked( $default_shipping_method, $method->id, false ) . ' />
<input type="hidden" name="method_order[]" value="' . $method->id . '" />
<td>
<p><strong>' . $method->get_title() . '</strong><br/>
<small>' . __( 'Method ID', 'woocommerce' ) . ': ' . $method->id . '</small></p>
</td>
<td>';
if ($method->enabled == 'yes')
echo '<img src="' . $woocommerce->plugin_url() . '/assets/images/success.png" width="16 height="14" alt="yes" />';
else
echo '<img src="' . $woocommerce->plugin_url() . '/assets/images/success-off.png" width="16" height="14" alt="no" />';
echo '</td>
</tr>';
}
?>
</tbody>
</table>
</td>
</tr>
<?php
}
add_action( 'woocommerce_admin_field_shipping_methods', 'woocommerce_shipping_methods_setting' );

View File

@ -0,0 +1,472 @@
<?php
/**
* Additional tax settings
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Settings
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Output tax rate settings.
*
* @access public
* @return void
*/
function woocommerce_tax_rates_setting() {
global $woocommerce, $current_section, $wpdb;
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('woocommerce_tax_classes' ) ) ) );
$current_class = '';
foreach( $tax_classes as $class )
if ( sanitize_title( $class ) == $current_section )
$current_class = $class;
?>
<h3><?php printf( __( 'Tax Rates for the "%s" Class', 'woocommerce' ), $current_class ? esc_html( $current_class ) : __( 'Standard', 'woocommerce' ) ); ?></h3>
<p><?php printf( __( 'Define tax rates for countries and states below. <a href="%s">See here</a> for available country/state codes.', 'woocommerce' ), 'http://wcdocs.woothemes.com/?p=2163' ); ?></p>
<table class="wc_tax_rates widefat">
<thead>
<tr>
<th class="sort">&nbsp;</th>
<th width="8%"><?php _e( 'Country&nbsp;Code', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('A 2 digit country code, e.g. US. Leave blank to apply to all.', 'woocommerce'); ?>">[?]</span></th>
<th width="8%"><?php _e( 'State&nbsp;Code', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('A 2 digit state code, e.g. AL. Leave blank to apply to all.', 'woocommerce'); ?>">[?]</span></th>
<th><?php _e( 'ZIP/Postcode', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Postcode for this rule. Semi-colon (;) separate multiple values. Leave blank to apply to all areas. Wildcards (*) can be used. Ranges for numeric postcodes (e.g. 12345-12350) will be expanded into individual postcodes.', 'woocommerce'); ?>">[?]</span></th>
<th><?php _e( 'City', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Cities for this rule. Semi-colon (;) separate multiple values. Leave blank to apply to all cities.', 'woocommerce'); ?>">[?]</span></th>
<th width="8%"><?php _e( 'Rate&nbsp;%', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e( 'Enter a tax rate (percentage) to 4 decimal places.', 'woocommerce' ); ?>">[?]</span></th>
<th width="8%"><?php _e( 'Tax&nbsp;Name', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Enter a name for this tax rate.', 'woocommerce'); ?>">[?]</span></th>
<th width="8%"><?php _e( 'Priority', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Choose a priority for this tax rate. Only 1 matching rate per priority will be used. To define multiple tax rates for a single area you need to specify a different priority per rate.', 'woocommerce'); ?>">[?]</span></th>
<th width="8%"><?php _e( 'Compound', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Choose whether or not this is a compound rate. Compound tax rates are applied on top of other tax rates.', 'woocommerce'); ?>">[?]</span></th>
<th width="8%"><?php _e( 'Shipping', 'woocommerce' ); ?>&nbsp;<span class="tips" data-tip="<?php _e('Choose whether or not this tax rate also gets applied to shipping.', 'woocommerce'); ?>">[?]</span></th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="10">
<a href="#" class="button plus insert"><?php _e( 'Insert row', 'woocommerce' ); ?></a>
<a href="#" class="button minus remove"><?php _e( 'Remove selected row(s)', 'woocommerce' ); ?></a>
<a href="#" download="tax_rates.csv" class="button export"><?php _e( 'Export CSV', 'woocommerce' ); ?></a>
<a href="<?php echo admin_url( 'admin.php?import=woocommerce_tax_rate_csv' ); ?>" class="button import"><?php _e( 'Import CSV', 'woocommerce' ); ?></a>
</th>
</tr>
</tfoot>
<tbody id="rates">
<?php
$rates = $wpdb->get_results( $wpdb->prepare(
"SELECT * FROM {$wpdb->prefix}woocommerce_tax_rates
WHERE tax_rate_class = %s
ORDER BY tax_rate_order
" , $current_class ) );
foreach ( $rates as $rate ) {
?>
<tr>
<td class="sort"><input type="hidden" class="remove_tax_rate" name="remove_tax_rate[<?php echo $rate->tax_rate_id ?>]" value="0" /></td>
<td class="country" width="8%">
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_country ) ?>" placeholder="*" name="tax_rate_country[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="state" width="8%">
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_state ) ?>" placeholder="*" name="tax_rate_state[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="postcode">
<input type="text" value="<?php
$locations = $wpdb->get_col( $wpdb->prepare( "SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='postcode' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id ) );
echo esc_attr( implode( '; ', $locations ) );
?>" placeholder="*" data-name="tax_rate_postcode[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="city">
<input type="text" value="<?php
$locations = $wpdb->get_col( $wpdb->prepare( "SELECT location_code FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE location_type='city' AND tax_rate_id = %d ORDER BY location_code", $rate->tax_rate_id ) );
echo esc_attr( implode( '; ', $locations ) );
?>" placeholder="*" data-name="tax_rate_city[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="rate" width="8%">
<input type="number" step="any" min="0" value="<?php echo esc_attr( $rate->tax_rate ) ?>" placeholder="0" name="tax_rate[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="name" width="8%">
<input type="text" value="<?php echo esc_attr( $rate->tax_rate_name ) ?>" name="tax_rate_name[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="priority" width="8%">
<input type="number" step="1" min="1" value="<?php echo esc_attr( $rate->tax_rate_priority ) ?>" name="tax_rate_priority[<?php echo $rate->tax_rate_id ?>]" />
</td>
<td class="compound" width="8%">
<input type="checkbox" class="checkbox" name="tax_rate_compound[<?php echo $rate->tax_rate_id ?>]" <?php checked( $rate->tax_rate_compound, '1' ); ?> />
</td>
<td class="apply_to_shipping" width="8%">
<input type="checkbox" class="checkbox" name="tax_rate_shipping[<?php echo $rate->tax_rate_id ?>]" <?php checked($rate->tax_rate_shipping, '1' ); ?> />
</td>
</tr>
<?php
}
?>
</tbody>
</table>
<script type="text/javascript">
jQuery( function() {
jQuery('.wc_tax_rates tbody').sortable({
items:'tr',
cursor:'move',
axis:'y',
scrollSensitivity:40,
forcePlaceholderSize: true,
helper: 'clone',
opacity: 0.65,
placeholder: 'wc-metabox-sortable-placeholder',
start:function(event,ui){
ui.item.css('background-color','#f6f6f6');
},
stop:function(event,ui){
ui.item.removeAttr('style');
}
});
jQuery('.wc_tax_rates .remove').click(function() {
var $tbody = jQuery('.wc_tax_rates').find('tbody');
if ( $tbody.find('tr.current').size() > 0 ) {
$current = $tbody.find('tr.current');
$current.find('input').val('');
$current.find('input.remove_tax_rate').val('1');
$current.each(function(){
if ( jQuery(this).is('.new') )
jQuery(this).remove();
else
jQuery(this).hide();
});
} else {
alert('<?php _e( 'No row(s) selected', 'woocommerce' ); ?>');
}
return false;
});
var shifted = false;
jQuery(document).bind('keyup keydown', function(e){shifted = e.shiftKey} );
jQuery('.wc_tax_rates input').live( 'click focus', function( e ) {
if ( ! shifted ) {
jQuery('.wc_tax_rates tr').removeClass('current');
}
jQuery(this).closest('tr').addClass('current');
});
jQuery('.wc_tax_rates .export').click(function() {
var csv_data = "data:application/csv;charset=utf-8,<?php _e( 'Country Code', 'woocommerce' ); ?>,<?php _e( 'State Code', 'woocommerce' ); ?>,<?php _e( 'ZIP/Postcode', 'woocommerce' ); ?>,<?php _e( 'City', 'woocommerce' ); ?>,<?php _e( 'Rate %', 'woocommerce' ); ?>,<?php _e( 'Tax Name', 'woocommerce' ); ?>,<?php _e( 'Priority', 'woocommerce' ); ?>,<?php _e( 'Compound', 'woocommerce' ); ?>,<?php _e( 'Shipping', 'woocommerce' ); ?>,<?php _e( 'Tax Class', 'woocommerce' ); ?>\n";
jQuery('#rates tr:visible').each(function() {
var row = '';
jQuery(this).find('td:not(.sort) input').each(function() {
if ( jQuery(this).is('.checkbox') ) {
if ( jQuery(this).is(':checked') ) {
val = 1;
} else {
val = 0;
}
} else {
var val = jQuery(this).val();
if ( ! val )
val = jQuery(this).attr('placeholder');
}
row = row + val + ',';
});
row = row + '<?php echo $current_class; ?>';
//row.substring( 0, row.length - 1 );
csv_data = csv_data + row + "\n";
});
jQuery(this).attr( 'href', encodeURI( csv_data ) );
return true;
});
jQuery('.wc_tax_rates .insert').click(function() {
var $tbody = jQuery('.wc_tax_rates').find('tbody');
var size = $tbody.find('tr').size();
var code = '<tr class="new">\
<td class="sort">&nbsp;</td>\
<td class="country" width="8%">\
<input type="text" placeholder="*" name="tax_rate_country[new][' + size + ']" />\
</td>\
<td class="state" width="8%">\
<input type="text" placeholder="*" name="tax_rate_state[new][' + size + ']" />\
</td>\
<td class="postcode">\
<input type="text" placeholder="*" name="tax_rate_postcode[new][' + size + ']" />\
</td>\
<td class="city">\
<input type="text" placeholder="*" name="tax_rate_city[new][' + size + ']" />\
</td>\
<td class="rate" width="8%">\
<input type="number" step="any" min="0" placeholder="0" name="tax_rate[new][' + size + ']" />\
</td>\
<td class="name" width="8%">\
<input type="text" name="tax_rate_name[new][' + size + ']" />\
</td>\
<td class="priority" width="8%">\
<input type="number" step="1" min="1" value="1" name="tax_rate_priority[new][' + size + ']" />\
</td>\
<td class="compound" width="8%">\
<input type="checkbox" class="checkbox" name="tax_rate_compound[new][' + size + ']" />\
</td>\
<td class="apply_to_shipping" width="8%">\
<input type="checkbox" class="checkbox" name="tax_rate_shipping[new][' + size + ']" checked="checked" />\
</td>\
</tr>';
if ( $tbody.find('tr.current').size() > 0 ) {
$tbody.find('tr.current').after( code );
} else {
$tbody.append( code );
}
return false;
});
jQuery('.wc_tax_rates td.postcode, .wc_tax_rates td.city').find('input').change(function() {
jQuery(this).attr( 'name', jQuery(this).attr( 'data-name' ) );
});
});
</script>
<?php
}
/**
* woocommerce_tax_rates_setting_save function.
*
* @access public
* @return void
*/
function woocommerce_tax_rates_setting_save() {
global $wpdb, $current_section;
// Get class
$tax_classes = array_filter( array_map( 'trim', explode( "\n", get_option('woocommerce_tax_classes' ) ) ) );
$current_class = '';
foreach( $tax_classes as $class )
if ( sanitize_title( $class ) == $current_section )
$current_class = $class;
// Get POST data
$tax_rate_country = isset( $_POST['tax_rate_country'] ) ? $_POST['tax_rate_country'] : array();
$tax_rate_state = isset( $_POST['tax_rate_state'] ) ? $_POST['tax_rate_state'] : array();
$tax_rate_postcode = isset( $_POST['tax_rate_postcode'] ) ? $_POST['tax_rate_postcode'] : array();
$tax_rate_city = isset( $_POST['tax_rate_city'] ) ? $_POST['tax_rate_city'] : array();
$tax_rate = isset( $_POST['tax_rate'] ) ? $_POST['tax_rate'] : array();
$tax_rate_name = isset( $_POST['tax_rate_name'] ) ? $_POST['tax_rate_name'] : array();
$tax_rate_priority = isset( $_POST['tax_rate_priority'] ) ? $_POST['tax_rate_priority'] : array();
$tax_rate_compound = isset( $_POST['tax_rate_compound'] ) ? $_POST['tax_rate_compound'] : array();
$tax_rate_shipping = isset( $_POST['tax_rate_shipping'] ) ? $_POST['tax_rate_shipping'] : array();
$i = 0;
// Loop posted fields
foreach ( $tax_rate_country as $key => $value ) {
// new keys are inserted...
if ( $key == 'new' ) {
foreach ( $value as $new_key => $new_value ) {
// Sanitize + format
$country = strtoupper( woocommerce_clean( $tax_rate_country[ $key ][ $new_key ] ) );
$state = strtoupper( woocommerce_clean( $tax_rate_state[ $key ][ $new_key ] ) );
$postcode = woocommerce_clean( $tax_rate_postcode[ $key ][ $new_key ] );
$city = woocommerce_clean( $tax_rate_city[ $key ][ $new_key ] );
$rate = number_format( woocommerce_clean( $tax_rate[ $key ][ $new_key ] ), 4, '.', '' );
$name = woocommerce_clean( $tax_rate_name[ $key ][ $new_key ] );
$priority = absint( woocommerce_clean( $tax_rate_priority[ $key ][ $new_key ] ) );
$compound = isset( $tax_rate_compound[ $key ][ $new_key ] ) ? 1 : 0;
$shipping = isset( $tax_rate_shipping[ $key ][ $new_key ] ) ? 1 : 0;
if ( ! $name )
$name = __( 'Tax', 'woocommerce' );
if ( $country == '*' )
$country = '';
if ( $state == '*' )
$state = '';
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rates",
array(
'tax_rate_country' => $country,
'tax_rate_state' => $state,
'tax_rate' => $rate,
'tax_rate_name' => $name,
'tax_rate_priority' => $priority,
'tax_rate_compound' => $compound,
'tax_rate_shipping' => $shipping,
'tax_rate_order' => $i,
'tax_rate_class' => $current_class
)
);
$tax_rate_id = $wpdb->insert_id;
if ( ! empty( $postcode ) ) {
$postcodes = explode( ';', $postcode );
$postcodes = array_map( 'strtoupper', array_map( 'woocommerce_clean', $postcodes ) );
foreach( $postcodes as $postcode ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $postcode,
'tax_rate_id' => $tax_rate_id,
'location_type' => 'postcode',
)
);
}
}
if ( ! empty( $city ) ) {
$cities = explode( ';', $city );
$cities = array_map( 'strtoupper', array_map( 'woocommerce_clean', $cities ) );
foreach( $cities as $city ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $city,
'tax_rate_id' => $tax_rate_id,
'location_type' => 'city',
)
);
}
}
$i++;
}
// ...whereas the others are updated
} else {
$tax_rate_id = absint( $key );
if ( $_POST['remove_tax_rate'][ $key ] == 1 ) {
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d;", $tax_rate_id ) );
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rates WHERE tax_rate_id = %d;", $tax_rate_id ) );
continue;
}
// Sanitize + format
$country = strtoupper( woocommerce_clean( $tax_rate_country[ $key ] ) );
$state = strtoupper( woocommerce_clean( $tax_rate_state[ $key ] ) );
$rate = number_format( woocommerce_clean( $tax_rate[ $key ] ), 4, '.', '' );
$name = woocommerce_clean( $tax_rate_name[ $key ] );
$priority = absint( woocommerce_clean( $tax_rate_priority[ $key ] ) );
$compound = isset( $tax_rate_compound[ $key ] ) ? 1 : 0;
$shipping = isset( $tax_rate_shipping[ $key ] ) ? 1 : 0;
if ( ! $name )
$name = __( 'Tax', 'woocommerce' );
if ( $country == '*' )
$country = '';
if ( $state == '*' )
$state = '';
$wpdb->update(
$wpdb->prefix . "woocommerce_tax_rates",
array(
'tax_rate_country' => $country,
'tax_rate_state' => $state,
'tax_rate' => $rate,
'tax_rate_name' => $name,
'tax_rate_priority' => $priority,
'tax_rate_compound' => $compound,
'tax_rate_shipping' => $shipping,
'tax_rate_order' => $i,
'tax_rate_class' => $current_class
),
array(
'tax_rate_id' => $tax_rate_id
)
);
if ( isset( $tax_rate_postcode[ $key ] ) ) {
// Delete old
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'postcode';", $tax_rate_id ) );
// Add changed
$postcode = woocommerce_clean( $tax_rate_postcode[ $key ] );
$postcodes = explode( ';', $postcode );
$postcodes = array_map( 'strtoupper', array_map( 'woocommerce_clean', $postcodes ) );
$postcode_query = array();
foreach( $postcodes as $postcode )
if ( strstr( $postcode, '-' ) ) {
$postcode_parts = explode( '-', $postcode );
if ( is_numeric( $postcode_parts[0] ) && is_numeric( $postcode_parts[1] ) && $postcode_parts[1] > $postcode_parts[0] ) {
for ( $i = $postcode_parts[0]; $i <= $postcode_parts[1]; $i ++ ) {
$postcode_query[] = "( '$i', $tax_rate_id, 'postcode' )";
}
}
} else {
$postcode_query[] = "( '$postcode', $tax_rate_id, 'postcode' )";
}
$wpdb->query( "INSERT INTO {$wpdb->prefix}woocommerce_tax_rate_locations ( location_code, tax_rate_id, location_type ) VALUES " . implode( ',', $postcode_query ) );
}
if ( isset( $tax_rate_city[ $key ] ) ) {
// Delete old
$wpdb->query( $wpdb->prepare( "DELETE FROM {$wpdb->prefix}woocommerce_tax_rate_locations WHERE tax_rate_id = %d AND location_type = 'city';", $tax_rate_id ) );
// Add changed
$city = woocommerce_clean( $tax_rate_city[ $key ] );
$cities = explode( ';', $city );
$cities = array_map( 'strtoupper', array_map( 'woocommerce_clean', $cities ) );
foreach( $cities as $city ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_tax_rate_locations",
array(
'location_code' => $city,
'tax_rate_id' => $tax_rate_id,
'location_type' => 'city',
)
);
}
}
$i++;
}
}
}

View File

@ -1,155 +1,276 @@
<?php <?php
/** /**
* Functions used for the attributes section in WordPress Admin * Functions used for the attributes section in WordPress Admin
* *
* The attributes section lets users add custom attributes to assign to products - they can also be used in the layered nav widget. * The attributes section lets users add custom attributes to assign to products - they can also be used in the layered nav widget.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Attributes admin panel * Attributes admin panel
* *
* Shows the created attributes and lets you add new ones. * Shows the created attributes and lets you add new ones.
* The added attributes are stored in the database and can be used for layered navigation. * The added attributes are stored in the database and can be used for layered navigation.
*
* @access public
* @return void
*/ */
function woocommerce_attributes() { function woocommerce_attributes() {
global $wpdb, $woocommerce; global $wpdb, $woocommerce;
if (isset($_POST['add_new_attribute']) && $_POST['add_new_attribute']) : if ( ! empty( $_POST['add_new_attribute'] ) ) {
check_admin_referer( 'woocommerce-add-new_attribute' ); check_admin_referer( 'woocommerce-add-new_attribute' );
$attribute_name = (string) sanitize_title($_POST['attribute_name']);
$attribute_type = (string) $_POST['attribute_type']; $attribute_name = sanitize_title( esc_attr( $_POST['attribute_name'] ) );
$attribute_label = (string) $_POST['attribute_label']; $attribute_type = esc_attr( $_POST['attribute_type'] );
$attribute_label = esc_attr( $_POST['attribute_label'] );
if ($attribute_name && strlen($attribute_name)<30 && $attribute_type && !taxonomy_exists( $woocommerce->attribute_taxonomy_name($attribute_name) )) : $attribute_orderby = esc_attr( $_POST['attribute_orderby'] );
$wpdb->insert( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_name' => $attribute_name, 'attribute_label' => $attribute_label, 'attribute_type' => $attribute_type ), array( '%s', '%s' ) ); if ( ! $attribute_label )
$attribute_label = ucwords( $attribute_name );
wp_safe_redirect( get_admin_url() . 'admin.php?page=woocommerce_attributes' );
if ( ! $attribute_name )
$attribute_name = sanitize_title( $attribute_label );
if ( $attribute_name && strlen( $attribute_name ) < 30 && $attribute_type && ! taxonomy_exists( $woocommerce->attribute_taxonomy_name( $attribute_name ) ) ) {
$wpdb->insert(
$wpdb->prefix . "woocommerce_attribute_taxonomies",
array(
'attribute_name' => $attribute_name,
'attribute_label' => $attribute_label,
'attribute_type' => $attribute_type,
'attribute_orderby' => $attribute_orderby
)
);
wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
exit; exit;
}
endif;
} elseif ( ! empty( $_POST['save_attribute'] ) && ! empty( $_GET['edit'] ) ) {
elseif (isset($_POST['save_attribute']) && $_POST['save_attribute'] && isset($_GET['edit'])) :
$edit = absint( $_GET['edit'] );
$edit = absint($_GET['edit']);
check_admin_referer( 'woocommerce-save-attribute_' . $edit ); check_admin_referer( 'woocommerce-save-attribute_' . $edit );
if ($edit>0) :
$attribute_name = sanitize_title( esc_attr( $_POST['attribute_name'] ) );
$attribute_type = $_POST['attribute_type']; $attribute_type = esc_attr( $_POST['attribute_type'] );
$attribute_label = (string) $_POST['attribute_label']; $attribute_label = esc_attr( $_POST['attribute_label'] );
$attribute_orderby = esc_attr( $_POST['attribute_orderby'] );
$wpdb->update( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_type' => $attribute_type, 'attribute_label' => $attribute_label ), array( 'attribute_id' => $_GET['edit'] ), array( '%s', '%s' ) );
if ( ! $attribute_label )
endif; $attribute_label = ucwords( $attribute_name );
wp_safe_redirect( get_admin_url() . 'admin.php?page=woocommerce_attributes' ); if ( ! $attribute_name )
exit; $attribute_name = sanitize_title( $attribute_label );
elseif (isset($_GET['delete'])) : $old_attribute_name = sanitize_title( $wpdb->get_var( "SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $edit" ) );
check_admin_referer( 'woocommerce-delete-attribute_' . absint( $_GET['delete'] ) );
$delete = absint($_GET['delete']); if ( $old_attribute_name != $attribute_name && taxonomy_exists( $woocommerce->attribute_taxonomy_name( $attribute_name ) ) ) {
if ($delete>0) : echo '<div id="woocommerce_errors" class="error fade"><p>' . __( 'Taxonomy exists - please change the slug', 'woocommerce' ) . '</p></div>';
$att_name = $wpdb->get_var("SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$delete'"); } elseif ( $attribute_name && strlen( $attribute_name ) < 30 && $attribute_type ) {
if ($att_name && $wpdb->query("DELETE FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$delete'")) : $wpdb->update(
$wpdb->prefix . "woocommerce_attribute_taxonomies",
$taxonomy = $woocommerce->attribute_taxonomy_name($att_name); array(
'attribute_name' => $attribute_name,
if (taxonomy_exists($taxonomy)) : 'attribute_label' => $attribute_label,
'attribute_type' => $attribute_type,
$terms = get_terms($taxonomy, 'orderby=name&hide_empty=0'); 'attribute_orderby' => $attribute_orderby
foreach ($terms as $term) { ),
wp_delete_term( $term->term_id, $taxonomy ); array(
} 'attribute_id' => $edit
)
endif; );
wp_safe_redirect( get_admin_url() . 'admin.php?page=woocommerce_attributes' ); if ( $old_attribute_name != $attribute_name && ! empty( $old_attribute_name ) ) {
exit;
// Update taxonomies in the wp term taxonomy table
endif; $wpdb->update(
$wpdb->term_taxonomy,
endif; array(
'taxonomy' => $woocommerce->attribute_taxonomy_name( $attribute_name )
endif; ),
array(
if (isset($_GET['edit']) && $_GET['edit'] > 0) : 'taxonomy' => $woocommerce->attribute_taxonomy_name( $old_attribute_name )
)
);
// Update taxonomy ordering term meta
$wpdb->update(
$wpdb->prefix . "woocommerce_termmeta",
array(
'meta_key' => 'order_pa_' . sanitize_title( $attribute_name )
),
array(
'meta_key' => 'order_pa_' . sanitize_title( $old_attribute_name )
)
);
// Update product attributes which use this taxonomy
$old_attribute_name_length = strlen($old_attribute_name) + 3;
$attribute_name_length = strlen($attribute_name) + 3;
$wpdb->query( "
UPDATE {$wpdb->postmeta}
SET meta_value = replace( meta_value, 's:{$old_attribute_name_length}:\"pa_{$old_attribute_name}\"', 's:{$attribute_name_length}:\"pa_{$attribute_name}\"' )
WHERE meta_key = '_product_attributes'"
);
// Update variations which use this taxonomy
$wpdb->update(
$wpdb->postmeta,
array(
'meta_key' => 'attribute_pa_' . sanitize_title( $attribute_name )
),
array(
'meta_key' => 'attribute_pa_' . sanitize_title( $old_attribute_name )
)
);
}
wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
exit;
}
} elseif ( ! empty( $_GET['delete'] ) ) {
$delete = absint( $_GET['delete'] );
check_admin_referer( 'woocommerce-delete-attribute_' . $delete );
$att_name = $wpdb->get_var( "SELECT attribute_name FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $delete" );
if ( $att_name && $wpdb->query( "DELETE FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = $delete" ) ) {
$taxonomy = $woocommerce->attribute_taxonomy_name( $att_name );
if ( taxonomy_exists( $taxonomy ) ) {
$terms = get_terms( $taxonomy, 'orderby=name&hide_empty=0');
foreach ( $terms as $term )
wp_delete_term( $term->term_id, $taxonomy );
}
wp_safe_redirect( get_admin_url() . 'edit.php?post_type=product&page=woocommerce_attributes' );
exit;
}
}
if ( ! empty( $_GET['edit'] ) && $_GET['edit'] > 0 )
woocommerce_edit_attribute(); woocommerce_edit_attribute();
else : else
woocommerce_add_attribute(); woocommerce_add_attribute();
endif;
} }
/** /**
* Edit Attribute admin panel * Edit Attribute admin panel
* *
* Shows the interface for changing an attributes type between select and text * Shows the interface for changing an attributes type between select and text
*
* @access public
* @return void
*/ */
function woocommerce_edit_attribute() { function woocommerce_edit_attribute() {
global $wpdb; global $wpdb;
$edit = absint($_GET['edit']); $edit = absint( $_GET['edit'] );
$att_type = $wpdb->get_var("SELECT attribute_type FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'"); $attribute_to_edit = $wpdb->get_row("SELECT * FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'");
$att_label = $wpdb->get_var("SELECT attribute_label FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_id = '$edit'");
$att_type = $attribute_to_edit->attribute_type;
$att_label = $attribute_to_edit->attribute_label;
$att_name = $attribute_to_edit->attribute_name;
$att_orderby = $attribute_to_edit->attribute_orderby;
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<div class="icon32 icon32-attributes" id="icon-woocommerce"><br/></div> <div class="icon32 icon32-attributes" id="icon-woocommerce"><br/></div>
<h2><?php _e('Attributes', 'woothemes') ?></h2> <h2><?php _e( 'Edit Attribute', 'woocommerce' ) ?></h2>
<br class="clear" /> <form action="admin.php?page=woocommerce_attributes&amp;edit=<?php echo absint( $edit ); ?>" method="post">
<div id="col-container"> <table class="form-table">
<div id="col-left"> <tbody>
<div class="col-wrap"> <tr class="form-field form-required">
<div class="form-wrap"> <th scope="row" valign="top">
<h3><?php _e('Edit Attribute', 'woothemes') ?></h3> <label for="attribute_label"><?php _e( 'Name', 'woocommerce' ); ?></label>
<p><?php _e('Attribute taxonomy names cannot be changed; you may only change an attributes type.', 'woothemes') ?></p> </th>
<form action="admin.php?page=woocommerce_attributes&amp;edit=<?php echo absint( $edit ); ?>" method="post"> <td>
<input name="attribute_label" id="attribute_label" type="text" value="<?php echo esc_attr( $att_label ); ?>" />
<div class="form-field"> <p class="description"><?php _e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p>
<label for="attribute_label"><?php _e('Attribute Label', 'woothemes'); ?></label> </td>
<input name="attribute_label" id="attribute_label" type="text" value="<?php echo esc_attr( $att_label ); ?>" /> </tr>
<p class="description"><?php _e('Label for the attribute (shown on the front-end).', 'woothemes'); ?></p> <tr class="form-field form-required">
</div> <th scope="row" valign="top">
<div class="form-field"> <label for="attribute_name"><?php _e( 'Slug', 'woocommerce' ); ?></label>
<label for="attribute_type"><?php _e('Attribute type', 'woothemes'); ?></label> </th>
<select name="attribute_type" id="attribute_type"> <td>
<option value="select" <?php selected($att_type, 'select'); ?>><?php _e('Select', 'woothemes') ?></option> <input name="attribute_name" id="attribute_name" type="text" value="<?php echo esc_attr( $att_name ); ?>" maxlength="28" />
<option value="text" <?php selected($att_type, 'text'); ?>><?php _e('Text', 'woothemes') ?></option> <p class="description"><?php _e( 'Unique slug/reference for the attribute; must be shorter than 28 characters.', 'woocommerce' ); ?></p>
</select> </td>
</div> </tr>
<tr class="form-field form-required">
<p class="submit"><input type="submit" name="save_attribute" id="submit" class="button" value="<?php _e('Save Attribute', 'woothemes'); ?>"></p> <th scope="row" valign="top">
<?php wp_nonce_field( 'woocommerce-save-attribute_' . $edit ); ?> <label for="attribute_type"><?php _e( 'Type', 'woocommerce' ); ?></label>
</form> </th>
</div> <td>
</div> <select name="attribute_type" id="attribute_type">
</div> <option value="select" <?php selected( $att_type, 'select' ); ?>><?php _e( 'Select', 'woocommerce' ) ?></option>
</div> <option value="text" <?php selected( $att_type, 'text' ); ?>><?php _e( 'Text', 'woocommerce' ) ?></option>
</select>
<p class="description"><?php _e( 'Determines how you select attributes for products. <strong>Text</strong> allows manual entry via the product page, whereas <strong>select</strong> attribute terms can be defined from this section. If you plan on using an attribute for variations use <strong>select</strong>.', 'woocommerce' ); ?></p>
</td>
</tr>
<tr class="form-field form-required">
<th scope="row" valign="top">
<label for="attribute_orderby"><?php _e( 'Default sort order', 'woocommerce' ); ?></label>
</th>
<td>
<select name="attribute_orderby" id="attribute_orderby">
<option value="menu_order" <?php selected( $att_orderby, 'menu_order' ); ?>><?php _e( 'Custom ordering', 'woocommerce' ) ?></option>
<option value="name" <?php selected( $att_orderby, 'name' ); ?>><?php _e( 'Name', 'woocommerce' ) ?></option>
<option value="id" <?php selected( $att_orderby, 'id' ); ?>><?php _e( 'Term ID', 'woocommerce' ) ?></option>
</select>
<p class="description"><?php _e( 'Determines the sort order on the frontend for this attribute. If using custom ordering, you can drag and drop the terms in this attribute', 'woocommerce' ); ?></p>
</td>
</tr>
</tbody>
</table>
<p class="submit"><input type="submit" name="save_attribute" id="submit" class="button-primary" value="<?php _e( 'Update', 'woocommerce' ); ?>"></p>
<?php wp_nonce_field( 'woocommerce-save-attribute_' . $edit ); ?>
</form>
</div> </div>
<?php <?php
} }
/** /**
* Add Attribute admin panel * Add Attribute admin panel
* *
* Shows the interface for adding new attributes * Shows the interface for adding new attributes
*
* @access public
* @return void
*/ */
function woocommerce_add_attribute() { function woocommerce_add_attribute() {
global $woocommerce; global $woocommerce;
?> ?>
<div class="wrap woocommerce"> <div class="wrap woocommerce">
<div class="icon32 icon32-attributes" id="icon-woocommerce"><br/></div> <div class="icon32 icon32-attributes" id="icon-woocommerce"><br/></div>
<h2><?php _e('Attributes', 'woothemes') ?></h2> <h2><?php _e( 'Attributes', 'woocommerce' ) ?></h2>
<br class="clear" /> <br class="clear" />
<div id="col-container"> <div id="col-container">
<div id="col-right"> <div id="col-right">
@ -157,10 +278,11 @@ function woocommerce_add_attribute() {
<table class="widefat fixed" style="width:100%"> <table class="widefat fixed" style="width:100%">
<thead> <thead>
<tr> <tr>
<th scope="col"><?php _e('Name', 'woothemes') ?></th> <th scope="col"><?php _e( 'Name', 'woocommerce' ) ?></th>
<th scope="col"><?php _e('Label', 'woothemes') ?></th> <th scope="col"><?php _e( 'Slug', 'woocommerce' ) ?></th>
<th scope="col"><?php _e('Type', 'woothemes') ?></th> <th scope="col"><?php _e( 'Type', 'woocommerce' ) ?></th>
<th scope="col" colspan="2"><?php _e('Terms', 'woothemes') ?></th> <th scope="col"><?php _e( 'Order by', 'woocommerce' ) ?></th>
<th scope="col" colspan="2"><?php _e( 'Terms', 'woocommerce' ) ?></th>
</tr> </tr>
</thead> </thead>
<tbody> <tbody>
@ -168,17 +290,28 @@ function woocommerce_add_attribute() {
$attribute_taxonomies = $woocommerce->get_attribute_taxonomies(); $attribute_taxonomies = $woocommerce->get_attribute_taxonomies();
if ( $attribute_taxonomies ) : if ( $attribute_taxonomies ) :
foreach ($attribute_taxonomies as $tax) : foreach ($attribute_taxonomies as $tax) :
$att_title = $tax->attribute_name;
if ( isset( $tax->attribute_label ) ) { $att_title = $tax->attribute_label; }
?><tr> ?><tr>
<td><a href="edit-tags.php?taxonomy=<?php echo $woocommerce->attribute_taxonomy_name($tax->attribute_name); ?>&amp;post_type=product"><?php echo $tax->attribute_name; ?></a> <td><a href="edit-tags.php?taxonomy=<?php echo esc_html($woocommerce->attribute_taxonomy_name($tax->attribute_name)); ?>&amp;post_type=product"><?php echo esc_html( $tax->attribute_label ); ?></a>
<div class="row-actions"><span class="edit"><a href="<?php echo esc_url( add_query_arg('edit', $tax->attribute_id, 'admin.php?page=woocommerce_attributes') ); ?>"><?php _e('Edit', 'woothemes'); ?></a> | </span><span class="delete"><a class="delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg('delete', $tax->attribute_id, 'admin.php?page=woocommerce_attributes'), 'woocommerce-delete-attribute_' . $tax->attribute_id ) ); ?>"><?php _e('Delete', 'woothemes'); ?></a></span></div> <div class="row-actions"><span class="edit"><a href="<?php echo esc_url( add_query_arg('edit', $tax->attribute_id, 'admin.php?page=woocommerce_attributes') ); ?>"><?php _e( 'Edit', 'woocommerce' ); ?></a> | </span><span class="delete"><a class="delete" href="<?php echo esc_url( wp_nonce_url( add_query_arg('delete', $tax->attribute_id, 'admin.php?page=woocommerce_attributes'), 'woocommerce-delete-attribute_' . $tax->attribute_id ) ); ?>"><?php _e( 'Delete', 'woocommerce' ); ?></a></span></div>
</td> </td>
<td><?php echo esc_html( ucwords( $att_title ) ); ?></td> <td><?php echo esc_html( $tax->attribute_name ); ?></td>
<td><?php echo esc_html( ucwords( $tax->attribute_type ) ); ?></td> <td><?php echo esc_html( ucwords( $tax->attribute_type ) ); ?></td>
<td><?php <td><?php
switch ( $tax->attribute_orderby ) {
case 'name' :
_e( 'Name', 'woocommerce' );
break;
case 'id' :
_e( 'Term ID', 'woocommerce' );
break;
default:
_e( 'Custom ordering', 'woocommerce' );
break;
}
?></td>
<td><?php
if (taxonomy_exists($woocommerce->attribute_taxonomy_name($tax->attribute_name))) : if (taxonomy_exists($woocommerce->attribute_taxonomy_name($tax->attribute_name))) :
$terms_array = array(); $terms_array = array();
$terms = get_terms( $woocommerce->attribute_taxonomy_name($tax->attribute_name), 'orderby=name&hide_empty=0' ); $terms = get_terms( $woocommerce->attribute_taxonomy_name($tax->attribute_name), 'orderby=name&hide_empty=0' );
@ -194,11 +327,11 @@ function woocommerce_add_attribute() {
echo '<span class="na">&ndash;</span>'; echo '<span class="na">&ndash;</span>';
endif; endif;
?></td> ?></td>
<td><a href="edit-tags.php?taxonomy=<?php echo $woocommerce->attribute_taxonomy_name($tax->attribute_name); ?>&amp;post_type=product" class="button alignright"><?php _e('Configure&nbsp;terms', 'woothemes'); ?></a></td> <td><a href="edit-tags.php?taxonomy=<?php echo esc_html($woocommerce->attribute_taxonomy_name($tax->attribute_name)); ?>&amp;post_type=product" class="button alignright"><?php _e( 'Configure&nbsp;terms', 'woocommerce' ); ?></a></td>
</tr><?php </tr><?php
endforeach; endforeach;
else : else :
?><tr><td colspan="5"><?php _e('No attributes currently exist.', 'woothemes') ?></td></tr><?php ?><tr><td colspan="6"><?php _e( 'No attributes currently exist.', 'woocommerce' ) ?></td></tr><?php
endif; endif;
?> ?>
</tbody> </tbody>
@ -208,31 +341,41 @@ function woocommerce_add_attribute() {
<div id="col-left"> <div id="col-left">
<div class="col-wrap"> <div class="col-wrap">
<div class="form-wrap"> <div class="form-wrap">
<h3><?php _e('Add New Attribute', 'woothemes') ?></h3> <h3><?php _e( 'Add New Attribute', 'woocommerce' ) ?></h3>
<p><?php _e('Attributes let you define extra product data, such as size or colour. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woothemes') ?></p> <p><?php _e( 'Attributes let you define extra product data, such as size or colour. You can use these attributes in the shop sidebar using the "layered nav" widgets. Please note: you cannot rename an attribute later on.', 'woocommerce' ) ?></p>
<form action="admin.php?page=woocommerce_attributes" method="post"> <form action="admin.php?page=woocommerce_attributes" method="post">
<div class="form-field"> <div class="form-field">
<label for="attribute_label"><?php _e('Attribute label', 'woothemes'); ?></label> <label for="attribute_label"><?php _e( 'Name', 'woocommerce' ); ?></label>
<input name="attribute_label" id="attribute_label" type="text" value="" /> <input name="attribute_label" id="attribute_label" type="text" value="" />
<p class="description"><?php _e('Name for the attribute (shown on the front-end).', 'woothemes'); ?></p> <p class="description"><?php _e( 'Name for the attribute (shown on the front-end).', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_name"><?php _e('Attribute slug', 'woothemes'); ?></label> <label for="attribute_name"><?php _e( 'Slug', 'woocommerce' ); ?></label>
<input name="attribute_name" id="attribute_name" type="text" value="" maxlength="29" /> <input name="attribute_name" id="attribute_name" type="text" value="" maxlength="28" />
<p class="description"><?php _e('Unique slug/reference for the attribute; must be shorter than 28 characters.', 'woothemes'); ?></p> <p class="description"><?php _e( 'Unique slug/reference for the attribute; must be shorter than 28 characters.', 'woocommerce' ); ?></p>
</div> </div>
<div class="form-field"> <div class="form-field">
<label for="attribute_type"><?php _e('Attribute type', 'woothemes'); ?></label> <label for="attribute_type"><?php _e( 'Type', 'woocommerce' ); ?></label>
<select name="attribute_type" id="attribute_type"> <select name="attribute_type" id="attribute_type">
<option value="select"><?php _e('Select', 'woothemes') ?></option> <option value="select"><?php _e( 'Select', 'woocommerce' ) ?></option>
<option value="text"><?php _e('Text', 'woothemes') ?></option> <option value="text"><?php _e( 'Text', 'woocommerce' ) ?></option>
</select> </select>
<p class="description"><?php _e('Determines how you select attributes for products. <strong>Text</strong> allows manual entry via the product page, whereas <strong>select</strong> attribute terms can be defined from this section. If you plan on using an attribute for variations use <strong>select</strong>.', 'woothemes'); ?></p> <p class="description"><?php _e( 'Determines how you select attributes for products. <strong>Text</strong> allows manual entry via the product page, whereas <strong>select</strong> attribute terms can be defined from this section. If you plan on using an attribute for variations use <strong>select</strong>.', 'woocommerce' ); ?></p>
</div> </div>
<p class="submit"><input type="submit" name="add_new_attribute" id="submit" class="button" value="<?php _e('Add Attribute', 'woothemes'); ?>"></p> <div class="form-field">
<label for="attribute_orderby"><?php _e( 'Default sort order', 'woocommerce' ); ?></label>
<select name="attribute_orderby" id="attribute_orderby">
<option value="menu_order"><?php _e( 'Custom ordering', 'woocommerce' ) ?></option>
<option value="name"><?php _e( 'Name', 'woocommerce' ) ?></option>
<option value="id"><?php _e( 'Term ID', 'woocommerce' ) ?></option>
</select>
<p class="description"><?php _e( 'Determines the sort order on the frontend for this attribute. If using custom ordering, you can drag and drop the terms in this attribute', 'woocommerce' ); ?></p>
</div>
<p class="submit"><input type="submit" name="add_new_attribute" id="submit" class="button" value="<?php _e( 'Add Attribute', 'woocommerce' ); ?>"></p>
<?php wp_nonce_field( 'woocommerce-add-new_attribute' ); ?> <?php wp_nonce_field( 'woocommerce-add-new_attribute' ); ?>
</form> </form>
</div> </div>
@ -241,13 +384,13 @@ function woocommerce_add_attribute() {
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
/* <![CDATA[ */ /* <![CDATA[ */
jQuery('a.delete').click(function(){ jQuery('a.delete').click(function(){
var answer = confirm ("<?php _e('Are you sure you want to delete this attribute?', 'woothemes'); ?>"); var answer = confirm ("<?php _e( 'Are you sure you want to delete this attribute?', 'woocommerce' ); ?>");
if (answer) return true; if (answer) return true;
return false; return false;
}); });
/* ]]> */ /* ]]> */
</script> </script>
</div> </div>

View File

@ -0,0 +1,89 @@
<?php
/**
* Functions used for the showing help/links to WooCommerce resources in admin
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Help Tab Content
*
* Shows some text about WooCommerce and links to docs.
*
* @access public
* @return void
*/
function woocommerce_admin_help_tab_content() {
$screen = get_current_screen();
$screen->add_help_tab( array(
'id' => 'woocommerce_overview_tab',
'title' => __( 'Overview', 'woocommerce' ),
'content' =>
'<p>' . sprintf(__( 'Thank you for using WooCommerce :) Should you need help using or extending WooCommerce please <a href="%s">read the documentation</a>. For further assistance you can use the <a href="%s">community forum</a> or if you have access, <a href="%s">the members forum</a>.', 'woocommerce' ), 'http://www.woothemes.com/woocommerce-docs/', 'http://www.woothemes.com/support-forum/?viewforum=150', 'http://www.woothemes.com/support-forum/') . '</p>' .
'<p>' . __( 'If you are having problems, or to assist us with support, please check the status page to identify any problems with your configuration:', 'woocommerce' ) . '</p>' .
'<p><a href="' . admin_url('admin.php?page=woocommerce_status') . '" class="button">' . __( 'System Status', 'woocommerce' ) . '</a></p>' .
'<p>' . sprintf(__( 'If you come across a bug, or wish to contribute to the project you can also <a href="%s">get involved on GitHub</a>.', 'woocommerce' ), 'https://github.com/woothemes/woocommerce') . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'woocommerce_settings_tab',
'title' => __( 'Settings', 'woocommerce' ),
'content' =>
'<p>' . __( 'Here you can set up your store and customise it to fit your needs. The sections available from the settings page include:', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'General', 'woocommerce' ) . '</strong> - ' . __( 'General settings such as your shop base, currency, and script/styling options which affect features used in your store.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Pages', 'woocommerce' ) . '</strong> - ' . __( 'This is where important store page are defined. You can also set up other pages (such as a Terms page) here.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Catalog', 'woocommerce' ) . '</strong> - ' . __( 'Options for how things like price, images and weights appear in your product catalog.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Inventory', 'woocommerce' ) . '</strong> - ' . __( 'Options concerning stock and stock notices.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Tax', 'woocommerce' ) . '</strong> - ' . __( 'Options concerning tax, including international and local tax rates.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Shipping', 'woocommerce' ) . '</strong> - ' . __( 'This is where shipping options are defined, and shipping methods are set up.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Payment Methods', 'woocommerce' ) . '</strong> - ' . __( 'This is where payment gateway options are defined, and individual payment gateways are set up.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Emails', 'woocommerce' ) . '</strong> - ' . __( 'Here you can customise the way WooCommerce emails appear.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Integration', 'woocommerce' ) . '</strong> - ' . __( 'The integration section contains options for third party services which integrate with WooCommerce.', 'woocommerce' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'woocommerce_overview_tab_2',
'title' => __( 'Reports', 'woocommerce' ),
'content' =>
'<p>' . __( 'The reports section can be accessed from the left-hand navigation menu. Here you can generate reports for sales and customers.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Sales', 'woocommerce' ) . '</strong> - ' . __( 'Reports for sales based on date, top sellers and top earners.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Customers', 'woocommerce' ) . '</strong> - ' . __( 'Customer reports, such as signups per day.', 'woocommerce' ) . '</p>' .
'<p><strong>' . __( 'Stock', 'woocommerce' ) . '</strong> - ' . __( 'Stock reports for low stock and out of stock items.', 'woocommerce' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'woocommerce_overview_tab_3',
'title' => __( 'Orders', 'woocommerce' ),
'content' =>
'<p>' . __( 'The orders section can be accessed from the left-hand navigation menu. Here you can view and manage customer orders.', 'woocommerce' ) . '</p>' .
'<p>' . __( 'Orders can also be added from this section if you want to set them up for a customer manually.', 'woocommerce' ) . '</p>'
) );
$screen->add_help_tab( array(
'id' => 'woocommerce_overview_tab_4',
'title' => __( 'Coupons', 'woocommerce' ),
'content' =>
'<p>' . __( 'Coupons can be managed from this section. Once added, customers will be able to enter coupon codes on the cart/checkout page. If a customer uses a coupon code they will be viewable when viewing orders.', 'woocommerce' ) . '</p>'
) );
$screen->set_help_sidebar(
'<p><strong>' . __( 'For more information:', 'woocommerce' ) . '</strong></p>' .
'<p>' . __( '<a href="http://www.woothemes.com/woocommerce/" target="_blank">WooCommerce</a>', 'woocommerce' ) . '</p>' .
'<p>' . __( '<a href="http://wordpress.org/extend/plugins/woocommerce/" target="_blank">Project on WordPress.org</a>', 'woocommerce' ) . '</p>' .
'<p>' . __( '<a href="https://github.com/woothemes/woocommerce" target="_blank">Project on Github</a>', 'woocommerce' ) . '</p>' .
'<p>' . __( '<a href="http://www.woothemes.com/woocommerce-docs/" target="_blank">WooCommerce Docs</a>', 'woocommerce' ) . '</p>' .
'<p>' . __( '<a href="http://www.woothemes.com/extensions/woocommerce-extensions/" target="_blank">Official Extensions</a>', 'woocommerce' ) . '</p>' .
'<p>' . __( '<a href="http://www.woothemes.com/themes/woocommerce-themes/" target="_blank">Official Themes</a>', 'woocommerce' ) . '</p>'
);
}

View File

@ -4,219 +4,348 @@
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Dashboard
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
// Only hook in admin parts if the user has admin access // Only hook in admin parts if the user has admin access
if (current_user_can('manage_woocommerce')) : if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'manage_woocommerce' ) || current_user_can( 'publish_shop_orders' ) )
add_action('right_now_content_table_end', 'woocommerce_content_right_now'); add_action( 'wp_dashboard_setup', 'woocommerce_init_dashboard_widgets' );
add_action('right_now_table_end', 'woocommerce_right_now');
add_action('wp_dashboard_setup', 'woocommerce_init_dashboard_widgets' );
add_action('admin_footer', 'woocommmerce_dashboard_sales_js');
endif;
/** /**
* Right now widget hooks/content * Init the dashboard widgets.
*/ *
function woocommerce_content_right_now() { * @access public
* @return void
global $woocommerce;
?>
</table>
<p class="sub woocommerce_sub"><?php _e('Shop Content', 'woothemes'); ?></p>
<table>
<tr>
<td class="first b"><a href="edit.php?post_type=product"><?php
$num_posts = wp_count_posts( 'product' );
$num = number_format_i18n( $num_posts->publish );
echo $num;
?></a></td>
<td class="t"><a href="edit.php?post_type=product"><?php _e('Products', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="first b"><a href="edit-tags.php?taxonomy=product_cat&post_type=product"><?php
echo wp_count_terms('product_cat');
?></a></td>
<td class="t"><a href="edit-tags.php?taxonomy=product_cat&post_type=product"><?php _e('Product Categories', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="first b"><a href="edit-tags.php?taxonomy=product_tag&post_type=product"><?php
echo wp_count_terms('product_tag');
?></a></td>
<td class="t"><a href="edit-tags.php?taxonomy=product_tag&post_type=product"><?php _e('Product Tags', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="first b"><a href="admin.php?page=woocommerce_attributes"><?php
echo sizeof($woocommerce->get_attribute_taxonomies());
?></a></td>
<td class="t"><a href="admin.php?page=woocommerce_attributes"><?php _e('Attribute taxonomies', 'woothemes'); ?></a></td>
</tr>
<?php
}
function woocommerce_right_now() {
$pending_count = get_term_by( 'slug', 'pending', 'shop_order_status' )->count;
$completed_count = get_term_by( 'slug', 'completed', 'shop_order_status' )->count;
$on_hold_count = get_term_by( 'slug', 'on-hold', 'shop_order_status' )->count;
$processing_count = get_term_by( 'slug', 'processing', 'shop_order_status' )->count;
?>
</table>
<p class="sub woocommerce_sub"><?php _e('Orders', 'woothemes'); ?></p>
<table>
<tr>
<td class="b"><a href="edit.php?post_type=shop_order&shop_order_status=pending"><span class="total-count"><?php echo $pending_count; ?></span></a></td>
<td class="last t"><a class="pending" href="edit.php?post_type=shop_order&shop_order_status=pending"><?php _e('Pending', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="b"><a href="edit.php?post_type=shop_order&shop_order_status=on-hold"><span class="total-count"><?php echo $on_hold_count; ?></span></a></td>
<td class="last t"><a class="onhold" href="edit.php?post_type=shop_order&shop_order_status=on-hold"><?php _e('On-Hold', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="b"><a href="edit.php?post_type=shop_order&shop_order_status=processing"><span class="total-count"><?php echo $processing_count; ?></span></a></td>
<td class="last t"><a class="processing" href="edit.php?post_type=shop_order&shop_order_status=processing"><?php _e('Processing', 'woothemes'); ?></a></td>
</tr>
<tr>
<td class="b"><a href="edit.php?post_type=shop_order&shop_order_status=completed"><span class="total-count"><?php echo $completed_count; ?></span></a></td>
<td class="last t"><a class="complete" href="edit.php?post_type=shop_order&shop_order_status=completed"><?php _e('Completed', 'woothemes'); ?></a></td>
</tr>
<?php
}
/**
* Dashboard Widgets - init
*/ */
function woocommerce_init_dashboard_widgets() { function woocommerce_init_dashboard_widgets() {
global $current_month_offset; global $current_month_offset, $the_month_num, $the_year;
$current_month_offset = (int) date('m'); $current_month_offset = 0;
if (isset($_GET['month'])) $current_month_offset = (int) $_GET['month']; if (isset($_GET['wc_sales_month'])) $current_month_offset = (int) $_GET['wc_sales_month'];
$sales_heading = ''; $the_month_num = date('n', strtotime('NOW '.($current_month_offset).' MONTH'));
$the_year = date('Y', strtotime('NOW '.($current_month_offset).' MONTH'));
if ($current_month_offset!=date('m')) :
$sales_heading .= '<a href="index.php?month='.($current_month_offset+1).'" class="next">'.date('F', strtotime('01-'.($current_month_offset+1).'-2011')).' &rarr;</a>'; $sales_heading = '';
endif;
if ($the_month_num!=date('m')) :
$sales_heading .= '<a href="index.php?month='.($current_month_offset-1).'" class="previous">&larr; '.date('F', strtotime('01-'.($current_month_offset-1).'-2011')).'</a><span>'.__('Monthly Sales', 'woothemes').'</span>'; $sales_heading .= '<a href="index.php?wc_sales_month='.($current_month_offset+1).'" class="next">'.date_i18n('F', strtotime('01-'.($the_month_num+1).'-2011')).' &rarr;</a>';
endif;
$sales_heading .= '<a href="index.php?wc_sales_month='.($current_month_offset-1).'" class="previous">&larr; '.date_i18n('F', strtotime('01-'.($the_month_num-1).'-2011')).'</a><span>'.__( 'Monthly Sales', 'woocommerce' ).'</span>';
if ( current_user_can( 'publish_shop_orders' ) ) {
wp_add_dashboard_widget( 'woocommerce_dashboard_right_now', __( 'WooCommerce Right Now', 'woocommerce' ), 'woocommerce_dashboard_widget_right_now' );
wp_add_dashboard_widget( 'woocommerce_dashboard_recent_orders', __( 'WooCommerce Recent Orders', 'woocommerce' ), 'woocommerce_dashboard_recent_orders');
wp_add_dashboard_widget( 'woocommerce_dashboard_recent_reviews', __( 'WooCommerce Recent Reviews', 'woocommerce' ), 'woocommerce_dashboard_recent_reviews' );
}
if ( current_user_can( 'view_woocommerce_reports' ) || current_user_can( 'publish_shop_orders' ) ) {
wp_add_dashboard_widget( 'woocommerce_dashboard_sales', $sales_heading, 'woocommerce_dashboard_sales' );
}
}
/**
* WooCommerce Right Now widget.
*
* Adds a dashboard widget with shop statistics.
*
* @access public
* @return void
*/
function woocommerce_dashboard_widget_right_now() {
global $woocommerce;
$product_count = wp_count_posts( 'product' );
$product_cat_count = wp_count_terms( 'product_cat' );
$product_tag_count = wp_count_terms( 'product_tag' );
$product_attr_count = count( $woocommerce->get_attribute_taxonomies() );
$pending_count = get_term_by( 'slug', 'pending', 'shop_order_status' )->count;
$completed_count = get_term_by( 'slug', 'completed', 'shop_order_status' )->count;
$on_hold_count = get_term_by( 'slug', 'on-hold', 'shop_order_status' )->count;
$processing_count = get_term_by( 'slug', 'processing', 'shop_order_status' )->count;
?>
<div class="table table_shop_content">
<p class="sub woocommerce_sub"><?php _e( 'Shop Content', 'woocommerce' ); ?></p>
<table>
<tr class="first">
<?php
$num = number_format_i18n( $product_count->publish );
$text = _n( 'Product', 'Products', intval( $product_count->publish ), 'woocommerce' );
$link = add_query_arg( array( 'post_type' => 'product' ), get_admin_url( null, 'edit.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="first b b-products"><?php echo $num; ?></td>
<td class="t products"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $product_cat_count );
$text = _n( 'Product Category', 'Product Categories', $product_cat_count, 'woocommerce' );
$link = add_query_arg( array( 'taxonomy' => 'product_cat', 'post_type' => 'product' ), get_admin_url( null, 'edit-tags.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="first b b-product_cats"><?php echo $num; ?></td>
<td class="t product_cats"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $product_tag_count );
$text = _n( 'Product Tag', 'Product Tags', $product_tag_count, 'woocommerce' );
$link = add_query_arg( array( 'taxonomy' => 'product_tag', 'post_type' => 'product' ), get_admin_url( null, 'edit-tags.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="first b b-product_tag"><?php echo $num; ?></td>
<td class="t product_tag"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $product_attr_count );
$text = _n( 'Attribute', 'Attributes', $product_attr_count, 'woocommerce' );
$link = add_query_arg( array( 'page' => 'woocommerce_attributes' ), get_admin_url( null, 'admin.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="first b b-attributes"><?php echo $num; ?></td>
<td class="t attributes"><?php echo $text; ?></td>
</tr>
<?php do_action( 'woocommerce_right_now_shop_content_table_end' ); ?>
</table>
</div>
<div class="table table_orders">
<p class="sub woocommerce_sub"><?php _e( 'Orders', 'woocommerce' ); ?></p>
<table>
<tr class="first">
<?php
$num = number_format_i18n( $pending_count );
$text = __( 'Pending', 'woocommerce' );
$link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'pending' ), get_admin_url( null, 'edit.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="b b-pending"><?php echo $num; ?></td>
<td class="last t pending"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $on_hold_count );
$text = __( 'On-Hold', 'woocommerce' );
$link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'on-hold' ), get_admin_url( null, 'edit.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="b b-on-hold"><?php echo $num; ?></td>
<td class="last t on-hold"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $processing_count );
$text = __( 'Processing', 'woocommerce' );
$link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'processing' ), get_admin_url( null, 'edit.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="b b-processing"><?php echo $num; ?></td>
<td class="last t processing"><?php echo $text; ?></td>
</tr>
<tr>
<?php
$num = number_format_i18n( $completed_count );
$text = __( 'Completed', 'woocommerce' );
$link = add_query_arg( array( 'post_type' => 'shop_order', 'shop_order_status' => 'completed' ), get_admin_url( null, 'edit.php' ) );
$num = '<a href="' . esc_url($link ) . '">' . esc_html( $num ) . '</a>';
$text = '<a href="' . esc_url( $link ) . '">' . esc_html( $text ) . '</a>';
?>
<td class="b b-completed"><?php echo $num; ?></td>
<td class="last t completed"><?php echo $text; ?></td>
</tr>
<?php do_action( 'woocommerce_right_now_orders_table_end' ); ?>
</table>
</div>
<div class="versions">
<p id="wp-version-message">
<?php printf( __( 'You are using <strong>WooCommerce %s</strong>.', 'woocommerce' ), $woocommerce->version ); ?>
</p>
</div>
<?php
}
wp_add_dashboard_widget('woocommmerce_dashboard_sales', $sales_heading, 'woocommmerce_dashboard_sales');
wp_add_dashboard_widget('woocommmerce_dashboard_recent_orders', __('WooCommerce recent orders', 'woothemes'), 'woocommmerce_dashboard_recent_orders');
wp_add_dashboard_widget('woocommmerce_dashboard_recent_reviews', __('WooCommerce recent reviews', 'woothemes'), 'woocommmerce_dashboard_recent_reviews');
}
/** /**
* Recent orders widget * Recent orders widget
*
* @access public
* @return void
*/ */
function woocommmerce_dashboard_recent_orders() { function woocommerce_dashboard_recent_orders() {
$args = array( $args = array(
'numberposts' => 8, 'numberposts' => 8,
'orderby' => 'post_date', 'orderby' => 'post_date',
'order' => 'DESC', 'order' => 'DESC',
'post_type' => 'shop_order', 'post_type' => 'shop_order',
'post_status' => 'publish' 'post_status' => 'publish'
); );
$orders = get_posts( $args ); $orders = get_posts( $args );
if ($orders) : if ($orders) :
echo '<ul class="recent-orders">'; echo '<ul class="recent-orders">';
foreach ($orders as $order) : foreach ($orders as $order) :
$this_order = &new woocommerce_order( $order->ID ); $this_order = new WC_Order( $order->ID );
echo ' echo '
<li> <li>
<span class="order-status '.sanitize_title($this_order->status).'">'.ucwords($this_order->status).'</span> <a href="'.admin_url('post.php?post='.$order->ID).'&action=edit">'.get_the_time('l jS \of F Y h:i:s A', $order->ID).'</a><br /> <span class="order-status '.sanitize_title($this_order->status).'">'.ucwords(__($this_order->status, 'woocommerce')).'</span> <a href="'.admin_url('post.php?post='.$order->ID).'&action=edit">' . get_the_time( __( 'l jS \of F Y h:i:s A', 'woocommerce' ), $order->ID ) . '</a><br />
<small>'.sizeof($this_order->items).' '._n('item', 'items', sizeof($this_order->items), 'woothemes').' <span class="order-cost">'.__('Total:', 'woothemes') . ' ' . woocommerce_price($this_order->order_total).'</span></small> <small>'.sizeof($this_order->get_items()).' '._n('item', 'items', sizeof($this_order->get_items()), 'woocommerce').' <span class="order-cost">'.__('Total:', 'woocommerce' ) . ' ' . woocommerce_price($this_order->order_total).'</span></small>
</li>'; </li>';
endforeach; endforeach;
echo '</ul>'; echo '</ul>';
else:
echo '<p>' . __( 'There are no product orders yet.', 'woocommerce' ) . '</p>';
endif; endif;
} }
/** /**
* Recent reviews widget * Recent reviews widget
*
* @access public
* @return void
*/ */
function woocommmerce_dashboard_recent_reviews() { function woocommerce_dashboard_recent_reviews() {
global $wpdb; global $wpdb;
$comments = $wpdb->get_results("SELECT *, SUBSTRING(comment_content,1,100) AS comment_excerpt $comments = $wpdb->get_results( "SELECT *, SUBSTRING(comment_content,1,100) AS comment_excerpt
FROM $wpdb->comments FROM $wpdb->comments
LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID) LEFT JOIN $wpdb->posts ON ($wpdb->comments.comment_post_ID = $wpdb->posts.ID)
WHERE comment_approved = '1' WHERE comment_approved = '1'
AND comment_type = '' AND comment_type = ''
AND post_password = '' AND post_password = ''
AND post_type = 'product' AND post_type = 'product'
ORDER BY comment_date_gmt DESC ORDER BY comment_date_gmt DESC
LIMIT 5" ); LIMIT 5" );
if ($comments) : if ( $comments ) {
echo '<ul>'; echo '<ul>';
foreach ($comments as $comment) : foreach ( $comments as $comment ) {
echo '<li>'; echo '<li>';
echo get_avatar($comment->comment_author, '32'); echo get_avatar( $comment->comment_author, '32' );
$rating = get_comment_meta( $comment->comment_ID, 'rating', true ); $rating = get_comment_meta( $comment->comment_ID, 'rating', true );
echo '<div class="star-rating" title="'.$rating.'"> echo '<div class="star-rating" title="' . $rating . '">
<span style="width:'.($rating*10).'px">'.$rating.' '.__('out of 5', 'woothemes').'</span></div>'; <span style="width:'. ( $rating * 10 ) . 'px">' . $rating . ' ' . __( 'out of 5', 'woocommerce' ) . '</span></div>';
echo '<h4 class="meta"><a href="'.get_permalink($comment->ID).'#comment-'.$comment->comment_ID .'">'.$comment->post_title.'</a> reviewed by ' .strip_tags($comment->comment_author) .'</h4>'; echo '<h4 class="meta"><a href="' . get_permalink( $comment->ID ) . '#comment-' . absint( $comment->comment_ID ) .'">' . esc_html__( $comment->post_title ) . '</a> reviewed by ' . esc_html( $comment->comment_author ) .'</h4>';
echo '<blockquote>'.strip_tags($comment->comment_excerpt).' [...]</blockquote></li>'; echo '<blockquote>' . wp_kses_data( $comment->comment_excerpt ) . ' [...]</blockquote></li>';
endforeach; }
echo '</ul>'; echo '</ul>';
else : } else {
echo '<p>'.__('There are no product reviews yet.', 'woothemes').'</p>'; echo '<p>' . __( 'There are no product reviews yet.', 'woocommerce' ) . '</p>';
endif; }
} }
/** /**
* Orders this month filter function * Orders this month filter function - filters orders for the month
*
* @access public
* @param string $where (default: '')
* @return void
*/ */
function orders_this_month( $where = '' ) { function orders_this_month( $where = '' ) {
global $current_month_offset; global $the_month_num, $the_year;
$month = $current_month_offset; $month = $the_month_num;
$year = (int) date('Y'); $year = (int) $the_year;
$first_day = strtotime("{$year}-{$month}-01"); $first_day = strtotime("{$year}-{$month}-01");
//$last_day = strtotime('-1 second', strtotime('+1 month', $first_day)); //$last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
$last_day = strtotime('+1 month', $first_day); $last_day = strtotime('+1 month', $first_day);
$after = date('Y-m-d', $first_day); $after = date('Y-m-d', $first_day);
$before = date('Y-m-d', $last_day); $before = date('Y-m-d', $last_day);
$where .= " AND post_date > '$after'"; $where .= " AND post_date > '$after'";
$where .= " AND post_date < '$before'"; $where .= " AND post_date < '$before'";
return $where; return $where;
} }
/** /**
* Sales widget * Sales widget
*
* @access public
* @return void
*/ */
function woocommmerce_dashboard_sales() { function woocommerce_dashboard_sales() {
add_action( 'admin_footer', 'woocommerce_dashboard_sales_js' );
?><div id="placeholder" style="width:100%; height:300px; position:relative;"></div><?php ?><div id="placeholder" style="width:100%; height:300px; position:relative;"></div><?php
} }
/** /**
* Sales widget javascript * Sales widget javascript
*
* @access public
* @return void
*/ */
function woocommmerce_dashboard_sales_js() { function woocommerce_dashboard_sales_js() {
global $woocommerce; global $woocommerce, $wp_locale;
$screen = get_current_screen(); $screen = get_current_screen();
if (!$screen || $screen->id!=='dashboard') return; if (!$screen || $screen->id!=='dashboard') return;
global $current_month_offset; global $current_month_offset, $the_month_num, $the_year;
// Get orders to display in widget // Get orders to display in widget
add_filter( 'posts_where', 'orders_this_month' ); add_filter( 'posts_where', 'orders_this_month' );
@ -230,97 +359,101 @@ function woocommmerce_dashboard_sales_js() {
'tax_query' => array( 'tax_query' => array(
array( array(
'taxonomy' => 'shop_order_status', 'taxonomy' => 'shop_order_status',
'terms' => array('completed', 'processing', 'on-hold'), 'terms' => apply_filters( 'woocommerce_reports_order_statuses', array( 'completed', 'processing', 'on-hold' ) ),
'field' => 'slug', 'field' => 'slug',
'operator' => 'IN' 'operator' => 'IN'
) )
) )
); );
$orders = get_posts( $args ); $orders = get_posts( $args );
$order_counts = array(); $order_counts = array();
$order_amounts = array(); $order_amounts = array();
// Blank date ranges to begin // Blank date ranges to begin
$month = $current_month_offset; $month = $the_month_num;
$year = (int) date('Y'); $year = (int) $the_year;
$first_day = strtotime("{$year}-{$month}-01"); $first_day = strtotime("{$year}-{$month}-01");
$last_day = strtotime('-1 second', strtotime('+1 month', $first_day)); $last_day = strtotime('-1 second', strtotime('+1 month', $first_day));
if ((date('m') - $current_month_offset)==0) : if ((date('m') - $the_month_num)==0) :
$up_to = date('d', strtotime('NOW')); $up_to = date('d', strtotime('NOW'));
else : else :
$up_to = date('d', $last_day); $up_to = date('d', $last_day);
endif; endif;
$count = 0; $count = 0;
while ($count < $up_to) : while ($count < $up_to) :
$time = strtotime(date('Ymd', strtotime('+ '.$count.' DAY', $first_day))).'000'; $time = strtotime(date('Ymd', strtotime('+ '.$count.' DAY', $first_day))).'000';
$order_counts[$time] = 0; $order_counts[$time] = 0;
$order_amounts[$time] = 0; $order_amounts[$time] = 0;
$count++; $count++;
endwhile; endwhile;
if ($orders) : if ($orders) :
foreach ($orders as $order) : foreach ($orders as $order) :
$order_data = &new woocommerce_order($order->ID); $order_data = new WC_Order($order->ID);
if ($order_data->status=='cancelled' || $order_data->status=='refunded') continue; if ($order_data->status=='cancelled' || $order_data->status=='refunded') continue;
$time = strtotime(date('Ymd', strtotime($order->post_date))).'000'; $time = strtotime(date('Ymd', strtotime($order->post_date))).'000';
if (isset($order_counts[$time])) : if (isset($order_counts[$time])) :
$order_counts[$time]++; $order_counts[$time]++;
else : else :
$order_counts[$time] = 1; $order_counts[$time] = 1;
endif; endif;
if (isset($order_amounts[$time])) : if (isset($order_amounts[$time])) :
$order_amounts[$time] = $order_amounts[$time] + $order_data->order_total; $order_amounts[$time] = $order_amounts[$time] + $order_data->order_total;
else : else :
$order_amounts[$time] = (float) $order_data->order_total; $order_amounts[$time] = (float) $order_data->order_total;
endif; endif;
endforeach; endforeach;
endif; endif;
remove_filter( 'posts_where', 'orders_this_month' ); remove_filter( 'posts_where', 'orders_this_month' );
/* Script variables */ /* Script variables */
$params = array( $params = array(
'currency_symbol' => get_woocommerce_currency_symbol() 'currency_symbol' => get_woocommerce_currency_symbol(),
'number_of_sales' => absint( array_sum( $order_counts ) ),
'sales_amount' => woocommerce_price( array_sum( $order_amounts ) ),
'sold' => __( 'Sold', 'woocommerce' ),
'earned' => __( 'Earned', 'woocommerce' ),
'month_names' => array_values( $wp_locale->month_abbrev ),
); );
$order_counts_array = array(); $order_counts_array = array();
foreach ($order_counts as $key => $count) : foreach ($order_counts as $key => $count) :
$order_counts_array[] = array($key, $count); $order_counts_array[] = array($key, $count);
endforeach; endforeach;
$order_amounts_array = array(); $order_amounts_array = array();
foreach ($order_amounts as $key => $amount) : foreach ($order_amounts as $key => $amount) :
$order_amounts_array[] = array($key, $amount); $order_amounts_array[] = array($key, $amount);
endforeach; endforeach;
$order_data = array( 'order_counts' => $order_counts_array, 'order_amounts' => $order_amounts_array ); $order_data = array( 'order_counts' => $order_counts_array, 'order_amounts' => $order_amounts_array );
$params['order_data'] = json_encode($order_data); $params['order_data'] = json_encode($order_data);
// Queue scripts // Queue scripts
$suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min'; $suffix = defined('SCRIPT_DEBUG') && SCRIPT_DEBUG ? '' : '.min';
wp_register_script( 'woocommerce_dashboard_sales', $woocommerce->plugin_url() . '/assets/js/admin/dashboard_sales'.$suffix.'.js', 'jquery', '1.0' ); wp_register_script( 'woocommerce_dashboard_sales', $woocommerce->plugin_url() . '/assets/js/admin/dashboard_sales'.$suffix.'.js', 'jquery', '1.0' );
wp_register_script( 'flot', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot'.$suffix.'.js', 'jquery', '1.0' ); wp_register_script( 'flot', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot'.$suffix.'.js', 'jquery', '1.0' );
wp_register_script( 'flot-resize', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot.resize'.$suffix.'.js', 'jquery', '1.0' ); wp_register_script( 'flot-resize', $woocommerce->plugin_url() . '/assets/js/admin/jquery.flot.resize'.$suffix.'.js', 'jquery', '1.0' );
wp_localize_script( 'woocommerce_dashboard_sales', 'params', $params ); wp_localize_script( 'woocommerce_dashboard_sales', 'params', $params );
wp_print_scripts('flot'); wp_print_scripts('flot');
wp_print_scripts('flot-resize'); wp_print_scripts('flot-resize');
wp_print_scripts('woocommerce_dashboard_sales'); wp_print_scripts('woocommerce_dashboard_sales');
}
}

View File

@ -1,166 +1,259 @@
<?php <?php
/** /**
* WooCommerce Admin Functions * WooCommerce Admin Functions
* *
* Hooked-in functions for WooCommerce related events in admin. * Hooked-in functions for WooCommerce related events in admin.
* *
* @package WooCommerce * @author WooThemes
* @category Actions * @category Admin
* @author WooThemes * @package WooCommerce/Admin
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Checks which method we're using to serve downloads * Checks which method we're using to serve downloads
* *
* If using force or x-sendfile, this ensures the .htaccess is in place * If using force or x-sendfile, this ensures the .htaccess is in place
*
* @access public
* @return void
*/ */
function woocomerce_check_download_folder_protection() { function woocomerce_check_download_folder_protection() {
$upload_dir = wp_upload_dir(); $upload_dir = wp_upload_dir();
$downloads_url = $upload_dir['basedir'] . '/woocommerce_uploads'; $downloads_url = $upload_dir['basedir'] . '/woocommerce_uploads';
$download_method = get_option('woocommerce_file_download_method'); $download_method = get_option('woocommerce_file_download_method');
if ($download_method=='redirect') : if ($download_method=='redirect') :
// Redirect method - don't protect // Redirect method - don't protect
if (file_exists($downloads_url.'/.htaccess')) : if (file_exists($downloads_url.'/.htaccess')) :
unlink( $downloads_url . '/.htaccess' ); unlink( $downloads_url . '/.htaccess' );
endif; endif;
flush_rewrite_rules( true );
else : else :
// Force method - protect, add rules to the htaccess file // Force method - protect, add rules to the htaccess file
if (!file_exists($downloads_url.'/.htaccess')) : if (!file_exists($downloads_url.'/.htaccess')) :
if ($file_handle = fopen( $downloads_url . '/.htaccess', 'w' )) : if ($file_handle = @fopen( $downloads_url . '/.htaccess', 'w' )) :
fwrite($file_handle, 'deny from all'); fwrite($file_handle, 'deny from all');
fclose($file_handle); fclose($file_handle);
endif; endif;
endif; endif;
flush_rewrite_rules( true );
endif; endif;
} }
/** /**
* Deleting products sync * Protect downlodas from ms-files.php in multisite
* *
* Removes variations etc belonging to a deleted post * @access public
* @param mixed $rewrite
* @return string
*/ */
function woocommerce_delete_product_sync( $id ) { function woocommerce_ms_protect_download_rewite_rules( $rewrite ) {
global $wp_rewrite;
if (!current_user_can('delete_posts')) return;
$download_method = get_option('woocommerce_file_download_method');
if ( $id > 0 ) :
if (!is_multisite() || $download_method=='redirect') return $rewrite;
if ( $children_products =& get_children( 'post_parent='.$id.'&post_type=product_variation' ) ) :
$rule = "\n# WooCommerce Rules - Protect Files from ms-files.php\n\n";
if ($children_products) : $rule .= "<IfModule mod_rewrite.c>\n";
$rule .= "RewriteEngine On\n";
foreach ($children_products as $child) : $rule .= "RewriteCond %{QUERY_STRING} file=woocommerce_uploads/ [NC]\n";
$rule .= "RewriteRule /ms-files.php$ - [F]\n";
wp_delete_post( $child->ID, true ); $rule .= "</IfModule>\n\n";
endforeach; return $rule . $rewrite;
endif;
endif;
endif;
} }
/** /**
* Preview Emails * Removes variations etc belonging to a deleted post, and clears transients
**/ *
function woocommerce_preview_emails() { * @access public
if (isset($_GET['preview_woocommerce_mail'])) : * @param mixed $id ID of post being deleted
$nonce = $_REQUEST['_wpnonce']; * @return void
if (!wp_verify_nonce($nonce, 'preview-mail') ) die('Security check'); */
function woocommerce_delete_post( $id ) {
global $woocommerce, $email_heading; global $woocommerce;
$mailer = $woocommerce->mailer(); if ( ! current_user_can( 'delete_posts' ) ) return;
$email_heading = __('Email preview', 'woothemes'); if ( $id > 0 ) :
$message = '<h2>WooCommerce sit amet</h2>'; if ( $children_products =& get_children( 'post_parent='.$id.'&post_type=product_variation' ) ) :
$message.= wpautop('Ut ut est qui euismod parum. Dolor veniam tation nihil assum mazim. Possim fiant habent decima et claritatem. Erat me usus gothica laoreet consequat. Clari facer litterarum aliquam insitam dolor. if ($children_products) :
foreach ($children_products as $child) :
wp_delete_post( $child->ID, true );
endforeach;
endif;
endif;
Gothica minim lectores demonstraverunt ut soluta. Sequitur quam exerci veniam aliquip litterarum. Lius videntur nisl facilisis claritatem nunc. Praesent in iusto me tincidunt iusto. Dolore lectores sed putamus exerci est. ');
echo $mailer->wrap_message( $email_heading, $message );
exit;
endif; endif;
$woocommerce->clear_product_transients();
delete_transient( 'woocommerce_processing_order_count' );
} }
/**
* Preview Emails in WP admin
*
* @access public
* @return void
*/
function woocommerce_preview_emails() {
if ( isset( $_GET['preview_woocommerce_mail'] ) ) {
$nonce = $_REQUEST['_wpnonce'];
if ( ! wp_verify_nonce( $nonce, 'preview-mail') )
die( 'Security check' );
global $woocommerce, $email_heading;
$mailer = $woocommerce->mailer();
$email_heading = __( 'Order Received', 'woocommerce' );
$message = wpautop( __( 'Thank you, we are now processing your order. Your order\'s details are below.', 'woocommerce' ) );
$message .= '<h2>' . __( 'Order:', 'woocommerce' ) . ' ' . '#1000</h2>';
$message .= '
<table cellspacing="0" cellpadding="6" style="width: 100%; border: 1px solid #eee; margin: 0 0 20px" border="1" bordercolor="#eee">
<thead>
<tr>
<th scope="col" style="text-align:left; border: 1px solid #eee;">' . __( 'Product', 'woocommerce' ) . '</th>
<th scope="col" style="text-align:left; border: 1px solid #eee;">' . __( 'Quantity', 'woocommerce' ) . '</th>
<th scope="col" style="text-align:left; border: 1px solid #eee;">' . __( 'Price', 'woocommerce' ) . '</th>
</tr>
</thead>
<tbody>
<tr>
<td>An awesome product</td>
<td>1</td>
<td>$9.99</td>
</tr>
</tbody>
<tfoot>
<tr>
<th colspan="2">' . __( 'Order total:', 'woocommerce' ) . '</td>
<td>$9.99</td>
</tr>
</tfoot>
</table>';
$message .= '<h2>' . __( 'Customer details', 'woocommerce' ) . '</h2>';
$message .= '
<table cellspacing="0" cellpadding="0" style="width: 100%; vertical-align: top;" border="0">
<tr>
<td valign="top" width="50%">
<h3>' . __( 'Billing address', 'woocommerce' ) . '</h3>
<p>Some Guy
1 infinite loop
Cupertino
CA 95014</p>
</td>
<td valign="top" width="50%">
<h3>' . __( 'Shipping address', 'woocommerce' ) . '</h3>
<p>Some Guy
1 infinite loop
Cupertino
CA 95014</p>
</td>
</tr>
</table>';
echo $mailer->wrap_message( $email_heading, $message );
exit;
}
}
/** /**
* Prevent non-admin access to backend * Prevent non-admin access to backend
*
* @access public
* @return void
*/ */
function woocommerce_prevent_admin_access() { function woocommerce_prevent_admin_access() {
if ( get_option('woocommerce_lock_down_admin')=='yes' && !is_ajax() && !current_user_can('edit_posts') ) : if ( get_option('woocommerce_lock_down_admin') == 'yes' && ! is_ajax() && ! ( current_user_can('edit_posts') || current_user_can('manage_woocommerce') ) ) {
wp_safe_redirect(get_permalink(get_option('woocommerce_myaccount_page_id'))); wp_safe_redirect(get_permalink(woocommerce_get_page_id('myaccount')));
exit; exit;
endif; }
} }
/**
* Redirect to settings after installation
*/
function install_woocommerce_redirect() {
global $pagenow, $woocommerce;
if ( is_admin() && isset( $_GET['activate'] ) && ($_GET['activate'] == true) && $pagenow == 'plugins.php' && get_option( "woocommerce_installed" ) == 1 ) :
// Clear transient cache
$woocommerce->clear_product_transients();
// Unset installed flag
update_option( "woocommerce_installed", 0 );
// Flush rewrites
flush_rewrite_rules( false );
// Redirect to settings
wp_redirect(admin_url('admin.php?page=woocommerce&installed=true'));
exit;
endif;
}
/** /**
* Fix 'insert into post' buttons for images * Fix 'insert into post' buttons for images
**/ *
function woocommerce_allow_img_insertion($vars) { * @access public
* @param mixed $vars
* @return array
*/
function woocommerce_allow_img_insertion( $vars ) {
$vars['send'] = true; // 'send' as in "Send to Editor" $vars['send'] = true; // 'send' as in "Send to Editor"
return($vars); return($vars);
} }
/** /**
* Directory for uploads * Filter the directory for uploads.
*
* @access public
* @param mixed $pathdata
* @return void
*/ */
function woocommerce_downloads_upload_dir( $pathdata ) { function woocommerce_downloads_upload_dir( $pathdata ) {
if (isset($_POST['type']) && $_POST['type'] == 'downloadable_product') : if (isset($_POST['type']) && $_POST['type'] == 'downloadable_product') :
// Uploading a downloadable file // Uploading a downloadable file
$subdir = '/woocommerce_uploads'.$pathdata['subdir']; $subdir = '/woocommerce_uploads'.$pathdata['subdir'];
$pathdata['path'] = str_replace($pathdata['subdir'], $subdir, $pathdata['path']); $pathdata['path'] = str_replace($pathdata['subdir'], $subdir, $pathdata['path']);
$pathdata['url'] = str_replace($pathdata['subdir'], $subdir, $pathdata['url']); $pathdata['url'] = str_replace($pathdata['subdir'], $subdir, $pathdata['url']);
$pathdata['subdir'] = str_replace($pathdata['subdir'], $subdir, $pathdata['subdir']); $pathdata['subdir'] = str_replace($pathdata['subdir'], $subdir, $pathdata['subdir']);
return $pathdata; return $pathdata;
endif; endif;
return $pathdata; return $pathdata;
} }
/**
* Run a filter when uploading a downloadable product.
*
* @access public
* @return void
*/
function woocommerce_media_upload_downloadable_product() { function woocommerce_media_upload_downloadable_product() {
do_action('media_upload_file'); do_action('media_upload_file');
} }
/** /**
* Shortcode button in post editor * Add a button for shortcodes to the WP editor.
**/ *
* @access public
* @return void
*/
function woocommerce_add_shortcode_button() { function woocommerce_add_shortcode_button() {
if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) return; if ( ! current_user_can('edit_posts') && ! current_user_can('edit_pages') ) return;
if ( get_user_option('rich_editing') == 'true') : if ( get_user_option('rich_editing') == 'true') :
@ -169,56 +262,247 @@ function woocommerce_add_shortcode_button() {
endif; endif;
} }
/**
* woocommerce_add_tinymce_lang function.
*
* @access public
* @param mixed $arr
* @return void
*/
function woocommerce_add_tinymce_lang( $arr ) {
global $woocommerce;
$arr[] = $woocommerce->plugin_path() . '/assets/js/admin/editor_plugin_lang.php';
return $arr;
}
add_filter( 'mce_external_languages', 'woocommerce_add_tinymce_lang', 10, 1 );
/**
* Register the shortcode button.
*
* @access public
* @param mixed $buttons
* @return array
*/
function woocommerce_register_shortcode_button($buttons) { function woocommerce_register_shortcode_button($buttons) {
array_push($buttons, "|", "woocommerce_shortcodes_button"); array_push($buttons, "|", "woocommerce_shortcodes_button");
return $buttons; return $buttons;
} }
/**
* Add the shortcode button to TinyMCE
*
* @access public
* @param mixed $plugin_array
* @return array
*/
function woocommerce_add_shortcode_tinymce_plugin($plugin_array) { function woocommerce_add_shortcode_tinymce_plugin($plugin_array) {
global $woocommerce; global $woocommerce;
$plugin_array['WooCommerceShortcodes'] = $woocommerce->plugin_url() . '/assets/js/admin/editor_plugin.js'; $plugin_array['WooCommerceShortcodes'] = $woocommerce->plugin_url() . '/assets/js/admin/editor_plugin.js';
return $plugin_array; return $plugin_array;
} }
function woocommerce_refresh_mce($ver) {
/**
* Force TinyMCE to refresh.
*
* @access public
* @param mixed $ver
* @return int
*/
function woocommerce_refresh_mce( $ver ) {
$ver += 3; $ver += 3;
return $ver; return $ver;
} }
/**
* Reorder categories on term insertion
*/
function woocommerce_create_term( $term_id, $tt_id, $taxonomy ) {
if (!$taxonomy=='product_cat' && !strstr($taxonomy, 'pa_')) return;
$next_id = null;
$term = get_term($term_id, $taxonomy);
// gets the sibling terms
$siblings = get_terms($taxonomy, "parent={$term->parent}&menu_order=ASC&hide_empty=0");
foreach ($siblings as $sibling) {
if( $sibling->term_id == $term_id ) continue;
$next_id = $sibling->term_id; // first sibling term of the hierarchy level
break;
}
// reorder /**
woocommerce_order_terms( $term, $next_id, $taxonomy ); * Order term when created (put in position 0).
*
* @access public
* @param mixed $term_id
* @param mixed $tt_id
* @param mixed $taxonomy
* @return void
*/
function woocommerce_create_term( $term_id, $tt_id = '', $taxonomy = '' ) {
if ( ! $taxonomy == 'product_cat' && ! strstr( $taxonomy, 'pa_' ) )
return;
$meta_name = strstr( $taxonomy, 'pa_' ) ? 'order_' . esc_attr( $taxonomy ) : 'order';
update_woocommerce_term_meta( $term_id, $meta_name, 0 );
} }
/** /**
* Delete terms metas on deletion * When a term is deleted, delete its meta.
*
* @access public
* @param mixed $term_id
* @return void
*/ */
function woocommerce_delete_term( $term_id, $tt_id, $taxonomy ) { function woocommerce_delete_term( $term_id ) {
$term_id = (int) $term_id; $term_id = (int) $term_id;
if(!$term_id) return; if ( ! $term_id )
return;
global $wpdb; global $wpdb;
$wpdb->query("DELETE FROM {$wpdb->woocommerce_termmeta} WHERE `woocommerce_term_id` = " . $term_id); $wpdb->query( "DELETE FROM {$wpdb->woocommerce_termmeta} WHERE `woocommerce_term_id` = " . $term_id );
}
/**
* Generate CSS from the less file when changing colours.
*
* @access public
* @return void
*/
function woocommerce_compile_less_styles() {
global $woocommerce;
$colors = array_map( 'esc_attr', (array) get_option( 'woocommerce_frontend_css_colors' ) );
$base_file = $woocommerce->plugin_path() . '/assets/css/woocommerce-base.less';
$less_file = $woocommerce->plugin_path() . '/assets/css/woocommerce.less';
$css_file = $woocommerce->plugin_path() . '/assets/css/woocommerce.css';
// Write less file
if ( is_writable( $base_file ) && is_writable( $css_file ) ) {
// Colours changed - recompile less
if ( ! class_exists( 'lessc' ) )
include_once('includes/class-lessc.php');
if ( ! class_exists( 'cssmin' ) )
include_once('includes/class-cssmin.php');
try {
// Set default if colours not set
if ( ! $colors['primary'] ) $colors['primary'] = '#ad74a2';
if ( ! $colors['secondary'] ) $colors['secondary'] = '#f7f6f7';
if ( ! $colors['highlight'] ) $colors['highlight'] = '#85ad74';
if ( ! $colors['content_bg'] ) $colors['content_bg'] = '#ffffff';
if ( ! $colors['subtext'] ) $colors['subtext'] = '#777777';
// Write new color to base file
$color_rules = "
@primary: " . $colors['primary'] . ";
@primarytext: " . woocommerce_light_or_dark( $colors['primary'], 'desaturate(darken(@primary,50%),18%)', 'desaturate(lighten(@primary,50%),18%)' ) . ";
@secondary: " . $colors['secondary'] . ";
@secondarytext: " . woocommerce_light_or_dark( $colors['secondary'], 'desaturate(darken(@secondary,60%),18%)', 'desaturate(lighten(@secondary,60%),18%)' ) . ";
@highlight: " . $colors['highlight'] . ";
@highlightext: " . woocommerce_light_or_dark( $colors['highlight'], 'desaturate(darken(@highlight,60%),18%)', 'desaturate(lighten(@highlight,60%),18%)' ) . ";
@contentbg: " . $colors['content_bg'] . ";
@subtext: " . $colors['subtext'] . ";
";
file_put_contents( $base_file, $color_rules );
$less = new lessc( $less_file );
$compiled_css = $less->parse();
$compiled_css = CssMin::minify( $compiled_css );
if ( $compiled_css )
file_put_contents( $css_file, $compiled_css );
} catch ( exception $ex ) {
wp_die( __( 'Could not compile woocommerce.less:', 'woocommerce' ) . ' ' . $ex->getMessage() );
}
}
}
/**
* Add extra bulk action options to mark orders as complete or processing
*
* Using Javascript until WordPress core fixes: http://core.trac.wordpress.org/ticket/16031
*
* @access public
* @return void
*/
function woocommerce_bulk_admin_footer() {
global $post_type;
if ( 'shop_order' == $post_type ) {
?>
<script type="text/javascript">
jQuery(document).ready(function() {
jQuery('<option>').val('mark_processing').text('<?php _e( 'Mark processing', 'woocommerce' )?>').appendTo("select[name='action']");
jQuery('<option>').val('mark_processing').text('<?php _e( 'Mark processing', 'woocommerce' )?>').appendTo("select[name='action2']");
jQuery('<option>').val('mark_completed').text('<?php _e( 'Mark completed', 'woocommerce' )?>').appendTo("select[name='action']");
jQuery('<option>').val('mark_completed').text('<?php _e( 'Mark completed', 'woocommerce' )?>').appendTo("select[name='action2']");
});
</script>
<?php
}
}
/**
* Process the new bulk actions for changing order status
*
* @access public
* @return void
*/
function woocommerce_order_bulk_action() {
$wp_list_table = _get_list_table( 'WP_Posts_List_Table' );
$action = $wp_list_table->current_action();
switch ( $action ) {
case 'mark_completed':
$new_status = 'completed';
$report_action = 'marked_completed';
break;
case 'mark_processing':
$new_status = 'processing';
$report_action = 'marked_processing';
break;
default:
return;
}
$changed = 0;
$post_ids = array_map( 'absint', (array) $_REQUEST['post'] );
foreach( $post_ids as $post_id ) {
$order = new WC_Order( $post_id );
$order->update_status( $new_status, __( 'Order status changed by bulk edit:', 'woocommerce' ) );
$changed++;
}
$sendback = add_query_arg( array( 'post_type' => 'shop_order', $report_action => $changed, 'ids' => join( ',', $post_ids ) ), '' );
wp_redirect( $sendback );
exit();
}
/**
* Show confirmation message that order status changed for number of orders
*
* @access public
* @return void
*/
function woocommerce_order_bulk_admin_notices() {
global $post_type, $pagenow;
if ( isset( $_REQUEST['marked_completed'] ) || isset( $_REQUEST['marked_processing'] ) ) {
$number = isset( $_REQUEST['marked_processing'] ) ? absint( $_REQUEST['marked_processing'] ) : absint( $_REQUEST['marked_completed'] );
if ( 'edit.php' == $pagenow && 'shop_order' == $post_type ) {
$message = sprintf( _n( 'Order status changed.', '%s order statuses changed.', $number ), number_format_i18n( $number ) );
echo '<div class="updated"><p>' . $message . '</p></div>';
}
}
} }

View File

@ -1,38 +1,73 @@
<?php <?php
/** /**
* WooCommerce Admin Hooks * WooCommerce Admin Hooks
*
* Action/filter hooks used for WooCommerce functions
* *
* @package WooCommerce * Action/filter hooks used for WooCommerce functions.
* @category Admin *
* @author WooThemes * @author WooThemes
* @category Admin
* @package WooCommerce/Admin
* @version 1.6.4
*/ */
global $woocommerce;
/** Events ****************************************************************/ if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
add_action('delete_post', 'woocommerce_delete_product_sync', 10); /**
* Events
*
* @see woocommerce_delete_post()
* @see woocommerce_preview_emails()
* @see woocommerce_prevent_admin_access()
* @see woocomerce_check_download_folder_protection()
* @see woocommerce_ms_protect_download_rewite_rules()
*/
add_action('delete_post', 'woocommerce_delete_post');
add_action('admin_init', 'woocommerce_preview_emails'); add_action('admin_init', 'woocommerce_preview_emails');
add_action('admin_init', 'woocommerce_prevent_admin_access'); add_action('admin_init', 'woocommerce_prevent_admin_access');
add_action('admin_init', 'install_woocommerce_redirect');
add_action('woocommerce_settings_saved', 'woocomerce_check_download_folder_protection'); add_action('woocommerce_settings_saved', 'woocomerce_check_download_folder_protection');
add_filter('mod_rewrite_rules', 'woocommerce_ms_protect_download_rewite_rules');
/** Filters ***************************************************************/ /**
* Filters
*
* @see woocommerce_allow_img_insertion()
*/
add_filter('get_media_item_args', 'woocommerce_allow_img_insertion'); add_filter('get_media_item_args', 'woocommerce_allow_img_insertion');
/** File Uploads **********************************************************/ /**
* File uploads
*
* @see woocommerce_downloads_upload_dir()
* @see woocommerce_media_upload_downloadable_product()
*/
add_filter('upload_dir', 'woocommerce_downloads_upload_dir'); add_filter('upload_dir', 'woocommerce_downloads_upload_dir');
add_action('media_upload_downloadable_product', 'woocommerce_media_upload_downloadable_product'); add_action('media_upload_downloadable_product', 'woocommerce_media_upload_downloadable_product');
/** Shortcode buttons *****************************************************/ /**
* Shortcode buttons
*
* @see woocommerce_add_shortcode_button()
* @see woocommerce_refresh_mce()
*/
add_action( 'init', 'woocommerce_add_shortcode_button' ); add_action( 'init', 'woocommerce_add_shortcode_button' );
add_filter( 'tiny_mce_version', 'woocommerce_refresh_mce' ); add_filter( 'tiny_mce_version', 'woocommerce_refresh_mce' );
/** Category/Term ordering ************************************************/ /**
* Category/term ordering
*
* @see woocommerce_create_term()
* @see woocommerce_delete_term()
*/
add_action( "create_term", 'woocommerce_create_term', 5, 3 );
add_action( "delete_term", 'woocommerce_delete_term', 5 );
add_action("create_term", 'woocommerce_create_term', 5, 3); /**
add_action("delete_product_term", 'woocommerce_delete_term', 5, 3); * Bulk editing
*
* @see woocommerce_bulk_admin_footer()
* @see woocommerce_order_bulk_action()
* @see woocommerce_order_bulk_admin_notices()
*/
add_action( 'admin_footer', 'woocommerce_bulk_admin_footer', 10 );
add_action( 'load-edit.php', 'woocommerce_order_bulk_action' );
add_action( 'admin_notices', 'woocommerce_order_bulk_admin_notices' );

View File

@ -7,13 +7,24 @@
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Import
* @version 1.6.4
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* When running the WP importer, ensure attributes exist.
*
* @access public
* @return void
*/ */
function woocommerce_import_start() { function woocommerce_import_start() {
global $wpdb; global $wpdb;
if (!isset($_POST['import_id'])) return;
if (!class_exists('WXR_Parser')) return;
$id = (int) $_POST['import_id']; $id = (int) $_POST['import_id'];
$file = get_attached_file( $id ); $file = get_attached_file( $id );
@ -22,68 +33,56 @@ function woocommerce_import_start() {
if (isset($import_data['posts'])) : if (isset($import_data['posts'])) :
$posts = $import_data['posts']; $posts = $import_data['posts'];
if ($posts && sizeof($posts)>0) foreach ($posts as $post) : if ($posts && sizeof($posts)>0) foreach ($posts as $post) :
if ($post['post_type']=='product') : if ($post['post_type']=='product') :
if ($post['terms'] && sizeof($post['terms'])>0) : if ($post['terms'] && sizeof($post['terms'])>0) :
foreach ($post['terms'] as $term) : foreach ($post['terms'] as $term) :
$domain = $term['domain']; $domain = $term['domain'];
if (strstr($domain, 'pa_')) : if (strstr($domain, 'pa_')) :
// Make sure it exists! // Make sure it exists!
if (!taxonomy_exists( $domain )) : if (!taxonomy_exists( $domain )) :
$nicename = strtolower(sanitize_title(str_replace('pa_', '', $domain))); $nicename = strtolower(sanitize_title(str_replace('pa_', '', $domain)));
$exists_in_db = $wpdb->get_var("SELECT attribute_id FROM ".$wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = '".$nicename."';"); $exists_in_db = $wpdb->get_var( $wpdb->prepare( "SELECT attribute_id FROM " . $wpdb->prefix . "woocommerce_attribute_taxonomies WHERE attribute_name = %s;", $nicename ) );
if (!$exists_in_db) : if (!$exists_in_db) :
// Create the taxonomy // Create the taxonomy
$wpdb->insert( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_name' => $nicename, 'attribute_type' => 'select' ), array( '%s', '%s' ) ); $wpdb->insert( $wpdb->prefix . "woocommerce_attribute_taxonomies", array( 'attribute_name' => $nicename, 'attribute_type' => 'select', 'attribute_orderby' => 'menu_order' ), array( '%s', '%s', '%s' ) );
endif; endif;
// Register the taxonomy now so that the import works! // Register the taxonomy now so that the import works!
register_taxonomy( $domain, register_taxonomy( $domain,
array('product'), array('product'),
array( array(
'hierarchical' => true, 'hierarchical' => true,
'labels' => array(
'name' => $nicename,
'singular_name' => $nicename,
'search_items' => __( 'Search', 'woothemes') . ' ' . $nicename,
'all_items' => __( 'All', 'woothemes') . ' ' . $nicename,
'parent_item' => __( 'Parent', 'woothemes') . ' ' . $nicename,
'parent_item_colon' => __( 'Parent', 'woothemes') . ' ' . $nicename . ':',
'edit_item' => __( 'Edit', 'woothemes') . ' ' . $nicename,
'update_item' => __( 'Update', 'woothemes') . ' ' . $nicename,
'add_new_item' => __( 'Add New', 'woothemes') . ' ' . $nicename,
'new_item_name' => __( 'New', 'woothemes') . ' ' . $nicename
),
'show_ui' => false, 'show_ui' => false,
'query_var' => true, 'query_var' => true,
'rewrite' => array( 'slug' => strtolower(sanitize_title($nicename)), 'with_front' => false, 'hierarchical' => true ), 'rewrite' => false,
) )
); );
endif; endif;
endif; endif;
endforeach; endforeach;
endif; endif;
endif; endif;
endforeach; endforeach;
endif; endif;
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,351 +1,362 @@
<?php <?php
/** /**
* WooCommerce Install * WooCommerce Install
* *
* Plugin install script which adds default pages, taxonomies, and database tables * Plugin install script which adds default pages, taxonomies, and database tables to WordPress. Runs on activation and upgrade.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Install
* @version 2.0.0
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Install woocommerce * Runs the installer.
*
* @access public
* @return void
*/ */
function do_install_woocommerce() { function do_install_woocommerce() {
global $woocommerce_settings, $woocommerce; global $woocommerce_settings, $woocommerce;
// Do install // Do install
woocommerce_default_options(); woocommerce_default_options();
woocommerce_tables_install(); woocommerce_tables_install();
woocommerce_install_custom_fields(); woocommerce_init_roles();
// Register post types
$woocommerce->init_taxonomy();
// Add default taxonomies
woocommerce_default_taxonomies(); woocommerce_default_taxonomies();
// Install folder for uploading files and prevent hotlinking // Install files and folders for uploading files and prevent hotlinking
$upload_dir = wp_upload_dir(); $upload_dir = wp_upload_dir();
$downloads_url = $upload_dir['basedir'] . '/woocommerce_uploads';
if ( wp_mkdir_p($downloads_url) && !file_exists($downloads_url.'/.htaccess') ) : $files = array(
if ($file_handle = fopen( $downloads_url . '/.htaccess', 'w' )) : array(
fwrite($file_handle, 'deny from all'); 'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
fclose($file_handle); 'file' => '.htaccess',
endif; 'content' => 'deny from all'
endif; ),
array(
// Install folder for logs 'base' => $upload_dir['basedir'] . '/woocommerce_uploads',
$logs_url = WP_PLUGIN_DIR . "/" . plugin_basename( dirname(dirname(__FILE__))) . '/logs'; 'file' => 'index.html',
if ( wp_mkdir_p($logs_url) && !file_exists($logs_url.'/.htaccess') ) : 'content' => ''
if ($file_handle = fopen( $logs_url . '/.htaccess', 'w' )) : ),
fwrite($file_handle, 'deny from all'); array(
fclose($file_handle); 'base' => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
endif; 'file' => '.htaccess',
endif; 'content' => 'deny from all'
),
// Clear transient cache (if this is an upgrade then woocommerce_class will be defined) array(
if ( $woocommerce instanceof woocommerce ) $woocommerce->clear_product_transients(); 'base' => WP_PLUGIN_DIR . "/" . plugin_basename( dirname( dirname( __FILE__ ) ) ) . '/logs',
'file' => 'index.html',
'content' => ''
)
);
foreach ( $files as $file ) {
if ( wp_mkdir_p( $file['base'] ) && ! file_exists( trailingslashit( $file['base'] ) . $file['file'] ) ) {
if ( $file_handle = @fopen( trailingslashit( $file['base'] ) . $file['file'], 'w' ) ) {
fwrite( $file_handle, $file['content'] );
fclose( $file_handle );
}
}
}
// Clear transient cache
$woocommerce->clear_product_transients();
// Recompile LESS styles if they are custom
if ( get_option( 'woocommerce_frontend_css' ) == 'yes' ) {
$colors = get_option( 'woocommerce_frontend_css_colors' );
if ( ( ! empty( $colors['primary'] ) && ! empty( $colors['secondary'] ) && ! empty( $colors['highlight'] ) && ! empty( $colors['content_bg'] ) && ! empty( $colors['subtext'] ) ) && ( $colors['primary'] != '#ad74a2' || $colors['secondary'] != '#f7f6f7' || $colors['highlight'] != '#85ad74' || $colors['content_bg'] != '#ffffff' || $colors['subtext'] != '#777777' ) )
woocommerce_compile_less_styles();
}
// Queue upgrades
$current_version = get_option( 'woocommerce_version', null );
$current_db_version = get_option( 'woocommerce_db_version', null );
if ( version_compare( $current_db_version, '2.0', '<' ) && null !== $current_version ) {
update_option( 'woocommerce_needs_update', 1 );
} else {
update_option( 'woocommerce_db_version', $woocommerce->version );
}
// Update version // Update version
update_option( "woocommerce_db_version", $woocommerce->version ); update_option( 'woocommerce_version', $woocommerce->version );
} }
/**
* Add required post meta so queries work
*/
function woocommerce_install_custom_fields() {
// Attachment exclusion
$args = array(
'post_type' => 'attachment',
'numberposts' => -1,
'post_status' => null,
'fields' => 'ids'
);
$attachments = get_posts($args);
if ($attachments) foreach ($attachments as $id) :
add_post_meta($id, '_woocommerce_exclude_image', 0, true);
endforeach;
}
/** /**
* Default options * Default options
* *
* Sets up the default options used on the settings page * Sets up the default options used on the settings page
*
* @access public
* @return void
*/ */
function woocommerce_default_options() { function woocommerce_default_options() {
global $woocommerce_settings; global $woocommerce_settings;
// Include settings so that we can run through defaults
include_once( 'woocommerce-admin-settings.php' );
foreach ($woocommerce_settings as $section) :
foreach ($section as $value) :
if (isset($value['std'])) :
if ($value['type']=='image_width') :
add_option($value['id'].'_width', $value['std']);
add_option($value['id'].'_height', $value['std']);
else :
add_option($value['id'], $value['std']);
endif;
endif;
endforeach;
endforeach;
add_option('woocommerce_shop_slug', 'shop'); // Include settings so that we can run through defaults
include_once( 'settings/settings-init.php' );
foreach ( $woocommerce_settings as $section ) {
foreach ( $section as $value ) {
if ( isset( $value['default'] ) && isset( $value['id'] ) ) {
add_option( $value['id'], $value['default'] );
}
}
}
} }
/** /**
* Create a page * Create a page
*
* @access public
* @param mixed $slug Slug for the new page
* @param mixed $option Option name to store the page's ID
* @param string $page_title (default: '') Title for the new page
* @param string $page_content (default: '') Content for the new page
* @param int $post_parent (default: 0) Parent for the new page
* @return void
*/ */
function woocommerce_create_page( $slug, $option, $page_title = '', $page_content = '', $post_parent = 0 ) { function woocommerce_create_page( $slug, $option, $page_title = '', $page_content = '', $post_parent = 0 ) {
global $wpdb; global $wpdb;
$option_value = get_option($option); $option_value = get_option( $option );
if ($option_value>0) : if ( $option_value > 0 && get_post( $option_value ) )
if (get_post( $option_value )) :
// Page exists
return;
endif;
endif;
$page_found = $wpdb->get_var("SELECT ID FROM " . $wpdb->posts . " WHERE post_name = '$slug' LIMIT 1;");
if ($page_found) :
// Page exists
if (!$option_value) update_option($option, $page_found);
return; return;
endif;
$page_found = $wpdb->get_var( $wpdb->prepare( "SELECT ID FROM " . $wpdb->posts . " WHERE post_name = %s LIMIT 1;", $slug ) );
if ( $page_found ) {
if ( ! $option_value )
update_option( $option, $page_found );
return;
}
$page_data = array( $page_data = array(
'post_status' => 'publish', 'post_status' => 'publish',
'post_type' => 'page', 'post_type' => 'page',
'post_author' => 1, 'post_author' => 1,
'post_name' => $slug, 'post_name' => $slug,
'post_title' => $page_title, 'post_title' => $page_title,
'post_content' => $page_content, 'post_content' => $page_content,
'post_parent' => $post_parent, 'post_parent' => $post_parent,
'comment_status' => 'closed' 'comment_status' => 'closed'
); );
$page_id = wp_insert_post($page_data); $page_id = wp_insert_post( $page_data );
update_option($option, $page_id); update_option( $option, $page_id );
} }
/** /**
* Create pages * Create pages that the plugin relies on, storing page id's in variables.
* *
* Creates pages that the plugin relies on, storing page id's in variables. * @access public
* @return void
*/ */
function woocommerce_create_pages() { function woocommerce_create_pages() {
// Shop page // Shop page
woocommerce_create_page( esc_sql( _x('shop', 'page_slug', 'woothemes') ), 'woocommerce_shop_page_id', __('Shop', 'woothemes'), '' ); woocommerce_create_page( esc_sql( _x( 'shop', 'page_slug', 'woocommerce' ) ), 'woocommerce_shop_page_id', __( 'Shop', 'woocommerce' ), '' );
// Cart page // Cart page
woocommerce_create_page( esc_sql( _x('cart', 'page_slug', 'woothemes') ), 'woocommerce_cart_page_id', __('Cart', 'woothemes'), '[woocommerce_cart]' ); woocommerce_create_page( esc_sql( _x( 'cart', 'page_slug', 'woocommerce' ) ), 'woocommerce_cart_page_id', __( 'Cart', 'woocommerce' ), '[woocommerce_cart]' );
// Checkout page // Checkout page
woocommerce_create_page( esc_sql( _x('checkout', 'page_slug', 'woothemes') ), 'woocommerce_checkout_page_id', __('Checkout', 'woothemes'), '[woocommerce_checkout]' ); woocommerce_create_page( esc_sql( _x( 'checkout', 'page_slug', 'woocommerce' ) ), 'woocommerce_checkout_page_id', __( 'Checkout', 'woocommerce' ), '[woocommerce_checkout]' );
// Order tracking page // Order tracking page
woocommerce_create_page( esc_sql( _x('order-tracking', 'page_slug', 'woothemes') ), 'woocommerce_order_tracking_page_id', __('Track your order', 'woothemes'), '[woocommerce_order_tracking]' ); woocommerce_create_page( esc_sql( _x( 'order-tracking', 'page_slug', 'woocommerce' ) ), 'woocommerce_order_tracking_page_id', __( 'Track your order', 'woocommerce' ), '[woocommerce_order_tracking]' );
// My Account page // My Account page
woocommerce_create_page( esc_sql( _x('my-account', 'page_slug', 'woothemes') ), 'woocommerce_myaccount_page_id', __('My Account', 'woothemes'), '[woocommerce_my_account]' ); woocommerce_create_page( esc_sql( _x( 'my-account', 'page_slug', 'woocommerce' ) ), 'woocommerce_myaccount_page_id', __( 'My Account', 'woocommerce' ), '[woocommerce_my_account]' );
// Lost password page
woocommerce_create_page( esc_sql( _x( 'lost-password', 'page_slug', 'woocommerce' ) ), 'woocommerce_lost_password_page_id', __( 'Lost Password', 'woocommerce' ), '[woocommerce_lost_password]', woocommerce_get_page_id( 'myaccount' ) );
// Edit address page // Edit address page
woocommerce_create_page( esc_sql( _x('edit-address', 'page_slug', 'woothemes') ), 'woocommerce_edit_address_page_id', __('Edit My Address', 'woothemes'), '[woocommerce_edit_address]', get_option('woocommerce_myaccount_page_id') ); woocommerce_create_page( esc_sql( _x( 'edit-address', 'page_slug', 'woocommerce' ) ), 'woocommerce_edit_address_page_id', __( 'Edit My Address', 'woocommerce' ), '[woocommerce_edit_address]', woocommerce_get_page_id( 'myaccount' ) );
// View order page // View order page
woocommerce_create_page( esc_sql( _x('view-order', 'page_slug', 'woothemes') ), 'woocommerce_view_order_page_id', __('View Order', 'woothemes'), '[woocommerce_view_order]', get_option('woocommerce_myaccount_page_id') ); woocommerce_create_page( esc_sql( _x( 'view-order', 'page_slug', 'woocommerce' ) ), 'woocommerce_view_order_page_id', __( 'View Order', 'woocommerce' ), '[woocommerce_view_order]', woocommerce_get_page_id( 'myaccount' ) );
// Change password page // Change password page
woocommerce_create_page( esc_sql( _x('change-password', 'page_slug', 'woothemes') ), 'woocommerce_change_password_page_id', __('Change Password', 'woothemes'), '[woocommerce_change_password]', get_option('woocommerce_myaccount_page_id') ); woocommerce_create_page( esc_sql( _x( 'change-password', 'page_slug', 'woocommerce' ) ), 'woocommerce_change_password_page_id', __( 'Change Password', 'woocommerce' ), '[woocommerce_change_password]', woocommerce_get_page_id( 'myaccount' ) );
// Pay page // Pay page
woocommerce_create_page( esc_sql( _x('pay', 'page_slug', 'woothemes') ), 'woocommerce_pay_page_id', __('Checkout &rarr; Pay', 'woothemes'), '[woocommerce_pay]', get_option('woocommerce_checkout_page_id') ); woocommerce_create_page( esc_sql( _x( 'pay', 'page_slug', 'woocommerce' ) ), 'woocommerce_pay_page_id', __( 'Checkout &rarr; Pay', 'woocommerce' ), '[woocommerce_pay]', woocommerce_get_page_id( 'checkout' ) );
// Thanks page // Thanks page
woocommerce_create_page( esc_sql( _x('order-received', 'page_slug', 'woothemes') ), 'woocommerce_thanks_page_id', __('Order Received', 'woothemes'), '[woocommerce_thankyou]', get_option('woocommerce_checkout_page_id') ); woocommerce_create_page( esc_sql( _x( 'order-received', 'page_slug', 'woocommerce' ) ), 'woocommerce_thanks_page_id', __( 'Order Received', 'woocommerce' ), '[woocommerce_thankyou]', woocommerce_get_page_id( 'checkout' ) );
} }
/** /**
* Table Install * Set up the database tables which the plugin needs to function.
* *
* Sets up the database tables which the plugin needs to function. * @access public
* @return void
*/ */
function woocommerce_tables_install() { function woocommerce_tables_install() {
global $wpdb; global $wpdb, $woocommerce;
$wpdb->hide_errors(); $wpdb->hide_errors();
$collate = ''; $collate = '';
if($wpdb->supports_collation()) { if ( $wpdb->has_cap( 'collation' ) ) {
if(!empty($wpdb->charset)) $collate = "DEFAULT CHARACTER SET $wpdb->charset"; if( ! empty($wpdb->charset ) )
if(!empty($wpdb->collate)) $collate .= " COLLATE $wpdb->collate"; $collate .= "DEFAULT CHARACTER SET $wpdb->charset";
if( ! empty($wpdb->collate ) )
$collate .= " COLLATE $wpdb->collate";
} }
require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
// Table for storing attribute taxonomies - these are user defined // Table for storing attribute taxonomies - these are user defined
$sql = "CREATE TABLE ". $wpdb->prefix . "woocommerce_attribute_taxonomies" ." ( $sql = "
attribute_id mediumint(9) NOT NULL AUTO_INCREMENT, CREATE TABLE ". $wpdb->prefix . "woocommerce_attribute_taxonomies (
attribute_name varchar(200) NOT NULL, attribute_id bigint(20) NOT NULL auto_increment,
attribute_label longtext NULL, attribute_name varchar(200) NOT NULL,
attribute_type varchar(200) NOT NULL, attribute_label longtext NULL,
PRIMARY KEY id (attribute_id)) $collate;"; attribute_type varchar(200) NOT NULL,
dbDelta($sql); attribute_orderby varchar(200) NOT NULL,
PRIMARY KEY (attribute_id)
// Table for storing user and guest download permissions ) $collate;
$downloadable_products_table = $wpdb->prefix . "woocommerce_downloadable_product_permissions"; ";
dbDelta( $sql );
// Drop primary key first
if ($wpdb->get_var("SHOW TABLES LIKE '$downloadable_products_table'") == $downloadable_products_table) {
$wpdb->query("ALTER TABLE $downloadable_products_table DROP PRIMARY KEY");
}
// Now create it
$sql = "CREATE TABLE ". $downloadable_products_table ." (
product_id mediumint(9) NOT NULL,
order_id mediumint(9) NOT NULL DEFAULT 0,
order_key varchar(200) NOT NULL,
user_email varchar(200) NOT NULL,
user_id mediumint(9) NULL,
downloads_remaining varchar(9) NULL,
PRIMARY KEY id (product_id,order_id,order_key)) $collate;";
dbDelta($sql);
// Term meta table - sadly WordPress does not have termmeta so we need our own // Term meta table - sadly WordPress does not have termmeta so we need our own
$sql = "CREATE TABLE ". $wpdb->prefix . "woocommerce_termmeta" ." ( $sql = "
meta_id bigint(20) NOT NULL AUTO_INCREMENT, CREATE TABLE ". $wpdb->prefix . "woocommerce_termmeta (
woocommerce_term_id bigint(20) NOT NULL, meta_id bigint(20) NOT NULL AUTO_INCREMENT,
meta_key varchar(255) NULL, woocommerce_term_id bigint(20) NOT NULL,
meta_value longtext NULL, meta_key varchar(255) NULL,
PRIMARY KEY id (meta_id)) $collate;"; meta_value longtext NULL,
dbDelta($sql); PRIMARY KEY (meta_id)
) $collate;
// Update woocommerce_downloadable_product_permissions table to include order ID's as well as keys ";
$results = $wpdb->get_results( "SELECT * FROM ".$wpdb->prefix."woocommerce_downloadable_product_permissions WHERE order_id = 0;" ); dbDelta( $sql );
if ($results) foreach ($results as $result) :
if (!$result->order_key) continue;
$order_id = $wpdb->get_var( $wpdb->prepare("SELECT post_id FROM ".$wpdb->postmeta." WHERE meta_key = '_order_key' AND meta_value = '%s' LIMIT 1;", $result->order_key) );
if ($order_id) :
$wpdb->update( $wpdb->prefix . "woocommerce_downloadable_product_permissions", array(
'order_id' => $order_id,
), array(
'product_id' => $result->product_id,
'order_key' => $result->order_key
), array( '%s' ), array( '%s', '%s' ) );
endif;
endforeach;
// Upgrade old meta keys for product data
$meta = array('sku', 'downloadable', 'virtual', 'price', 'visibility', 'stock', 'stock_status', 'backorders', 'manage_stock', 'sale_price', 'regular_price', 'weight', 'length', 'width', 'height', 'tax_status', 'tax_class', 'upsell_ids', 'crosssell_ids', 'sale_price_dates_from', 'sale_price_dates_to', 'min_variation_price', 'max_variation_price', 'featured', 'product_attributes', 'file_path', 'download_limit', 'product_url', 'min_variation_price', 'max_variation_price');
$wpdb->query("
UPDATE $wpdb->postmeta
LEFT JOIN $wpdb->posts ON ( $wpdb->postmeta.post_id = $wpdb->posts.ID )
SET meta_key = CONCAT('_', meta_key)
WHERE meta_key IN ('". implode("', '", $meta) ."')
AND $wpdb->posts.post_type = 'product'
");
$wpdb->show_errors();
// Table for storing user and guest download permissions
// KEY(order_id, product_id, download_id) used for organizing downloads on the My Account page
$sql = "
CREATE TABLE ". $wpdb->prefix . "woocommerce_downloadable_product_permissions (
download_id varchar(32) NOT NULL,
product_id bigint(20) NOT NULL,
order_id bigint(20) NOT NULL DEFAULT 0,
order_key varchar(200) NOT NULL,
user_email varchar(200) NOT NULL,
user_id bigint(20) NULL,
downloads_remaining varchar(9) NULL,
access_granted datetime NOT NULL default '0000-00-00 00:00:00',
access_expires datetime NULL default null,
download_count bigint(20) NOT NULL DEFAULT 0,
PRIMARY KEY (product_id,order_id,order_key,download_id),
KEY (order_id,product_id,download_id)
) $collate;
";
dbDelta( $sql );
// Order line items are stored in a table to make them easily queryable for reports
$sql = "
CREATE TABLE ". $wpdb->prefix . "woocommerce_order_items (
order_item_id bigint(20) NOT NULL auto_increment,
order_item_name longtext NOT NULL DEFAULT '',
order_item_type varchar(200) NOT NULL DEFAULT '',
order_id bigint(20) NOT NULL,
PRIMARY KEY (order_item_id)
) $collate;
";
dbDelta( $sql );
// Order line item meta is stored in a table for storing extra data.
$sql = "
CREATE TABLE ". $wpdb->prefix . "woocommerce_order_itemmeta (
meta_id bigint(20) NOT NULL auto_increment,
order_item_id bigint(20) NOT NULL,
meta_key varchar(255) NULL,
meta_value longtext NULL,
PRIMARY KEY (meta_id)
) $collate;
";
dbDelta( $sql );
// Tax Rates are stored inside 2 tables making tax queries simple and efficient.
$sql = "
CREATE TABLE ". $wpdb->prefix . "woocommerce_tax_rates (
tax_rate_id bigint(20) NOT NULL auto_increment,
tax_rate_country varchar(200) NOT NULL DEFAULT '',
tax_rate_state varchar(200) NOT NULL DEFAULT '',
tax_rate varchar(200) NOT NULL DEFAULT '',
tax_rate_name varchar(200) NOT NULL DEFAULT '',
tax_rate_priority bigint(20) NOT NULL,
tax_rate_compound int(1) NOT NULL DEFAULT 0,
tax_rate_shipping int(1) NOT NULL DEFAULT 1,
tax_rate_order bigint(20) NOT NULL,
tax_rate_class varchar(200) NOT NULL DEFAULT '',
PRIMARY KEY (tax_rate_id)
) $collate;
";
dbDelta( $sql );
// Each rate can be applied to more than one postcode/city hence the second table.
$sql = "
CREATE TABLE ". $wpdb->prefix . "woocommerce_tax_rate_locations (
location_id bigint(20) NOT NULL auto_increment,
location_code varchar(255) NOT NULL,
tax_rate_id bigint(20) NOT NULL,
location_type varchar(40) NOT NULL,
PRIMARY KEY (location_id)
) $collate;
";
dbDelta( $sql );
} }
/** /**
* Default taxonomies * Add the default terms for WC taxonomies - product types and order statuses. Modify this at your own risk.
* *
* Adds the default terms for taxonomies - product types and order statuses. Modify at your own risk. * @access public
* @return void
*/ */
function woocommerce_default_taxonomies() { function woocommerce_default_taxonomies() {
if (!post_type_exists('product')) :
register_post_type('product',
array(
'public' => true,
'show_ui' => true,
'capability_type' => 'post',
'publicly_queryable' => true,
'exclude_from_search' => false,
'hierarchical' => true,
'query_var' => true,
'supports' => array( 'title', 'editor', 'excerpt', 'thumbnail', 'comments' ),
'show_in_nav_menus' => false,
)
);
endif;
if (!taxonomy_exists('product_type')) :
register_taxonomy( 'product_type', array('post', 'product'));
register_taxonomy( 'shop_order_status', array('post', 'product'));
endif;
$product_types = array(
'simple',
'grouped',
'variable',
'external'
);
foreach($product_types as $type) {
if (!get_term_by( 'slug', sanitize_title($type), 'product_type')) {
wp_insert_term($type, 'product_type');
}
}
$order_status = array(
'pending',
'failed',
'on-hold',
'processing',
'completed',
'refunded',
'cancelled'
);
foreach($order_status as $status) {
if (!get_term_by( 'slug', sanitize_title($status), 'shop_order_status')) {
wp_insert_term($status, 'shop_order_status');
}
}
// Upgrade from old downloadable/virtual product types
$downloadable_type = get_term_by('slug', 'downloadable', 'product_type');
if ($downloadable_type) :
$products = get_objects_in_term( $downloadable_type->term_id, 'product_type' );
foreach ($products as $product) :
update_post_meta( $product, '_downloadable', 'yes' );
update_post_meta( $product, '_virtual', 'yes' );
wp_set_object_terms( $product, 'simple', 'product_type');
endforeach;
endif;
$virtual_type = get_term_by('slug', 'virtual', 'product_type');
if ($virtual_type) :
$products = get_objects_in_term( $virtual_type->term_id, 'product_type' );
foreach ($products as $product) :
update_post_meta( $product, '_downloadable', 'no' );
update_post_meta( $product, '_virtual', 'yes' );
wp_set_object_terms( $product, 'simple', 'product_type');
endforeach;
endif;
$taxonomies = array(
'product_type' => array(
'simple',
'grouped',
'variable',
'external'
),
'shop_order_status' => array(
'pending',
'failed',
'on-hold',
'processing',
'completed',
'refunded',
'cancelled'
)
);
foreach ( $taxonomies as $taxonomy => $terms ) {
foreach ( $terms as $term ) {
if ( ! get_term_by( 'slug', sanitize_title( $term ), $taxonomy ) ) {
wp_insert_term( $term, $taxonomy );
}
}
}
} }

File diff suppressed because it is too large Load Diff

View File

@ -1,558 +0,0 @@
<?php
/**
* Functions for outputting and updating settings pages
*
* @author WooThemes
* @category Admin
* @package WooCommerce
*/
/**
* Update options
*
* Updates the options on the woocommerce settings pages. Returns true if saved.
*/
function woocommerce_update_options($options) {
if(!isset($_POST) || !$_POST) return false;
foreach ($options as $value) {
if (isset($value['id']) && $value['id']=='woocommerce_tax_rates') :
// Tate rates saving
$tax_classes = array();
$tax_countries = array();
$tax_rate = array();
$tax_rates = array();
$tax_shipping = array();
if (isset($_POST['tax_class'])) $tax_classes = $_POST['tax_class'];
if (isset($_POST['tax_country'])) $tax_countries = $_POST['tax_country'];
if (isset($_POST['tax_rate'])) $tax_rate = $_POST['tax_rate'];
if (isset($_POST['tax_shipping'])) $tax_shipping = $_POST['tax_shipping'];
for ($i=0; $i<sizeof($tax_classes); $i++) :
if (isset($tax_classes[$i]) && isset($tax_countries[$i]) && isset($tax_rate[$i]) && is_numeric($tax_rate[$i])) :
$rate = esc_attr(trim($tax_rate[$i]));
if ($rate>100) $rate = 100;
$rate = number_format($rate, 4, '.', '');
$class = woocommerce_clean($tax_classes[$i]);
if (isset($tax_shipping[$i]) && $tax_shipping[$i]) $shipping = 'yes'; else $shipping = 'no';
// Handle countries
$counties_array = array();
$countries = $tax_countries[$i];
if ($countries) foreach ($countries as $country) :
$country = woocommerce_clean($country);
$state = '*';
if (strstr($country, ':')) :
$cr = explode(':', $country);
$country = current($cr);
$state = end($cr);
endif;
$counties_array[trim($country)][] = trim($state);
endforeach;
$tax_rates[] = array(
'countries' => $counties_array,
'rate' => $rate,
'shipping' => $shipping,
'class' => $class
);
endif;
endfor;
update_option($value['id'], $tax_rates);
elseif (isset($value['type']) && $value['type']=='multi_select_countries') :
// Get countries array
if (isset($_POST[$value['id']])) $selected_countries = $_POST[$value['id']]; else $selected_countries = array();
update_option($value['id'], $selected_countries);
elseif ( isset($value['id']) && ( $value['id'] == 'woocommerce_price_thousand_sep' || $value['id'] == 'woocommerce_price_decimal_sep' ) ):
// price separators get a special treatment as they should allow a spaces (don't trim)
if( isset( $_POST[ $value['id'] ] ) ) {
update_option($value['id'], $_POST[$value['id']] );
} else {
delete_option($value['id']);
}
elseif (isset($value['type']) && $value['type']=='checkbox') :
if(isset($value['id']) && isset($_POST[$value['id']])) {
update_option($value['id'], 'yes');
} else {
update_option($value['id'], 'no');
}
elseif (isset($value['type']) && $value['type']=='image_width') :
if(isset($value['id']) && isset($_POST[$value['id'].'_width'])) {
update_option($value['id'].'_width', woocommerce_clean($_POST[$value['id'].'_width']));
update_option($value['id'].'_height', woocommerce_clean($_POST[$value['id'].'_height']));
if (isset($_POST[$value['id'].'_crop'])) :
update_option($value['id'].'_crop', 1);
else :
update_option($value['id'].'_crop', 0);
endif;
} else {
update_option($value['id'].'_width', $value['std']);
update_option($value['id'].'_height', $value['std']);
update_option($value['id'].'_crop', 1);
}
else :
if(isset($value['id']) && isset($_POST[$value['id']])) {
update_option($value['id'], woocommerce_clean($_POST[$value['id']]));
} else {
delete_option($value['id']);
}
endif;
}
return true;
}
/**
* Admin fields
*
* Loops though the woocommerce options array and outputs each field.
*/
function woocommerce_admin_fields($options) {
global $woocommerce;
foreach ($options as $value) :
if (!isset( $value['name'] ) ) $value['name'] = '';
if (!isset( $value['class'] )) $value['class'] = '';
if (!isset( $value['css'] )) $value['css'] = '';
if (!isset( $value['std'] )) $value['std'] = '';
switch($value['type']) :
case 'title':
if (isset($value['name']) && $value['name']) echo '<h3>'.$value['name'].'</h3>';
if (isset($value['desc']) && $value['desc']) echo wpautop(wptexturize($value['desc']));
echo '<table class="form-table">'. "\n\n";
if (isset($value['id']) && $value['id']) do_action('woocommerce_settings_'.sanitize_title($value['id']));
break;
case 'sectionend':
if (isset($value['id']) && $value['id']) do_action('woocommerce_settings_'.sanitize_title($value['id']).'_end');
echo '</table>';
if (isset($value['id']) && $value['id']) do_action('woocommerce_settings_'.sanitize_title($value['id']).'_after');
break;
case 'text':
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name']; ?></th>
<td class="forminp"><input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="<?php echo esc_attr( $value['type'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>" value="<?php if ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) { echo esc_attr( stripslashes( get_option($value['id'] ) ) ); } else { echo esc_attr( $value['std'] ); } ?>" /> <span class="description"><?php echo $value['desc']; ?></span></td>
</tr><?php
break;
case 'color' :
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name']; ?></th>
<td class="forminp"><input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="text" style="<?php echo esc_attr( $value['css'] ); ?>" value="<?php if ( get_option( $value['id'] ) !== false && get_option( $value['id'] ) !== null ) { echo esc_attr( stripslashes( get_option($value['id'] ) ) ); } else { echo esc_attr( $value['std'] ); } ?>" class="colorpick" /> <span class="description"><?php echo $value['desc']; ?></span> <div id="colorPickerDiv_<?php echo esc_attr( $value['id'] ); ?>" class="colorpickdiv" style="z-index: 100;background:#eee;border:1px solid #ccc;position:absolute;display:none;"></div></td>
</tr><?php
break;
case 'image_width' :
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<?php _e('Width', 'woothemes'); ?> <input name="<?php echo esc_attr( $value['id'] ); ?>_width" id="<?php echo esc_attr( $value['id'] ); ?>_width" type="text" size="3" value="<?php if ( $size = get_option( $value['id'].'_width') ) echo stripslashes($size); else echo $value['std']; ?>" />
<?php _e('Height', 'woothemes'); ?> <input name="<?php echo esc_attr( $value['id'] ); ?>_height" id="<?php echo esc_attr( $value['id'] ); ?>_height" type="text" size="3" value="<?php if ( $size = get_option( $value['id'].'_height') ) echo stripslashes($size); else echo $value['std']; ?>" />
<label><?php _e('Hard Crop', 'woothemes'); ?> <input name="<?php echo esc_attr( $value['id'] ); ?>_crop" id="<?php echo esc_attr( $value['id'] ); ?>_crop" type="checkbox" <?php if (get_option( $value['id'].'_crop')!='') checked(get_option( $value['id'].'_crop'), 1); else checked(1); ?> /></label>
<span class="description"><?php echo $value['desc'] ?></span></td>
</tr><?php
break;
case 'select':
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp"><select name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>" class="<?php if (isset($value['class'])) echo $value['class']; ?>">
<?php
foreach ($value['options'] as $key => $val) {
?>
<option value="<?php echo esc_attr( $key ); ?>" <?php if (get_option($value['id']) == $key) { ?> selected="selected" <?php } ?>><?php echo ucfirst($val) ?></option>
<?php
}
?>
</select> <span class="description"><?php echo $value['desc'] ?></span>
</td>
</tr><?php
break;
case 'checkbox' :
if (!isset($value['hide_if_checked'])) $value['hide_if_checked'] = false;
if (!isset($value['show_if_checked'])) $value['show_if_checked'] = false;
if (!isset($value['checkboxgroup']) || (isset($value['checkboxgroup']) && $value['checkboxgroup']=='start')) :
?>
<tr valign="top" class="<?php
if ($value['hide_if_checked']=='yes' || $value['show_if_checked']=='yes') echo 'hidden_option';
if ($value['hide_if_checked']=='option') echo 'hide_options_if_checked';
if ($value['show_if_checked']=='option') echo 'show_options_if_checked';
?>">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<fieldset>
<?php
else :
?>
<fieldset class="<?php
if ($value['hide_if_checked']=='yes' || $value['show_if_checked']=='yes') echo 'hidden_option';
if ($value['hide_if_checked']=='option') echo 'hide_options_if_checked';
if ($value['show_if_checked']=='option') echo 'show_options_if_checked';
?>">
<?php
endif;
?>
<legend class="screen-reader-text"><span><?php echo $value['name'] ?></span></legend>
<label for="<?php echo $value['id'] ?>">
<input name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" type="checkbox" value="1" <?php checked(get_option($value['id']), 'yes'); ?> />
<?php echo $value['desc'] ?></label><br>
<?php
if (!isset($value['checkboxgroup']) || (isset($value['checkboxgroup']) && $value['checkboxgroup']=='end')) :
?>
</fieldset>
</td>
</tr>
<?php
else :
?>
</fieldset>
<?php
endif;
break;
case 'textarea':
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<textarea <?php if ( isset($value['args']) ) echo $value['args'] . ' '; ?>name="<?php echo esc_attr( $value['id'] ); ?>" id="<?php echo esc_attr( $value['id'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>"><?php if (get_option($value['id'])) echo esc_textarea(stripslashes(get_option($value['id']))); else echo esc_textarea( $value['std'] ); ?></textarea> <span class="description"><?php echo $value['desc'] ?></span>
</td>
</tr><?php
break;
case 'single_select_page' :
$page_setting = (int) get_option($value['id']);
$args = array( 'name' => $value['id'],
'id' => $value['id'],
'sort_column' => 'menu_order',
'sort_order' => 'ASC',
'show_option_none' => ' ',
'class' => $value['class'],
'echo' => false,
'selected' => $page_setting);
if( isset($value['args']) ) $args = wp_parse_args($value['args'], $args);
?><tr valign="top" class="single_select_page">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<?php echo str_replace(' id=', " data-placeholder='".__('Select a page...', 'woothemes')."' style='".$value['css']."' class='".$value['class']."' id=", wp_dropdown_pages($args)); ?> <span class="description"><?php echo $value['desc'] ?></span>
</td>
</tr><?php
break;
case 'single_select_country' :
$countries = $woocommerce->countries->countries;
$country_setting = (string) get_option($value['id']);
if (strstr($country_setting, ':')) :
$country = current(explode(':', $country_setting));
$state = end(explode(':', $country_setting));
else :
$country = $country_setting;
$state = '*';
endif;
?><tr valign="top">
<th scope="rpw" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp"><select name="<?php echo esc_attr( $value['id'] ); ?>" style="<?php echo esc_attr( $value['css'] ); ?>" data-placeholder="<?php _e('Choose a country&hellip;', 'woothemes'); ?>" title="Country" class="chosen_select">
<?php echo $woocommerce->countries->country_dropdown_options($country, $state); ?>
</select> <span class="description"><?php echo $value['desc'] ?></span>
</td>
</tr><?php
break;
case 'multi_select_countries' :
$countries = $woocommerce->countries->countries;
asort($countries);
$selections = (array) get_option($value['id']);
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<select multiple="multiple" name="<?php echo esc_attr( $value['id'] ); ?>[]" style="width:450px;" data-placeholder="<?php _e('Choose countries&hellip;', 'woothemes'); ?>" title="Country" class="chosen_select">
<?php
if ($countries) foreach ($countries as $key=>$val) :
echo '<option value="'.$key.'" '.selected( in_array($key, $selections), true, false ).'>'.$val.'</option>';
endforeach;
?>
</select>
</td>
</tr><?php
break;
case 'tax_rates' :
$tax_classes = array_filter(array_map('trim', explode("\n", get_option('woocommerce_tax_classes'))));
$tax_rates = get_option('woocommerce_tax_rates');
?><tr valign="top">
<th scope="row" class="titledesc"><?php echo $value['name'] ?></th>
<td class="forminp">
<table class="taxrows widefat" cellspacing="0">
<thead>
<tr>
<th class="check-column"><input type="checkbox"></th>
<th class="country"><?php _e('Countries/states', 'woothemes'); ?></th>
<th><?php _e('Tax Class', 'woothemes'); ?></th>
<th><?php _e('Rate', 'woothemes'); ?> <a class="tips" tip="<?php _e('Enter a tax rate (percentage) to 4 decimal places.', 'woothemes'); ?>">[?]</a></th>
<th><?php _e('Apply to shipping', 'woothemes'); ?> <a class="tips" tip="<?php _e('Choose whether or not this tax rate also gets applied to shipping.', 'woothemes'); ?>">[?]</a></th>
</tr>
</thead>
<tfoot>
<tr>
<th colspan="2"><a href="#" class="add button"><?php _e('+ Add Tax Rate', 'woothemes'); ?></a></th>
<th colspan="3"><a href="#" class="dupe button"><?php _e('Duplicate selected rows', 'woothemes'); ?></a> <a href="#" class="remove button"><?php _e('Delete selected rows', 'woothemes'); ?></a></th>
</tr>
</tfoot>
<tbody id="tax_rates">
<?php $i = -1; if ($tax_rates && is_array($tax_rates) && sizeof($tax_rates)>0) foreach( $tax_rates as $rate ) : $i++; ?>
<tr class="tax_rate">
<td class="check-column"><input type="checkbox" name="select" /></td>
<td class="country">
<p class="edit"><button class="edit_options button"><?php _e('Edit', 'woothemes') ?></button> <label><?php echo woocommerce_tax_row_label( $rate['countries'] ); ?></label></p>
<div class="options" style="display:none">
<select name="tax_country[<?php echo $i; ?>][]" data-placeholder="<?php _e('Select countries/states&hellip;', 'woothemes'); ?>" class="tax_chosen_select select" size="10" multiple="multiple">
<?php echo $woocommerce->countries->country_multiselect_options( $rate['countries'] ); ?>
</select>
<?php echo '<p><button class="select_all button">'.__('All', 'woothemes').'</button><button class="select_none button">'.__('None', 'woothemes').'</button><button class="button select_us_states">'.__('US States', 'woothemes').'</button><button class="button select_europe">'.__('EU States', 'woothemes').'</button></p>'; ?>
</div>
</td>
<td class="tax_class">
<select name="tax_class[<?php echo $i; ?>]" title="Tax Class" class="select">
<option value=""><?php _e('Standard Rate', 'woothemes'); ?></option>
<?php
if ($tax_classes) foreach ($tax_classes as $class) :
echo '<option value="'.sanitize_title($class).'"';
selected($rate['class'], sanitize_title($class));
echo '>'.$class.'</option>';
endforeach;
?>
</select>
</td>
<td class="rate">
<input type="text" class="text" value="<?php echo esc_attr( $rate['rate'] ); ?>" name="tax_rate[<?php echo $i; ?>]" title="<?php _e('Rate', 'woothemes'); ?>" placeholder="<?php _e('Rate', 'woothemes'); ?>" maxlength="8" />%
</td>
<td class="apply_to_shipping">
<input type="checkbox" class="checkbox" name="tax_shipping[<?php echo $i; ?>]" <?php if (isset($rate['shipping'])) checked($rate['shipping'], 'yes'); ?> />
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<script type="text/javascript">
jQuery(function() {
jQuery('tr.tax_rate .edit_options').live('click', function(){
jQuery(this).closest('td').find('.options').slideToggle();
if (jQuery(this).text()=='<?php _e('Edit', 'woothemes'); ?>') {
jQuery(this).closest('tr').find("select.tax_chosen_select").chosen();
jQuery(this).text('<?php _e('Done', 'woothemes'); ?>');
} else {
jQuery(this).text('<?php _e('Edit', 'woothemes'); ?>');
}
return false;
});
jQuery('tr.tax_rate .select_all').live('click', function(){
jQuery(this).closest('td').find('select option').attr("selected","selected");
jQuery(this).closest('td').find('select.tax_chosen_select').trigger("change");
return false;
});
jQuery('tr.tax_rate .select_none').live('click', function(){
jQuery(this).closest('td').find('select option').removeAttr("selected");
jQuery(this).closest('td').find('select.tax_chosen_select').trigger("change");
return false;
});
jQuery('tr.tax_rate .select_us_states').live('click', function(){
jQuery(this).closest('td').find('select optgroup[label="United States"] option').attr("selected","selected");
jQuery(this).closest('td').find('select.tax_chosen_select').trigger("change");
return false;
});
jQuery('tr.tax_rate .options select').live('change', function(){
jQuery(this).trigger("liszt:updated");
jQuery(this).closest('td').find('label').text( jQuery(":selected", this).length + '<?php _e(' countries/states selected', 'woothemes') ?>' );
});
jQuery('tr.tax_rate .select_europe').live('click', function(){
jQuery(this).closest('td').find('option[value="AL"], option[value="AD"], option[value="AM"], option[value="AT"], option[value="BY"], option[value="BE"], option[value="BA"], option[value="BG"], option[value="CH"], option[value="CY"], option[value="CZ"], option[value="DE"], option[value="DK"], option[value="EE"], option[value="ES"], option[value="FO"], option[value="FI"], option[value="FR"], option[value="GB"], option[value="GE"], option[value="GI"], option[value="GR"], option[value="HU"], option[value="HR"], option[value="IE"], option[value="IS"], option[value="IT"], option[value="LT"], option[value="LU"], option[value="LV"], option[value="MC"], option[value="MK"], option[value="MT"], option[value="NO"], option[value="NL"], option[value="PO"], option[value="PT"], option[value="RO"], option[value="RU"], option[value="SE"], option[value="SI"], option[value="SK"], option[value="SM"], option[value="TR"], option[value="UA"], option[value="VA"]').attr("selected","selected");
jQuery(this).closest('td').find('select.tax_chosen_select').trigger("change");
return false;
});
jQuery('.taxrows a.add').live('click', function(){
var size = jQuery('#tax_rates tr').size();
// Add the row
jQuery('<tr class="tax_rate new_rate">\
<td class="check-column"><input type="checkbox" name="select" /></td>\
<td class="country">\
<p class="edit"><button class="edit_options button"><?php _e('Edit', 'woothemes') ?></button> <label><?php _e('No countries selected', 'woothemes'); ?></label></p>\
<div class="options" style="display:none">\
<select name="tax_country[' + size + '][]" data-placeholder="<?php _e('Select countries/states&hellip;', 'woothemes'); ?>" class="tax_chosen_select select" size="10" multiple="multiple">\
<?php echo $woocommerce->countries->country_multiselect_options(); ?>\
</select>\
<?php echo '<p><button class="select_all button">'.__('All', 'woothemes').'</button><button class="select_none button">'.__('None', 'woothemes').'</button><button class="button select_us_states">'.__('US States', 'woothemes').'</button><button class="button select_europe">'.__('EU States', 'woothemes').'</button></p>'; ?>\
</div>\
</td>\
<td class="tax_class">\
<select name="tax_class[' + size + ']" title="Tax Class" class="select">\
<option value=""><?php _e('Standard Rate', 'woothemes'); ?></option>\
<?php
if ($tax_classes) foreach ($tax_classes as $class) :
echo '<option value="'.sanitize_title($class).'">'.$class.'</option>';
endforeach;
?>
</select>\
</td>\
<td class="rate">\
<input type="text" class="text" name="tax_rate[' + size + ']" title="<?php _e('Rate', 'woothemes'); ?>" placeholder="<?php _e('Rate', 'woothemes'); ?>" maxlength="8" />%\
</td>\
<td class="apply_to_shipping">\
<input type="checkbox" class="checkbox" name="tax_shipping[' + size + ']" />\
</td>\
</tr>').appendTo('#tax_rates');
jQuery(".new_rate select.tax_chosen_select").chosen();
jQuery(".new_rate").removeClass('new_rate');
return false;
});
// Remove row
jQuery('.taxrows a.remove').live('click', function(){
var answer = confirm("<?php _e('Delete the selected rates?', 'woothemes'); ?>")
if (answer) {
jQuery('table.taxrows tbody tr td.check-column input:checked').each(function(i, el){
jQuery(el).closest('tr').find('input.text, input.checkbox, select.select').val('');
jQuery(el).closest('tr').hide();
});
}
return false;
});
// Dupe row
jQuery('.taxrows a.dupe').live('click', function(){
var answer = confirm("<?php _e('Duplicate the selected rates?', 'woothemes'); ?>")
if (answer) {
jQuery('table.taxrows tbody tr td.check-column input:checked').each(function(i, el){
var dupe = jQuery(el).closest('tr').clone()
// Remove chosen selector
dupe.find('.chzn-done').removeClass('chzn-done').removeAttr('id').removeAttr('style');
dupe.find('.chzn-container').remove();
// Append
jQuery('table.taxrows tbody').append( dupe );
});
// Re-index keys
var loop = 0;
jQuery('#tax_rates tr.tax_rate').each(function( index, row ){
jQuery('input.text, input.checkbox, select.select', row).each(function( i, el ){
var t = jQuery(el);
t.attr('name', t.attr('name').replace(/\[([^[]*)\]/, "[" + loop + "]"));
});
loop++;
});
}
return false;
});
});
</script>
</td>
</tr>
<?php
break;
default:
do_action( 'woocommerce_admin_field_'.$value['type'], $value );
break;
endswitch;
endforeach;
}
/**
* Tax Row Label
*
* Show a label based on user selections
*/
function woocommerce_tax_row_label( $selected ) {
global $woocommerce;
$return = '';
// Get counts/countries
$counties_array = array();
$states_count = 0;
if ($selected) foreach ($selected as $country => $value) :
$country = woocommerce_clean($country);
if (sizeof($value)>1) :
$states_count+=sizeof($value);
endif;
if (!in_array($country, $counties_array)) $counties_array[] = $woocommerce->countries->countries[$country];
endforeach;
$states_text = '';
$countries_text = implode(', ', $counties_array);
// Show label
if (sizeof($counties_array)==0) :
$return .= __('No countries selected', 'woothemes');
elseif ( sizeof($counties_array) < 6 ) :
if ($states_count>0) $states_text = sprintf(_n('(1 state)', '(%s states)', $states_count, 'woothemes'), $states_count);
$return .= $countries_text . ' ' . $states_text;
else :
if ($states_count>0) $states_text = sprintf(_n('and 1 state', 'and %s states', $states_count, 'woothemes'), $states_count);
$return .= sprintf(_n('1 country', '%1$s countries', sizeof($counties_array), 'woothemes'), sizeof($counties_array)) . ' ' . $states_text;
endif;
return $return;
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,474 @@
<?php
/**
* Debug/Status page
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/System Status
* @version 1.6.4
*/
/**
* Output the content of the debugging page.
*
* @access public
* @return void
*/
function woocommerce_status() {
global $woocommerce;
$tools = apply_filters( 'wc_debug_tools', array(
'clear_transients' => array(
'name' => __( 'Transients','woocommerce'),
'button' => __('Clear Transients','woocommerce'),
'desc' => __( 'This tool will clear the product/shop transients cache.', 'woocommerce' ),
),
'recount_terms' => array(
'name' => __('Term counts','woocommerce'),
'button' => __('Recount Terms','woocommerce'),
'desc' => __( 'This tool will recount product terms - useful when changing your settings in a way which hides products from the catalog.', 'woocommerce' ),
),
'reset_roles' => array(
'name' => __('Capabilities','woocommerce'),
'button' => __('Reset Capabilities','woocommerce'),
'desc' => __( 'This tool will reset the admin, customer and shop_manager roles to default. Use this if your users cannot access all of the WooCommerce admin pages.', 'woocommerce' ),
),
) );
?>
<div class="wrap woocommerce">
<div class="icon32 icon32-woocommerce-status" id="icon-woocommerce"><br /></div>
<h2><?php _e( 'System Status', 'woocommerce' ); ?> <a href="#" class="add-new-h2 debug-report"><?php _e('Generate report', 'woocommerce' ); ?></a></h2>
<?php
if ( ! empty( $_GET['action'] ) && ! empty( $_REQUEST['_wpnonce'] ) && wp_verify_nonce( $_REQUEST['_wpnonce'], 'debug_action' ) ) {
switch ( $_GET['action'] ) {
case "clear_transients" :
$woocommerce->clear_product_transients();
echo '<div class="updated"><p>' . __( 'Product Transients Cleared', 'woocommerce' ) . '</p></div>';
break;
case "reset_roles" :
// Remove then re-add caps and roles
woocommerce_remove_roles();
woocommerce_init_roles();
echo '<div class="updated"><p>' . __( 'Roles successfully reset', 'woocommerce' ) . '</p></div>';
break;
case "recount_terms" :
$product_cats = get_terms( 'product_cat', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
_woocommerce_term_recount( $product_cats, get_taxonomy( 'product_cat' ), false, false );
$product_tags = get_terms( 'product_tag', array( 'hide_empty' => false, 'fields' => 'id=>parent' ) );
_woocommerce_term_recount( $product_cats, get_taxonomy( 'product_tag' ), false, false );
echo '<div class="updated"><p>' . __( 'Terms successfully recounted', 'woocommerce' ) . '</p></div>';
break;
default:
$action = esc_attr( $_GET['action'] );
if( isset( $tools[ $action ]['callback'] ) ) {
$callback = $tools[ $action ]['callback'];
$return = call_user_func( $callback );
if( $return === false ) {
if( is_array( $callback ) ) {
echo '<div class="error"><p>' . sprintf( __( 'There was an error calling %s::%s', 'woocommerce' ), get_class( $callback[0] ), $callback[1] ) . '</p></div>';
} else {
echo '<div class="error"><p>' . sprintf( __( 'There was an error calling %s', 'woocommerce' ), $callback ) . '</p></div>';
}
}
}
}
}
?>
<br/>
<textarea id="debug-report" readonly="readonly"></textarea>
<table class="wc_status_table widefat" cellspacing="0">
<thead>
<tr>
<th colspan="2"><?php _e( 'Versions', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><?php _e('WooCommerce version','woocommerce')?></td>
<td><?php echo esc_html( $woocommerce->version ); ?></td>
</tr>
<tr>
<td><?php _e('WooCommerce DB version','woocommerce')?></td>
<td><?php echo esc_html( get_option( 'woocommerce_db_version' ) ); ?></td>
</tr>
<tr>
<td><?php _e('WordPress version','woocommerce')?></td>
<td><?php if ( is_multisite() ) echo 'WPMU'; else echo 'WP'; ?> <?php echo bloginfo('version'); ?></td>
</tr>
<tr>
<td><?php _e('Installed plugins','woocommerce')?></td>
<td><?php
$active_plugins = (array) get_option( 'active_plugins', array() );
if ( is_multisite() )
$active_plugins = array_merge( $active_plugins, get_site_option( 'active_sitewide_plugins', array() ) );
$wc_plugins = array();
foreach ( $active_plugins as $plugin ) {
$plugin_data = @get_plugin_data( WP_PLUGIN_DIR . '/' . $plugin );
if ( ! empty( $plugin_data['Name'] ) ) {
$wc_plugins[] = $plugin_data['Name'] . ' ' . __( 'by', 'woocommerce' ) . ' ' . $plugin_data['Author'] . ' ' . __( 'version', 'woocommerce' ) . ' ' . $plugin_data['Version'];
}
}
if ( sizeof( $wc_plugins ) == 0 ) echo '-'; else echo '<ul><li>' . implode( ', </li><li>', $wc_plugins ) . '</li></ul>';
?></td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="2"><?php _e( 'Settings', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><?php _e('Home URL','woocommerce')?></td>
<td><?php echo home_url(); ?></td>
</tr>
<tr>
<td><?php _e('Site URL','woocommerce')?></td>
<td><?php echo site_url(); ?></td>
</tr>
<tr>
<td><?php _e('Force SSL','woocommerce')?></td>
<td><?php echo ( get_option( 'woocommerce_force_ssl_checkout' ) === 'yes' ) ? '<mark class="yes">'.__( 'Yes', 'woocommerce' ).'</mark>' : '<mark class="no">'.__( 'No', 'woocommerce' ).'</mark>'; ?></td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="2"><?php _e( 'Shop Pages', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<?php
$check_pages = array(
__( 'Shop base page', 'woocommerce' ) => array(
'option' => 'woocommerce_shop_page_id',
'shortcode' => ''
),
__( 'Cart Page', 'woocommerce' ) => array(
'option' => 'woocommerce_cart_page_id',
'shortcode' => '[woocommerce_cart]'
),
__( 'Checkout Page', 'woocommerce' ) => array(
'option' => 'woocommerce_checkout_page_id',
'shortcode' => '[woocommerce_checkout]'
),
__( 'Pay Page', 'woocommerce' ) => array(
'option' => 'woocommerce_pay_page_id',
'shortcode' => '[woocommerce_pay]'
),
__( 'Thanks Page', 'woocommerce' ) => array(
'option' => 'woocommerce_thanks_page_id',
'shortcode' => '[woocommerce_thankyou]'
),
__( 'My Account Page', 'woocommerce' ) => array(
'option' => 'woocommerce_myaccount_page_id',
'shortcode' => '[woocommerce_my_account]'
),
__( 'Edit Address Page', 'woocommerce' ) => array(
'option' => 'woocommerce_edit_address_page_id',
'shortcode' => '[woocommerce_edit_address]'
),
__( 'View Order Page', 'woocommerce' ) => array(
'option' => 'woocommerce_view_order_page_id',
'shortcode' => '[woocommerce_view_order]'
),
__( 'Change Password Page', 'woocommerce' ) => array(
'option' => 'woocommerce_change_password_page_id',
'shortcode' => '[woocommerce_change_password]'
)
);
$alt = 1;
foreach ( $check_pages as $page_name => $values ) {
if ( $alt == 1 ) echo '<tr>'; else echo '<tr>';
echo '<td>' . esc_html( $page_name ) . '</td><td>';
$error = false;
$page_id = get_option($values['option']);
// Page ID check
if ( ! $page_id ) {
echo '<mark class="error">' . __( 'Page not set', 'woocommerce' ) . '</mark>';
$error = true;
} else {
// Shortcode check
if ( $values['shortcode'] ) {
$page = get_post( $page_id );
if ( ! strstr( $page->post_content, $values['shortcode'] ) ) {
echo '<mark class="error">' . sprintf(__( 'Page does not contain the shortcode: %s', 'woocommerce' ), $values['shortcode'] ) . '</mark>';
$error = true;
}
}
}
if ( ! $error ) echo '<mark class="yes">#' . absint( $page_id ) . ' - ' . get_permalink( $page_id ) . '</mark>';
echo '</td></tr>';
$alt = $alt * -1;
}
?>
</tbody>
<thead>
<tr>
<th colspan="2"><?php _e( 'Core Taxonomies', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><?php _e('Order Statuses','woocommerce')?></td>
<td><?php
$order_statuses = get_terms( 'shop_order_status', array( 'fields' => 'names', 'hide_empty' => 0 ) );
echo implode( ', ', array_map( 'esc_html', $order_statuses ) );
?></td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="2"><?php _e( 'Server Environment', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody>
<tr>
<td><?php _e('PHP Version','woocommerce')?></td>
<td><?php
if ( function_exists( 'phpversion' ) )
echo esc_html( phpversion() );
?></td>
</tr>
<tr>
<td><?php _e('Server Software','woocommerce')?></td>
<td><?php
echo esc_html( $_SERVER['SERVER_SOFTWARE'] );
?></td>
</tr>
<tr>
<td><?php _e('WP Max Upload Size','woocommerce'); ?></td>
<td><?php
echo wp_convert_bytes_to_hr( wp_max_upload_size() );
?></td>
</tr>
<tr>
<td><?php _e('Server upload_max_filesize','woocommerce')?></td>
<td><?php
if(function_exists('phpversion'))
echo wp_convert_bytes_to_hr( woocommerce_let_to_num( ini_get('upload_max_filesize') ) );
?></td>
</tr>
<tr>
<td><?php _e('Server post_max_size','woocommerce')?></td>
<td><?php
if(function_exists('phpversion'))
echo wp_convert_bytes_to_hr( woocommerce_let_to_num( ini_get('post_max_size') ) );
?></td>
</tr>
<tr>
<td><?php _e('WP Memory Limit','woocommerce')?></td>
<td><?php
$memory = woocommerce_let_to_num( WP_MEMORY_LIMIT );
if ( $memory < 67108864 ) {
echo '<mark class="error">' . sprintf( __( '%s - We recommend setting memory to at least 64MB. See: <a href="%s">Increasing memory allocated to PHP</a>', 'woocommerce' ), wp_convert_bytes_to_hr( $memory ), 'http://codex.wordpress.org/Editing_wp-config.php#Increasing_memory_allocated_to_PHP' ) . '</mark>';
} else {
echo '<mark class="yes">' . wp_convert_bytes_to_hr( $memory ) . '</mark>';
}
?></td>
</tr>
<tr>
<td><?php _e('WP Debug Mode','woocommerce')?></td>
<td><?php if ( defined('WP_DEBUG') && WP_DEBUG ) echo '<mark class="yes">' . __( 'Yes', 'woocommerce' ) . '</mark>'; else echo '<mark class="no">' . __( 'No', 'woocommerce' ) . '</mark>'; ?></td>
</tr>
<tr>
<td><?php _e('WC Logging','woocommerce')?></td>
<td><?php
if ( @fopen( $woocommerce->plugin_path() . '/logs/paypal.txt', 'a' ) )
echo '<mark class="yes">' . __( 'Log directory is writable.', 'woocommerce' ) . '</mark>';
else
echo '<mark class="error">' . __( 'Log directory (<code>woocommerce/logs/</code>) is not writable. Logging will not be possible.', 'woocommerce' ) . '</mark>';
?></td>
</tr>
</tbody>
<thead>
<tr>
<th colspan="2"><?php _e( 'Remote Posting/IPN', 'woocommerce' ); ?></th>
</tr>
</thead>
<?php
$posting = array();
// fsockopen/cURL
$posting['fsockopen_curl']['name'] = __( 'fsockopen/cURL','woocommerce');
if ( function_exists( 'fsockopen' ) || function_exists( 'curl_init' ) ) {
if ( function_exists( 'fsockopen' ) && function_exists( 'curl_init' )) {
$posting['fsockopen_curl']['note'] = __('Your server has fsockopen and cURL enabled.', 'woocommerce' );
} elseif ( function_exists( 'fsockopen' )) {
$posting['fsockopen_curl']['note'] = __( 'Your server has fsockopen enabled, cURL is disabled.', 'woocommerce' );
} else {
$posting['fsockopen_curl']['note'] = __( 'Your server has cURL enabled, fsockopen is disabled.', 'woocommerce' );
}
$posting['fsockopen_curl']['success'] = true;
} else {
$posting['fsockopen_curl']['note'] = __( 'Your server does not have fsockopen or cURL enabled - PayPal IPN and other scripts which communicate with other servers will not work. Contact your hosting provider.', 'woocommerce' ). '</mark>';
$posting['fsockopen_curl']['success'] = false;
}
// SOAP
$posting['soap_client']['name'] = __( 'SOAP Client','woocommerce' );
if ( class_exists( 'SoapClient' ) ) {
$posting['soap_client']['note'] = __('Your server has the SOAP Client class enabled.', 'woocommerce' );
$posting['soap_client']['success'] = true;
} else {
$posting['soap_client']['note'] = sprintf( __( 'Your server does not have the <a href="%s">SOAP Client</a> class enabled - some gateway plugins which use SOAP may not work as expected.', 'woocommerce' ), 'http://php.net/manual/en/class.soapclient.php' ) . '</mark>';
$posting['soap_client']['success'] = false;
}
// WP Remote Post Check
$posting['wp_remote_post']['name'] = __( 'WP Remote Post Check','woocommerce');
$request['cmd'] = '_notify-validate';
$params = array(
'sslverify' => false,
'timeout' => 60,
'user-agent' => 'WooCommerce/' . $woocommerce->version,
'body' => $request
);
$response = wp_remote_post( 'https://www.paypal.com/cgi-bin/webscr', $params );
if ( ! is_wp_error( $response ) && $response['response']['code'] >= 200 && $response['response']['code'] < 300 ) {
$posting['wp_remote_post']['note'] = __('wp_remote_post() was successful - PayPal IPN is working.', 'woocommerce' );
$posting['wp_remote_post']['success'] = true;
} elseif ( is_wp_error( $response ) ) {
$posting['wp_remote_post']['note'] = __( 'wp_remote_post() failed. PayPal IPN won\'t work with your server. Contact your hosting provider. Error:', 'woocommerce' ) . ' ' . $response->get_error_message();
$posting['wp_remote_post']['success'] = false;
} else {
$posting['wp_remote_post']['note'] = __( 'wp_remote_post() failed. PayPal IPN may not work with your server.', 'woocommerce' );
$posting['wp_remote_post']['success'] = false;
}
$posting = apply_filters( 'wc_debug_posting', $posting );
?>
<tbody>
<?php foreach($posting as $post) { $mark = ( isset( $post['success'] ) && $post['success'] == true ) ? 'yes' : 'error'; ?>
<tr>
<td><?php echo esc_html( $post['name'] ); ?></td>
<td>
<mark class="<?php echo $mark; ?>">
<?php echo wp_kses_data( $post['note'] ); ?>
</mark>
</td>
</tr>
<?php } ?>
</tbody>
<thead class="tools">
<tr>
<th colspan="2"><?php _e( 'Tools', 'woocommerce' ); ?></th>
</tr>
</thead>
<tbody class="tools">
<?php foreach($tools as $action => $tool) { ?>
<tr>
<td><?php echo esc_html( $tool['name'] ); ?></td>
<td>
<p>
<a href="<?php echo wp_nonce_url( admin_url('admin.php?page=woocommerce_status&action=' . $action ), 'debug_action' ); ?>" class="button"><?php echo esc_html( $tool['button'] ); ?></a>
<span class="description"><?php echo wp_kses_post( $tool['desc'] ); ?></span>
</p>
</td>
</tr>
<?php } ?>
</tbody>
</table>
</div>
<script type="text/javascript">
jQuery('a.debug-report').click(function(){
if ( ! jQuery('#debug-report').val() ) {
// Generate report - user can paste into forum
var report = '`';
jQuery('thead:not(".tools"), tbody:not(".tools")', '.wc_status_table').each(function(){
$this = jQuery( this );
if ( $this.is('thead') ) {
report = report + "\n=============================================================================================\n";
report = report + " " + jQuery.trim( $this.text() ) + "\n";
report = report + "=============================================================================================\n";
} else {
jQuery('tr', $this).each(function(){
$this = jQuery( this );
report = report + $this.find('td:eq(0)').text() + ": \t";
report = report + $this.find('td:eq(1)').text() + "\n";
});
}
});
report = report + '`';
jQuery('#debug-report').val( report );
}
jQuery('#debug-report').slideToggle('500', function() {
jQuery(this).select();
});
return false;
});
</script>
<?php
}

View File

@ -1,125 +1,169 @@
<?php <?php
/** /**
* Functions used for taxonomies in admin * Admin taxonomy functions
* *
* These functions control admin interface bits like category ordering. * These functions control admin interface bits like category ordering.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Taxonomies
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Category thumbnails * Category thumbnail fields.
*
* @access public
* @return void
*/ */
add_action('product_cat_add_form_fields', 'woocommerce_add_category_thumbnail_field'); function woocommerce_add_category_fields() {
add_action('product_cat_edit_form_fields', 'woocommerce_edit_category_thumbnail_field', 10,2);
function woocommerce_add_category_thumbnail_field() {
global $woocommerce; global $woocommerce;
?> ?>
<div class="form-field"> <div class="form-field">
<label><?php _e('Thumbnail', 'woothemes'); ?></label> <label for="display_type"><?php _e( 'Display type', 'woocommerce' ); ?></label>
<div id="product_cat_thumbnail" style="float:left;margin-right:10px;"><img src="<?php echo $woocommerce->plugin_url().'/assets/images/placeholder.png' ?>" width="60px" height="60px" /></div> <select id="display_type" name="display_type" class="postform">
<option value=""><?php _e( 'Default', 'woocommerce' ); ?></option>
<option value="products"><?php _e( 'Products', 'woocommerce' ); ?></option>
<option value="subcategories"><?php _e( 'Subcategories', 'woocommerce' ); ?></option>
<option value="both"><?php _e( 'Both', 'woocommerce' ); ?></option>
</select>
</div>
<div class="form-field">
<label><?php _e( 'Thumbnail', 'woocommerce' ); ?></label>
<div id="product_cat_thumbnail" style="float:left;margin-right:10px;"><img src="<?php echo woocommerce_placeholder_img_src(); ?>" width="60px" height="60px" /></div>
<div style="line-height:60px;"> <div style="line-height:60px;">
<input type="hidden" id="product_cat_thumbnail_id" name="product_cat_thumbnail_id" /> <input type="hidden" id="product_cat_thumbnail_id" name="product_cat_thumbnail_id" />
<button type="submit" class="upload_image_button button"><?php _e('Upload/Add image', 'woothemes'); ?></button> <button type="submit" class="upload_image_button button"><?php _e( 'Upload/Add image', 'woocommerce' ); ?></button>
<button type="submit" class="remove_image_button button"><?php _e('Remove image', 'woothemes'); ?></button> <button type="submit" class="remove_image_button button"><?php _e( 'Remove image', 'woocommerce' ); ?></button>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
// Only show the "remove image" button when needed
if ( ! jQuery('#product_cat_thumbnail_id').val() )
jQuery('.remove_image_button').hide();
window.send_to_editor_default = window.send_to_editor;
window.send_to_termmeta = function(html) { window.send_to_termmeta = function(html) {
jQuery('body').append('<div id="temp_image">' + html + '</div>'); jQuery('body').append('<div id="temp_image">' + html + '</div>');
var img = jQuery('#temp_image').find('img'); var img = jQuery('#temp_image').find('img');
imgurl = img.attr('src'); imgurl = img.attr('src');
imgclass = img.attr('class'); imgclass = img.attr('class');
imgid = parseInt(imgclass.replace(/\D/g, ''), 10); imgid = parseInt(imgclass.replace(/\D/g, ''), 10);
jQuery('#product_cat_thumbnail_id').val(imgid); jQuery('#product_cat_thumbnail_id').val(imgid);
jQuery('#product_cat_thumbnail img').attr('src', imgurl); jQuery('#product_cat_thumbnail img').attr('src', imgurl);
jQuery('.remove_image_button').show();
jQuery('#temp_image').remove(); jQuery('#temp_image').remove();
tb_remove(); tb_remove();
window.send_to_editor = window.send_to_editor_default;
} }
jQuery('.upload_image_button').live('click', function(){ jQuery('.upload_image_button').live('click', function(){
var post_id = 0; var post_id = 0;
window.send_to_editor = window.send_to_termmeta; window.send_to_editor = window.send_to_termmeta;
tb_show('', 'media-upload.php?post_id=' + post_id + '&amp;type=image&amp;TB_iframe=true'); tb_show('', 'media-upload.php?post_id=' + post_id + '&amp;type=image&amp;TB_iframe=true');
return false; return false;
}); });
jQuery('.remove_image_button').live('click', function(){ jQuery('.remove_image_button').live('click', function(){
jQuery('#product_cat_thumbnail img').attr('src', '<?php echo $woocommerce->plugin_url().'/assets/images/placeholder.png'; ?>'); jQuery('#product_cat_thumbnail img').attr('src', '<?php echo woocommerce_placeholder_img_src(); ?>');
jQuery('#product_cat_thumbnail_id').val(''); jQuery('#product_cat_thumbnail_id').val('');
jQuery('.remove_image_button').hide();
return false; return false;
}); });
</script> </script>
<div class="clear"></div> <div class="clear"></div>
</div> </div>
<?php <?php
} }
function woocommerce_edit_category_thumbnail_field( $term, $taxonomy ) { add_action( 'product_cat_add_form_fields', 'woocommerce_add_category_fields' );
/**
* Edit category thumbnail field.
*
* @access public
* @param mixed $term Term (category) being edited
* @param mixed $taxonomy Taxonomy of the term being edited
* @return void
*/
function woocommerce_edit_category_fields( $term, $taxonomy ) {
global $woocommerce; global $woocommerce;
$display_type = get_woocommerce_term_meta( $term->term_id, 'display_type', true );
$image = ''; $image = '';
$thumbnail_id = get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true ); $thumbnail_id = absint( get_woocommerce_term_meta( $term->term_id, 'thumbnail_id', true ) );
if ($thumbnail_id) : if ($thumbnail_id) :
$image = wp_get_attachment_url( $thumbnail_id ); $image = wp_get_attachment_url( $thumbnail_id );
else : else :
$image = $woocommerce->plugin_url().'/assets/images/placeholder.png'; $image = woocommerce_placeholder_img_src();
endif; endif;
?> ?>
<tr class="form-field"> <tr class="form-field">
<th scope="row" valign="top"><label><?php _e('Thumbnail', 'woothemes'); ?></label></th> <th scope="row" valign="top"><label><?php _e( 'Display type', 'woocommerce' ); ?></label></th>
<td>
<select id="display_type" name="display_type" class="postform">
<option value="" <?php selected( '', $display_type ); ?>><?php _e( 'Default', 'woocommerce' ); ?></option>
<option value="products" <?php selected( 'products', $display_type ); ?>><?php _e( 'Products', 'woocommerce' ); ?></option>
<option value="subcategories" <?php selected( 'subcategories', $display_type ); ?>><?php _e( 'Subcategories', 'woocommerce' ); ?></option>
<option value="both" <?php selected( 'both', $display_type ); ?>><?php _e( 'Both', 'woocommerce' ); ?></option>
</select>
</td>
</tr>
<tr class="form-field">
<th scope="row" valign="top"><label><?php _e( 'Thumbnail', 'woocommerce' ); ?></label></th>
<td> <td>
<div id="product_cat_thumbnail" style="float:left;margin-right:10px;"><img src="<?php echo $image; ?>" width="60px" height="60px" /></div> <div id="product_cat_thumbnail" style="float:left;margin-right:10px;"><img src="<?php echo $image; ?>" width="60px" height="60px" /></div>
<div style="line-height:60px;"> <div style="line-height:60px;">
<input type="hidden" id="product_cat_thumbnail_id" name="product_cat_thumbnail_id" value="<?php echo $thumbnail_id; ?>" /> <input type="hidden" id="product_cat_thumbnail_id" name="product_cat_thumbnail_id" value="<?php echo $thumbnail_id; ?>" />
<button type="submit" class="upload_image_button button"><?php _e('Upload/Add image', 'woothemes'); ?></button> <button type="submit" class="upload_image_button button"><?php _e( 'Upload/Add image', 'woocommerce' ); ?></button>
<button type="submit" class="remove_image_button button"><?php _e('Remove image', 'woothemes'); ?></button> <button type="submit" class="remove_image_button button"><?php _e( 'Remove image', 'woocommerce' ); ?></button>
</div> </div>
<script type="text/javascript"> <script type="text/javascript">
window.send_to_termmeta = function(html) { window.send_to_termmeta = function(html) {
jQuery('body').append('<div id="temp_image">' + html + '</div>'); jQuery('body').append('<div id="temp_image">' + html + '</div>');
var img = jQuery('#temp_image').find('img'); var img = jQuery('#temp_image').find('img');
imgurl = img.attr('src'); imgurl = img.attr('src');
imgclass = img.attr('class'); imgclass = img.attr('class');
imgid = parseInt(imgclass.replace(/\D/g, ''), 10); imgid = parseInt(imgclass.replace(/\D/g, ''), 10);
jQuery('#product_cat_thumbnail_id').val(imgid); jQuery('#product_cat_thumbnail_id').val(imgid);
jQuery('#product_cat_thumbnail img').attr('src', imgurl); jQuery('#product_cat_thumbnail img').attr('src', imgurl);
jQuery('#temp_image').remove(); jQuery('#temp_image').remove();
tb_remove(); tb_remove();
} }
jQuery('.upload_image_button').live('click', function(){ jQuery('.upload_image_button').live('click', function(){
var post_id = 0; var post_id = 0;
window.send_to_editor = window.send_to_termmeta; window.send_to_editor = window.send_to_termmeta;
tb_show('', 'media-upload.php?post_id=' + post_id + '&amp;type=image&amp;TB_iframe=true'); tb_show('', 'media-upload.php?post_id=' + post_id + '&amp;type=image&amp;TB_iframe=true');
return false; return false;
}); });
jQuery('.remove_image_button').live('click', function(){ jQuery('.remove_image_button').live('click', function(){
jQuery('#product_cat_thumbnail img').attr('src', '<?php echo $woocommerce->plugin_url().'/assets/images/placeholder.png'; ?>'); jQuery('#product_cat_thumbnail img').attr('src', '<?php echo woocommerce_placeholder_img_src(); ?>');
jQuery('#product_cat_thumbnail_id').val(''); jQuery('#product_cat_thumbnail_id').val('');
return false; return false;
}); });
</script> </script>
<div class="clear"></div> <div class="clear"></div>
</td> </td>
@ -127,118 +171,184 @@ function woocommerce_edit_category_thumbnail_field( $term, $taxonomy ) {
<?php <?php
} }
add_action('created_term', 'woocommerce_category_thumbnail_field_save', 10,3); add_action( 'product_cat_edit_form_fields', 'woocommerce_edit_category_fields', 10,2 );
add_action('edit_term', 'woocommerce_category_thumbnail_field_save', 10,3);
function woocommerce_category_thumbnail_field_save( $term_id, $tt_id, $taxonomy ) {
if (isset($_POST['product_cat_thumbnail_id'])) {
update_woocommerce_term_meta($term_id, 'thumbnail_id', $_POST['product_cat_thumbnail_id']);
}
}
/** /**
* Description for product_cat page * woocommerce_category_fields_save function.
*
* @access public
* @param mixed $term_id Term ID being saved
* @param mixed $tt_id
* @param mixed $taxonomy Taxonomy of the term being saved
* @return void
*/ */
add_action('product_cat_pre_add_form', 'woocommerce_product_cat_description'); function woocommerce_category_fields_save( $term_id, $tt_id, $taxonomy ) {
if ( isset( $_POST['display_type'] ) )
update_woocommerce_term_meta( $term_id, 'display_type', esc_attr( $_POST['display_type'] ) );
if ( isset( $_POST['product_cat_thumbnail_id'] ) )
update_woocommerce_term_meta( $term_id, 'thumbnail_id', absint( $_POST['product_cat_thumbnail_id'] ) );
}
add_action( 'created_term', 'woocommerce_category_fields_save', 10,3 );
add_action( 'edit_term', 'woocommerce_category_fields_save', 10,3 );
/**
* Description for product_cat page to aid users.
*
* @access public
* @return void
*/
function woocommerce_product_cat_description() { function woocommerce_product_cat_description() {
echo wpautop(__('Product categories for your store can be managed here. To change the order of categories on the front-end you can drag and drop to sort them. To see more categories listed click the "screen options" link at the top of the page.', 'woothemes')); echo wpautop( __( 'Product categories for your store can be managed here. To change the order of categories on the front-end you can drag and drop to sort them. To see more categories listed click the "screen options" link at the top of the page.', 'woocommerce' ) );
} }
/** add_action( 'product_cat_pre_add_form', 'woocommerce_product_cat_description' );
* Description for shipping class page
*/
add_action('product_shipping_class_pre_add_form', 'woocommerce_shipping_class_description');
/**
* Description for shipping class page to aid users.
*
* @access public
* @return void
*/
function woocommerce_shipping_class_description() { function woocommerce_shipping_class_description() {
echo wpautop(__('Shipping classes can be used to group products of similar type. These groups can then be used by certain shipping methods to provide different rates to different products.', 'woothemes')); echo wpautop(__( 'Shipping classes can be used to group products of similar type. These groups can then be used by certain shipping methods to provide different rates to different products.', 'woocommerce' ));
} }
/** add_action( 'product_shipping_class_pre_add_form', 'woocommerce_shipping_class_description' );
* Fix for per_page option
* Trac: http://core.trac.wordpress.org/ticket/19465
*/
add_filter('edit_posts_per_page', 'woocommerce_fix_edit_posts_per_page', 1, 2);
/**
* Fix for the per_page option
*
* Trac: http://core.trac.wordpress.org/ticket/19465
*
* @access public
* @param mixed $per_page
* @param mixed $post_type
* @return void
*/
function woocommerce_fix_edit_posts_per_page( $per_page, $post_type ) { function woocommerce_fix_edit_posts_per_page( $per_page, $post_type ) {
if ($post_type!=='product') return $per_page; if ( $post_type !== 'product' )
return $per_page;
$screen = get_current_screen(); $screen = get_current_screen();
if (strstr($screen->id, '-')) { if ( strstr( $screen->id, '-' ) ) {
$option = 'edit_' . str_replace('edit-', '', $screen->id) . '_per_page'; $option = 'edit_' . str_replace( 'edit-', '', $screen->id ) . '_per_page';
if (isset($_POST['wp_screen_options']['option']) && $_POST['wp_screen_options']['option'] == $option ) : if ( isset( $_POST['wp_screen_options']['option'] ) && $_POST['wp_screen_options']['option'] == $option ) {
update_user_meta( get_current_user_id(), $option, $_POST['wp_screen_options']['value'] ); update_user_meta( get_current_user_id(), $option, $_POST['wp_screen_options']['value'] );
wp_redirect( remove_query_arg( array('pagenum', 'apage', 'paged'), wp_get_referer() ) ); wp_redirect( remove_query_arg( array('pagenum', 'apage', 'paged'), wp_get_referer() ) );
exit; exit;
endif; }
$user_per_page = (int) get_user_meta( get_current_user_id(), $option, true ); $user_per_page = (int) get_user_meta( get_current_user_id(), $option, true );
if ($user_per_page) $per_page = $user_per_page; if ( $user_per_page )
$per_page = $user_per_page;
} }
return $per_page; return $per_page;
} }
/** add_filter( 'edit_posts_per_page', 'woocommerce_fix_edit_posts_per_page', 1, 2 );
* Thumbnail column for categories
*/
add_filter("manage_edit-product_cat_columns", 'woocommerce_product_cat_columns');
add_filter("manage_product_cat_custom_column", 'woocommerce_product_cat_column', 10, 3);
function woocommerce_product_cat_columns( $columns ) {
$new_columns = array();
$new_columns['cb'] = $columns['cb'];
$new_columns['thumb'] = __('Image', 'woothemes');
unset($columns['cb']);
$columns = array_merge( $new_columns, $columns );
return $columns;
}
function woocommerce_product_cat_column( $columns, $column, $id ) {
if ($column=='thumb') :
global $woocommerce;
$image = '';
$thumbnail_id = get_woocommerce_term_meta( $id, 'thumbnail_id', true );
if ($thumbnail_id) :
$image = wp_get_attachment_url( $thumbnail_id );
else :
$image = $woocommerce->plugin_url().'/assets/images/placeholder.png';
endif;
$columns .= '<img src="'.$image.'" alt="Thumbnail" class="wp-post-image" height="48" width="48" />';
endif;
return $columns;
}
/** /**
* Configure button for shipping classes page * Thumbnail column added to category admin.
*
* @access public
* @param mixed $columns
* @return void
*/ */
add_filter("manage_edit-product_shipping_class_columns", 'woocommerce_shipping_class_columns'); function woocommerce_product_cat_columns( $columns ) {
add_filter("manage_product_shipping_class_custom_column", 'woocommerce_shipping_class_column', 10, 3); $new_columns = array();
$new_columns['cb'] = $columns['cb'];
function woocommerce_shipping_class_columns( $columns ) { $new_columns['thumb'] = __( 'Image', 'woocommerce' );
$columns['configure'] = '&nbsp;';
return $columns; unset( $columns['cb'] );
}
return array_merge( $new_columns, $columns );
function woocommerce_shipping_class_column( $columns, $column, $id ) { }
if ($column=='configure') $columns .= '<a href="'. admin_url( 'edit-tags.php?action=edit&taxonomy=product_shipping_class&tag_ID='. $id .'&post_type=product' ) .'" class="button alignright">'.__('Configure shipping class', 'woothemes').'</a>';
add_filter( 'manage_edit-product_cat_columns', 'woocommerce_product_cat_columns' );
return $columns;
}
/**
* Thumbnail column value added to category admin.
*
* @access public
* @param mixed $columns
* @param mixed $column
* @param mixed $id
* @return void
*/
function woocommerce_product_cat_column( $columns, $column, $id ) {
global $woocommerce;
if ( $column == 'thumb' ) {
$image = '';
$thumbnail_id = get_woocommerce_term_meta( $id, 'thumbnail_id', true );
if ($thumbnail_id)
$image = wp_get_attachment_url( $thumbnail_id );
else
$image = woocommerce_placeholder_img_src();
$columns .= '<img src="' . $image . '" alt="Thumbnail" class="wp-post-image" height="48" width="48" />';
}
return $columns;
}
add_filter( 'manage_product_cat_custom_column', 'woocommerce_product_cat_column', 10, 3 );
/**
* Add a configure button column for the shipping classes page.
*
* @access public
* @param mixed $columns
* @return void
*/
function woocommerce_shipping_class_columns( $columns ) {
$columns['configure'] = '&nbsp;';
return $columns;
}
add_filter( 'manage_edit-product_shipping_class_columns', 'woocommerce_shipping_class_columns' );
/**
* Add a configure button for the shipping classes page.
*
* @access public
* @param mixed $columns
* @param mixed $column
* @param mixed $id
* @return void
*/
function woocommerce_shipping_class_column( $columns, $column, $id ) {
if ( $column == 'configure' )
$columns .= '<a href="'. admin_url( 'edit-tags.php?action=edit&taxonomy=product_shipping_class&tag_ID='. $id .'&post_type=product' ) .'" class="button alignright">'.__( 'Configure shipping class', 'woocommerce' ).'</a>';
return $columns;
}
add_filter( 'manage_product_shipping_class_custom_column', 'woocommerce_shipping_class_column', 10, 3 );

View File

@ -0,0 +1,43 @@
<?php
/**
* WooCommerce Updates
*
* Plugin updates script which updates the database.
*
* @author WooThemes
* @category Admin
* @package WooCommerce/Admin/Updates
* @version 2.0.0
*/
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/**
* Runs the installer.
*
* @access public
* @return void
*/
function do_update_woocommerce() {
global $woocommerce;
// Do updates
$current_db_version = get_option( 'woocommerce_db_version' );
if ( version_compare( $current_db_version, '1.4', '<' ) ) {
include( 'includes/updates/woocommerce-update-1.4.php' );
update_option( 'woocommerce_db_version', '1.4' );
}
if ( version_compare( $current_db_version, '1.5', '<' ) ) {
include( 'includes/updates/woocommerce-update-1.5.php' );
update_option( 'woocommerce_db_version', '1.5' );
}
if ( version_compare( $current_db_version, '2.0', '<' ) ) {
include( 'includes/updates/woocommerce-update-2.0.php' );
update_option( 'woocommerce_db_version', '2.0' );
}
update_option( 'woocommerce_db_version', $woocommerce->version );
}

View File

@ -1,47 +1,75 @@
<?php <?php
/** /**
* Functions used for modifying the users panel * Admin user functions
*
* Functions used for modifying the users panel in admin.
* *
* @author WooThemes * @author WooThemes
* @category Admin * @category Admin
* @package WooCommerce * @package WooCommerce/Admin/Users
* @version 1.6.4
*/ */
if ( ! defined( 'ABSPATH' ) ) exit; // Exit if accessed directly
/** /**
* Define columns to show on the users page * Define columns to show on the users page.
*
* @access public
* @param array $columns Columns on the manage users page
* @return array The modified columns
*/ */
add_filter('manage_users_columns', 'woocommerce_user_columns', 10, 1);
function woocommerce_user_columns( $columns ) { function woocommerce_user_columns( $columns ) {
if (!current_user_can('manage_woocommerce')) return $columns; if ( ! current_user_can( 'manage_woocommerce' ) )
return $columns;
$columns['woocommerce_billing_address'] = __('Billing Address', 'woothemes'); $columns['woocommerce_billing_address'] = __( 'Billing Address', 'woocommerce' );
$columns['woocommerce_shipping_address'] = __('Shipping Address', 'woothemes'); $columns['woocommerce_shipping_address'] = __( 'Shipping Address', 'woocommerce' );
$columns['woocommerce_paying_customer'] = __('Paying Customer?', 'woothemes'); $columns['woocommerce_paying_customer'] = __( 'Paying Customer?', 'woocommerce' );
$columns['woocommerce_order_count'] = __('Orders', 'woothemes'); $columns['woocommerce_order_count'] = __( 'Completed Orders', 'woocommerce' );
return $columns; return $columns;
} }
/**
* Define values for custom columns
*/
add_action('manage_users_custom_column', 'woocommerce_user_column_values', 10, 3);
function woocommerce_user_column_values($value, $column_name, $user_id) { add_filter( 'manage_users_columns', 'woocommerce_user_columns', 10, 1 );
/**
* Define values for custom columns.
*
* @access public
* @param mixed $value The value of the column being displayed
* @param mixed $column_name The name of the column being displayed
* @param mixed $user_id The ID of the user being displayed
* @return string Value for the column
*/
function woocommerce_user_column_values( $value, $column_name, $user_id ) {
global $woocommerce, $wpdb; global $woocommerce, $wpdb;
switch ($column_name) : switch ( $column_name ) :
case "woocommerce_order_count" : case "woocommerce_order_count" :
$count = $wpdb->get_var( "SELECT COUNT(*) if ( ! $count = get_user_meta( $user_id, '_order_count', true ) ) {
FROM $wpdb->posts
LEFT JOIN $wpdb->postmeta ON $wpdb->posts.ID = $wpdb->postmeta.post_id $count = $wpdb->get_var( "SELECT COUNT(*)
WHERE meta_value = $user_id FROM $wpdb->posts as posts
AND meta_key = '_customer_user'
AND post_type IN ('shop_order') LEFT JOIN {$wpdb->postmeta} AS meta ON posts.ID = meta.post_id
AND post_status = 'publish'" ); LEFT JOIN {$wpdb->term_relationships} AS rel ON posts.ID=rel.object_ID
LEFT JOIN {$wpdb->term_taxonomy} AS tax USING( term_taxonomy_id )
$value = '<a href="'.admin_url('edit.php?post_status=all&post_type=shop_order&_customer_user='.$user_id.'').'">'.$count.'</a>'; LEFT JOIN {$wpdb->terms} AS term USING( term_id )
WHERE meta.meta_key = '_customer_user'
AND posts.post_type = 'shop_order'
AND posts.post_status = 'publish'
AND tax.taxonomy = 'shop_order_status'
AND term.slug IN ( 'completed' )
AND meta_value = $user_id
" );
update_user_meta( $user_id, '_order_count', $count );
}
$value = '<a href="' . admin_url( 'edit.php?post_status=all&post_type=shop_order&shop_order_status=completed&_customer_user=' . absint( $user_id ) . '' ) . '">' . absint( $count ) . '</a>';
break; break;
case "woocommerce_billing_address" : case "woocommerce_billing_address" :
$address = array( $address = array(
@ -50,17 +78,20 @@ function woocommerce_user_column_values($value, $column_name, $user_id) {
'company' => get_user_meta( $user_id, 'billing_company', true ), 'company' => get_user_meta( $user_id, 'billing_company', true ),
'address_1' => get_user_meta( $user_id, 'billing_address_1', true ), 'address_1' => get_user_meta( $user_id, 'billing_address_1', true ),
'address_2' => get_user_meta( $user_id, 'billing_address_2', true ), 'address_2' => get_user_meta( $user_id, 'billing_address_2', true ),
'city' => get_user_meta( $user_id, 'billing_city', true ), 'city' => get_user_meta( $user_id, 'billing_city', true ),
'state' => get_user_meta( $user_id, 'billing_state', true ), 'state' => get_user_meta( $user_id, 'billing_state', true ),
'postcode' => get_user_meta( $user_id, 'billing_postcode', true ), 'postcode' => get_user_meta( $user_id, 'billing_postcode', true ),
'country' => get_user_meta( $user_id, 'billing_country', true ) 'country' => get_user_meta( $user_id, 'billing_country', true )
); );
$formatted_address = $woocommerce->countries->get_formatted_address( $address ); $formatted_address = $woocommerce->countries->get_formatted_address( $address );
if (!$formatted_address) $value = __('N/A', 'woothemes'); else $value = $formatted_address; if ( ! $formatted_address )
$value = __( 'N/A', 'woocommerce' );
$value = wpautop($value); else
$value = $formatted_address;
$value = wpautop( $value );
break; break;
case "woocommerce_shipping_address" : case "woocommerce_shipping_address" :
$address = array( $address = array(
@ -69,124 +100,154 @@ function woocommerce_user_column_values($value, $column_name, $user_id) {
'company' => get_user_meta( $user_id, 'shipping_company', true ), 'company' => get_user_meta( $user_id, 'shipping_company', true ),
'address_1' => get_user_meta( $user_id, 'shipping_address_1', true ), 'address_1' => get_user_meta( $user_id, 'shipping_address_1', true ),
'address_2' => get_user_meta( $user_id, 'shipping_address_2', true ), 'address_2' => get_user_meta( $user_id, 'shipping_address_2', true ),
'city' => get_user_meta( $user_id, 'shipping_city', true ), 'city' => get_user_meta( $user_id, 'shipping_city', true ),
'state' => get_user_meta( $user_id, 'shipping_state', true ), 'state' => get_user_meta( $user_id, 'shipping_state', true ),
'postcode' => get_user_meta( $user_id, 'shipping_postcode', true ), 'postcode' => get_user_meta( $user_id, 'shipping_postcode', true ),
'country' => get_user_meta( $user_id, 'shipping_country', true ) 'country' => get_user_meta( $user_id, 'shipping_country', true )
); );
$formatted_address = $woocommerce->countries->get_formatted_address( $address ); $formatted_address = $woocommerce->countries->get_formatted_address( $address );
if (!$formatted_address) $value = __('N/A', 'woothemes'); else $value = $formatted_address; if ( ! $formatted_address )
$value = __( 'N/A', 'woocommerce' );
$value = wpautop($value); else
$value = $formatted_address;
$value = wpautop( $value );
break; break;
case "woocommerce_paying_customer" : case "woocommerce_paying_customer" :
$paying_customer = get_user_meta( $user_id, 'paying_customer', true ); $paying_customer = get_user_meta( $user_id, 'paying_customer', true );
if ($paying_customer) $value = '<img src="'.$woocommerce->plugin_url().'/assets/images/success.gif" alt="yes" />'; if ( $paying_customer )
else $value = '<img src="'.$woocommerce->plugin_url().'/assets/images/success-off.gif" alt="no" />'; $value = '<img src="' . $woocommerce->plugin_url() . '/assets/images/success.png" alt="yes" />';
else
$value = '<img src="' . $woocommerce->plugin_url() . '/assets/images/success-off.png" alt="no" />';
break; break;
endswitch; endswitch;
return $value; return $value;
} }
add_action( 'manage_users_custom_column', 'woocommerce_user_column_values', 10, 3 );
/** /**
* Show Address Fields on edit user pages * Get Address Fields for the edit user pages.
*
* @access public
* @return array Fields to display which are filtered through woocommerce_customer_meta_fields before being returned
*/ */
add_action( 'show_user_profile', 'woocommerce_customer_meta_fields' ); function woocommerce_get_customer_meta_fields() {
add_action( 'edit_user_profile', 'woocommerce_customer_meta_fields' );
function woocommerce_customer_meta_fields( $user ) {
if (!current_user_can('manage_woocommerce')) return $columns;
$show_fields = apply_filters('woocommerce_customer_meta_fields', array( $show_fields = apply_filters('woocommerce_customer_meta_fields', array(
'billing' => array( 'billing' => array(
'title' => __('Customer Billing Address', 'woothemes'), 'title' => __( 'Customer Billing Address', 'woocommerce' ),
'fields' => array( 'fields' => array(
'billing_first_name' => array( 'billing_first_name' => array(
'label' => __('First name', 'woothemes'), 'label' => __( 'First name', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_last_name' => array( 'billing_last_name' => array(
'label' => __('Last name', 'woothemes'), 'label' => __( 'Last name', 'woocommerce' ),
'description' => ''
),
'billing_company' => array(
'label' => __( 'Company', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_address_1' => array( 'billing_address_1' => array(
'label' => __('Address 1', 'woothemes'), 'label' => __( 'Address 1', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_address_2' => array( 'billing_address_2' => array(
'label' => __('Address 2', 'woothemes'), 'label' => __( 'Address 2', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_city' => array( 'billing_city' => array(
'label' => __('City', 'woothemes'), 'label' => __( 'City', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_postcode' => array( 'billing_postcode' => array(
'label' => __('Postcode', 'woothemes'), 'label' => __( 'Postcode', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_state' => array( 'billing_state' => array(
'label' => __('State/County', 'woothemes'), 'label' => __( 'State/County', 'woocommerce' ),
'description' => 'Country or state code' 'description' => __( 'Country or state code', 'woocommerce' ),
), ),
'billing_country' => array( 'billing_country' => array(
'label' => __('Country', 'woothemes'), 'label' => __( 'Country', 'woocommerce' ),
'description' => '2 letter Country code' 'description' => __( '2 letter Country code', 'woocommerce' ),
), ),
'billing_phone' => array( 'billing_phone' => array(
'label' => __('Telephone', 'woothemes'), 'label' => __( 'Telephone', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'billing_email' => array( 'billing_email' => array(
'label' => __('Email', 'woothemes'), 'label' => __( 'Email', 'woocommerce' ),
'description' => '' 'description' => ''
) )
) )
), ),
'shipping' => array( 'shipping' => array(
'title' => __('Customer Shipping Address', 'woothemes'), 'title' => __( 'Customer Shipping Address', 'woocommerce' ),
'fields' => array( 'fields' => array(
'shipping_first_name' => array( 'shipping_first_name' => array(
'label' => __('First name', 'woothemes'), 'label' => __( 'First name', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_last_name' => array( 'shipping_last_name' => array(
'label' => __('Last name', 'woothemes'), 'label' => __( 'Last name', 'woocommerce' ),
'description' => ''
),
'shipping_company' => array(
'label' => __( 'Company', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_address_1' => array( 'shipping_address_1' => array(
'label' => __('Address 1', 'woothemes'), 'label' => __( 'Address 1', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_address_2' => array( 'shipping_address_2' => array(
'label' => __('Address 2', 'woothemes'), 'label' => __( 'Address 2', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_city' => array( 'shipping_city' => array(
'label' => __('City', 'woothemes'), 'label' => __( 'City', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_postcode' => array( 'shipping_postcode' => array(
'label' => __('Postcode', 'woothemes'), 'label' => __( 'Postcode', 'woocommerce' ),
'description' => '' 'description' => ''
), ),
'shipping_state' => array( 'shipping_state' => array(
'label' => __('State/County', 'woothemes'), 'label' => __( 'State/County', 'woocommerce' ),
'description' => __('State/County or state code', 'woothemes') 'description' => __( 'State/County or state code', 'woocommerce' )
), ),
'shipping_country' => array( 'shipping_country' => array(
'label' => __('Country', 'woothemes'), 'label' => __( 'Country', 'woocommerce' ),
'description' => __('2 letter Country code', 'woothemes') 'description' => __( '2 letter Country code', 'woocommerce' )
) )
) )
) )
)); ));
return $show_fields;
}
/**
* Show Address Fields on edit user pages.
*
* @access public
* @param mixed $user User (object) being displayed
* @return void
*/
function woocommerce_customer_meta_fields( $user ) {
if ( ! current_user_can( 'manage_woocommerce' ) )
return;
$show_fields = woocommerce_get_customer_meta_fields();
foreach( $show_fields as $fieldset ) : foreach( $show_fields as $fieldset ) :
?> ?>
<h3><?php echo $fieldset['title']; ?></h3> <h3><?php echo $fieldset['title']; ?></h3>
@ -195,10 +256,10 @@ function woocommerce_customer_meta_fields( $user ) {
foreach( $fieldset['fields'] as $key => $field ) : foreach( $fieldset['fields'] as $key => $field ) :
?> ?>
<tr> <tr>
<th><label for="<?php echo $key; ?>"><?php echo $field['label']; ?></label></th> <th><label for="<?php echo esc_attr( $key ); ?>"><?php echo esc_html( $field['label'] ); ?></label></th>
<td> <td>
<input type="text" name="<?php echo $key; ?>" id="<?php echo $key; ?>" value="<?php echo esc_attr( get_user_meta( $user->ID, $key, true ) ); ?>" class="regular-text" /><br/> <input type="text" name="<?php echo esc_attr( $key ); ?>" id="<?php echo esc_attr( $key ); ?>" value="<?php echo esc_attr( get_user_meta( $user->ID, $key, true ) ); ?>" class="regular-text" /><br/>
<span class="description"><?php echo $field['description']; ?></span> <span class="description"><?php echo wp_kses_post( $field['description'] ); ?></span>
</td> </td>
</tr> </tr>
<?php <?php
@ -207,4 +268,30 @@ function woocommerce_customer_meta_fields( $user ) {
</table> </table>
<?php <?php
endforeach; endforeach;
} }
add_action( 'show_user_profile', 'woocommerce_customer_meta_fields' );
add_action( 'edit_user_profile', 'woocommerce_customer_meta_fields' );
/**
* Save Address Fields on edit user pages
*
* @access public
* @param mixed $user_id User ID of the user being saved
* @return void
*/
function woocommerce_save_customer_meta_fields( $user_id ) {
if ( ! current_user_can( 'manage_woocommerce' ) )
return $columns;
$save_fields = woocommerce_get_customer_meta_fields();
foreach( $save_fields as $fieldset )
foreach( $fieldset['fields'] as $key => $field )
if ( isset( $_POST[ $key ] ) )
update_user_meta( $user_id, $key, woocommerce_clean( $_POST[ $key ] ) );
}
add_action( 'personal_options_update', 'woocommerce_save_customer_meta_fields' );
add_action( 'edit_user_profile_update', 'woocommerce_save_customer_meta_fields' );

View File

@ -0,0 +1 @@
.woocommerce-message{position:relative;z-index:100;border:1px solid #b76ca9!important;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;-webkit-box-shadow:inset 0 0 15px rgba(0,0,0,0.04);-moz-box-shadow:inset 0 0 15px rgba(0,0,0,0.04);box-shadow:inset 0 0 15px rgba(0,0,0,0.04);overflow:hidden;padding:10px 0 10px!important;background:#cc99c2 url(../images/message.png) no-repeat right bottom!important}.woocommerce-message .squeezer{max-width:960px;margin:0;padding:0 10px;text-align:left;overflow:hidden}.woocommerce-message h4{margin:0 10px 0 0;font-size:18px;line-height:36px;font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;font-weight:normal;color:#fff;text-shadow:0 1px 1px #b574a8;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;float:left;vertical-align:middle}.woocommerce-message p{margin:0!important;padding:2px 0!important;float:left!important;line-height:32px;vertical-align:middle}.woocommerce-message p a.button-primary{font-size:16px!important;line-height:16px!important;height:auto!important;margin:0 5px 0 0;padding:6px 15px;vertical-align:middle;color:#fff;text-align:center;text-decoration:none;-moz-border-radius:5px;-webkit-border-radius:5px;border-radius:5px;border:1px solid #88537e;background:#a46497;-moz-box-shadow:inset 0 0 2px #fff,0 1px 1px rgba(0,0,0,0.1);-webkit-box-shadow:inset 0 0 2px #fff,0 1px 1px rgba(0,0,0,0.1);box-shadow:inset 0 0 2px #fff,0 1px 1px rgba(0,0,0,0.1);text-shadow:0 -1px 0 rgba(0,0,0,0.3);-webkit-transition-duration:.3s;-moz-transition-duration:.3s;cursor:pointer;font-family:"Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif}.woocommerce-message p a.button-primary:hover,.woocommerce-message p a.button-primary:active{background-color:#f0a000;border-color:#c87800;-webkit-transition-duration:.3s;outline:0;opacity:1}.woocommerce-message p a.skip,.woocommerce-message p a.docs{opacity:.5}.woocommerce-message .twitter-share-button{vertical-align:middle}

View File

@ -0,0 +1,79 @@
.woocommerce-message {
position: relative;
z-index: 100;
border: 1px solid #b76ca9 !important;
-moz-border-radius: 3px;
-webkit-border-radius: 3px;
border-radius: 3px;
-webkit-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
-moz-box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
box-shadow: inset 0 0 15px rgba( 0,0,0,0.04 );
overflow: hidden;
padding: 10px 0 10px !important;
background: #cc99c2 url(../images/message.png) no-repeat right bottom !important;
.squeezer {
max-width: 960px;
margin: 0;
padding: 0 10px;
text-align: left;
overflow: hidden;
}
h4 {
margin: 0 10px 0 0;
font-size: 18px;
line-height: 36px;
font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
font-weight: normal;
color: #fff;
text-shadow: 0px 1px 1px #b574a8;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
float: left;
vertical-align: middle;
}
p {
margin: 0 !important;
padding: 2px 0 !important;
float: left !important;
line-height: 32px;
vertical-align: middle;
a.button-primary {
font-size: 16px !important;
line-height: 16px !important;
height: auto !important;
margin: 0 5px 0 0;
padding: 6px 15px;
vertical-align: middle;
color: #fff;
text-align: center;
text-decoration: none;
-moz-border-radius: 5px;
-webkit-border-radius: 5px;
border-radius: 5px;
border: 1px solid #88537e;
background: #a46497;
-moz-box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
-webkit-box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
box-shadow: inset 0 0 2px rgba( 255,255,255,1), 0 1px 1px rgba( 0,0,0,0.1 );
text-shadow: 0px -1px 0px rgba( 0,0,0,0.3);
-webkit-transition-duration: .3s;
-moz-transition-duration: .3s;
cursor: pointer;
font-family: "Helvetica Neue",Helvetica,Arial,"Lucida Grande",Verdana,"Bitstream Vera Sans",sans-serif;
}
a.button-primary:hover, a.button-primary:active {
background-color: #f0a000;
border-color: #c87800;
-webkit-transition-duration: .3s;
outline: none;
opacity: 1;
}
a.skip, a.docs {
opacity: 0.5;
}
}
.twitter-share-button {
vertical-align: middle;
}
}

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

457
assets/css/chosen.less Normal file
View File

@ -0,0 +1,457 @@
/* WooCommerce styles */
.woocommerce-checkout .form-row {
.chzn-container {
width: 100% !important;
}
.chzn-container-single .chzn-single {
height: 28px;
line-height: 29px;
}
.chzn-container-single .chzn-single div b {
background: url('../images/chosen-sprite.png') no-repeat 0 3px !important;
}
.chzn-container-active .chzn-single-with-drop div b {
background-position: -18px 4px !important;
}
.chzn-container-single .chzn-search input {
line-height: 13px;
width: 100% !important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
.chzn-container .chzn-drop {
width: 100% !important;
-webkit-box-sizing: border-box; /* Safari/Chrome, other WebKit */
-moz-box-sizing: border-box; /* Firefox, other Gecko */
box-sizing: border-box; /* Opera/IE 8+ */
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
.woocommerce-checkout .form-row {
.chzn-container-single .chzn-single div b {
background-image: url('../images/chosen-sprite@2x.png') !important;
background-position: 0 5px !important;
background-repeat: no-repeat !important;
background-size: 52px 37px !important;
}
.chzn-container-active .chzn-single-with-drop div b {
background-position: -18px 5px !important;
}
}
}
/* @group Base */
.chzn-container {
font-size: 13px;
position: relative;
display: inline-block;
zoom: 1;
*display: inline;
}
.chzn-container .chzn-drop {
background: #fff;
border: 1px solid #aaa;
border-top: 0;
position: absolute;
top: 29px;
left: 0;
-webkit-box-shadow: 0 4px 5px rgba(0,0,0,.15);
-moz-box-shadow : 0 4px 5px rgba(0,0,0,.15);
box-shadow : 0 4px 5px rgba(0,0,0,.15);
z-index: 1010;
}
/* @end */
/* @group Single Chosen */
.chzn-container-single .chzn-single {
background-color: #ffffff;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#ffffff', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #ffffff), color-stop(50%, #f6f6f6), color-stop(52%, #eeeeee), color-stop(100%, #f4f4f4));
background-image: -webkit-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: -moz-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: -o-linear-gradient(top, #ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
background-image: linear-gradient(#ffffff 20%, #f6f6f6 50%, #eeeeee 52%, #f4f4f4 100%);
-webkit-border-radius: 5px;
-moz-border-radius : 5px;
border-radius : 5px;
-moz-background-clip : padding;
-webkit-background-clip: padding-box;
background-clip : padding-box;
border: 1px solid #aaaaaa;
-webkit-box-shadow: 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
-moz-box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
box-shadow : 0 0 3px #ffffff inset, 0 1px 1px rgba(0,0,0,0.1);
display: block;
overflow: hidden;
white-space: nowrap;
position: relative;
height: 23px;
line-height: 24px;
padding: 0 0 0 8px;
color: #444444;
text-decoration: none;
}
.chzn-container-single .chzn-default {
color: #999;
}
.chzn-container-single .chzn-single span {
margin-right: 26px;
display: block;
overflow: hidden;
white-space: nowrap;
-o-text-overflow: ellipsis;
-ms-text-overflow: ellipsis;
text-overflow: ellipsis;
}
.chzn-container-single .chzn-single abbr {
display: block;
position: absolute;
right: 26px;
top: 6px;
width: 12px;
height: 12px;
font-size: 1px;
background: url('../images/chosen-sprite.png') -44px 2px no-repeat;
}
.chzn-container-single .chzn-single abbr:hover {
background-position: -44px -9px;
}
.chzn-container-single.chzn-disabled .chzn-single abbr:hover {
background-position: -44px -9px;
}
.chzn-container-single .chzn-single div {
position: absolute;
right: 0;
top: 0;
display: block;
height: 100%;
width: 18px;
}
.chzn-container-single .chzn-single div b {
background: url('../images/chosen-sprite.png') no-repeat 0px 2px;
display: block;
width: 100%;
height: 100%;
}
.chzn-container-single .chzn-search {
padding: 3px 4px;
position: relative;
margin: 0;
white-space: nowrap;
z-index: 1010;
}
.chzn-container-single .chzn-search input {
background: #fff url('../images/chosen-sprite.png') no-repeat 100% -20px;
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat 100% -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
margin: 1px 0;
padding: 4px 20px 4px 5px;
outline: 0;
border: 1px solid #aaa;
font-family: sans-serif;
font-size: 1em;
}
.chzn-container-single .chzn-drop {
-webkit-border-radius: 0 0 4px 4px;
-moz-border-radius : 0 0 4px 4px;
border-radius : 0 0 4px 4px;
-moz-background-clip : padding;
-webkit-background-clip: padding-box;
background-clip : padding-box;
}
/* @end */
.chzn-container-single-nosearch .chzn-search input {
position: absolute;
left: -9000px;
}
/* @group Multi Chosen */
.chzn-container-multi .chzn-choices {
background-color: #fff;
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background-image: -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background-image: linear-gradient(#eeeeee 1%, #ffffff 15%);
border: 1px solid #aaa;
margin: 0;
padding: 0;
cursor: text;
overflow: hidden;
height: auto !important;
height: 1%;
position: relative;
}
.chzn-container-multi .chzn-choices li {
float: left;
list-style: none;
}
.chzn-container-multi .chzn-choices .search-field {
white-space: nowrap;
margin: 0;
padding: 0;
}
.chzn-container-multi .chzn-choices .search-field input {
color: #666;
background: transparent !important;
border: 0 !important;
font-family: sans-serif;
font-size: 100%;
height: 15px;
padding: 5px;
margin: 1px 0;
outline: 0;
-webkit-box-shadow: none;
-moz-box-shadow : none;
box-shadow : none;
}
.chzn-container-multi .chzn-choices .search-field .default {
color: #999;
}
.chzn-container-multi .chzn-choices .search-choice {
-webkit-border-radius: 3px;
-moz-border-radius : 3px;
border-radius : 3px;
-moz-background-clip : padding;
-webkit-background-clip: padding-box;
background-clip : padding-box;
background-color: #e4e4e4;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(#f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
-webkit-box-shadow: 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
-moz-box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
box-shadow : 0 0 2px #ffffff inset, 0 1px 0 rgba(0,0,0,0.05);
color: #333;
border: 1px solid #aaaaaa;
line-height: 13px;
padding: 3px 20px 3px 5px;
margin: 3px 0 3px 5px;
position: relative;
cursor: default;
}
.chzn-container-multi .chzn-choices .search-choice.search-choice-disabled {
background-color: #e4e4e4;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#f4f4f4', endColorstr='#eeeeee', GradientType=0 );
background-image: -webkit-gradient(linear, 0% 0%, 0% 100%, color-stop(20%, #f4f4f4), color-stop(50%, #f0f0f0), color-stop(52%, #e8e8e8), color-stop(100%, #eeeeee));
background-image: -webkit-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -moz-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -o-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: -ms-linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
background-image: linear-gradient(top, #f4f4f4 20%, #f0f0f0 50%, #e8e8e8 52%, #eeeeee 100%);
color: #666;
border: 1px solid #cccccc;
padding-right: 5px;
}
.chzn-container-multi .chzn-choices .search-choice-focus {
background: #d4d4d4;
}
.chzn-container-multi .chzn-choices .search-choice .search-choice-close {
display: block;
position: absolute;
right: 3px;
top: 4px;
width: 12px;
height: 12px;
font-size: 1px;
background: url('../images/chosen-sprite.png') -44px 2px no-repeat;
}
.chzn-container-multi .chzn-choices .search-choice .search-choice-close:hover {
background-position: -44px -9px;
}
.chzn-container-multi .chzn-choices .search-choice-focus .search-choice-close {
background-position: -44px -9px;
}
/* @end */
/* @group Results */
.chzn-container .chzn-results {
margin: 0 4px 4px 0;
max-height: 240px;
padding: 0 0 0 4px;
position: relative;
overflow-x: hidden;
overflow-y: auto;
-webkit-overflow-scrolling: touch;
}
.chzn-container-multi .chzn-results {
margin: -1px 0 0;
padding: 0;
}
.chzn-container .chzn-results li {
display: none;
line-height: 15px;
padding: 5px 6px;
margin: 0;
list-style: none;
}
.chzn-container .chzn-results .active-result {
cursor: pointer;
display: list-item;
}
.chzn-container .chzn-results .highlighted {
background-color: #3875d7;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#3875d7', endColorstr='#2a62bc', GradientType=0 );
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #3875d7), color-stop(90%, #2a62bc));
background-image: -webkit-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: -moz-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: -o-linear-gradient(top, #3875d7 20%, #2a62bc 90%);
background-image: linear-gradient(#3875d7 20%, #2a62bc 90%);
color: #fff;
}
.chzn-container .chzn-results li em {
background: #feffde;
font-style: normal;
}
.chzn-container .chzn-results .highlighted em {
background: transparent;
}
.chzn-container .chzn-results .no-results {
background: #f4f4f4;
display: list-item;
}
.chzn-container .chzn-results .group-result {
cursor: default;
color: #999;
font-weight: bold;
}
.chzn-container .chzn-results .group-option {
padding-left: 15px;
}
.chzn-container-multi .chzn-drop .result-selected {
display: none;
}
.chzn-container .chzn-results-scroll {
background: white;
margin: 0 4px;
position: absolute;
text-align: center;
width: 321px; /* This should by dynamic with js */
z-index: 1;
}
.chzn-container .chzn-results-scroll span {
display: inline-block;
height: 17px;
text-indent: -5000px;
width: 9px;
}
.chzn-container .chzn-results-scroll-down {
bottom: 0;
}
.chzn-container .chzn-results-scroll-down span {
background: url('../images/chosen-sprite.png') no-repeat -4px -3px;
}
.chzn-container .chzn-results-scroll-up span {
background: url('../images/chosen-sprite.png') no-repeat -22px -3px;
}
/* @end */
/* @group Active */
.chzn-container-active .chzn-single {
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
box-shadow : 0 0 5px rgba(0,0,0,.3);
border: 1px solid #5897fb;
}
.chzn-container-active .chzn-single-with-drop {
border: 1px solid #aaa;
-webkit-box-shadow: 0 1px 0 #fff inset;
-moz-box-shadow : 0 1px 0 #fff inset;
box-shadow : 0 1px 0 #fff inset;
background-color: #eee;
filter: progid:DXImageTransform.Microsoft.gradient( startColorstr='#eeeeee', endColorstr='#ffffff', GradientType=0 );
background-image: -webkit-gradient(linear, 0 0, 0 100%, color-stop(20%, #eeeeee), color-stop(80%, #ffffff));
background-image: -webkit-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: -moz-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: -o-linear-gradient(top, #eeeeee 20%, #ffffff 80%);
background-image: linear-gradient(#eeeeee 20%, #ffffff 80%);
-webkit-border-bottom-left-radius : 0;
-webkit-border-bottom-right-radius: 0;
-moz-border-radius-bottomleft : 0;
-moz-border-radius-bottomright: 0;
border-bottom-left-radius : 0;
border-bottom-right-radius: 0;
}
.chzn-container-active .chzn-single-with-drop div {
background: transparent;
border-left: none;
}
.chzn-container-active .chzn-single-with-drop div b {
background-position: -18px 2px;
}
.chzn-container-active .chzn-choices {
-webkit-box-shadow: 0 0 5px rgba(0,0,0,.3);
-moz-box-shadow : 0 0 5px rgba(0,0,0,.3);
box-shadow : 0 0 5px rgba(0,0,0,.3);
border: 1px solid #5897fb;
}
.chzn-container-active .chzn-choices .search-field input {
color: #111 !important;
}
/* @end */
/* @group Disabled Support */
.chzn-disabled {
cursor: default;
opacity:0.5 !important;
}
.chzn-disabled .chzn-single {
cursor: default;
}
.chzn-disabled .chzn-choices .search-choice .search-choice-close {
cursor: default;
}
/* @group Right to Left */
.chzn-rtl { text-align: right; }
.chzn-rtl .chzn-single { padding: 0 8px 0 0; overflow: visible; }
.chzn-rtl .chzn-single span { margin-left: 26px; margin-right: 0; direction: rtl; }
.chzn-rtl .chzn-single div { left: 3px; right: auto; }
.chzn-rtl .chzn-single abbr {
left: 26px;
right: auto;
}
.chzn-rtl .chzn-choices .search-field input { direction: rtl; }
.chzn-rtl .chzn-choices li { float: right; }
.chzn-rtl .chzn-choices .search-choice { padding: 3px 5px 3px 19px; margin: 3px 5px 3px 0; }
.chzn-rtl .chzn-choices .search-choice .search-choice-close { left: 4px; right: auto; background-position: -44px 2px;}
.chzn-rtl.chzn-container-single .chzn-results { margin: 0 0 4px 4px; padding: 0 4px 0 0; }
.chzn-rtl .chzn-results .group-option { padding-left: 0; padding-right: 15px; }
.chzn-rtl.chzn-container-active .chzn-single-with-drop div { border-right: none; }
.chzn-rtl .chzn-search input {
background: #fff url('../images/chosen-sprite.png') no-repeat -30px -20px;
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -webkit-gradient(linear, 0 0, 0 100%, color-stop(1%, #eeeeee), color-stop(15%, #ffffff));
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -webkit-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -moz-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, -o-linear-gradient(top, #eeeeee 1%, #ffffff 15%);
background: url('../images/chosen-sprite.png') no-repeat -30px -20px, linear-gradient(#eeeeee 1%, #ffffff 15%);
padding: 4px 5px 4px 20px;
direction: rtl;
}
.chzn-container-single.chzn-rtl .chzn-single div b {
background-position: 6px 2px;
}
.chzn-container-single.chzn-rtl.chzn-container-active .chzn-single div b {
background-position: -12px 2px;
}
/* @end */
/* @group Retina compatibility */
@media only screen and (-webkit-min-device-pixel-ratio: 2), only screen and (min-resolution: 144dpi) {
.chzn-rtl .chzn-search input, .chzn-container-single .chzn-single abbr, .chzn-container-single .chzn-single div b, .chzn-container-single .chzn-search input, .chzn-container-multi .chzn-choices .search-choice .search-choice-close, .chzn-container .chzn-results-scroll-down span, .chzn-container .chzn-results-scroll-up span {
background-image: url('../images/chosen-sprite@2x.png') !important;
background-repeat: no-repeat !important;
background-size: 52px 37px !important;
}
}
/* @end */

File diff suppressed because one or more lines are too long

324
assets/css/fancybox.css Executable file → Normal file
View File

@ -1,323 +1 @@
/* #fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:11104;display:none}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/fancybox/fancybox.png')}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:11100;display:none}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:11101;outline:0;display:none}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em;-webkit-box-shadow:0 0 1em rgba(0,0,0,0.6);-moz-box-shadow:0 0 1em rgba(0,0,0,0.6);box-shadow:0 0 1em rgba(0,0,0,0.6)}#fancybox-content{width:0;height:0;padding:0;outline:0;position:relative;overflow:hidden;z-index:11102;border:0 solid #fff;-webkit-border-radius:1em;-moz-border-radius:1em;border-radius:1em}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:11101}#fancybox-close{position:absolute;top:-15px;right:-15px;width:24px;height:24px;line-height:24px!important;font-size:16px!important;font-family:sans-serif!important;cursor:pointer;z-index:11103;display:none;text-align:center;background:#000;display:inline-block;border:2px solid #fff;-webkit-border-radius:2em;-moz-border-radius:2em;border-radius:2em;font-weight:bold;color:#fff;text-shadow:none;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.8);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.8);box-shadow:0 1px 3px rgba(0,0,0,0.8);-webkit-transition:all ease-in-out .2s}#fancybox-close:hover{background:#a36396;text-decoration:none!important}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:0;outline:0;line-height:0;vertical-align:top}#fancybox-frame{width:100%;height:100%;border:0;display:block}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:0;background:transparent url('../images/fancybox/blank.gif');z-index:11102;display:none}#fancybox-left{left:0}#fancybox-right{right:0}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:11102;display:block}#fancybox-left-ico{background-image:url('../images/fancybox/fancybox.png');background-position:-40px -30px}#fancybox-right-ico{background-image:url('../images/fancybox/fancybox.png');background-position:-40px -60px}#fancybox-left:hover,#fancybox-right:hover{visibility:visible}#fancybox-left:hover span{left:20px}#fancybox-right:hover span{left:auto;right:20px}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:11001}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:11102;text-align:center;padding-top:10px}#fancybox-title-float{padding:3px 10px;background:#000;display:inline-block;border:2px solid #fff;-webkit-border-radius:2em;-moz-border-radius:2em;border-radius:2em;font-weight:bold;color:#fff;text-shadow:none;-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.8);-moz-box-shadow:0 1px 3px rgba(0,0,0,0.8);box-shadow:0 1px 3px rgba(0,0,0,0.8)}
* FancyBox - jQuery Plugin
* Simple and fancy lightbox alternative
*
* Examples and documentation at: http://fancybox.net
*
* Copyright (c) 2008 - 2010 Janis Skarnelis
* That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
*
* Version: 1.3.4 (11/11/2010)
* Requires: jQuery v1.3+
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
#fancybox-loading {
position: fixed;
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-top: -20px;
margin-left: -20px;
cursor: pointer;
overflow: hidden;
z-index: 1104;
display: none;
}
#fancybox-loading div {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 480px;
background-image: url('../images/fancybox/fancybox.png');
}
#fancybox-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 1100;
display: none;
}
#fancybox-tmp {
padding: 0;
margin: 0;
border: 0;
overflow: auto;
display: none;
}
#fancybox-wrap {
position: absolute;
top: 0;
left: 0;
padding: 20px;
z-index: 1101;
outline: none;
display: none;
}
#fancybox-outer {
position: relative;
width: 100%;
height: 100%;
background: #fff;
}
#fancybox-content {
width: 0;
height: 0;
padding: 0;
outline: none;
position: relative;
overflow: hidden;
z-index: 1102;
border: 0px solid #fff;
}
#fancybox-hide-sel-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
z-index: 1101;
}
#fancybox-close {
position: absolute;
top: -15px;
right: -15px;
width: 25px;
height: 25px;
background: transparent url('../images/fancybox/fancybox.png') -40px 0px;
cursor: pointer;
z-index: 1103;
display: none;
}
#fancybox-error {
color: #444;
font: normal 12px/20px Arial;
padding: 14px;
margin: 0;
}
#fancybox-img {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
border: none;
outline: none;
line-height: 0;
vertical-align: top;
}
#fancybox-frame {
width: 100%;
height: 100%;
border: none;
display: block;
}
#fancybox-left, #fancybox-right {
position: absolute;
bottom: 0px;
height: 100%;
width: 35%;
cursor: pointer;
outline: none;
background: transparent url('../images/fancybox/blank.gif');
z-index: 1102;
display: none;
}
#fancybox-left {
left: 0px;
}
#fancybox-right {
right: 0px;
}
#fancybox-left-ico, #fancybox-right-ico {
position: absolute;
top: 50%;
left: -9999px;
width: 30px;
height: 30px;
margin-top: -15px;
cursor: pointer;
z-index: 1102;
display: block;
}
#fancybox-left-ico {
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -30px;
}
#fancybox-right-ico {
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -60px;
}
#fancybox-left:hover, #fancybox-right:hover {
visibility: visible; /* IE6 */
}
#fancybox-left:hover span {
left: 20px;
}
#fancybox-right:hover span {
left: auto;
right: 20px;
}
.fancybox-bg {
position: absolute;
padding: 0;
margin: 0;
border: 0;
width: 20px;
height: 20px;
z-index: 1001;
}
#fancybox-bg-n {
top: -20px;
left: 0;
width: 100%;
background-image: url('../images/fancybox/fancybox-x.png');
}
#fancybox-bg-ne {
top: -20px;
right: -20px;
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -162px;
}
#fancybox-bg-e {
top: 0;
right: -20px;
height: 100%;
background-image: url('../images/fancybox/fancybox-y.png');
background-position: -20px 0px;
}
#fancybox-bg-se {
bottom: -20px;
right: -20px;
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -182px;
}
#fancybox-bg-s {
bottom: -20px;
left: 0;
width: 100%;
background-image: url('../images/fancybox/fancybox-x.png');
background-position: 0px -20px;
}
#fancybox-bg-sw {
bottom: -20px;
left: -20px;
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -142px;
}
#fancybox-bg-w {
top: 0;
left: -20px;
height: 100%;
background-image: url('../images/fancybox/fancybox-y.png');
}
#fancybox-bg-nw {
top: -20px;
left: -20px;
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -122px;
}
#fancybox-title {
font-family: Helvetica;
font-size: 12px;
z-index: 1102;
}
.fancybox-title-inside {
padding-bottom: 10px;
text-align: center;
color: #333;
background: #fff;
position: relative;
}
.fancybox-title-outside {
padding-top: 10px;
color: #fff;
}
.fancybox-title-over {
position: absolute;
bottom: 0;
left: 0;
color: #FFF;
text-align: left;
}
#fancybox-title-over {
padding: 10px;
background-image: url('../images/fancybox/fancy_title_over.png');
display: block;
}
.fancybox-title-float {
position: absolute;
left: 0;
bottom: -20px;
height: 32px;
}
#fancybox-title-float-wrap {
border: none;
border-collapse: collapse;
width: auto;
}
#fancybox-title-float-wrap td {
border: none;
white-space: nowrap;
}
#fancybox-title-float-left {
padding: 0 0 0 15px;
background: url('../images/fancybox/fancybox.png') -40px -90px no-repeat;
}
#fancybox-title-float-main {
color: #FFF;
line-height: 29px;
font-weight: bold;
padding: 0 0 3px 0;
background: url('../images/fancybox/fancybox-x.png') 0px -40px;
}
#fancybox-title-float-right {
padding: 0 0 0 15px;
background: url('../images/fancybox/fancybox.png') -55px -90px no-repeat;
}

250
assets/css/fancybox.less Executable file
View File

@ -0,0 +1,250 @@
/*
* FancyBox - jQuery Plugin
* Simple and fancy lightbox alternative
*
* Examples and documentation at: http://fancybox.net
*
* Copyright (c) 2008 - 2010 Janis Skarnelis
* That said, it is hardly a one-person project. Many people have submitted bugs, code, and offered their advice freely. Their support is greatly appreciated.
*
* Version: 1.3.4 (11/11/2010)
* Requires: jQuery v1.3+
*
* Dual licensed under the MIT and GPL licenses:
* http://www.opensource.org/licenses/mit-license.php
* http://www.gnu.org/licenses/gpl.html
*/
#fancybox-loading {
position: fixed;
top: 50%;
left: 50%;
width: 40px;
height: 40px;
margin-top: -20px;
margin-left: -20px;
cursor: pointer;
overflow: hidden;
z-index: 11104;
display: none;
}
#fancybox-loading div {
position: absolute;
top: 0;
left: 0;
width: 40px;
height: 480px;
background-image: url('../images/fancybox/fancybox.png');
}
#fancybox-overlay {
position: absolute;
top: 0;
left: 0;
width: 100%;
z-index: 11100;
display: none;
}
#fancybox-tmp {
padding: 0;
margin: 0;
border: 0;
overflow: auto;
display: none;
}
#fancybox-wrap {
position: absolute;
top: 0;
left: 0;
padding: 20px;
z-index: 11101;
outline: none;
display: none;
}
#fancybox-outer {
position: relative;
width: 100%;
height: 100%;
background: #fff;
-webkit-border-radius:1em;
-moz-border-radius:1em;
border-radius:1em;
-webkit-box-shadow:0 0 1em rgba(0,0,0,0.6);
-moz-box-shadow:0 0 1em rgba(0,0,0,0.6);
box-shadow:0 0 1em rgba(0,0,0,0.6);
}
#fancybox-content {
width: 0;
height: 0;
padding: 0;
outline: none;
position: relative;
overflow: hidden;
z-index: 11102;
border: 0px solid #fff;
-webkit-border-radius:1em;
-moz-border-radius:1em;
border-radius:1em;
}
#fancybox-hide-sel-frame {
position: absolute;
top: 0;
left: 0;
width: 100%;
height: 100%;
background: transparent;
z-index: 11101;
}
#fancybox-close {
position: absolute;
top: -15px;
right: -15px;
width: 24px;
height: 24px;
line-height: 24px !important;
font-size:16px !important;
font-family: sans-serif !important;
cursor: pointer;
z-index: 11103;
display: none;
text-align: center;
background: #000;
display: inline-block;
border:2px solid #fff;
-webkit-border-radius:2em;
-moz-border-radius:2em;
border-radius:2em;
font-weight: bold;
color: #fff;
text-shadow:none;
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.8);
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.8);
box-shadow:0 1px 3px rgba(0,0,0,0.8);
-webkit-transition:all ease-in-out .2s;
}
#fancybox-close:hover {
background: #a36396;
text-decoration:none !important;
}
#fancybox-error {
color: #444;
font: normal 12px/20px Arial;
padding: 14px;
margin: 0;
}
#fancybox-img {
width: 100%;
height: 100%;
padding: 0;
margin: 0;
border: none;
outline: none;
line-height: 0;
vertical-align: top;
}
#fancybox-frame {
width: 100%;
height: 100%;
border: none;
display: block;
}
#fancybox-left, #fancybox-right {
position: absolute;
bottom: 0px;
height: 100%;
width: 35%;
cursor: pointer;
outline: none;
background: transparent url('../images/fancybox/blank.gif');
z-index: 11102;
display: none;
}
#fancybox-left {
left: 0px;
}
#fancybox-right {
right: 0px;
}
#fancybox-left-ico, #fancybox-right-ico {
position: absolute;
top: 50%;
left: -9999px;
width: 30px;
height: 30px;
margin-top: -15px;
cursor: pointer;
z-index: 11102;
display: block;
}
#fancybox-left-ico {
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -30px;
}
#fancybox-right-ico {
background-image: url('../images/fancybox/fancybox.png');
background-position: -40px -60px;
}
#fancybox-left:hover, #fancybox-right:hover {
visibility: visible; /* IE6 */
}
#fancybox-left:hover span {
left: 20px;
}
#fancybox-right:hover span {
left: auto;
right: 20px;
}
.fancybox-bg {
position: absolute;
padding: 0;
margin: 0;
border: 0;
width: 20px;
height: 20px;
z-index: 11001;
}
#fancybox-title {
font-family: Helvetica;
font-size: 12px;
z-index: 11102;
text-align: center;
padding-top:10px;
}
#fancybox-title-float {
padding:3px 10px;
background: #000;
display: inline-block;
border:2px solid #fff;
-webkit-border-radius:2em;
-moz-border-radius:2em;
border-radius:2em;
font-weight: bold;
color: #fff;
text-shadow:none;
-webkit-box-shadow:0 1px 3px rgba(0,0,0,0.8);
-moz-box-shadow:0 1px 3px rgba(0,0,0,0.8);
box-shadow:0 1px 3px rgba(0,0,0,0.8);
}

View File

@ -1 +0,0 @@
#fancybox-loading{position:fixed;top:50%;left:50%;width:40px;height:40px;margin-top:-20px;margin-left:-20px;cursor:pointer;overflow:hidden;z-index:1104;display:none;}#fancybox-loading div{position:absolute;top:0;left:0;width:40px;height:480px;background-image:url('../images/fancybox/fancybox.png');}#fancybox-overlay{position:absolute;top:0;left:0;width:100%;z-index:1100;display:none;}#fancybox-tmp{padding:0;margin:0;border:0;overflow:auto;display:none;}#fancybox-wrap{position:absolute;top:0;left:0;padding:20px;z-index:1101;outline:none;display:none;}#fancybox-outer{position:relative;width:100%;height:100%;background:#fff;}#fancybox-content{width:0;height:0;padding:0;outline:none;position:relative;overflow:hidden;z-index:1102;border:0 solid #fff;}#fancybox-hide-sel-frame{position:absolute;top:0;left:0;width:100%;height:100%;background:transparent;z-index:1101;}#fancybox-close{position:absolute;top:-15px;right:-15px;width:25px;height:25px;background:transparent url('../images/fancybox/fancybox.png') -40px 0;cursor:pointer;z-index:1103;display:none;}#fancybox-error{color:#444;font:normal 12px/20px Arial;padding:14px;margin:0;}#fancybox-img{width:100%;height:100%;padding:0;margin:0;border:none;outline:none;line-height:0;vertical-align:top;}#fancybox-frame{width:100%;height:100%;border:none;display:block;}#fancybox-left,#fancybox-right{position:absolute;bottom:0;height:100%;width:35%;cursor:pointer;outline:none;background:transparent url('../images/fancybox/blank.gif');z-index:1102;display:none;}#fancybox-left{left:0;}#fancybox-right{right:0;}#fancybox-left-ico,#fancybox-right-ico{position:absolute;top:50%;left:-9999px;width:30px;height:30px;margin-top:-15px;cursor:pointer;z-index:1102;display:block;}#fancybox-left-ico{background-image:url('../images/fancybox/fancybox.png');background-position:-40px -30px;}#fancybox-right-ico{background-image:url('../images/fancybox/fancybox.png');background-position:-40px -60px;}#fancybox-left:hover,#fancybox-right:hover{visibility:visible;}#fancybox-left:hover span{left:20px;}#fancybox-right:hover span{left:auto;right:20px;}.fancybox-bg{position:absolute;padding:0;margin:0;border:0;width:20px;height:20px;z-index:1001;}#fancybox-bg-n{top:-20px;left:0;width:100%;background-image:url('../images/fancybox/fancybox-x.png');}#fancybox-bg-ne{top:-20px;right:-20px;background-image:url('../images/fancybox/fancybox.png');background-position:-40px -162px;}#fancybox-bg-e{top:0;right:-20px;height:100%;background-image:url('../images/fancybox/fancybox-y.png');background-position:-20px 0;}#fancybox-bg-se{bottom:-20px;right:-20px;background-image:url('../images/fancybox/fancybox.png');background-position:-40px -182px;}#fancybox-bg-s{bottom:-20px;left:0;width:100%;background-image:url('../images/fancybox/fancybox-x.png');background-position:0 -20px;}#fancybox-bg-sw{bottom:-20px;left:-20px;background-image:url('../images/fancybox/fancybox.png');background-position:-40px -142px;}#fancybox-bg-w{top:0;left:-20px;height:100%;background-image:url('../images/fancybox/fancybox-y.png');}#fancybox-bg-nw{top:-20px;left:-20px;background-image:url('../images/fancybox/fancybox.png');background-position:-40px -122px;}#fancybox-title{font-family:Helvetica;font-size:12px;z-index:1102;}.fancybox-title-inside{padding-bottom:10px;text-align:center;color:#333;background:#fff;position:relative;}.fancybox-title-outside{padding-top:10px;color:#fff;}.fancybox-title-over{position:absolute;bottom:0;left:0;color:#FFF;text-align:left;}#fancybox-title-over{padding:10px;background-image:url('../images/fancybox/fancy_title_over.png');display:block;}.fancybox-title-float{position:absolute;left:0;bottom:-20px;height:32px;}#fancybox-title-float-wrap{border:none;border-collapse:collapse;width:auto;}#fancybox-title-float-wrap td{border:none;white-space:nowrap;}#fancybox-title-float-left{padding:0 0 0 15px;background:url('../images/fancybox/fancybox.png') -40px -90px no-repeat;}#fancybox-title-float-main{color:#FFF;line-height:29px;font-weight:bold;padding:0 0 3px 0;background:url('../images/fancybox/fancybox-x.png') 0 -40px;}#fancybox-title-float-right{padding:0 0 0 15px;background:url('../images/fancybox/fancybox.png') -55px -90px no-repeat;}

1
assets/css/menu.css Normal file
View File

@ -0,0 +1 @@
#adminmenu #menu-posts-product div.wp-menu-image,#adminmenu #menu-posts-shop_order div.wp-menu-image,#adminmenu #menu-posts-shop_coupon div.wp-menu-image,#adminmenu #toplevel_page_woocommerce div.wp-menu-image{background-image:url(../images/icons/menu_icons.png)}#adminmenu #menu-posts-product div.wp-menu-image{background-position:-32px -32px}#adminmenu #menu-posts-product.wp-menu-open div.wp-menu-image,#adminmenu #menu-posts-product:hover div.wp-menu-image{background-position:-32px 0}#adminmenu #menu-posts-product img{display:none}#adminmenu #menu-posts-shop_order div.wp-menu-image{background-position:-64px -32px}#adminmenu #menu-posts-shop_order.wp-menu-open div.wp-menu-image,#adminmenu #menu-posts-shop_order:hover div.wp-menu-image{background-position:-64px 0}#adminmenu #menu-posts-shop_order img{display:none}#adminmenu #menu-posts-shop_coupon div.wp-menu-image{background-position:-96px -32px}#adminmenu #menu-posts-shop_coupon.wp-menu-open div.wp-menu-image,#adminmenu #menu-posts-shop_coupon:hover div.wp-menu-image{background-position:-96px 0}#adminmenu #menu-posts-shop_coupon img{display:none}#adminmenu #toplevel_page_woocommerce div.wp-menu-image{background-position:0 -32px}#adminmenu #toplevel_page_woocommerce.wp-menu-open div.wp-menu-image,#adminmenu #toplevel_page_woocommerce:hover div.wp-menu-image{background-position:0 0}#adminmenu #toplevel_page_woocommerce img{display:none}@media only screen and (-webkit-min-device-pixel-ratio:1.5){#adminmenu #menu-posts-product div.wp-menu-image,#adminmenu #menu-posts-shop_order div.wp-menu-image,#adminmenu #menu-posts-shop_coupon div.wp-menu-image,#adminmenu #toplevel_page_woocommerce div.wp-menu-image{background-image:url(../images/icons/menu_icons-x2.png);background-size:200px 64px}}span.mce_woocommerce_shortcodes_button{background-image:url(../images/icons/wc_icon.png)!important;background-repeat:no-repeat!important;background-position:center!important}

67
assets/css/menu.less Normal file
View File

@ -0,0 +1,67 @@
/* Menu */
#adminmenu {
#menu-posts-product div.wp-menu-image, #menu-posts-shop_order div.wp-menu-image, #menu-posts-shop_coupon div.wp-menu-image, #toplevel_page_woocommerce div.wp-menu-image {
background-image: url(../images/icons/menu_icons.png);
}
#menu-posts-product {
div.wp-menu-image {
background-position: -32px -32px;
}
&.wp-menu-open div.wp-menu-image, &:hover div.wp-menu-image {
background-position: -32px 0px;
}
img {
display: none;
}
}
#menu-posts-shop_order {
div.wp-menu-image {
background-position: -64px -32px;
}
&.wp-menu-open div.wp-menu-image, &:hover div.wp-menu-image {
background-position: -64px 0px;
}
img {
display: none;
}
}
#menu-posts-shop_coupon {
div.wp-menu-image {
background-position: -96px -32px;
}
&.wp-menu-open div.wp-menu-image, &:hover div.wp-menu-image {
background-position: -96px 0px;
}
img {
display: none;
}
}
#toplevel_page_woocommerce {
div.wp-menu-image {
background-position: 0px -32px;
}
&.wp-menu-open div.wp-menu-image, &:hover div.wp-menu-image {
background-position: 0px 0px;
}
img {
display: none;
}
}
}
@media only screen and (-webkit-min-device-pixel-ratio: 1.5) {
#adminmenu {
#menu-posts-product div.wp-menu-image, #menu-posts-shop_order div.wp-menu-image, #menu-posts-shop_coupon div.wp-menu-image, #toplevel_page_woocommerce div.wp-menu-image {
background-image: url(../images/icons/menu_icons-x2.png);
background-size: 200px 64px;
}
}
}
/* Editor button */
span.mce_woocommerce_shortcodes_button {
background-image: url(../images/icons/wc_icon.png) !important;
background-repeat: no-repeat !important;
background-position: center !important;
}

82
assets/css/mixins.less Normal file
View File

@ -0,0 +1,82 @@
.clearfix() {
&:after {
content:"";
display:block;
clear:both;
}
}
.border_radius(@radius:4px) {
-webkit-border-radius:@radius;
-moz-border-radius:@radius;
border-radius:@radius;
}
.border_radius_right(@radius:4px) {
-webkit-border-top-right-radius: @radius;
-webkit-border-bottom-right-radius: @radius;
-moz-border-radius-topright: @radius;
-moz-border-radius-bottomright: @radius;
border-top-right-radius: @radius;
border-bottom-right-radius: @radius;
}
.border_radius_left(@radius:4px) {
-webkit-border-top-left-radius: @radius;
-webkit-border-bottom-left-radius: @radius;
-moz-border-radius-topleft: @radius;
-moz-border-radius-bottomleft: @radius;
border-top-left-radius: @radius;
border-bottom-left-radius: @radius;
}
.border_radius_bottom(@radius:4px) {
-webkit-border-bottom-left-radius: @radius;
-webkit-border-bottom-right-radius: @radius;
-moz-border-radius-bottomleft: @radius;
-moz-border-radius-bottomright: @radius;
border-bottom-left-radius: @radius;
border-bottom-right-radius: @radius;
}
.border_radius_top(@radius:4px) {
-webkit-border-top-left-radius: @radius;
-webkit-border-top-right-radius: @radius;
-moz-border-radius-topleft: @radius;
-moz-border-radius-topright: @radius;
border-top-left-radius: @radius;
border-top-right-radius: @radius;
}
.opacity(@opacity:0.75) {
filter:~"alpha(opacity=@opacity * 100)";
-moz-opacity:@opacity;
-khtml-opacity: @opacity;
opacity: @opacity;
}
.box_shadow(@shadow_x:3px, @shadow_y:3px, @shadow_rad:3px, @shadow_in:3px, @shadow_color:#888) {
box-shadow:@shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
-webkit-box-shadow:@shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
-moz-box-shadow:@shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
}
.inset_box_shadow(@shadow_x:3px, @shadow_y:3px, @shadow_rad:3px, @shadow_in:3px, @shadow_color:#888) {
box-shadow:inset @shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
-webkit-box-shadow:inset @shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
-moz-box-shadow:inset @shadow_x @shadow_y @shadow_rad @shadow_in @shadow_color;
}
.text_shadow(@shadow_x:3px, @shadow_y:3px, @shadow_rad:3px, @shadow_color:#fff) {
text-shadow:@shadow_x @shadow_y @shadow_rad @shadow_color;
}
.vertical_gradient(@from: #000, @to: #FFF) {
background: @from;
background: -webkit-gradient(linear, left top, left bottom, from(@from), to(@to));
background: -webkit-linear-gradient(@from, @to);
background: -moz-linear-gradient(center top, @from 0%, @to 100%);
background: -moz-gradient(center top, @from 0%, @to 100%);
}
.transition(@selector:all, @animation:ease-in-out, @duration:.2s) {
-webkit-transition:@selector @animation @duration;
-moz-transition:@selector @animation @duration;
-o-transition:@selector @animation @duration;
transition:@selector @animation @duration;
}
.clear { clear: both; }
.nobr { white-space: nowrap; }
.darkorlighttextshadow ( @a, @opacity: 0.8 ) when (lightness(@a) >= 65%) { .text_shadow( 0, -1px, 0, rgba(0,0,0,@opacity) ); }
.darkorlighttextshadow ( @a, @opacity: 0.8 ) when (lightness(@a) < 65%) { .text_shadow( 0, 1px, 0, rgba(255,255,255,@opacity) ); }

View File

@ -0,0 +1,11 @@
@primary: #ad74a2; /* Primary colour for buttons (alt) */
@primarytext: desaturate(lighten(@primary,50%),18%); /* Text on primary colour bg */
@secondary: desaturate(lighten(@primary,40%),18%); /* Secondary buttons */
@secondarytext: desaturate(darken(@secondary,60%),18%); /* Text on secondary colour bg */
@highlight: spin( @primary, 150 ); /* Prices, In stock labels, sales flash */
@highlightext: desaturate(lighten(@highlight,50%),18%); /* Text on highlight colour bg */
@contentbg: #fff; /* Content BG - Tabs (active state) */
@subtext: #777; /* small, breadcrumbs etc */

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

Binary file not shown.

Before

Width:  |  Height:  |  Size: 256 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 490 B

After

Width:  |  Height:  |  Size: 409 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 9.2 KiB

After

Width:  |  Height:  |  Size: 911 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 500 B

After

Width:  |  Height:  |  Size: 424 B

BIN
assets/images/chosen-sprite.png Executable file → Normal file

Binary file not shown.

Before

Width:  |  Height:  |  Size: 396 B

After

Width:  |  Height:  |  Size: 806 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 141 B

After

Width:  |  Height:  |  Size: 135 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 107 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 101 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 330 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 322 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 106 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 352 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 340 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 99 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 503 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 96 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 68 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 506 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 174 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 143 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 858 B

BIN
assets/images/featured.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 654 B

BIN
assets/images/gear.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 814 B

Binary file not shown.

Before

Width:  |  Height:  |  Size: 224 B

After

Width:  |  Height:  |  Size: 126 B

BIN
assets/images/help.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 690 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 587 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 378 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 220 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 444 B

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