728x90

This was a small issue I came across recently and the solution I found was so brilliant I thought it was worth sharing on here.

So the problem was that I had an array like this:

 

var obj = [
    {
        "one": 1,
        "two": 9
    }, {
        "one": 3,
        "two": 5
    }, {
        "one": 1,
        "two": 2
    }
];

 

 

and I wanted to sort it by "one" and then by "two" to get a result like this:

var obj = [
    {
        "one": 1,
        "two": 2,
    }, {
        "one": 1,
        "two": 9
    }, {
        "one": 3,
        "two": 5
    }
];

 

sounds simple enough right? I thought so too, but the sorting algorithm that the browser is using limits your options when it comes to sorting by multiple fields. After a bit of researching I stumbled upon this wonderful solution: http://stackoverflow.com/questions/13211709/javascript-sort-array-by-multiple-number-fields

 

JavaScript sort array by multiple (number) fields

How can I implement a ORDER BY sort1 DESC, sort2 DESC logic in an JSON array like such: var items = '[ { "sort1": 1, "sort2": 3, "name" : "a", ...

stackoverflow.com

obj.sort(function(a, b) {
    return a["one"] - b["one"] || a["two"] - b["two"];
});

This will sort your array by "one" and if they are the same (ie. 0) then it will sort by "two". It's simple, concise, readable, and best of all - works perfectly.

728x90

자바스크립트의 2차원 배열이란?

  • 자바스크립트는 진정한 2차원 배열은 없다
  • var arr = [][]; 이와 같은 한 번에 2차원 배열 선언이 불가능하다
  • 약간의 트릭을 통하여 2차원 배열과 비슷한 배열을 만들 수 있다

아래의 예제 중 상황에 맞는 방법을 사용하면 된다

 

초기값을 할당하여 배열 생성

// arr[5][2]
var arr = [['a','b'], ['c', 'd'], ['e', 'f'], ['g', 'h'], ['i', 'j']]; 

 

반복문을 사용하여 빈 배열 생성

// arr[5][2]
var arr = new Array(5);

for (var i = 0; i < arr.length; i++) {
    arr[i] = new Array(2);
}

 

2차원 배열 생성 함수를 만들어서 사용

function create2DArray(rows, columns) {
    var arr = new Array(rows);
    for (var i = 0; i < rows; i++) {
        arr[i] = new Array(columns);
    }
    return arr;
}

// arr[5][2]
var arr = create2DArray(5, 2);

 

Array 객체에 배열 생성 함수를 추가하여 사용

Array.matrix = function (m, n, initial) {
    var a, i, j, mat = [];
    for (i = 0; i < m; i += 1) {
        a = [];
        for (j = 0; j < n; j += 1) {
            a[j] = initial;
        }
        mat[i] = a;
    }
    return mat;
};

// matrix('행', '열', '기본값')
var arr = Array.matrix(5, 2, 0);

- 자바스크립트 핵심 가이드 (더글라스 크락포드) p109

 

ES6를 지원하는 최신 브라우저라면 사용 가능한 방법

// arr[5][2] (빈 배열 생성)
const arr1 = Array.from(Array(5), () => new Array(2)

// arr[5][2] (null로 초기화하여 생성)
const arr2 = Array.from(Array(5), () => Array(2).fill(null))

 

자바스크립트의 2차원 배열은 1차원 배열에 또 다른 배열 객체를 추가하여 2차원 배열 만드는 방법을 사용한다. 자바스크립트 배열의 특성을 잘 모른다면 조금 이상한 방법으로 보일 수도 있다.

자바스크립트의 배열은 동적으로 배열의 크기를 조절할 수 있으며, 배열에는 모든 유형의 변수 그리고 함수, 객체도 담을 수 있어서 유연하게 사용할 수 있지만 그만큼 충분히 이해를 하고 사용해야 한다.

728x90

In this article, we cover breakdown Bubble Sort and then also share its implementation in Javascript.

Firstly, let's get it out of the way. When we say "sort", the idea is to re-arrange the elements such that they are in ascending order.

If you are new to the concept of sorting, each section of the article would be useful - concept of bubble sort, its algorithms, efficiency, etc. However, If you are here to refresh your knowledge, jump straight to the javascript implementation of the sort. Go to code

Table of Contents

 

Explanation of Bubble Sort

If you are a newbie to sorting, Bubble sort is a great place to start! It is one of the more intuitive sorting methods as its algorithm mirrors how our brain generally thinks about sorting - by comparing.

Let's remove the vagueness and delve deeper into it.

A. What Bubble Sort Does?

To achieve sorting in Bubble Sort, the adjacent elements in the array are compared and the positions are swapped if the first element is greater than the second. In this fashion, the largest value "bubbles" to the top.

Usually, after each iteration the elements furthest to the right are in correct order. The process is repeated until all the elements are in their right position.

B. What Bubble Sort Does?

1. Starting with the first element, compare the current element with the next element of the array.

2. If the current element is greater than the next element of the array, swap them.

3. If the current element is less than the next element, just move to the next element.

4. Start again from Step 1.

C. Illustrating the Bubble sort method

Iteration 1: [6,4,2,5,7] → [4,6,2,5,7] → [4,2,6,5,7] → [4,2,5,6,7] → [4,2,5,6,7]

Iteration 2:[4,2,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7]

Iteration 3: [2,4,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7] → [2,4,5,6,7]

Other Alternatives

As you might have noticed, Bubble Sort only considers one element at a time. Thus, it is highly time consuming and inefficient. Due to its inefficiency, bubble sort is almost never used in production code.

You can use a built in function Array.prototype.sort() for sorting. This is an inplace algorithm just like bubble sort which converts the elements of the input array into strings and compares them based on their UTF-16 code unit values. Also, if you are interested, you can read about index sort which is another simple comparison based sort method that has a better performance than Bubble sort.

Implementing Bubble Sort using Javascript

Now as we have seen the logic behind bubble sort, we can write the code for it in a straightforward manner, using two nested loops.

 

 

let bubbleSort = (inputArr) => {
    let len = inputArr.length;
    for (let i = 0; i < len; i++) {
        for (let j = 0; j < len; j++) {
            if (inputArr[j] > inputArr[j + 1]) {
                let tmp = inputArr[j];
                inputArr[j] = inputArr[j + 1];
                inputArr[j + 1] = tmp;
            }
        }
    }
    return inputArr;
};

As you can see here, the sorting function will run until the variable "i" is equal to the length of the array. This might not be the most efficient solution as it means the function will run on an already sorted array more than once.

A slightly better solution involves tracking a variable called "checked" which is initially set to FALSE and becomes true when there is a swap during the iteration. Running this code on a do while loop to run the sorting function only when "checked" is true ensures that the function will not run on a sorted array more than once.

 

 

let bubbleSort = (inputArr) => {
    let len = inputArr.length;
    let checked;
    do {
        checked = false;
        for (let i = 0; i < len; i++) {
            if (inputArr[i] > inputArr[i + 1]) {
                let tmp = inputArr[i];
                inputArr[i] = inputArr[i + 1];
                inputArr[i + 1] = tmp;
                checked = true;
            }
        }
    } while (checked);
    return inputArr;
 };

 

Visualization

If you are finding it hard to visualize Bubble Sort, you can check this website https://visualgo.net/bn/sorting?slide=1.

You can play around with the code and see the specific function of each part of the code and how they play together to get the final sorted array.

Complexity of Bubble Sort

The worst case scenario: quadratic O(n²): this is the case when every element of the input array is exactly opposite of the sorted order.

Best case scenario: linear O(n): when the input array is already sorted. Even in this case, we have to iterate through each set of numbers once.

The space complexity of Bubble Sort is O(1).

728x90

Want to create a plugin to extend WooCommerce? WooCommerce plugins are the same as regular WordPress plugins. For more information, visit Writing a plugin.

Your WooCommerce extension should:

  • Adhere to all WordPress plugin coding standards, as well as best practice guidelines for harmonious existence within WordPress and alongside other WordPress plugins.
  • Have a single core purpose and use WooCommerce features as much as possible.
  • Not do anything malicious or underhanded — for example, inserting spam links or up selling services outside of the WooCommerce.com ecosystem.
  • Not subvert or override Marketplace connections in core — for example, extensions cannot create branded top level menu items or introduce their own telemetry.

Merchants make use of WooCommerce extensions daily, and should have an unified and pleasant experience while doing so without advertising invading their WP Admin or store.

Note: We provide this page as a best practice for developers.

 

Note: We are unable to provide support for custom code under our Support Policy. If you are unfamiliar with code and resolving potential conflicts, select a WooExpert or Developer  for assistance.

Check if WooCommerce is active

Most WooCommerce plugins do not need to run unless WooCommerce is already active. You can wrap your plugin in a check to see if WooCommerce is installed:

/** * Check if WooCommerce is active **/ if ( in_array( 'woocommerce/woocommerce.php', apply_filters( 'active_plugins', get_option( 'active_plugins' ) ) ) ) { // Put your plugin code here }

Note that this check will fail if the WC plugin folder is named anything other than woocommerce.

Main file naming

The main plugin file should adopt the name of the plugin, e.g., A plugin with the directory name plugin-name would have its main file named plugin-name.php.

Text domains

Follow guidelines for Internationalization for WordPress Developers, the text domain should match your plugin directory name, e.g., A plugin with a directory name of plugin-name would have the text domain plugin-name. Do not use underscores.

Localization

All text strings within the plugin code should be in English. This is the WordPress default locale, and English should always be the first language. If your plugin is intended for a specific market (e.g., Spain or Italy), include appropriate translation files for those languages within your plugin package. Learn more at Using Makepot to translate your plugin.

Follow WordPress PHP Guidelines

WordPress has a set of guidelines to keep all WordPress code consistent and easy to read. This includes quotes, indentation, brace style, shorthand php tags, yoda conditions, naming conventions, and more. Please review the guidelines.

Code conventions also prevent basic mistakes, as Apple made with iOS 7.0.6.

Custom Database Tables & Data Storage

Avoid creating custom database tables. Whenever possible, use WordPress post types, taxonomies, and options.

Consider the permanence of your data. Here’s a quick primer:

  • If the data may not always be present (i.e., it expires), use a transient.
  • If the data is persistent but not always present, consider using the WP Cache.
  • If the data is persistent and always present, consider the wp_options table.
  • If the data type is an entity with n units, consider a post type.
  • If the data is a means or sorting/categorizing an entity, consider a taxonomy.

Logs should be written to a file using the WC_Logger class.

Prevent Data Leaks

Try to prevent direct access data leaks. Add this line of code after the opening PHP tag in each PHP file:

if ( ! defined( 'ABSPATH' ) ) { exit; // Exit if accessed directly }

Readme

All plugins need a standard WordPress readme.

Your readme might look something like this:

=== Plugin Name === Contributors: (this should be a list of wordpress.org userid's) Tags: comments, spam Requires at least: 4.0.1 Tested up to: 4.3 Requires PHP: 5.6 Stable tag: 4.3 License: GPLv3 or later License URI: http://www.gnu.org/licenses/gpl-3.0.html

Plugin Author Name

Consistency is important to us and our customers. Products offered through WooCommerce.com should provide a consistent experience for all aspects of the product, including finding information on who to contact with queries.

Customers should be able to easily to differentiate a product purchased at WooCommerce.com from a product purchased elsewhere, just by looking through their plugin list in WordPress.

Thus, the following plugin headers should be in place:

  • The Plugin Author isYourName/YourCompany
  • The Developer header is YourName/YourCompany, with the Developer URI field listed as http://yourdomain.com/

For example:

/** * Plugin Name: WooCommerce Extension * Plugin URI: http://woocommerce.com/products/woocommerce-extension/ * Description: Your extension's description text. * Version: 1.0.0 * Author: Your Name * Author URI: http://yourdomain.com/ * Developer: Your Name * Developer URI: http://yourdomain.com/ * Text Domain: woocommerce-extension * Domain Path: /languages * * Woo: 12345:342928dfsfhsf8429842374wdf4234sfd * WC requires at least: 2.2 * WC tested up to: 2.3 * * License: GNU General Public License v3.0 * License URI: http://www.gnu.org/licenses/gpl-3.0.html */

Declaring required and supported WooCommerce version

Use the follow headers to declare “required” and “tested up to” versions:

  • WC requires at least
  • WC tested up to

Plugin URI

Ensure that the Plugin URI line of the above plugin header is provided. This line should contain the URL of the plugin’s product/sale page on WooCommerce.com (if sold by WooCommerce) or to a dedicated page for the plugin on your website.

Woo Plugin Header For Updates

WooCommerce core looks for a Woo line in the plugin header comment, to ensure it can check for updates to your plugin, on WooCommerce.com. This line looks like this:

Woo: 12345:342928dfsfhsf8429842374wdf4234sfd

This is only required for products sold on WooCommerce.com.  Using this line for products listed on WordPress.org or elsewhere is not required or necessary.

For products sold on WooCommerce.com, Vendors can find this snippet by logging in to their logging in to the Vendors Dashboard and going to Extensions > All Extensions. Then, select the product and click Edit product page. This snippet will be in the upper-right-hand corner of the screen.

See the plugin header comment example above for how the Woo header looks in context.

Make it Extensible

Developers should use WordPress actions and filters to allow for modification/customization without requiring users to touch the plugin’s core code base.

If your plugin creates a front-end output, we recommend to having a templating engine in place so users can create custom template files in their theme’s WooCommerce folder to overwrite the plugin’s template files.

For more information, check out Pippin’s post on Writing Extensible Plugins with Actions and Filters.

Remove Unused Code

With version control, there’s no reason to leave commented-out code; it’s annoying to scroll through and read. Remove it and add it back later if needed.

Comment

If you have a function, what does the function do? There should be comments for most if not all functions in your code. Someone/You may want to modify the plugin, and comments are helpful for that. We recommend using PHP Doc Blocks  similar to WooCommerce.

Avoid God Objects

God Objects are objects that know or do too much. The point of object-oriented programming is to take a large problem and break it into smaller parts. When functions do too much, it’s hard to follow their logic, making bugs harder to fix. Instead of having massive functions, break them down into smaller pieces.

Test Your Code with WP_DEBUG

Always develop with WP_DEBUG mode on, so you can see all PHP warnings sent to the screen. This will flag things like making sure a variable is set before checking the value.

Separate Business Logic & Presentation Logic

It’s a good practice to separate business logic (i.e., how the plugin works) from presentation logic (i.e., how it looks). Two separate pieces of logic are more easily maintained and swapped if necessary. An example is to have two different classes — one for displaying the end results, and one for the admin settings page.

Use Transients to Store Offsite Information

If you provide a service via an API, it’s best to store that information so future queries can be done faster and the load on your service is lessened. WordPress transients can be used to store data for a certain amount of time.

Logging Data

You may want to log data that can be useful for debugging purposes. This is great with two conditions:

  • Allow any logging as an ‘opt in’.
  • Use the WC_Logger class. A user can then view logs on their system status page.

If adding logging to your extension, here’s a snippet for presenting a link to the logs, in a way the extension user can easily make use of.

  $label = __( 'Enable Logging', 'your-textdomain-here' );
  $description = __( 'Enable the logging of errors.', 'your-textdomain-here' );
   
  if ( defined( 'WC_LOG_DIR' ) ) {
  $log_url = add_query_arg( 'tab', 'logs', add_query_arg( 'page', 'wc-status', admin_url( 'admin.php' ) ) );
  $log_key = 'your-plugin-slug-here-' . sanitize_file_name( wp_hash( 'your-plugin-slug-here' ) ) . '-log';
  $log_url = add_query_arg( 'log_file', $log_key, $log_url );
   
  $label .= ' | ' . sprintf( __( '%1$sView Log%2$s', 'your-textdomain-here' ), '<a href="' . esc_url( $log_url ) . '">', '</a>' );
  }
   
  $form_fields['wc_yourpluginslug_debug'] = array(
  'title' => __( 'Debug Log', 'your-textdomain-here' ),
  'label' => $label,
  'description' => $description,
  'type' => 'checkbox',
  'default' => 'no'
  );

view raw
wc-view-log-setting-snippet.php
hosted with 

 by GitHub

Error codes

This information is intended for the third-party developers so products they write can better handle errors. Error codes are produced by the Product Build Server when uploading a new submission or updating an existing product on the Marketplace.

error_success

The operation has completed successfully.

error_pbs_prepare_apache

Internal error with the Product Build Server – cannot initialize the Apache daemon.

error_pbs_prepare_mysql

Internal error with the Product Build Server – cannot initialize the MySQL daemon.

error_pbs_prepare_wp

Internal error with the Product Build Server – cannot initialize WordPress.

error_pbs_prepare_wc

Internal error with the Product Build Server – cannot initialize WooCommerce.

error_pbs_prepare_dependencies

Internal error with the Product Build Server – cannot configure dependencies.

error_pbs_test_malware_scanning

Malware scanning error. This can happen if your product contains malware in the code.

Here’s an example output:

ObfuscatedPhp /tmp/product_clone/woocommerce-example/includes/views/html-settings-page.php 0x406:$ini_set: ini_set( 0x506:$ini_set: ini_set( ObfuscatedPhp /tmp/product_clone/woocommerce-example/includes/views/html-extras-page.php 0x406:$eval: exec(

This means that the character at the absolute position 0x406 (1030) and 0x506 (1286) in the file html-settings-page.php doesn’t pass the $ini_set rule, because it is using call_user_func in that file. Also, the other file html-extras-page.php doesn’t pass the rule $register_function which is using exec call.

error_pbs_test_extracting

Cannot extract the product. Most common issue is the top directory of the zip does not match its slug.

error_pbs_test_phpcs

phpcs checks failed. The check uses the WooCommerce-Core sniffs with following phpcs.xml:

  <?xml version="1.0"?>
  <ruleset name="WordPress Coding Standards">
  <description>WooCommerce extension PHP_CodeSniffer ruleset.</description>
   
  <!– Exclude paths –>
  <exclude-pattern>tests/</exclude-pattern>
  <exclude-pattern>woo-includes/woo-functions.php</exclude-pattern>
  <exclude-pattern>woo-includes/class-wc-dependencies.php</exclude-pattern>
  <exclude-pattern>*/node_modules/*</exclude-pattern>
  <exclude-pattern>*/vendor/*</exclude-pattern>
   
  <!– Configs –>
  <config name="minimum_supported_wp_version" value="4.7" />
  <config name="testVersion" value="5.6-" />
   
  <!– Rules –>
  <rule ref="WordPress-Extra">
  <exclude name="Generic.Commenting.DocComment.SpacingAfter" />
  <exclude name="Generic.Files.LineEndings.InvalidEOLChar" />
  <exclude name="Generic.Functions.FunctionCallArgumentSpacing.SpaceBeforeComma" />
  <exclude name="PEAR.Functions.FunctionCallSignature" />
  <exclude name="Squiz.Commenting" />
  <exclude name="Squiz.PHP.DisallowSizeFunctionsInLoops.Found" />
  <exclude name="Squiz.WhiteSpace" />
  <exclude name="WordPress.Arrays" />
  <exclude name="WordPress.Files.FileName" />
  <exclude name="WordPress.NamingConventions" />
  <exclude name="WordPress.Security.ValidatedSanitizedInput.MissingUnslash" />
  <exclude name="WordPress.WP.I18n.NonSingularStringLiteralText" />
  <exclude name="WordPress.WhiteSpace" />
  </rule>
   
  <rule ref="WooCommerce-Core">
  <exclude name="Core.Commenting.CommentTags.AuthorTag" />
  <exclude name="WordPress.PHP.DontExtract" />
  <exclude name="Generic.Arrays.DisallowShortArraySyntax" />
  <exclude name="Generic.WhiteSpace.ScopeIndent.Incorrect" />
  </rule>
   
  <rule ref="PHPCompatibility">
  <exclude-pattern>tests/</exclude-pattern>
  </rule>
  </ruleset>

view raw
phpcs.xml
hosted with 

 by GitHub

To install locally:

  1. Go to your product directory.
  2. Install WooCommerce sniffs with composer require woocommerce/woocommerce-sniffs.
  3. Put phpcs.xml above in the product directory.
  4. Run ./vendor/bin/phpcs --warning-severity=0 -s --ignore-annotations --extensions=php,html . .

error_pbs_test_installing

Cannot install the product. Most common issue is the top directory of the zip does not match its slug.

error_pbs_test_activating

Cannot activate the product. Refer to the build output for more details.

error_pbs_test_deactivating

Cannot deactivate the product. Refer to the build output for more details.

error_pbs_test_host_plan_installing

This error means that your product is incompatible with other products in the host plan. Refer to the build output for more details.

error_pbs_test_host_plan_activating

This error means that your product is incompatible with other products in the host plan. Refer to the build output for more details.

error_pbs_test_host_plan_deactivating

This error means that your product is incompatible with other products in the host plan. Refer to the build output for more details.

error_pbs_missing_theme_info_file

Your theme is missing the theme info file theme_info.txt under the root directory.

error_pbs_incomplete_theme_info

Your theme info file theme_info.txt contains malformed data structure. It should contain the product ID, hash and main file, all separated by new lines. For example:

887931 2429c1dde521031cd053886b15844bbf storechild/style.css

error_pbs_incomplete_theme_header

Your theme main file contains malformed data structure. Provide Theme Name, Version, and the Woo headers in your main file.

error_pbs_incomplete_plugin_header

Your plugin main file contains malformed data structure. Provide Plugin Name, Version, and the Woo headers in your main file.

error_pbs_invalid_woo_header

Your product main file contains an invalid Woo header structure. Use the format ID:HASH. For example:

* Woo: 390890:911c438934af094c2b38d5560b9f50f3

error_pbs_invalid_id

Your product main file contains an invalid product ID in the Woo header.

error_pbs_invalid_hash

Your product main file contains an invalid hash in the Woo header.

error_pbs_missing_main_file

Your product is missing the main file.

error_pbs_missing_changelog_file

Your product is missing the changelog.txt file.

error_pbs_product_version_mismatch

The version in your product’s main file does not match with the provided version in changelog.txt.

error_pbs_invalid_changelog_format

Your product contains malformed changelog.txt structure. Refer to changelog.txt as an example.

 

 

 

https://docs.woocommerce.com/document/create-a-plugin/

+ Recent posts