Last active
October 9, 2017 11:24
-
-
Save qutek/5a6913a843f218e2cca810635f333fda to your computer and use it in GitHub Desktop.
WP Quiz
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Question #1 | |
* Scenario: | |
* 1. We have a list of companies in the Company custom post type. | |
* 2. Each Company has a ranking which is stored in post meta with a key called `ranking. The ranking is a decimal value between 0 and 100. A sample `ranking` is 94.9. | |
* 3. Each Company can also be marked as sponsored. If a Company is sponsored, a post meta with a key called `sponsored` is updated to 1. Otherwise, the `sponsored` meta value is `0` for each Company. | |
* | |
* Problem: | |
* Given the above scenario, provide the correct array of $args to pass into a new WP_Query instance so that we can return 100 companies with the "sponsored" companies first, and then after that sorted, from highest to lowest based off the `ranking` value. | |
* | |
* Assumed: | |
* - The custom post type key for Company is `company` | |
* - The ACF Field Name / metakey for Sponsored is `sponsored` | |
* - The ACF Field Name / metakey for Ranking is ``ranking`` | |
* - Both Sponsored Company and Non Sponsored Company should be displayed on result, | |
* but keep the sponsored company on top of result as well as sorted by highest ranking | |
*/ | |
add_action( 'pre_get_posts', 'sort_by_sponsored_and_rank', 10, 1 ); | |
function sort_by_sponsored_and_rank($query){ | |
/** | |
* Only process if on archive page of custom post type `company` | |
* or may you can change per your need like `$query->is_home()` if this query need to be perform on homepage | |
*/ | |
if( is_admin() || !$query->is_main_query() || !is_post_type_archive( 'company' ) ) | |
return; | |
/** | |
* Get original meta_query, | |
* in case some other scripts has modified the meta_query | |
* so we are not screwed up other functionality | |
* @var [type] | |
*/ | |
$meta_query = $query->get('meta_query'); | |
/** | |
* Add our meta query to the original meta queries | |
* on WordPress 4.0 above we can now pass an array to WP_Query as the value for orderby | |
* and use an associative array, with a key for each meta clause | |
* @see https://make.wordpress.org/core/2014/08/29/a-more-powerful-order-by-in-wordpress-4-0/ | |
*/ | |
$meta_query[] = array( | |
'relation' => 'AND', | |
'sponsored_clause' => array( | |
'key'=>'sponsored', | |
// 'value'=>'1', // uncomment this if you want to exclude non sponsored company | |
'compare' => 'EXISTS', // change `compare` to `=` if you want to exclude non sponsored company | |
'type' => 'NUMERIC' // make sure we are cast the value as number / float | |
), | |
'ranking_clause' => array( | |
'key'=>'ranking', | |
// 'value'=>'0', | |
'compare' => 'EXISTS', | |
'type' => 'NUMERIC' | |
) | |
); | |
// set meta query | |
$query->set('meta_query',$meta_query); | |
// set order by | |
$query->set('orderby', array( | |
'sponsored_clause' => 'DESC', | |
'ranking_clause' => 'DESC', | |
)); | |
$query->set('posts_per_page', 100); // set 100 per page | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Question #2 | |
* Scenario: | |
* 1. We have a list of companies in the Company custom post type. | |
* 2. We have a custom admin interface that we built that allows for the owners of the company to update the data about the company. | |
* 3. One of the pieces of data that is stored on each company is an array of email addresses. | |
* The email addresses are stored in an Advanced Custom Field Repeater field that has a key of: `email_notifiers`. | |
* Each item in this repeater field has one field which is called `email`. | |
* The `email` contains the email address. | |
* 4. In the custom admin interface, we have a form where the owner can add new email addresses and save them (into the `email_notifiers` repeater field) | |
* | |
* Problem: | |
* Given the above scenario, provide the code for the API endpoint that would allow us to make POST request to this URL to perform the action outlined below | |
* - Endpoint example : http://yourwpsite.dev/wp-admin/admin-ajax.php?action=add-notifier-email&[email protected] m&company_id=12345 | |
* - add the submitted email address to the `email_notifiers` ACF repeater field on the submitted `company_id` Company post. | |
* | |
* Assumed: | |
* - Ajax button has beed set | |
* - Ajax action name is `add-notifier-email` | |
* - The ACF Field Name / metakey for Email Notifiers is `email_notifiers` | |
* - The ACF Sub Field Name / metakey for email is `email` | |
* - Non logged in user allowed to perform the ajax action | |
* - Ajax response returning json | |
*/ | |
add_action( 'wp_ajax_add-notifier-email', 'ajax_add_notifier_email_to_company' ); | |
add_action( 'wp_ajax_nopriv_add-notifier-email', 'ajax_add_notifier_email_to_company' ); // allow non logged in user to perform this action | |
/** | |
* Uncomment if you want to add test ajax button on footer | |
*/ | |
// add_action( 'wp_footer', 'add_ajax_button' ); | |
/** | |
* Ajax callback to add email on `email_notifiers` repater fields | |
* on `company` post type | |
* @return [type] [description] | |
*/ | |
function ajax_add_notifier_email_to_company(){ | |
$response = array( | |
'success' => false, | |
'message' => 'Failed to process.' | |
); | |
try { | |
/** | |
* May need to perform authentication / security check with nonce | |
*/ | |
// if(!isset($_POST['nonce']) || ! wp_verify_nonce( $_POST['nonce'], 'add-notifier-email' )){ | |
// throw new Exception("Security check not passed!"); | |
// } | |
// make sure company id posted | |
if(!isset($_POST['company_id'])){ | |
throw new Exception("Company ID is required!"); | |
} | |
// make sure email is valid | |
if(!isset($_POST['email']) || !is_email( $_POST['email'] ) ){ | |
throw new Exception("Email address not valid!"); | |
} | |
// try to add row to `email_notifiers` field | |
$index = add_row('email_notifiers', array('email' => sanitize_text_field($_POST['email']) ), absint( $_POST['company_id'] )); | |
if(!$index){ | |
throw new Exception("Failed to insert notifier email!"); | |
} | |
// all done. | |
$response['success'] = true; | |
$response['message'] = 'Email added successfully.'; | |
} catch (Exception $e) { | |
$response['message'] = $e->getMessage(); | |
} | |
// send ajax response as json. | |
wp_send_json( $response ); | |
} | |
/** | |
* Sample ajax button on footer | |
*/ | |
function add_ajax_button(){ | |
?> | |
<p><a href="#" id="test-ajax">Test Add Notifier</a></p> | |
<script type="text/javascript"> | |
(function($){ | |
$(document).on('click', '#test-ajax', function(e){ | |
e.preventDefault(); | |
var _nonce = "<?php echo wp_create_nonce( 'add-notifier-email' ); ?>"; | |
if(typeof(ajax_url) == 'undefined'){ | |
var ajax_url = "<?php echo admin_url( 'admin-ajax.php', 'relative' ); ?>"; | |
} | |
$.ajax( { | |
dataType: 'json', | |
data: { | |
action: 'add-notifier-email', | |
email: '[email protected]', | |
company_id: 8, | |
nonce: _nonce, | |
}, | |
type: 'post', | |
url: ajax_url, | |
success: function(response) { | |
console.log(response); | |
alert(response.message); | |
} | |
} ); | |
}); | |
})(jQuery); | |
</script> | |
<?php | |
} |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/** | |
* Question #3 | |
* Scenario: | |
* 1. We have a list of companies in the Company custom post type. | |
* 2. We added a new field called "Upgraded" which is a True/False ACF field with the key of `upgraded` | |
* 3. When we deploy the new code, we need to make sure that the `upgraded` key is set to `true` on all Company posts that are already published | |
* | |
* Problem: | |
* In order to set all existing Company posts to have the "Upgraded" ACF field set to `true`, | |
* we are going to write a WP_CLI command to loop through all company posts, and then update the field value to true for the `upgraded` True/False ACF field. | |
* | |
* Assumed: | |
* - WP CLI already installed | |
* - The CLI comman is `wp upgrade-company` | |
* - The ACF Field Name / metakey for Upgraded is `upgraded` | |
* - By default it will update all posts with type `company` | |
* - By default the process will the field value to `true` | |
* | |
* To see available options you can run `wp upgrade-company --help` | |
*/ | |
if ( !defined( 'WP_CLI' ) || !WP_CLI ) { | |
return; | |
} | |
WP_CLI::add_command( 'upgrade-company', 'Upgrade_Company_CLI' ); | |
/** | |
* Upgrade ACF value for company. | |
*/ | |
class Upgrade_Company_CLI extends WP_CLI_Command { | |
/** | |
* Update acf custom field `upgrade` using WP CLI | |
* | |
* ## OPTIONS | |
* | |
* [--company_id=<id>] | |
* : Limit to process specific company id | |
* | |
* [--value=<value>] | |
* : Set upgrade value, default is true | |
* | |
* ## EXAMPLES | |
* | |
* wp upgrade-company --company_id=12 --value=false | |
* | |
* @alias upgrade-company | |
*/ | |
public function __invoke( $args, $assoc_args ) { | |
global $wpdb; | |
$start_time = microtime( true ); | |
if( !isset( $assoc_args['company_id'] )){ | |
$company_id = false; | |
WP_CLI::line( "Updating upgrade status for all companies." ); | |
} else { | |
$company_id = $assoc_args['company_id']; | |
WP_CLI::line( sprintf("Updating upgrade status for company %d.", $company_id) ); | |
} | |
try { | |
/** | |
* Base variable | |
* @var string | |
*/ | |
$post_type = 'company'; | |
$field_key = 'upgrade'; | |
$new_value = isset( $assoc_args['value'] ) ? $assoc_args['value'] : true; // default is true / 1 | |
$args = array( | |
'posts_per_page' => -1, | |
'post_type' => $post_type, | |
'fields' => 'ids', | |
); | |
if($company_id){ | |
$args['post__in'] = (array) $company_id; | |
} | |
$query = new WP_Query( $args ); | |
$ids = $query->posts; | |
if(empty($ids)){ | |
throw new Exception("Company id not found."); | |
} | |
/** | |
* May need to write some log | |
* @var array | |
*/ | |
$failed = array(); | |
$success = array(); | |
foreach ($ids as $company_id) { | |
$update = update_field( $field_key, $new_value, $company_id ); | |
if(!$update){ | |
// if the update process return false, might it because the value is already same | |
if($new_value != get_field( $field_key, $company_id ) ){ | |
$failed[] = $company_id; | |
} else { | |
$success[] = $company_id; | |
} | |
} else { | |
$success[] = $company_id; | |
} | |
} | |
if(!empty($failed)){ | |
WP_CLI::warning( sprintf( "Failed to process : %s.", implode(',', $failed) ) ); | |
} | |
if(!empty($success)){ | |
WP_CLI::success( sprintf("Update successfully for company : %s", implode(',', $success) ) ); | |
} | |
// maybe count the process time | |
$endtime = microtime(true) - $start_time; | |
WP_CLI::line( "Process completed!" ); | |
} catch (Exception $e) { | |
WP_CLI::error( $e->getMessage() ); | |
} | |
} | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment