Jump to content


Staff Alumni
  • Content Count

  • Joined

  • Last visited

  • Days Won


mac_gyver last won the day on June 9

mac_gyver had the most liked content!

Community Reputation

450 Excellent

1 Follower

About mac_gyver

  • Rank
    Staff Alumni

Profile Information

  • Gender
    Not Telling

Recent Profile Visitors

146,814 profile views
  1. no. $map is an array, with an element/line for each input/output mapping. starting what what i posted, to avoid making even more changes, add a line for each of your new role names and tax classes - $map['wholesale_silvia_silver'] = 'WholesalePSTGST'; $map['wholesale_silvia_gold'] = 'WholesalePSTGST'; ...
  2. yes. that is the ideal way of implementing this. but before you start making changes like this, make sure this is within your programming skill level. currently, the mapping of role (name) to tax class is hard-coded in the program logic you have shown in this thread, and it would appear that in an earlier version there were 5 different functions to do this, one for each possible input/output combination. the use of the $map array that i suggested, simplifies the current method, so that you are not writing out and fixing program logic for each possible combination. you just have an array that defines the input/output combinations. to change to having the tax class defined with the role, would require that you add a column to the database table (or perhaps just add a new key/value if the table is using the wordpress metadata style of storage), write a new ->getUserWholesaleClass() method to retrieve the value, then change the code you have posted in this thread so that it just gets and returns the tax class for the user.
  3. dreamweaver was never any good. the $map = []; line is valid for php 5.4 and higher. no. don't use the original logic. you should NOT find yourself adding program logic each time you add a new data value. this is a sign you are doing something wrong. in fact, wherever the roles are being defined, should have a column for the tax type, then just retrieve and use the tax type for the current user and all the code in this thread would go away.
  4. if the error is on the above line, it's missing a ) repeated in two places in the code.
  5. then, all the in_array() statement(s) can be removed. just get the role value (either using current() or the zero'th element of the array) and use it directly in comparisons. i suspect the code is using the returned values to dynamically/indirectly call user classes/methods, in which case the letter-case doesn't matter. if the error is on the $map = []; line, it is because you are using a very old and obsolete php version. the short array syntax [] was introduced in php 5.4.
  6. first, a couple of questions - 1. can a user have more than one role value at a time? i ask this because in the all_custom_tax_classes function, the last role found is what is returned, but in the in-line function, the first role found is what is returned. if there is only a single value in the user's role array, all this code can be greatly simplified. 2. the values being returned from the all_custom_tax_classes function have camel-case letter-case, but the values being returned from the in-line function are all lower-case. does the code at some point convert all values to lower-case? in any case, this code needs to be converted to be a general purpose data-driven design, where a data structure defines what simple code should do, since all it is doing is mapping found input values to output values. once this is done, all you need to do is edit the data structure to add new sets of values. the following (untested, could contain typos) is what the original/working code would look like - /* * APPLY DIFFERENT TAX RATE BASED ON CUSTOMER USER ROLE * (Code compacted in one unique hook instead of 5 functions with the same hook) */ // in the original version, the $tax_class input is conditionally modified and returned. $product is not used. function all_custom_tax_classes( $tax_class, $product ) { global $current_user; // used in isset() only // Getting the current user $curr_user = wp_get_current_user(); // not used in 'active' code $curr_user_data = get_userdata($current_user->ID); // not used in 'active' code // 1 customer_tax_exempt /* special tax rate: zero if role: Customer Tax Exempt */ /*if ( in_array( 'customer_tax_exempt', $curr_user_data->roles ) ) $tax_class = 'CustomerTaxExemptClass'; // 2 customer_pst_exempt // special tax rate: charge only GST if role: Customer PST Exempt if ( in_array( 'customer_pst_exempt', $curr_user_data->roles ) ) $tax_class = 'CustomerPSTExemptClass'; */ // 3, 4 & 5 WHOLESLE SUITE SPECIAL WHOLESALE TAX RATES if (isset($current_user) && class_exists('WWP_Wholesale_Roles')) { $wwp_wholesale_roles = WWP_Wholesale_Roles::getInstance(); $wwp_wholesale_role = $wwp_wholesale_roles->getUserWholesaleRole(); // get an array of the user roles - is there ever more than one element? // define an array that maps input values to output values - note: if the user role values were defined to be the same as the expected return values, this step wouldn't be needed $map = []; $map['wholesale_customer'] = 'WholesalePSTGST'; // charge both PST and GST $map['wholesale_pst_exempt'] = 'WholesalePSTExempt'; // charge only GST $map['wholesale_tax_exempt'] = 'WholesaleZeroTax'; // charge neither if (!empty($wwp_wholesale_role) { // the following assumes that the 1st role value found is what is returned. if a user can have more than one role, this differs from the original logic, in that the last role found is what is returned. // loop over the map array foreach($map as $key=>$value) { // test if the key is in the role array if(in_array($key,$wwp_wholesale_role)) { // if so, return the value corresponding to the key return $value; } } } } // if none of the role values was found in the user role(s), return the original $tax_class value to the calling code return $tax_class; } /* ADDITIONAL FILTERS TO ALTER THE SHIPPING TAX FOR DIFFERENT TAX CLASSES BASED ON CUSTOMER USER ROLE */ add_filter( 'woocommerce_product_get_tax_class', 'all_custom_tax_classes', 1, 2 ); // calls the above function add_filter( 'woocommerce_product_variation_get_tax_class', 'all_custom_tax_classes', 1, 2 ); // calls the above function // calls the in-line function. the $option_value input is returned if none of the logic returns first. add_filter( 'option_woocommerce_shipping_tax_class' , function( $option_value ) { global $wc_wholesale_prices; if ( $wc_wholesale_prices && is_a( $wc_wholesale_prices , 'WooCommerceWholeSalePrices' ) ) { $wwp_wholesale_role = $wc_wholesale_prices->wwp_wholesale_roles->getUserWholesaleRole(); // get an array of the user roles - is there ever more than one element? // define an array that maps input values to output values - note: if the user role values were defined to be the same as the expected return values, this step wouldn't be needed // use the same definition as above (you would actually do this through configuration data so as to not repeat it) // i'm assuming that the same letter-case values used above will work here. if not, alter this data as needed. $map = []; $map['wholesale_customer'] = 'WholesalePSTGST'; // charge both PST and GST $map['wholesale_pst_exempt'] = 'WholesalePSTExempt'; // charge only GST $map['wholesale_tax_exempt'] = 'WholesaleZeroTax'; // charge neither if (!empty($wwp_wholesale_role) { // the following assumes that the 1st role value found is what is returned. this is the same operation as the original code here. // loop over the map array foreach($map as $key=>$value) { // test if the key is in the role array if(in_array($key,$wwp_wholesale_role)) { // if so, return the value corresponding to the key return $value; } } } } return $option_value; } , 10 , 1 ); assuming no mistakes in the above code and it works correctly, all you would need to do is modify the $map array(s) to add your new definitions.
  7. mac_gyver

    Turn checkboxes on or off programatically

    assuming that you are dynamically producing the checkboxes (if not that would be your 1st step), you would test if the corresponding submitted post data isset() for the current checkbox you are outputting. to address that you are initially checking all the checkboxes, you would have a common program variable that you initially setup with the necessary data, then copy the submitted post data to the same variable once the form has been submitted. see the following example code - <?php // recursive trim call-back function function _trim($val) { if(is_array($val)) { return array_map('_trim',$val); } else { return trim($val); } } $post = []; // holds a trimmed, working copy, of the submitted post data or any initial data // post method form processing if($_SERVER['REQUEST_METHOD'] == 'POST') { // examine the submitted data echo '<pre>'; print_r($_POST); echo '</pre>'; $post = array_map('_trim',$_POST); // get a trimmed copy of the submitted post data. use elements in $post in the rest of the code on the page // the rest of the form processing code goes here... } // get method business logic - get/produce data needed to display the page // if you were editing existing stored data, you would initially (if the $post variable is empty) retrieve that here into the $post variable if(empty($post)) // note: this requires at least one non-checkbox/radio form field to be present in case all checkbox/radio fields are ever unchecked { // for a set of defined checkboxes that are initially set, the same as through you were editing existing data where all the checkboxes are initially checked, set that up here // loop over a 'defined' list of checkboxes. for demo purposes this is just a list of ids from 1-4 foreach(range(1,4) as $id) { $post['chk'][$id] = true; } } ?> <form method='post'> <input type='hidden' name='action' value='create'> <?php // loop over a 'defined' list of checkboxes. for demo purposes this is just a list of ids from 1-4 foreach(range(1,4) as $id) { // determine if checkbox is checked $chk = isset($post['chk'][$id]) ? ' checked' : ''; echo "<input type='checkbox' name='chk[$id]'$chk> Checkbox: $id<br>"; } ?> <input type='submit'></form>
  8. mac_gyver

    Optimize My Code

    your INSERT query is open to sql injection. anyone can cause that query to insert data from any of your database tables, especially since you are using the 'root' user, and the rest of your code on this page will happily show the content that was just inserted from the other database/tables. i recommend that you take this code off of a live/public site until you actually secure it against sql injection, don't use the 'root' user in you applications, create a user that has just the database permissions you need, your delete operation should use a post method form, and in real life data isn't actually deleted, it is updated to indicate it is not in use, in case it ever needs to be recovered.
  9. mac_gyver

    Check if User and Email already exists

    define the column(s) in your table as unique indexes. insert the data and detect if a duplicate key error occurred. in the error handling logic, execute one select query to find which column(s) contain the same values you just tried to insert.
  10. mac_gyver

    Need Help

    actually, you have an unnecessary ( which then doesn't have a matching ), both on line #6. as to the posted logic. you have far too much code, mainly because your form and for processing code are not on the same page and you are using the mysqli database extension. if you put the form processing code on the same page as the form, stop copying variables to other variables, store validation errors in an array, switch to the much simpler php PDO database extension, and use exceptions to handle database errors, about half of the code you have now will go away. you also have a logic mistake later in the code. your 'usernotfound' condition is part of the password check logic (which can only be either true of false, there's no point in the final else statement), not as part of the fetch check logic. this type of mistake can be avoided by properly indenting your code and also by eliminating unnecessary code (see the above paragraph.)
  11. mac_gyver

    Am I seeing windmills?!?!?

    that's a statement of an alternate method to get php code to run on your server.
  12. mac_gyver

    Am I seeing windmills?!?!?

    if someone manages to get their php code to run on your server (they don't even need to upload a file if allow_url_fopen and allow_url_include are on and you are blindly including/requiring files named from get parameters), they have access to all your files, so it doesn't matter where or how you store things like db connection credentials.
  13. just because you have two files, doesn't necessarily mean they cannot be used on the same page. just 'require' the file containing the html/minimal amount of php code, at the appropriate place to produce a single page with all the functionality on it. if you don't think your instructor would go for that distinction, you would need to store the validation errors in a session array variable and also store the submitted array of post data in a session variable so that when you redirect back to the form page you can use the data in the same way as suggested above. all page(s) that set or use session variables must have a session_start() statement on it. located before anything is output to the browser.
  14. here's a list of practices that will result in a web page that does what you are asking, with a minimum of code - 1. put the form processing code and the form on the same page. the form processing code goes above the start of the html document. the form processing code needs to detect if a post method form was submitted before executing any of its code. 2. in the form processing code, store validation error messages in an array, with the form field name as the array key. 3. after the end of the validation logic, if the array holding the validation error messages is empty, there are no errors and you can use the submitted data. 4. after successfully processing the form data, execute a redirect to the exact same URL of the current page to cause a get request. this will prevent the browser from trying to resubmit the form data if you refresh the page or browse back to the url of the page. this will also cause a blank form, with no error messages to be displayed. 5. at the point of (re)displaying the form fields, you would test if the element in the errors array matching the current field name isset() and output the error message. you would also test for and output the existing field value so that the user doesn't need to keep reentering the data over and over, just correct the errors in the existing data.
  15. mac_gyver

    Need help with this script

    because you are putting external/unknown values directly into the sql query, it is open to sql injection. if someone managed to create a username containing sql when they registered, the posted code/query could allow them to set any user's record to anything they want, which could allow them to take over an administrator's account. while you are using prepare/execute statements, you aren't using place-holders in the sql query for the values. have you read the documentation for prepared queries?

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.