WordPress plugin for shipping calculation











up vote
1
down vote

favorite












I am writing a WordPress plugin that allows shipping calculation on the product page. Originally, shipping calculation is only available in the cart.



To calculate shipping costs on product page, three things are necessary: A product with valid dimensions, the quantity and the destination postcode.



Here's what it does before getting to the getCostPerShippingMethod() method bellow:




  • Receives a REST request

  • Sanitizes and validates it

  • Generate the Payload object (which extracts product dimensions, etc)

  • Determines Shipping Zone and Shipping Methods (Example: We offer UPS for postcode X and also Local Pickup for postcode Y)

  • Passes an array of Shipping Methods to getCostPerShippingMethod() bellow.


Then, at getCostPerShippingMethod():




  • Create a Package object for it, which calculates cubage according to product dimensions, quantity and shipping method rules (each shipping method may calculate cubage differently)

  • Instantiate a Handler for this shipping method, which is a internal class prepared to handle the external shipping method calculation rules

  • Handler validates the package dimensions per shipping method. (Example: Local pickup: no limit | UPS: max 30kg, 200cm height, etc)

  • Then it calls the Handler's calculate method, which does it's magic depending on the Shipping Method and payload requested and return the shipping costs


The array returned by getCostPerShippingMethod() is then cascaded down to the frontend to be displayed to the user.



/**
* Calculates shipping costs for an array of shipping methods
*
* @param array $shipping_methods
* @param Payload $payload
* @return array
*/
public static function getCostPerShippingMethod(array $shipping_methods, Payload $payload)
{
$instance = new self;
$shipping_costs = array();

foreach ($shipping_methods as $shipping_method) {
$shipping_method_slug = sanitize_title(get_class($shipping_method));
$response = new Response($shipping_method);

try {
// Create Package based on product and quantities per Shipping Method
$package = Package::makeFrom($payload->getProduct(), $payload->getQuantity(), $shipping_method);
$payload->setPackage($package);

// Create CFPP handler for this Shipping Method
$cfpp_handler = Factory::createHandler($shipping_method);

// Gives a chance to set rules, then validate Payload per Shipping Method
$cfpp_handler->beforeValidate()->validate($payload);

// Calculate Costs
do_action('cfpp_before_calculate_cost', $payload, $shipping_method);
$shipping_costs = apply_filters('cfpp_response_success_' . $shipping_method_slug, $cfpp_handler->calculate($payload));

} catch(PackageException $e) {
do_action('cfpp_response_package_exception', $shipping_method_slug);
$shipping_costs = $response->error($e->getMessage());
} catch (FactoryException $e) {
do_action('cfpp_response_factory_exception', $shipping_method_slug);
$shipping_costs = $response->error($e->getMessage());
} catch (ValidationErrorException $e) {
do_action('cfpp_response_validation_exception', $shipping_method_slug);
$shipping_costs = $response->error($e->getMessage());
} catch (HandlerException $e) {
do_action('cfpp_response_handler_exception', $shipping_method_slug);
$shipping_costs = $response->error($e->getMessage());
}
}

// Successes first, errors last
$shipping_costs = $instance->orderShippingCosts($shipping_costs);

return $shipping_costs;
}


It all works fine. However, I'm having problems testing this class. I can't see how, but this method probably has poor architecture.



How can I improve this code to make it more testable and architecturally correct?










share|improve this question









New contributor




Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
























    up vote
    1
    down vote

    favorite












    I am writing a WordPress plugin that allows shipping calculation on the product page. Originally, shipping calculation is only available in the cart.



    To calculate shipping costs on product page, three things are necessary: A product with valid dimensions, the quantity and the destination postcode.



    Here's what it does before getting to the getCostPerShippingMethod() method bellow:




    • Receives a REST request

    • Sanitizes and validates it

    • Generate the Payload object (which extracts product dimensions, etc)

    • Determines Shipping Zone and Shipping Methods (Example: We offer UPS for postcode X and also Local Pickup for postcode Y)

    • Passes an array of Shipping Methods to getCostPerShippingMethod() bellow.


    Then, at getCostPerShippingMethod():




    • Create a Package object for it, which calculates cubage according to product dimensions, quantity and shipping method rules (each shipping method may calculate cubage differently)

    • Instantiate a Handler for this shipping method, which is a internal class prepared to handle the external shipping method calculation rules

    • Handler validates the package dimensions per shipping method. (Example: Local pickup: no limit | UPS: max 30kg, 200cm height, etc)

    • Then it calls the Handler's calculate method, which does it's magic depending on the Shipping Method and payload requested and return the shipping costs


    The array returned by getCostPerShippingMethod() is then cascaded down to the frontend to be displayed to the user.



    /**
    * Calculates shipping costs for an array of shipping methods
    *
    * @param array $shipping_methods
    * @param Payload $payload
    * @return array
    */
    public static function getCostPerShippingMethod(array $shipping_methods, Payload $payload)
    {
    $instance = new self;
    $shipping_costs = array();

    foreach ($shipping_methods as $shipping_method) {
    $shipping_method_slug = sanitize_title(get_class($shipping_method));
    $response = new Response($shipping_method);

    try {
    // Create Package based on product and quantities per Shipping Method
    $package = Package::makeFrom($payload->getProduct(), $payload->getQuantity(), $shipping_method);
    $payload->setPackage($package);

    // Create CFPP handler for this Shipping Method
    $cfpp_handler = Factory::createHandler($shipping_method);

    // Gives a chance to set rules, then validate Payload per Shipping Method
    $cfpp_handler->beforeValidate()->validate($payload);

    // Calculate Costs
    do_action('cfpp_before_calculate_cost', $payload, $shipping_method);
    $shipping_costs = apply_filters('cfpp_response_success_' . $shipping_method_slug, $cfpp_handler->calculate($payload));

    } catch(PackageException $e) {
    do_action('cfpp_response_package_exception', $shipping_method_slug);
    $shipping_costs = $response->error($e->getMessage());
    } catch (FactoryException $e) {
    do_action('cfpp_response_factory_exception', $shipping_method_slug);
    $shipping_costs = $response->error($e->getMessage());
    } catch (ValidationErrorException $e) {
    do_action('cfpp_response_validation_exception', $shipping_method_slug);
    $shipping_costs = $response->error($e->getMessage());
    } catch (HandlerException $e) {
    do_action('cfpp_response_handler_exception', $shipping_method_slug);
    $shipping_costs = $response->error($e->getMessage());
    }
    }

    // Successes first, errors last
    $shipping_costs = $instance->orderShippingCosts($shipping_costs);

    return $shipping_costs;
    }


    It all works fine. However, I'm having problems testing this class. I can't see how, but this method probably has poor architecture.



    How can I improve this code to make it more testable and architecturally correct?










    share|improve this question









    New contributor




    Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
    Check out our Code of Conduct.






















      up vote
      1
      down vote

      favorite









      up vote
      1
      down vote

      favorite











      I am writing a WordPress plugin that allows shipping calculation on the product page. Originally, shipping calculation is only available in the cart.



      To calculate shipping costs on product page, three things are necessary: A product with valid dimensions, the quantity and the destination postcode.



      Here's what it does before getting to the getCostPerShippingMethod() method bellow:




      • Receives a REST request

      • Sanitizes and validates it

      • Generate the Payload object (which extracts product dimensions, etc)

      • Determines Shipping Zone and Shipping Methods (Example: We offer UPS for postcode X and also Local Pickup for postcode Y)

      • Passes an array of Shipping Methods to getCostPerShippingMethod() bellow.


      Then, at getCostPerShippingMethod():




      • Create a Package object for it, which calculates cubage according to product dimensions, quantity and shipping method rules (each shipping method may calculate cubage differently)

      • Instantiate a Handler for this shipping method, which is a internal class prepared to handle the external shipping method calculation rules

      • Handler validates the package dimensions per shipping method. (Example: Local pickup: no limit | UPS: max 30kg, 200cm height, etc)

      • Then it calls the Handler's calculate method, which does it's magic depending on the Shipping Method and payload requested and return the shipping costs


      The array returned by getCostPerShippingMethod() is then cascaded down to the frontend to be displayed to the user.



      /**
      * Calculates shipping costs for an array of shipping methods
      *
      * @param array $shipping_methods
      * @param Payload $payload
      * @return array
      */
      public static function getCostPerShippingMethod(array $shipping_methods, Payload $payload)
      {
      $instance = new self;
      $shipping_costs = array();

      foreach ($shipping_methods as $shipping_method) {
      $shipping_method_slug = sanitize_title(get_class($shipping_method));
      $response = new Response($shipping_method);

      try {
      // Create Package based on product and quantities per Shipping Method
      $package = Package::makeFrom($payload->getProduct(), $payload->getQuantity(), $shipping_method);
      $payload->setPackage($package);

      // Create CFPP handler for this Shipping Method
      $cfpp_handler = Factory::createHandler($shipping_method);

      // Gives a chance to set rules, then validate Payload per Shipping Method
      $cfpp_handler->beforeValidate()->validate($payload);

      // Calculate Costs
      do_action('cfpp_before_calculate_cost', $payload, $shipping_method);
      $shipping_costs = apply_filters('cfpp_response_success_' . $shipping_method_slug, $cfpp_handler->calculate($payload));

      } catch(PackageException $e) {
      do_action('cfpp_response_package_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (FactoryException $e) {
      do_action('cfpp_response_factory_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (ValidationErrorException $e) {
      do_action('cfpp_response_validation_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (HandlerException $e) {
      do_action('cfpp_response_handler_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      }
      }

      // Successes first, errors last
      $shipping_costs = $instance->orderShippingCosts($shipping_costs);

      return $shipping_costs;
      }


      It all works fine. However, I'm having problems testing this class. I can't see how, but this method probably has poor architecture.



      How can I improve this code to make it more testable and architecturally correct?










      share|improve this question









      New contributor




      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      I am writing a WordPress plugin that allows shipping calculation on the product page. Originally, shipping calculation is only available in the cart.



      To calculate shipping costs on product page, three things are necessary: A product with valid dimensions, the quantity and the destination postcode.



      Here's what it does before getting to the getCostPerShippingMethod() method bellow:




      • Receives a REST request

      • Sanitizes and validates it

      • Generate the Payload object (which extracts product dimensions, etc)

      • Determines Shipping Zone and Shipping Methods (Example: We offer UPS for postcode X and also Local Pickup for postcode Y)

      • Passes an array of Shipping Methods to getCostPerShippingMethod() bellow.


      Then, at getCostPerShippingMethod():




      • Create a Package object for it, which calculates cubage according to product dimensions, quantity and shipping method rules (each shipping method may calculate cubage differently)

      • Instantiate a Handler for this shipping method, which is a internal class prepared to handle the external shipping method calculation rules

      • Handler validates the package dimensions per shipping method. (Example: Local pickup: no limit | UPS: max 30kg, 200cm height, etc)

      • Then it calls the Handler's calculate method, which does it's magic depending on the Shipping Method and payload requested and return the shipping costs


      The array returned by getCostPerShippingMethod() is then cascaded down to the frontend to be displayed to the user.



      /**
      * Calculates shipping costs for an array of shipping methods
      *
      * @param array $shipping_methods
      * @param Payload $payload
      * @return array
      */
      public static function getCostPerShippingMethod(array $shipping_methods, Payload $payload)
      {
      $instance = new self;
      $shipping_costs = array();

      foreach ($shipping_methods as $shipping_method) {
      $shipping_method_slug = sanitize_title(get_class($shipping_method));
      $response = new Response($shipping_method);

      try {
      // Create Package based on product and quantities per Shipping Method
      $package = Package::makeFrom($payload->getProduct(), $payload->getQuantity(), $shipping_method);
      $payload->setPackage($package);

      // Create CFPP handler for this Shipping Method
      $cfpp_handler = Factory::createHandler($shipping_method);

      // Gives a chance to set rules, then validate Payload per Shipping Method
      $cfpp_handler->beforeValidate()->validate($payload);

      // Calculate Costs
      do_action('cfpp_before_calculate_cost', $payload, $shipping_method);
      $shipping_costs = apply_filters('cfpp_response_success_' . $shipping_method_slug, $cfpp_handler->calculate($payload));

      } catch(PackageException $e) {
      do_action('cfpp_response_package_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (FactoryException $e) {
      do_action('cfpp_response_factory_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (ValidationErrorException $e) {
      do_action('cfpp_response_validation_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      } catch (HandlerException $e) {
      do_action('cfpp_response_handler_exception', $shipping_method_slug);
      $shipping_costs = $response->error($e->getMessage());
      }
      }

      // Successes first, errors last
      $shipping_costs = $instance->orderShippingCosts($shipping_costs);

      return $shipping_costs;
      }


      It all works fine. However, I'm having problems testing this class. I can't see how, but this method probably has poor architecture.



      How can I improve this code to make it more testable and architecturally correct?







      php validation wordpress e-commerce integration-testing






      share|improve this question









      New contributor




      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.











      share|improve this question









      New contributor




      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      share|improve this question




      share|improve this question








      edited yesterday









      200_success

      127k15149412




      127k15149412






      New contributor




      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.









      asked yesterday









      Lucas Bustamante

      1063




      1063




      New contributor




      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.





      New contributor





      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.






      Lucas Bustamante is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
      Check out our Code of Conduct.



























          active

          oldest

          votes











          Your Answer





          StackExchange.ifUsing("editor", function () {
          return StackExchange.using("mathjaxEditing", function () {
          StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix) {
          StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
          });
          });
          }, "mathjax-editing");

          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "196"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          convertImagesToLinks: false,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: null,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });






          Lucas Bustamante is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209009%2fwordpress-plugin-for-shipping-calculation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown






























          active

          oldest

          votes













          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes








          Lucas Bustamante is a new contributor. Be nice, and check out our Code of Conduct.










          draft saved

          draft discarded


















          Lucas Bustamante is a new contributor. Be nice, and check out our Code of Conduct.













          Lucas Bustamante is a new contributor. Be nice, and check out our Code of Conduct.












          Lucas Bustamante is a new contributor. Be nice, and check out our Code of Conduct.
















          Thanks for contributing an answer to Code Review Stack Exchange!


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          Use MathJax to format equations. MathJax reference.


          To learn more, see our tips on writing great answers.





          Some of your past answers have not been well-received, and you're in danger of being blocked from answering.


          Please pay close attention to the following guidance:


          • Please be sure to answer the question. Provide details and share your research!

          But avoid



          • Asking for help, clarification, or responding to other answers.

          • Making statements based on opinion; back them up with references or personal experience.


          To learn more, see our tips on writing great answers.




          draft saved


          draft discarded














          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f209009%2fwordpress-plugin-for-shipping-calculation%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown





















































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown

































          Required, but never shown














          Required, but never shown












          Required, but never shown







          Required, but never shown







          Popular posts from this blog

          Morgemoulin

          Scott Moir

          Souastre