WordPress教學 – 如何客製化帳單地址表單

Customize the WordPress Woocommerce billing address edit forms
https://docs.woocommerce.com/document/tutorial-customising-checkout-fields-using-actions-and-filters/

隱藏欄位範例:

So what I did is to add the following filter to the function.php page, for example I will hide the zip code fields, first you need to make it non required, and then hide it as follow:

add_filter( 'woocommerce_billing_fields', 'wc_npr_filter_postcode');

function wc_npr_filter_postcode( $address_fields ) {
    $address_fields['billing_postcode']['required'] = false;
    $address_fields['billing_postcode']['type'] = 'hidden';
    return $address_fields;
}

調整「顯示」順序範例:

 

add_filter( ‘woocommerce_localisation_address_formats’ , ‘woo_tw_address_formats’ );

function woo_tw_address_formats() {

$address = array(‘default’ => “{first_name}\n{state}{city} ({postcode})\n{address_1}”);

return $address;
}

解法只剩下,欄位全部打掉,換上自己的欄位,就解決了。 @[email protected];

看了一下 source code:

includes/wc-template-functions.php

原來可以直接改 ‘priority’:

 $label_id = $args['id'];
 $sort = $args['priority'] ? $args['priority'] : '';
 $field_container = '<p class="form-row %1$s" id="%2$s" data-sort="' . esc_attr( $sort ) . '">%3$s</p>';

改了,沒有效果。


找到了優秀範例:

WooCommerce Customize Checkout Fields
https://www.kathyisawesome.com/woocommerce-customize-checkout-fields/


最後,找到最佳範例:
https://cloudwp.pro/blog/woocommerce-%E7%B8%A3%E5%B8%82%E6%AC%84%E4%BD%8D%E4%B8%8B%E6%8B%89%E9%81%B8%E5%96%AE/

WooCommerce 縣市欄位下拉選單

 


Customizing checkout fields using actions and filters should be a task you are comfortable with.

If you are unfamiliar with code and resolving potential conflicts, we have an extension that can help: WooCommerce Checkout Field Editor. Installing and activating this extension overrides any code below that you try to implement; and you cannot have custom checkout field code in your functions.php file when the extension is activated.

Note: This is a Developer level doc. We are unable to provide support for customizations under our Support Policy. If you are unfamiliar with code/templates and resolving potential conflicts, select a WooExpert or Developer  for assistance.
Custom code should be copied into your child theme’s MARKDOWN_HASH78cd5aa3783a74555c9938a2a81d01c6MARKDOWN_HASH  file.

How are checkout fields loaded to WooCommerce?

The billing and shipping fields for checkout pull from the countries class (class-wc-countries.php) and the get_address_fields function. This allows WooCommerce to enable/disable fields based on the user’s location.

Before returning these fields, WooCommerce puts the fields through a filter. This allows them to be edited by third-party plugins, themes and your own custom code.

Billing:

$address_fields = apply_filters('woocommerce_billing_fields', $address_fields);

Shipping:

$address_fields = apply_filters('woocommerce_shipping_fields', $address_fields);

The checkout class adds the loaded fields to its ‘checkout_fields’ array, as well as adding a few other fields like “order notes”.

$this->checkout_fields['billing']    = $woocommerce->countries->get_address_fields( $this->get_value('billing_country'), 'billing_' );
$this->checkout_fields['shipping']   = $woocommerce->countries->get_address_fields( $this->get_value('shipping_country'), 'shipping_' );
$this->checkout_fields['account']    = array(
    'account_username' => array(
        'type' => 'text',
        'label' => __('Account username', 'woocommerce'),
        'placeholder' => _x('Username', 'placeholder', 'woocommerce')
        ),
    'account_password' => array(
        'type' => 'password',
        'label' => __('Account password', 'woocommerce'),
        'placeholder' => _x('Password', 'placeholder', 'woocommerce'),
        'class' => array('form-row-first')
        ),
    'account_password-2' => array(
        'type' => 'password',
        'label' => __('Account password', 'woocommerce'),
        'placeholder' => _x('Password', 'placeholder', 'woocommerce'),
        'class' => array('form-row-last'),
        'label_class' => array('hidden')
        )
    );
$this->checkout_fields['order']  = array(
    'order_comments' => array(
        'type' => 'textarea',
        'class' => array('notes'),
        'label' => __('Order Notes', 'woocommerce'),
        'placeholder' => _x('Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce')
        )
    );

This array is also passed through a filter:

$this->checkout_fields = apply_filters('woocommerce_checkout_fields', $this->checkout_fields);

That means you have full control over checkout fields – you only need to know how to access them.

Overriding core fields

Hooking into the  woocommerce_checkout_fields filter lets you override any field. As an example, let’s change the placeholder on the order_comments fields. Currently, it’s set to:

_x('Notes about your order, e.g. special notes for delivery.', 'placeholder', 'woocommerce')

We can change this by adding a function to our theme functions.php file:

// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
     $fields['order']['order_comments']['placeholder'] = 'My new placeholder';
     return $fields;
}

You can override other parts, such as labels:

// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
     $fields['order']['order_comments']['placeholder'] = 'My new placeholder';
     $fields['order']['order_comments']['label'] = 'My new label';
     return $fields;
}

Or remove fields:

// Hook in
add_filter( 'woocommerce_checkout_fields' , 'custom_override_checkout_fields' );

// Our hooked in function - $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
     unset($fields['order']['order_comments']);

     return $fields;
}

Here’s a full list of fields in the array passed to woocommerce_checkout_fields:

  • Billing
    • billing_first_name
    • billing_last_name
    • billing_company
    • billing_address_1
    • billing_address_2
    • billing_city
    • billing_postcode
    • billing_country
    • billing_state
    • billing_email
    • billing_phone
  • Shipping
    • shipping_first_name
    • shipping_last_name
    • shipping_company
    • shipping_address_1
    • shipping_address_2
    • shipping_city
    • shipping_postcode
    • shipping_country
    • shipping_state
  • Account
    • account_username
    • account_password
    • account_password-2
  • Order
    • order_comments

Each field contains an array of properties:

  • type – type of field (text, textarea, password, select)
  • label – label for the input field
  • placeholder – placeholder for the input
  • class – class for the input
  • required – true or false, whether or not the field is require
  • clear – true or false, applies a clear fix to the field/label
  • label_class – class for the label element
  • options – for select boxes, array of options (key => value pairs)

In specific cases you need to use the woocommerce_default_address_fields filter. This filter is applied to all billing and shipping default fields:

  • country
  • first_name
  • last_name
  • company
  • address_1
  • address_2
  • city
  • state
  • postcode

For example, to make the address_1 field optional:

// Hook in
add_filter( 'woocommerce_default_address_fields' , 'custom_override_default_address_fields' );

// Our hooked in function - $address_fields is passed via the filter!
function custom_override_default_address_fields( $address_fields ) {
     $address_fields['address_1']['required'] = false;

     return $address_fields;
}

Defining select options

If you are adding a field with type ‘select’, as stated above you would define key/value pairs. For example:

$fields['billing']['your_field']['options'] = array(
  'option_1' => 'Option 1 text',
  'option_2' => 'Option 2 text'
);

Priority

Priority in regards to PHP code helps establish when a bit of code — called a function — runs in relation to a page load. It is set inside of each function and is useful when overriding existing code for custom display.

Code with a higher number set as the priority will run after code with a lower number, meaning code with a priority of 20 will run after code with 10 priority.

The priority argument is set during the add_action function, after you establish which hook you’re connecting to and what the name of your custom function will be.

In the example below, blue text is the name of the hook we’re modifying, green text is the name of our custom function, and red is the priority we set.

Examples

In this example, the code is set to redirect the “Return to Shop” button found in the cart to a category that lists products for sale at http://example.com/category/specials/.

<?php
/**
* Changes the redirect URL for the Return To Shop button in the cart.
*/
function wc_empty_cart_redirect_url() {
return ‘http://example.com/category/specials/’;
}
add_filter( ‘woocommerce_return_to_shop_redirect’, ‘wc_empty_cart_redirect_url’, 10 );

view rawexample.php hosted with ❤ by GitHub

There, we can see the priority is set to 10. This is the typical default for WooCommerce functions and scripts, so that may not be sufficient to override that button’s functionality.

Instead we can change the priority to any number greater than 10. While 11 would work, best practice dictates we use increments of ten, so 20, 30, and so on.

<?php
/**
* Changes the redirect URL for the Return To Shop button in the cart.
*/
function wc_empty_cart_redirect_url() {
return ‘http://example.com/category/specials/’;
}
add_filter( ‘woocommerce_return_to_shop_redirect’, ‘wc_empty_cart_redirect_url’, 20 );

view rawexample.php hosted with ❤ by GitHub

With priority, we can have two functions that are acting on the same hook. Normally this would cause a variety of problems, but since we’ve established one has a higher priority than the other, our site will only load the appropriate function, and we will be taken to the Specials page as intended with the code below.

<?php

/**
* Changes the redirect URL for the Return To Shop button in the cart.
* BECAUSE THIS FUNCTION HAS THE PRIORITY OF 20, IT WILL RUN AFTER THE FUNCTION BELOW (HIGHER NUMBERS RUN LATER)
*/

function wc_empty_cart_redirect_url() {
return ‘http://example.com/category/specials/’;
}
add_filter( ‘woocommerce_return_to_shop_redirect’, ‘wc_empty_cart_redirect_url’, 20 );

/**
* Changes the redirect URL for the Return To Shop button in the cart.
* EVEN THOUGH THIS FUNCTION WOULD NORMALLY RUN LATER BECAUSE IT’S CODED AFTERWARDS, THE 10 PRIORITY IS LOWER THAN 20 ABOVE
*/

function wc_empty_cart_redirect_url() {
return ‘http://example.com/shop/’;
}
add_filter( ‘woocommerce_return_to_shop_redirect’, ‘wc_empty_cart_redirect_url’, 10 );

?>

view rawfunctions.php hosted with ❤ by GitHub

Adding custom shipping and billing fields

Adding fields is done in a similar way to overriding fields. For example, let’s add a new field to shipping fields – shipping_phone:

// Hook in
add_filter( ‘woocommerce_checkout_fields’ , ‘custom_override_checkout_fields’ );

// Our hooked in function – $fields is passed via the filter!
function custom_override_checkout_fields( $fields ) {
$fields[‘shipping’][‘shipping_phone’] = array(
‘label’ => __(‘Phone’, ‘woocommerce’),
‘placeholder’ => _x(‘Phone’, ‘placeholder’, ‘woocommerce’),
‘required’ => false,
‘class’ => array(‘form-row-wide’),
‘clear’ => true
);

return $fields;
}

/**
* Display field value on the order edit page
*/

add_action( ‘woocommerce_admin_order_data_after_shipping_address’, ‘my_custom_checkout_field_display_admin_order_meta’, 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
echo ‘<p><strong>’.__(‘Phone From Checkout Form’).’:</strong> ‘ . get_post_meta( $order->id, ‘_shipping_phone’, true ) . ‘</p>’;
}

It's alive!

It’s alive!

What do we do with the new field? Nothing. Because we defined the field in the checkout_fields array, the field is automatically processed and saved to the order post meta (in this case, _shipping_phone). If you want to add validation rules, see the checkout class where there are additional hooks you can use.

Adding a custom special field

To add a custom field is similar. Let’s add a new field to checkout, after the order notes, by hooking into the following:

/**
* Add the field to the checkout
*/
add_action( ‘woocommerce_after_order_notes’, ‘my_custom_checkout_field’ );

function my_custom_checkout_field( $checkout ) {

echo ‘<div id=”my_custom_checkout_field”><h2>’ . __(‘My Field’) . ‘</h2>’;

woocommerce_form_field( ‘my_field_name’, array(
‘type’ => ‘text’,
‘class’ => array(‘my-field-class form-row-wide’),
‘label’ => __(‘Fill in this field’),
‘placeholder’ => __(‘Enter something’),
), $checkout->get_value( ‘my_field_name’ ));

echo ‘</div>’;

}

view rawgistfile1.txt hosted with ❤ by GitHub

This gives us:

WooCommerce Codex - Checkout Field Hook

Next we need to validate the field when the checkout form is posted. For this example the field is required and not optional:

/**
* Process the checkout
*/
add_action(‘woocommerce_checkout_process’, ‘my_custom_checkout_field_process’);

function my_custom_checkout_field_process() {
// Check if set, if its not set add an error.
if ( ! $_POST[‘my_field_name’] )
wc_add_notice( __( ‘Please enter something into this new shiny field.’ ), ‘error’ );
}

view rawgistfile1.txt hosted with ❤ by GitHub

A checkout error is displayed if the field is blank:

WooCommerce Codex - Checkout Field Notice

Finally, let’s save the new field to order custom fields using the following code:

/**
* Update the order meta with field value
*/
add_action( ‘woocommerce_checkout_update_order_meta’, ‘my_custom_checkout_field_update_order_meta’ );

function my_custom_checkout_field_update_order_meta( $order_id ) {
if ( ! empty( $_POST[‘my_field_name’] ) ) {
update_post_meta( $order_id, ‘My Field’, sanitize_text_field( $_POST[‘my_field_name’] ) );
}
}

view rawgistfile1.txt hosted with ❤ by GitHub

The field is now saved to the order.

If you wish to display the custom field value on the admin order edition page, you can add this code:

/**
* Display field value on the order edit page
*/
add_action( ‘woocommerce_admin_order_data_after_billing_address’, ‘my_custom_checkout_field_display_admin_order_meta’, 10, 1 );

function my_custom_checkout_field_display_admin_order_meta($order){
echo ‘<p><strong>’.__(‘My Field’).’:</strong> ‘ . get_post_meta( $order->id, ‘My Field’, true ) . ‘</p>’;
}

view rawgistfile1.php hosted with ❤ by GitHub

This is the result:

checkout_field_custom_field_admin

Example: Make phone number not required

<?php

add_filter( ‘woocommerce_billing_fields’, ‘wc_npr_filter_phone’, 10, 1 );

function wc_npr_filter_phone( $address_fields ) {
$address_fields[‘billing_phone’][‘required’] = false;
return $address_fields;
}

?>

view rawgistfile1.php hosted with ❤ by GitHub

Adding custom fields to emails

To add a custom field value to WooCommerce emails — a completed order email, for example — use the following snippet:

/* To use:
1. Add this snippet to your theme’s functions.php file
2. Change the meta key names in the snippet
3. Create a custom field in the order post – e.g. key = “Tracking Code” value = abcdefg
4. When next updating the status, or during any other event which emails the user, they will see this field in their email
*/
add_filter(‘woocommerce_email_order_meta_keys’, ‘my_custom_order_meta_keys’);

function my_custom_order_meta_keys( $keys ) {
$keys[] = ‘Tracking Code’; // This will look for a custom field called ‘Tracking Code’ and add it to emails
return $keys;
}

view rawgistfile1.txt hosted with ❤ by GitHub

WordPress教學 – 如何關閉WordPress迴響留言功能?

WordPress內建的迴響功能其實滿方便的,等於是直接提供一個可留言的方式,不需再另外安裝外掛,但還是很多人不喜歡,想要換成自己喜歡的。

關閉留言,我是直接註解掉 theme 裡的 php code,

//comments_template();

通常放在 single.php 或 page.php

用 grep 指令,或 Notepad++ 去找檔案內容,一下就可以找到。

WooCommerce un-register user checkout

有人使用 WooCommerce v3.0.1 遇到,「開放未註冊訪客結帳」(woocommerce_enable_guest_checkout) 的 Checkout process 無效的問題嗎? 我試了「選取」和「未選取」沒註冊的會員都可以結帳.

 

先隨便找一支程式,丟出 woocommerce option:

<?php echo “woocommerce_enable_guest_checkout:”.get_option( ‘woocommerce_enable_guest_checkout’ ) ?>

測試結果是,設定值都是正確的。

 

檢查 includes/class-wc-checkout.php:

 /**
 * Is registration required to checkout?
 *
 * @since 3.0.0
 * @return boolean
 */
 public function is_registration_required() {
 return apply_filters( 'woocommerce_checkout_registration_required', 'yes' !== get_option( 'woocommerce_enable_guest_checkout' ) );
 }

原因是 templates/checkout/form-login.php:

if ( is_user_logged_in() || 'no' === get_option( 'woocommerce_enable_checkout_login_reminder' ) ) {
 return;
}

這段 code 檢查的是 woocommerce_enable_checkout_login_reminder (Display returning customer login reminder on the “Checkout” page.)而不是 woocommerce_enable_guest_checkout。

 


最後找到Bug, 在 checkout/form-checkout.php :

if ( ! $checkout->is_registration_enabled() && $checkout->is_registration_required() && ! is_user_logged_in() ) {
 echo apply_filters( 'woocommerce_checkout_must_be_logged_in_message', __( 'You must be logged in to checkout.', 'woocommerce' ) );
 return;
}

在 if 後面,多了一個 !,拿掉所有的結果都對了。

幫原作者開好bug, 並附上解法:
https://github.com/woocommerce/woocommerce/issues/14195

順便開了一個 PR(pull request):
https://github.com/woocommerce/woocommerce/pull/14197

issue 被關閉,PR也被打搶,但是我的問題也解決了,不能 commit 進去是真的,因為有side effect,這個改下去,別的情況會出包,github 上的神人真多~。

0.1 + 0.2 = 0.30000000000000004

今天才知道原來 0.1 + 0.2 不是 0.3

 

 

相關網站:

http://0.30000000000000004.com/

Language Code Result
C
#include<stdio.h>
int main(int argc, char** argv) {
    printf("%.17f\n", .1+.2);
    return 0;
}
0.30000000000000004
C++
#include <iomanip>
std::cout << setprecision(17) << 0.1 + 0.2 << std.endl;
0.30000000000000004
PHP echo .1 + .2; 0.3
PHP converts 0.30000000000000004 to a string and shortens it to “0.3”. To achieve the desired floating point result, adjust the precision ini setting: ini_set(“precision”, 17).
MySQL SELECT .1 + .2; 0.3
Postgres SELECT select 0.1::float + 0.2::float; 0.3
Delphi XE5 writeln(0.1 + 0.2); 3.00000000000000E-0001
Erlang io:format("~w~n", [0.1 + 0.2]). 0.30000000000000004
Elixir IO.puts(0.1 + 0.2) 0.30000000000000004
Ruby puts 0.1 + 0.2
And
puts 1/10r + 2/10r
0.30000000000000004
And
3/10
Ruby supports rational numbers in syntax with version 2.1 and newer directly. For older versions use Rational.
Ruby also has a library specifically for decimals: BigDecimal.
Python 2 print(.1 + .2)
And
float(decimal.Decimal(".1") + decimal.Decimal(".2")) And
.1 + .2
0.3
And
0.3
And
0.30000000000000004
Python 2’s “print” statement converts 0.30000000000000004 to a string and shortens it to “0.3”. To achieve the desired floating point result, use print(repr(.1 + .2)). This was fixed in Python 3 (see below).
Python 3 print(.1 + .2)
And
.1 + .2
0.30000000000000004
And
0.30000000000000004
Lua print(.1 + .2)
print(string.format("%0.17f", 0.1 + 0.2))
0.3
0.30000000000000004
JavaScript document.writeln(.1 + .2); 0.30000000000000004
Java System.out.println(.1 + .2);
And
System.out.println(.1F + .2F);
0.30000000000000004
And
0.3
Julia .1 + .2 0.30000000000000004
Julia has built-in rational numbers support and also a built-in arbitrary-precision BigFloat data type. To get the math right, 1//10 + 2//10 returns 3//10.
Clojure (+ 0.1 0.2) 0.30000000000000004
Clojure supports arbitrary precision and ratios. (+ 0.1M 0.2M) returns 0.3M, while (+ 1/10 2/10) returns 3/10.
C# Console.WriteLine("{0:R}", .1 + .2); 0.30000000000000004
GHC (Haskell) 0.1 + 0.2 0.30000000000000004
Haskell supports rational numbers. To get the math right, (1 % 10) + (2 % 10) returns 3 % 10.
Hugs (Haskell) 0.1 + 0.2 0.3
bc 0.1 + 0.2 0.3
Nim echo(0.1 + 0.2) 0.3
Gforth 0.1e 0.2e f+ f. 0.3
dc 0.1 0.2 + p .3
Racket (PLT Scheme) (+ .1 .2)
And
(+ 1/10 2/10)
0.30000000000000004
And
3/10
Rust
extern crate num;
use num::rational::Ratio;
fn main() {
	println!(.1+.2);
	println!("1/10 + 2/10 = {}", Ratio::new(1, 10) + Ratio::new(2, 10));
}
0.30000000000000004
3/10
Rust has rational number support from the num crate.
Emacs Lisp (+ .1 .2) 0.30000000000000004
Turbo Pascal 7.0 writeln(0.1 + 0.2); 3.0000000000E-01
Common Lisp * (+ .1 .2)
And
* (+ 1/10 2/10)
0.3
And
3/10
Go
package main
import "fmt"
func main() {
	fmt.Println(.1 + .2)
	var a float64 = .1
	var b float64 = .2
	fmt.Println(a + b)
	fmt.Printf("%.54f\n", .1 + .2)
}
0.3
0.30000000000000004
0.299999999999999988897769753748434595763683319091796875
Go numeric constants have arbitrary precision.
Objective-C 0.1 + 0.2; 0.300000012
OCaml 0.1 +. 0.2;; float = 0.300000000000000044
Powershell PS C:\>0.1 + 0.2 0.3
Prolog (SWI-Prolog) ?- X is 0.1 + 0.2. X = 0.30000000000000004.
Perl 5 perl -E 'say 0.1+0.2'
perl -e 'printf q{%.17f}, 0.1+0.2'
0.3
0.30000000000000004
Perl 6 perl6 -e 'say 0.1+0.2'
perl6 -e 'say sprintf(q{%.17f}, 0.1+0.2)'
perl6 -e 'say 1/10+2/10'
0.3
0.30000000000000000
0.3
Perl 6, unlike Perl 5, uses rationals by default, so .1 is stored something like { numerator => 1, denominator => 10 }..
R print(.1+.2)
print(.1+.2, digits=18)
0.3
0.300000000000000044
scala scala -e 'println(0.1 + 0.2)'
And
scala -e 'println(0.1F + 0.2F)' And
scala -e 'println(BigDecimal("0.1") + BigDecimal("0.2"))'
0.30000000000000004
And
0.3
And
0.3
Smalltalk 0.1 + 0.2. 0.30000000000000004
Swift 0.1 + 0.2
NSString(format: "%.17f", 0.1 + 0.2)
0.3
0.30000000000000004
D
import std.stdio;

void main(string[] args) {
    writefln("%.17f", .1+.2);
    writefln("%.17f", .1f+.2f);
    writefln("%.17f", .1L+.2L);
}
0.29999999999999999
0.30000001192092896
0.30000000000000000
ABAP WRITE / CONV f( '.1' + '.2' ).
And
WRITE / CONV decfloat16( '.1' + '.2' ).
3.0000000000000004E-01
And
0.3

$ is not a function – jQuery error

<script type="text/javascript">
    $("ol li:nth-child(1)").hide()
</script>

在  WordPress 上寫 javascript jQuery, 會錯,發現原來是 jQuery 會衝到,要多一個框框給jQuery:

In WordPress jQuery.noConflict() is called on the jQuery file it includes (scroll to the bottom of the file it’s including for jQuery to see this), which means $ doesn’t work, but jQuery does, so your code should look like this:

<script type="text/javascript">
  jQuery(function($) {
    for(var i=0; i <= 20; i++) 
      $("ol li:nth-child(" + i + ")").addClass('olli' + i);
  });
</script>

from: http://stackoverflow.com/questions/3931529/is-not-a-function-jquery-error

Mysql備份與還原資料庫

原來 mysql 的備份還有還原這麼簡單 @[email protected]

備份:

— 備份某個資料庫

mysqldump -u root -p db_name > backup.sql;

— 備份所有資料庫

mysqldump -u root -p --all-databases > backup.sql;

附註:備所有資料庫,遇到 database 版本不同時,會有問題,例如 mysql 5.6 到 5.7 會造成系統預設的欄位長度不符的錯誤。

備份用的 shell script:

#!/bin/sh 
pw='your-password'
mysqldump --all-databases --add-drop-table -h 127.0.0.1 -u root -p$pw > your-backup-file.sql
bzip2 -f your-backup-file.sql

bz2 壓縮:

bzip2 -z FileName

bz2 解壓縮:
bzip2 -d FileName.bz2


還原:

mysql -u root -p < backup.sql

如果出現 no database selected 是因為 backup.sql 裡沒有包括了 create database 的指令,只有去 drop table. 所以要在一還原的地方指定好要被貼回來的 database name:

mysql DATABASE_NAME -u root -p < backup.sql

進階一點的備份:

MySQL 自動備份 Shell Script
http://stackoverflow.max-everyday.com/2018/01/mysql-shell-script/

Stream a file with tornado

現在手機上的空間往往不夠,所以影片最好就是直接連到server 上透過串流回來看就好了,在tornado 上串流的 demo:

https://github.com/tornadoweb/tornado/issues/1046

完整版Source code:
http://tornado-doc-chs.readthedocs.io/en/latest/_modules/tornado/web.html

class StaticFileHandler(RequestHandler):


Alright this time I found the actual solution:

            # Note: only return HTTP 206 if less than the entire range has been
            # requested. Not only is this semantically correct, but Chrome
            # refuses to play audio if it gets an HTTP 206 in response to
            # ``Range: bytes=0-``.

This note applies to audio only, chrome will play video that begins be returning a 206.

    @asynchronous
    @gen.coroutine
    def get(self, path, include_body=True):
        #Assume that path is correct, validation will be handeled elsewhere
        self.absolute_path = os.path.abspath(path)
        self.path = self.absolute_path
        if self.absolute_path is None:
            return

        self.modified = self.get_modified_time()
        self.set_headers()

        if self.should_return_304():
            self.set_status(304)
            return

        request_range = None
        range_header = self.request.headers.get("Range")
        if range_header:
            # As per RFC 2616 14.16, if an invalid Range header is specified,
            # the request will be treated as if the header didn't exist.
            request_range = httputil._parse_request_range(range_header)

        if request_range:
            start, end = request_range
            size = self.get_content_size()
            if (start is not None and start >= size) or end == 0:
                # As per RFC 2616 14.35.1, a range is not satisfiable only: if
                # the first requested byte is equal to or greater than the
                # content, or when a suffix with length 0 is specified
                self.set_status(416)  # Range Not Satisfiable
                self.set_header("Content-Type", "text/plain")
                self.set_header("Content-Range", "bytes */%s" % (size, ))
                return
            if start is not None and start < 0:
                start += size
            if end is not None and end > size:
                # Clients sometimes blindly use a large range to limit their
                # download size; cap the endpoint at the actual file size.
                end = size

            self.set_status(206)  # Partial Content
            self.set_header("Content-Range",
                            httputil._get_content_range(start, end, size))
        else:
            start = end = None

        content = self.get_content(self.absolute_path, start, end)

        for chunk in content:
            self.write(chunk)
            yield gen.Task(self.flush)
        self.finish()

related:
HTTP STATUS: 206 PARTIAL CONTENT AND RANGE REQUESTS
https://benramsey.com/blog/2008/05/206-partial-content-and-range-requests/

ImportError: MemoryLoadLibrary failed loading netifaces.pyd

netifaces 在 py2exe 打包情況下會出錯:

File “zipextimporter.pyc”, line 98, in load_module
ImportError: MemoryLoadLibrary failed loading netifaces.pyd

錯誤畫面載圖:

 

發生的原因是 py2exe 無法透過 data_files 參數,或 includes 或 packages 這些參數把 netifaces.pyd 打包進去。

由於 py2exe for python 2.7 已經沒有在維護,不建議繼續使用,所以改用python 3 + py2exe 新版,或 pyinstaller + python 2.7.

全部改寫成 python 3 太累,太多 code 要重測,所以切換到 pyinstaller 比較快。

 

How to send an object from one Android Activity to another using Intents?

在 Activity 之間傳遞參數的方法:

文章1:
How to send an object from one Android Activity to another using Intents
http://stackoverflow.com/questions/2139134/how-to-send-an-object-from-one-android-activity-to-another-using-intents

文章2:
How to pass an object from one activity to another on Android
http://stackoverflow.com/questions/2736389/how-to-pass-an-object-from-one-activity-to-another-on-android


If you’re just passing objects around then Parcelable was designed for this. It requires a little more effort to use than using Java’s native serialization, but it’s way faster (and I mean way, WAY faster).

From the docs, a simple example for how to implement is:

// simple class that just has one member property as an example
public class MyParcelable implements Parcelable {
    private int mData;

    /* everything below here is for implementing Parcelable */

    // 99.9% of the time you can just ignore this
    @Override
    public int describeContents() {
        return 0;
    }

    // write your object's data to the passed-in Parcel
    @Override
    public void writeToParcel(Parcel out, int flags) {
        out.writeInt(mData);
    }

    // this is used to regenerate your object. All Parcelables must have a CREATOR that implements these two methods
    public static final Parcelable.Creator<MyParcelable> CREATOR = new Parcelable.Creator<MyParcelable>() {
        public MyParcelable createFromParcel(Parcel in) {
            return new MyParcelable(in);
        }

        public MyParcelable[] newArray(int size) {
            return new MyParcelable[size];
        }
    };

    // example constructor that takes a Parcel and gives you an object populated with it's values
    private MyParcelable(Parcel in) {
        mData = in.readInt();
    }
}

Observe that in the case you have more than one field to retrieve from a given Parcel, you must do this in the same order you put them in (that is, in a FIFO approach).

Once you have your objects implement Parcelable it’s just a matter of putting them into your Intents with putExtra():

Intent i = new Intent();
i.putExtra("name_of_extra", myParcelableObject);

Then you can pull them back out with getParcelableExtra():

Intent i = getIntent();
MyParcelable myParcelableObject = (MyParcelable) i.getParcelableExtra("name_of_extra");

If your Object Class implements Parcelable and Serializable then make sure you do cast to one of the following:

i.putExtra("parcelable_extra", (Parcelable) myParcelableObject);
i.putExtra("serializable_extra", (Serializable) myParcelableObject);

You can send serializable object through intent

// send where details is object
ClassName details = new ClassName();
Intent i = new Intent(context, EditActivity.class);
i.putExtra("Editing", details);
startActivity(i);


//receive
ClassName model = (ClassName) getIntent().getSerializableExtra("Editing");

And 

Class ClassName implements Serializable {
} 

//To pass:
intent.putExtra("MyClass", obj);

// To retrieve object in second Activity
getIntent().getSerializableExtra("MyClass");

How to close an ActionMode menu programmatically?

這個 ActionMode 用起來滿神奇的,他幾乎算是一個特定區塊的dialog,但是和 dialog 不同的是會和上一個 activity overlap 在一起,並可以存取 parent fragment 或 activity 裡的變數內容,更像是 toolbar 的概念。

要開始/結束 ActionMode 是用:

Whenever you are creating/starting ActionMode Create by

mMode = startActionMode(....);

To Dismiss it use following Syntax

if (mMode != null) 
 {
     mMode.finish();
 }

from:
http://stackoverflow.com/questions/11158957/how-to-close-an-actionmode-menu-programmatically-on-honeycomb