diff --git a/modules/basket/controllers/admin_configure.php b/modules/basket/controllers/admin_configure.php index e028d512..7831734d 100644 --- a/modules/basket/controllers/admin_configure.php +++ b/modules/basket/controllers/admin_configure.php @@ -1,7 +1,7 @@ validate()) { basket::extractForm($form); message::success(t("Basket Module Configured!")); - //url::redirect("admin/recaptcha"); } } else @@ -45,11 +43,121 @@ class Admin_Configure_Controller extends Controller $view = new Admin_View("admin.html"); $view->content = new View("admin_configure.html"); - - $view->content->form = $form; - //$view->content->products = ORM::factory("product")->order_by("name")->find_all(); print $view; } + + /** + * the index page of the user homes admin + */ + public function templates() + { + $form = basket::get_template_form(); + if (request::method() == "post") { + access::verify_csrf(); + + if ($form->validate()) { + + basket::extractTemplateForm($form); + message::success(t("Basket Module Configured!")); + } + } + else + { + basket::populateTemplateForm($form); + } + + $view = new Admin_View("admin.html"); + $view->content = new View("admin_templates.html"); + + $view->content->form = $form; + + print $view; + } + + public function paypal_encrypt_wizard_step1() + { + $view = new Admin_View("admin.html"); + $view->content = new View("pew1.html"); + + $view->content->form = self::keyGenerationForm(); + + print $view; + + } + + public function paypal_encrypt_wizard_step2() + { + access::verify_csrf(); + + $form = self::keyGenerationForm(); + + if (!$form->validate()) { + + self::paypal_encrypt_wizard_step1(); + return; + } + + $ssldir = str_replace('\\','/',VARPATH.'certificate'); + $ssldir= rtrim($ssldir, '/').'/'; + + if ( ! is_dir($ssldir)) + { + // Create the upload directory + mkdir($ssldir, 0777, TRUE); + } + + $prkeyfile = $ssldir . "myprvkey.pem"; + $pubcertfile = $ssldir . "mypubcert.pem"; + $certreqfile = $ssldir . "mycertreq.pem"; + + $dn = array("countryName" => $form->encrypt->countryName->value, + "stateOrProvinceName" => $form->encrypt->stateOrProvinceName->value, + "localityName" => $form->encrypt->localityName->value, + "organizationName" => $form->encrypt->organizationName->value, + "organizationalUnitName" => $form->encrypt->organizationalUnitName->value, + "commonName" => $form->encrypt->commonName->value, + "emailAddress" => $form->encrypt->emailAddress->value); + $privkeypass = $form->encrypt->privKeyPass->value; + $numberofdays = 365; + $config = array( + "private_key_bits" => 1024 + ); + + $privkey = openssl_pkey_new($config); + $csr = openssl_csr_new($dn, $privkey); + $sscert = openssl_csr_sign($csr, null, $privkey, $numberofdays); + openssl_x509_export($sscert, $publickey); + openssl_pkey_export($privkey, $privatekey, $privkeypass); + openssl_csr_export($csr, $csrStr); + + openssl_x509_export_to_file($sscert, $pubcertfile); + openssl_pkey_export_to_file ($privkey, $prkeyfile, $privkeypass); + openssl_csr_export_to_file($csr, $certreqfile); + + //echo "Your Public Certificate has been saved to " . $pubcertfile . "

"; + //echo "Your Private Key has been saved to " . $prkeyfile . "

"; + //echo "Your Certificate Request has been saved to " . $certreqfile . "

"; + + //echo $privatekey; // Will hold the exported PriKey + //echo $publickey; // Will hold the exported PubKey + //echo $csrStr; // Will hold the exported Certificate + } + + private function keyGenerationForm() + { + $form = new Forge("admin/configure/paypal_encrypt_wizard_step2", "", "post", array("id" => "generateKeys", "name" =>"generateKeys")); + $group = $form->group("encrypt")->label(t("Key Generation Details")); + $group->input("countryName")->label(t("Country Name"))->id("countryName"); + $group->input("stateOrProvinceName")->label(t("State or Province Name"))->id("stateOrProvinceName"); + $group->input("localityName")->label(t("Locality Name"))->id("localityName"); + $group->input("organizationName")->label(t("Organization Name"))->id("organizationName"); + $group->input("organizationalUnitName")->label(t("Organizational Unit Name"))->id("organizationalUnitName"); + $group->input("commonName")->label(t("Common Name"))->id("commonName"); + $group->input("emailAddress")->label(t("E-Mail Address"))->id("emailAddress"); + $group->input("privKeyPass")->label(t("Private Key Pass"))->id("privkeypass"); + return $form; + } + } diff --git a/modules/basket/controllers/admin_postage_bands.php b/modules/basket/controllers/admin_postage_bands.php index d1b9dc97..914d7537 100644 --- a/modules/basket/controllers/admin_postage_bands.php +++ b/modules/basket/controllers/admin_postage_bands.php @@ -1,7 +1,7 @@ validate(); - $postage_band = ORM::factory("postage_band"); - $postage_band->name = $form->add_postage->inputs["name"]->value; - $postage_band->flat_rate = $form->add_postage->flat_rate->value; - $postage_band->per_item = $form->add_postage->per_item->value; - $postage_band->validate(); - } catch (ORM_Validation_Exception $e) { - // Translate ORM validation errors into form error messages - foreach ($e->validation->errors() as $key => $error) { - $form->add_postage->inputs[$key]->add_error($error, 1); - } + $valid = $form->validate(); + $name = $form->add_postage->inputs["name"]->value; + $postage = ORM::factory("postage_band")->where("name","=", $name)->find(); + if ($postage->loaded()) { + $form->add_postage->inputs["name"]->add_error("in_use", 1); $valid = false; } if ($valid) { - $postage_band->save(); + $postage = postage_band::create( + $name, + $form->add_postage->flat_rate->value, + $form->add_postage->per_item->value + ); + + $postage->save(); message::success(t("Created postage band %postage_name", array( - "postage_name" => html::clean($postage_band->name)))); - json::reply(array("result" => "success")); + "postage_name" => html::clean($postage->name)))); + print json::reply(array("result" => "success")); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } } public function delete_postage_band_form($id) { $postage = ORM::factory("postage_band", $id); if (!$postage->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } print postage_band::get_delete_form_admin($postage); } @@ -77,13 +76,9 @@ class Admin_Postage_Bands_Controller extends Controller public function delete_postage_band($id) { access::verify_csrf(); - if ($id == user::active()->id || $id == user::guest()->id) { - access::forbidden(); - } - $postage = ORM::factory("postage_band", $id); if (!$postage->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = postage_band::get_delete_form_admin($postage); @@ -91,13 +86,13 @@ class Admin_Postage_Bands_Controller extends Controller $name = $postage->name; $postage->delete(); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } $message = t("Deleted user %postage_band", array("postage_band" => html::clean($name))); log::success("user", $message); message::success($message); - json::reply(array("result" => "success")); + print json::reply(array("result" => "success")); } public function edit_postage_band($id) { @@ -105,38 +100,43 @@ class Admin_Postage_Bands_Controller extends Controller $postage = ORM::factory("postage_band", $id); if (!$postage->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = postage_band::get_edit_form_admin($postage); - try { - $valid = $form->validate(); - $postage->name = $form->edit_postage->inputs["name"]->value; - $postage->flat_rate = $form->edit_postage->flat_rate->value; - $postage->per_item = $form->edit_postage->per_item->value; - $postage->validate(); - } catch (ORM_Validation_Exception $e) { - // Translate ORM validation errors into form error messages - foreach ($e->validation->errors() as $key => $error) { - $form->edit_postage->inputs[$key]->add_error($error, 1); + $valid = $form->validate(); + if ($valid) { + $new_name = $form->edit_postage->inputs["name"]->value; + if ($new_name != $postage->name && + ORM::factory("postage_band") + ->where("name", "=", $new_name) + ->where("id","!=", $postage->id) + ->find() + ->loaded()) { + $form->edit_postage->inputs["name"]->add_error("in_use", 1); + $valid = false; + } else { + $postage->name = $new_name; } - $valid = false; } if ($valid) { + $postage->flat_rate = $form->edit_postage->flat_rate->value; + $postage->per_item = $form->edit_postage->per_item->value; $postage->save(); + message::success(t("Changed postage band %postage_name", array("postage_name" => html::clean($postage->name)))); - json::reply(array("result" => "success")); + print json::reply(array("result" => "success")); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } } public function edit_postage_band_form($id) { $postage = ORM::factory("postage_band", $id); if (!$postage->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = postage_band::get_edit_form_admin($postage); diff --git a/modules/basket/controllers/admin_product_lines.php b/modules/basket/controllers/admin_product_lines.php index bc01c19b..752f4e63 100644 --- a/modules/basket/controllers/admin_product_lines.php +++ b/modules/basket/controllers/admin_product_lines.php @@ -1,7 +1,7 @@ validate(); - $product = ORM::factory("product"); - $product->name = $form->add_product->inputs["name"]->value; - $product->description = $form->add_product->description->value; - $product->postage_band_id = $form->add_product->postage_band->value; - $product->validate(); - } catch (ORM_Validation_Exception $e) { - // Translate ORM validation errors into form error messages - foreach ($e->validation->errors() as $key => $error) { - $form->add_product->inputs[$key]->add_error($error, 1); - } + $valid = $form->validate(); + $name = $form->add_product->inputs["name"]->value; + $product = ORM::factory("product")->where("name", "=", $name)->find(); + if ($product->loaded()) { + $form->add_product->inputs["name"]->add_error("in_use", 1); $valid = false; } if ($valid) { + $product = product::create( + $name, + $form->add_product->cost->value, + $form->add_product->description->value, + $form->add_product->postage_band->value + ); + $product->save(); message::success(t("Created product %product_name", array( "product_name" => html::clean($product->name)))); - json::reply(array("result" => "success")); + print json::reply(array("result" => "success")); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } } public function delete_product_form($id) { $product = ORM::factory("product", $id); if (!$product->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } print product::get_delete_form_admin($product); } @@ -77,13 +77,9 @@ class Admin_Product_Lines_Controller extends Controller public function delete_product($id) { access::verify_csrf(); - if ($id == user::active()->id || $id == user::guest()->id) { - access::forbidden(); - } - $product = ORM::factory("product", $id); if (!$product->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = product::get_delete_form_admin($product); @@ -91,13 +87,13 @@ class Admin_Product_Lines_Controller extends Controller $name = $product->name; $product->delete(); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } $message = t("Deleted user %product_name", array("product_name" => html::clean($name))); log::success("user", $message); message::success($message); - json::reply(array("result" => "success")); + print json::reply(array("result" => "success")); } public function edit_product($id) { @@ -105,39 +101,44 @@ class Admin_Product_Lines_Controller extends Controller $product = ORM::factory("product", $id); if (!$product->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = product::get_edit_form_admin($product); - try { - $valid = $form->validate(); - $product->name = $form->edit_product->inputs["name"]->value; - $product->cost = $form->edit_product->cost->value; - $product->description = $form->edit_product->description->value; - $product->postage_band_id = $form->edit_product->postage_band->value; - $product->validate(); - } catch (ORM_Validation_Exception $e) { - // Translate ORM validation errors into form error messages - foreach ($e->validation->errors() as $key => $error) { - $form->edit_product->inputs[$key]->add_error($error, 1); + $valid = $form->validate(); + if ($valid) { + $new_name = $form->edit_product->inputs["name"]->value; + if ($new_name != $product->name && + ORM::factory("product") + ->where("name", "=", $new_name) + ->where("id","!=", $product->id) + ->find() + ->loaded()) { + $form->edit_product->inputs["name"]->add_error("in_use", 1); + $valid = false; + } else { + $product->name = $new_name; } - $valid = false; } if ($valid) { + $product->cost = $form->edit_product->cost->value; + $product->description = $form->edit_product->description->value; + $product->postage_band_id = $form->edit_product->postage_band->value; $product->save(); + message::success(t("Changed product %product_name", array("product_name" => html::clean($product->name)))); - json::reply(array("result" => "success")); + print json::reply(array("result" => "success")); } else { - json::reply(array("result" => "error", "html" => (string)$form)); + print $form; } } public function edit_product_form($id) { $product = ORM::factory("product", $id); if (!$product->loaded()) { - throw new Kohana_404_Exception(); + kohana::show_404(); } $form = product::get_edit_form_admin($product); diff --git a/modules/basket/controllers/basket.php b/modules/basket/controllers/basket.php index 612708c4..a4ecbee3 100644 --- a/modules/basket/controllers/basket.php +++ b/modules/basket/controllers/basket.php @@ -1,7 +1,7 @@ query("ALTER TABLE {orders} ADD COLUMN `method` int(9) DEFAULT 0;"); + } + public function view_basket($pp="") { - $template = new Theme_View("page.html", "other", "basket"); + $template = new Theme_View("page.html", "basket"); + + $basket = Session_Basket::get(); + if (isset($pp)){ + if ($pp=="nopp"){ + $basket->disablepp(); + } + elseif ($pp=="ppon"){ + $basket->enablepp(); + } + } $view = new View("view_basket.html"); - $view->basket = Session_Basket::get(); + $view->basket = $basket; + $template->content = $view; print $template; } - private function getCheckoutForm(){ + public function preview($id) { + $item = ORM::factory("item", $id); + + print ""; + + } + + public function view_orders() { + self::check_view_orders(); + $template = new Theme_View("page.html", "basket"); + + $incomplete_orders = ORM::factory("order")->where('status',"<",20)->find_all(); + + $view = new View("view_orders.html"); + + $view->orders = $incomplete_orders; + + $template->content = $view; + + print $template; + } + + + public function view_ipn($orderid){ + self::check_view_orders(); + + $template = new Theme_View("page.html", "basket"); + + $order = ORM::factory("order")->where("id","=",$orderid)->find(); + $ipn_messages = ORM::factory("ipn_message")->where("key","=",$orderid)->find_all(); + //$ipn_messages = ORM::factory("ipn_message")->find_all(); + + $view = new View("view_ipn.html"); + + $view->order = $order; + $view->ipn_messages = $ipn_messages; + + $template->content = $view; + + print $template; + + } + + public function check_view_orders() { + if (!basket::can_view_orders()){ + die("Invalid access."); + } + } + + public function print_order($id){ + + access::verify_csrf(); + self::check_view_orders(); + + + $prefix = basket::getOrderPrefix(); + $length = strlen($prefix); + if (strlen($id)>$length ){ + if ($prefix === strtolower(substr($id,0,$length ))){ + $id = substr($id,$length); + } + } + $order = ORM::factory("order", $id); + $view = new View("print_order.html"); + + if ($order->loaded()){ + $view->order = str_replace(array("\r\n", "\n", "\r"),"
",$order->text); + }else{ + $view->order = "Order ".$id." not found."; + } + print $view; + } + + public function show_order($id){ + + access::verify_csrf(); + self::check_view_orders(); + $prefix = basket::getOrderPrefix(); + $length = strlen($prefix); + if (strlen($id)>$length ){ + if ($prefix === strtolower(substr($id,0,$length ))){ + $id = substr($id,$length); + } + } + + $order = ORM::factory("order", $id); + + if ($order->loaded()){ + $view = new View("view_order.html"); + $view->order = $order; + print $view; + }else{ + print "Order ".$id." not found."; + } + } + + public function show_ipn($id){ + access::verify_csrf(); + self::check_view_orders(); + $ipn_message = ORM::factory("ipn_message", $id); + + if ($ipn_message->loaded()){ + print $ipn_message->text; + }else{ + print "IPN Message ".$id." not found."; + } + + } + + public function confirm_order_delivery($id){ + access::verify_csrf(); + self::check_view_orders(); + $order = ORM::factory("order", $id); + + if ($order->loaded()){ + if ($order->status == 2) + { + $order->status = 20; + $order->save(); + } + } + url::redirect("basket/view_orders"); + } + + public function confirm_order_payment($id){ + access::verify_csrf(); + self::check_view_orders(); + $order = ORM::factory("order", $id); + + if ($order->loaded()){ + if ($order->status == 1) + { + $order->status = 2; + $order->save(); + } + } + url::redirect("basket/view_orders"); + } + + private function getCheckoutForm(){ $form = new Forge("basket/confirm", "", "post", array("id" => "checkout", "name" =>"checkout")); $group = $form->group("contact")->label(t("Contact Details")); $group->input("fullname")->label(t("Name"))->id("fullname"); @@ -42,13 +196,14 @@ class Basket_Controller extends Controller { $group->input("postcode")->label(t("Postcode"))->id("postcode"); $group->input("email")->label(t("E-Mail Address"))->id("email"); $group->input("phone")->label(t("Telephone Number"))->id("phone"); + $group->hidden("paypal")->id("paypal"); return $form; } public function checkout () { - $template = new Theme_View("page.html", "other", "basket"); + $template = new Theme_View("page.html", "basket"); $view = new View("checkout.html"); @@ -80,6 +235,12 @@ class Basket_Controller extends Controller { if ($valid){ $basket = Session_Basket::get(); + + if (!isset($basket->contents ) || count($basket->contents) == 0) { + self::view_basket(); + return; + } + $basket->name = $form->contact->fullname->value; $basket->house = $form->contact->house->value; $basket->street = $form->contact->street->value; @@ -89,14 +250,33 @@ class Basket_Controller extends Controller { $basket->email = $form->contact->email->value; $basket->phone = $form->contact->phone->value; - $template = new Theme_View("page.html", "other", "basket"); + $paypal=$form->contact->paypal->value=="true"; + $template = new Theme_View("page.html", "basket"); - $form = new Forge("basket/complete", "", "post", array("id" => "confirm", "name" =>"confirm")); - $view = new View("confirm_order.html"); - $view->basket = $basket; - $template->content = $view; - $view->form = $form; - print $template; + if ($paypal){ + // create a prelimary order + $order = basket::createOrder($basket, Order_Model::PAYMENT_PAYPAL); + $paypal = new Paypal(); + + // create the order first + $view = new View("paypal_redirect.html"); + $view ->form = $paypal->process($basket, + url::site("basket/paypal_complete/$order->id", "http"), + url::site("basket/paypal_cancel/$order->id", "http"), + url::site("basket/paypal_ipn/$order->id", "http")); + $template->content = $view; + print $template; + + // redirect to paypal + }else + { + $form = new Forge("basket/complete", "", "post", array("id" => "confirm", "name" =>"confirm")); + $view = new View("confirm_order.html"); + $view->basket = $basket; + $template->content = $view; + $view->form = $form; + print $template; + } } else { @@ -105,65 +285,92 @@ class Basket_Controller extends Controller { } } - public function complete () { - access::verify_csrf(); + function paypal_ipn($id){ + $order = ORM::factory("order")->where("id","=",$id)->find(); + if ($order->loaded()){ + + $paypal = new Paypal(); + + if ($paypal->validate_ipn($id)){ + if ($paypal->ipn_data['payment_status'] == "Completed"){ + + $order->status = Order_Model::PAYMENT_CONFIRMED; + + // send e-mails + basket::send_order($order); + basket::send_invoice($order); + + $order->save(); + } + return; + } + print "invalid access. tut tut!"; + } + return; + + } + + public function paypal_complete($id) { + $order = ORM::factory("order")->where("id","=",$id)->find(); $basket = Session_Basket::get(); + $basket->clear(); + $this->_complete($order); + } - //$admin_address = basket::getEmailAddress(); - $postage = $basket->postage_cost(); - $product_cost = $basket->cost(); + public function paypal_cancel($id){ + $order = ORM::factory("order")->where("id","=",$id)->find(); - $admin_email = "Order for : -".$basket->name." -".$basket->house." -".$basket->street." -".$basket->suburb." -".$basket->town." -".$basket->postcode." -".$basket->email." -".$basket->phone." -Placed at ".date("d F Y - H:i" ,time())." -Cost of Ordered Products = ".$product_cost." -Postage and Packaging Costs + ".$postage." -Total Owed ".($product_cost+$postage)." Total in ".basket::getCurrency()." - -Items Ordered: - -"; - - // create the order items - foreach ($basket->contents as $basket_item){ - $item = $basket_item->getItem(); - $prod = ORM::factory("product", $basket_item->product); - $admin_email = $admin_email." -".$item->title." - ".$item->url()." -".$prod->name." - ".$prod->description." -".$basket_item->quantity." @ ".$prod->cost." - -"; + if ($order->loaded()){ + $order->delete(); } + $this->checkout(); + } - $from = "From: ".basket::getEmailAddress(); - mail(basket::getEmailAddress(), "Order from ".$basket->name, $admin_email, $from); + public function complete () { + access::verify_csrf(); + $basket = Session_Basket::get(); + + if (!isset($basket->contents ) || count($basket->contents) == 0) { + self::view_basket(); + return; + } + + // create order + $order = basket::createOrder($basket, Order_Model::PAYMENT_OFFLINE); $basket->clear(); - $template = new Theme_View("page.html", "other", "basket"); + // send e-mails + basket::send_order($order); + basket::send_invoice($order); + + + $this->_complete($order); + } + + private function _complete($order){ + $template = new Theme_View("page.html", "basket"); $view = new View("order_complete.html"); + $ordernumber = basket::getOrderPrefix().$order->id; + $view->ordernumber = $ordernumber; + $view->order = $order; + $view->total_cost = $order->cost; + $template->content = $view; + print $template; } private function getAddToBasketForm($id){ - $form = new Forge("basket/add_to_basket", "", "post", array("id" => "g-add-to-basket-form")); + $form = new Forge("basket/add_to_basket", "", "post", array("id" => "gAddToBasketForm")); $group = $form->group("add_to_basket")->label(t("Add To Basket")); $group->hidden("id"); $group->dropdown("product") ->label(t("Product")) ->options(product::getProductArray($id)); - $group->input("quantity")->label(t("Quantity"))->id("g-quantity"); + $group->input("quantity")->label(t("Quantity"))->id("gQuantity"); $group->submit("")->value(t("Add")); //$group->submit("proceedToCheckout")->value(t("Proceed To Checkout")); @@ -189,7 +396,11 @@ Items Ordered: $form->add_to_basket->product->value, $form->add_to_basket->quantity->value); - json::reply(array("result" => "success")); + $item = ORM::factory("item", $form->add_to_basket->id->value); + + Session::instance()->set("redirect_home", $item->parent_id); + + print json::reply(array("result" => "success")); } else { diff --git a/modules/basket/css/basket.css b/modules/basket/css/basket.css index f660685d..107b8229 100644 --- a/modules/basket/css/basket.css +++ b/modules/basket/css/basket.css @@ -1,5 +1,17 @@ #basket {float:right;} #add_to_basket {float:right} -#basketForm {max-width:200px} -#basketThumb {float:left; padding:10px 10px 0 0;} +#basketForm {max-width:200px;float:left;} +#basketThumb {float:left; padding:10px;} #basketThumb img{max-width:100px;} +#payment {float:right; width:50%} +#checkout input, +#checkout select, +#checkout textarea { + display: block; + clear: both; + padding: .2em; + width: 100%; +} +#sidebar-basket {max-height:300px; overflow-y:auto; overflow-x:hidden;} +.order-status-1 a{color:#AA0000 !important} +.order-status-2 a{color:#00AA00 !important} diff --git a/modules/basket/helpers/basket.php b/modules/basket/helpers/basket.php index 7f1c4661..b9be6726 100644 --- a/modules/basket/helpers/basket.php +++ b/modules/basket/helpers/basket.php @@ -1,7 +1,7 @@ "Mexican Peso"); static $format= array( + "AUD" => "$", + "CAD" => "$", + "EUR" => "€", + "GBP" => "£", + "JPY" => "¥", + "USD" => "$", + "NZD" => "$", + "CHF" => "", + "HKD" => "$", + "SGD" => "$", + "SEK" => "", + "DKK" => "", + "PLN" => "", + "NOK" => "", + "HUF" => "", + "CZK" => "", + "ILS" => "", + "MXN" => ""); + + static $formatweb= array( "AUD" => "$", "CAD" => "$", "EUR" => "€", @@ -60,37 +80,108 @@ class basket_Core { "MXN" => ""); - static function get_configure_form() { + static public function can_view_orders() + { + if (identity::active_user()->admin){ + return true; + } + + print identity::active_user(); + foreach (identity::active_user()->groups() as $group){ + if ($group->name == 'shop'){ + return true; + } + } + + return false; + } + + + static function get_configure_form() { $form = new Forge("admin/configure", "", "post", array("id" => "g-configure-form")); $group = $form->group("configure")->label(t("Configure Basket")); $group->input("email")->label(t("Offline Paying Email Address"))->id("g-order-email-address"); $group->dropdown("currency") - ->label(t("Currency")) - ->options(self::$currencies); + ->label(t("Currency")) + ->options(self::$currencies); + + $group->checkbox("side_bar")->label(t("Use only side bar"))->id("g-side-bar-only"); $group->checkbox("paypal")->label(t("Use Paypal"))->id("g-paypal"); $group->input("paypal_account")->label(t("Paypal E-Mail Address"))->id("g-paypal-address"); + $group->checkbox("allow_pickup")->label(t("Allow Product Pickup"))->id("g-allow-pickup"); + $group->input("order_prefix")->label(t("Order Number Prefix"))->id("g-order-prefix"); + $group->submit("")->value(t("Save")); + return $form; + } + + static function get_template_form() { + $form = new Forge("admin/configure/templates", "", "post", array("id" => "g-configure-form")); + $group = $form->group("configure")->label(t("Configure Basket")); + $group->textarea("payment_details")->label(t("Payment Details Description"))->id("g-payment-details"); + $group->textarea("order_complete_page")->label(t("Order Complete Page"))->id("g-order-complete_page"); + $group->input("order_complete_email_subject")->label(t("Order Complete Email Subject"))->id("g-order-complete_email_subject"); + $group->textarea("order_complete_email")->label(t("Order Complete Email"))->id("g-order-complete_email"); $group->submit("")->value(t("Save")); return $form; } static function populateForm($form){ - $form->configure->email->value(basket::getEmailAddress()); - $form->configure->paypal->checked(basket::isPaypal()); - $form->configure->paypal_account->value(basket::getPaypalAccount()); - $form->configure->currency->selected(basket::getCurrency()); + $form->configure->email->value(basket::getEmailAddress()); + $form->configure->side_bar->checked(basket::is_side_bar_only()); + $form->configure->paypal->checked(basket::isPaypal()); + $form->configure->paypal_account->value(basket::getPaypalAccount()); + $form->configure->currency->selected(basket::getCurrency()); + $form->configure->allow_pickup->checked(basket::isAllowPickup()); + $form->configure->order_prefix->value(basket::getOrderPrefix()); + } + + static function populateTemplateForm($form){ + $form->configure->payment_details->value(basket::getPaymentDetails()); + $form->configure->order_complete_page->value(basket::getOrderCompletePage()); + $form->configure->order_complete_email_subject->value(basket::getOrderCompleteEmailSubject()); + $form->configure->order_complete_email->value(basket::getOrderCompleteEmail()); } static function extractForm($form){ - $email = $form->configure->email->value; - $isPaypal = $form->configure->paypal->value; - $paypal_account = $form->configure->paypal_account->value; - $currency = $form->configure->currency->selected; - basket::setEmailAddress($email); - basket::setPaypal($isPaypal); - basket::setPaypalAccount($paypal_account); - basket::setCurrency($currency); + $email = $form->configure->email->value; + $is_side_bar = $form->configure->side_bar->value; + $isPaypal = $form->configure->paypal->value; + $paypal_account = $form->configure->paypal_account->value; + $currency = $form->configure->currency->selected; + $allow_pickup = $form->configure->allow_pickup->value; + $order_prefix = $form->configure->order_prefix->value; + basket::setEmailAddress($email); + basket::set_side_bar_only($is_side_bar); + basket::setPaypal($isPaypal); + basket::setPaypalAccount($paypal_account); + basket::setCurrency($currency); + basket::setAllowPickup($allow_pickup); + basket::setOrderPrefix($order_prefix); } + static function extractTemplateForm($form){ + $payment_details = $form->configure->payment_details->value; + $order_complete_page = $form->configure->order_complete_page->value; + $order_complete_email_subject = $form->configure->order_complete_email_subject->value; + $order_complete_email = $form->configure->order_complete_email->value; + basket::setPaymentDetails($payment_details); + basket::setOrderCompletePage($order_complete_page); + basket::setOrderCompleteEmailSubject($order_complete_email_subject); + basket::setOrderCompleteEmail($order_complete_email); + } + + static public function is_side_bar_only() + { + return module::get_var("basket","is_side_bar_only"); + + } + + static public function set_side_bar_only($value) + { + module::set_var("basket","is_side_bar_only",$value); + + } + static function getEmailAddress(){ return module::get_var("basket","email"); @@ -113,10 +204,51 @@ class basket_Core { return $cur; } + static function getPaymentDetails(){ + return module::get_var("basket","payment_details"); + } + + static function getOrderPrefix(){ + return module::get_var("basket","order_prefix"); + } + + static function isAllowPickup(){ + return module::get_var("basket","allow_pickup"); + } + + static function getOrderCompletePage(){ + return module::get_var("basket","order_complete_page"); + } + + static function getOrderCompleteEmail(){ + return module::get_var("basket","order_complete_email"); + } + + static function getOrderCompleteEmailSubject(){ + return module::get_var("basket","order_complete_email_subject"); + } + static function formatMoney($money){ return self::$format[self::getCurrency()].number_format($money,2); } + static function formatMoneyForWeb($money){ + return self::$formatweb[self::getCurrency()].number_format($money,2); + } + + static function replaceStrings($string, $key_values) { + // Replace x_y before replacing x. + krsort($key_values, SORT_STRING); + + $keys = array(); + $values = array(); + foreach ($key_values as $key => $value) { + $keys[] = "%$key"; + $values[] = $value; + } + return str_replace($keys, $values, $string); + } + static function setEmailAddress($email){ module::set_var("basket","email",$email); } @@ -133,32 +265,129 @@ class basket_Core { module::set_var("basket","currency",$currency); } - static function generatePaypalForm($session_basket){ - $form = " -
- - - -"; + static function setPaymentDetails($details){ + module::set_var("basket","payment_details",$details); + } - $postage = $session_basket->postage_cost(); - if ($postage > 0) { - $form = $form." -"; + static function setAllowPickup($allow_pickup){ + module::set_var("basket","allow_pickup",$allow_pickup); + } + + static function setOrderPrefix($order_prefix){ + module::set_var("basket","order_prefix",strtolower($order_prefix)); + } + + static function setOrderCompletePage($details){ + module::set_var("basket","order_complete_page",$details); + } + + static function setOrderCompleteEmail($details){ + module::set_var("basket","order_complete_email",$details); + } + + static function setOrderCompleteEmailSubject($details){ + module::set_var("basket","order_complete_email_subject",$details); + } + + static function createOrder($basket, $method){ + + $order = ORM::factory("order"); + $order->text = "processing"; + $order->save(); + + $ordernumber = basket::getOrderPrefix().$order->id; + + //$admin_address = basket::getEmailAddress(); + $postage = $basket->postage_cost(); + $product_cost = $basket->cost(); + $ppon = $basket->ispp(); + + $text = " + Order Number : ".$ordernumber." + + for : +".$basket->name." +".$basket->house." +".$basket->street." +".$basket->suburb." +".$basket->town." +".$basket->postcode." +".$basket->email." +".$basket->phone." +Placed at ".date("d F Y - H:i" ,time())." +Cost of Ordered Products = ".$product_cost; + if ($ppon){ + $text = $text." +Postage and Packaging Costs + ".$postage." +Total Owed ".($product_cost+$postage)." Total in ".basket::getCurrency(); + } + else{ + $text = $text." +Person has chosen to pick up product. +Total Owed ".($product_cost)." Total in ".basket::getCurrency(); + } + $text = $text." + +Items Ordered: + +"; + + // create the order items + foreach ($basket->contents as $basket_item){ + $item = $basket_item->getItem(); + $prod = ORM::factory("product", $basket_item->product); + $text = $text." +".$item->title." - ".$item->url()." +".$prod->name." - ".$prod->description." +".$basket_item->quantity." @ ".$prod->cost." + +"; } - $id = 1; - foreach ($session_basket->contents as $key => $basket_item){ - $form = $form." -getCode()."\"/> -cost_per\"/> -quantity\"/>"; - $id++; + if ($ppon){ + $total_cost = ($product_cost+$postage); + } + else{ + $total_cost = $product_cost; } - $form = $form."
"; + $order->name = $basket->name; + $order->email = $basket->email; + $order->cost = $total_cost; + $order->text = $text; + $order->status = Order_Model::WAITING_PAYMENT; + $order->method = $method; + $order->save(); + + //$basket->clear(); + + return $order; + } + + public function send_order($order){ + + $from = "From: ".basket::getEmailAddress(); + $ordernumber = basket::getOrderPrefix().$order->id; + + mail(basket::getEmailAddress(), "Order ".$ordernumber." from ".$order->name, $order->text, $from); + + } + + public function send_invoice($order) + { + + $from = "From: ".basket::getEmailAddress(); + $ordernumber = basket::getOrderPrefix().$order->id; + $invoice_email = basket::replaceStrings(basket::getOrderCompleteEmail(),Array( + "name"=>$order->name, + "order_number"=> $ordernumber, + "total_cost" =>basket::formatMoney($order->cost), + "order_details"=>$order->text)); + + mail($order->email, + basket::replaceStrings(basket::getOrderCompleteEmailSubject(),Array("order_number"=>$ordernumber)), + $invoice_email, $from); - return $form; } } \ No newline at end of file diff --git a/modules/basket/helpers/basket_block.php b/modules/basket/helpers/basket_block.php new file mode 100644 index 00000000..9263a68e --- /dev/null +++ b/modules/basket/helpers/basket_block.php @@ -0,0 +1,21 @@ + t("Basket")); + } + + static function get($block_id, $theme) { + $block = ""; + switch ($block_id) { + case "shopping": + $block = new Block(); + $block->css_id = "g-view-basket"; + $block->title = t("Basket"); + $block->content = new View("basket-side-bar.html"); + $block->content->basket = Session_Basket::get(); + break; + } + return $block; + } +} \ No newline at end of file diff --git a/modules/basket/helpers/basket_event.php b/modules/basket/helpers/basket_event.php index 8e0b7df5..c22a48c6 100644 --- a/modules/basket/helpers/basket_event.php +++ b/modules/basket/helpers/basket_event.php @@ -1,7 +1,7 @@ label(t("Configure")) ->url(url::site("admin/configure"))); $basket_menu->append( + Menu::factory("link") + ->id("templates") + ->label(t("Templates")) + ->url(url::site("admin/configure/templates"))); + $basket_menu->append( Menu::factory("link") ->id("product_line") ->label(t("Product Lines")) @@ -43,6 +48,11 @@ class basket_event_Core{ ->id("postage_bands") ->label(t("Postage Bands")) ->url(url::site("admin/postage_bands"))); + $basket_menu->append( + Menu::factory("link") + ->id("view_orders") + ->label(t("View Orders")) + ->url(url::site("basket/view_orders"))); } @@ -65,8 +75,8 @@ class basket_event_Core{ if ($product_override->loaded()){ $item_product = ORM::factory("item_product") - ->where('product_override_id', "=", $product_override->id) - ->where('product_id', "=", $product->id)->find(); + ->where('product_override_id', "=", $product_override->id) + ->where('product_id', "=", $product->id)->find(); if ($item_product->loaded()){ $checked = $item_product->include; if ($item_product->cost != -1){ diff --git a/modules/basket/helpers/basket_installer.php b/modules/basket/helpers/basket_installer.php index 78bad98f..b92cd694 100644 --- a/modules/basket/helpers/basket_installer.php +++ b/modules/basket/helpers/basket_installer.php @@ -1,7 +1,7 @@ query("CREATE TABLE IF NOT EXISTS {products} ( `id` int(9) NOT NULL auto_increment, `name` TEXT NOT NULL, @@ -30,14 +31,14 @@ class basket_installer `description` varchar(1024), `postage_band_id` int(9) default 1, PRIMARY KEY (`id`)) - DEFAULT CHARSET=utf8;"); + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); $db->query("CREATE TABLE IF NOT EXISTS {product_overrides} ( `id` int(9) NOT NULL auto_increment, `item_id` int(9) NOT NULL, `none` BOOLEAN default false, PRIMARY KEY (`id`)) - DEFAULT CHARSET=utf8;"); + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); $db->query("CREATE TABLE IF NOT EXISTS {item_products} ( `id` int(9) NOT NULL auto_increment, @@ -54,34 +55,72 @@ class basket_installer `flat_rate` DECIMAL(10,2) default 0, `per_item` DECIMAL(10,2) default 0, PRIMARY KEY (`id`)) - DEFAULT CHARSET=utf8;"); + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - $postage_band = ORM::factory("postage_band"); - $postage_band->name = "No Postage"; - $postage_band->save(); + $db->query("CREATE TABLE IF NOT EXISTS {orders} ( + `id` int(9) NOT NULL auto_increment, + `status` int(9) DEFAULT 0, + `name` varchar(1024), + `email` varchar(1024), + `cost` DECIMAL(10,2) default 0, + `method` int(9) DEFAULT 0, + `text` TEXT NOT NULL, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - $product = ORM::factory("product"); - $product->name = "4x6"; - $product->cost = 5; - $product->description = "4\"x6\" print"; - $product->postage_band_id = 1; - $product->save(); + $db->query("CREATE TABLE IF NOT EXISTS `ipn_messages` ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `date` int(11) NOT NULL, + `key` varchar(20) NOT NULL, + `txn_id` varchar(20) NOT NULL, + `status` varchar(20) NOT NULL, + `success` bool default false, + `text` text, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - $product = ORM::factory("product"); - $product->name = "8x10"; - $product->cost = 25; - $product->description = "8\"x10\" print"; - $product->postage_band_id = 1; - $product->save(); - $product = ORM::factory("product"); - $product->name = "8x12"; - $product->cost = 30; - $product->description = "8\"x12\" print"; - $product->postage_band_id = 1; - $product->save(); + postage_band::create("No Postage",0,0); + + product::create("4x6",5,"4\"x6\" print",1); + product::create("8x10",25,"8\"x10\" print",1); + product::create("8x12",30,"8\"x12\" print",1); + + basket::setPaymentDetails( +"

Use the following options to pay for this order.

+

Send a chequre to..

+

Visit the shop..

+

By using internet banking..

" + ); + basket::setOrderPrefix("ORDER"); + basket::setOrderCompletePage( +"

Your order number is %order_number. To pay for this order please either:

+

- Send a cheque for %total_cost to with reference %order_number..

+

- Visit the shop and quote the order %order_number..

+

- Transfer %total_cost using internet banking with reference %order_number..

+

Order will be processed as soon as payment is received. You should receive an e-mail with your order details shortly.

" + ); + basket::setOrderCompleteEmail( +"Hi %name, + +Thank you for your order the order details are below. To pay for this order please either: + +- Send a cheque for %total_cost to with reference %order_number.. +- Visit the shop and quote the order %order_number.. +- Transfer %total_cost using internet banking with reference %order_number.. + +Order will be processed as soon as payment is received. For order pick-ups please visit.. + +Order Details +------------- +%order_details + +Thanks"); + basket::setOrderCompleteEmailSubject( +"Photography Order %order_number"); + + module::set_version("basket", 4); - module::set_version("basket", 2); } static function upgrade($version) { @@ -101,12 +140,77 @@ class basket_installer `per_item` DECIMAL(10,2) default 0, PRIMARY KEY (`id`)) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); - $postage_band = ORM::factory("postage_band"); - $postage_band->name = "No Postage"; - $postage_band->save(); + postage_band::create("No Postage",0,0); module::set_version("basket", $version = 2); } + + if ($version == 2) { + $db->query("CREATE TABLE IF NOT EXISTS {orders} ( + `id` int(9) NOT NULL auto_increment, + `text` TEXT NOT NULL, + PRIMARY KEY (`id`)) + ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + basket::setPaymentDetails( +"

Use the following options to pay for this order.

+

Send a chequre to..

+

Visit the shop..

+

By using internet banking..

" + ); + basket::setOrderPrefix("ORDER"); + basket::setOrderCompletePage( +"

Your order number is %order_number. To pay for this order please either:

+

- Send a cheque for %total_cost to with reference %order_number..

+

- Visit the shop and quote the order %order_number..

+

- Transfer %total_cost using internet banking with reference %order_number..

+

Order will be processed as soon as payment is received. You should receive an e-mail with your order details shortly.

" + ); + basket::setOrderCompleteEmail( +"Hi %name, + +Thank you for your order the order details are below. To pay for this order please either: + +- Send a cheque for %total_cost to with reference %order_number.. +- Visit the shop and quote the order %order_number.. +- Transfer %total_cost using internet banking with reference %order_number.. + +Order will be processed as soon as payment is received. For order pick-ups please visit.. + +Order Details +------------- +%order_details + +Thanks"); + basket::setOrderCompleteEmailSubject( +"Photography Order %order_number"); + + module::set_version("basket", $version = 3); + } + + if ($version ==3 ){ + $db->query("ALTER TABLE {orders} ADD COLUMN `status` int(9) DEFAULT 0;"); + + $db->query("CREATE TABLE IF NOT EXISTS {ipn_messages} ( + `id` int(11) UNSIGNED NOT NULL AUTO_INCREMENT, + `date` int(11) NOT NULL, + `key` varchar(20) NOT NULL, + `txn_id` varchar(20) NOT NULL, + `status` varchar(20) NOT NULL, + `success` bool default false, + `text` text, + PRIMARY KEY (`id`) + ) ENGINE=InnoDB DEFAULT CHARSET=utf8;"); + module::set_version("basket", $version = 4); + + } + + if ($version==4){ + $db->query("ALTER TABLE {orders} ADD COLUMN `name` varchar(1024);"); + $db->query("ALTER TABLE {orders} ADD COLUMN `email` varchar(1024);"); + $db->query("ALTER TABLE {orders} ADD COLUMN `method` int(9) DEFAULT 0;"); + $db->query("ALTER TABLE {orders} ADD COLUMN `cost` DECIMAL(10,2) default 0"); + module::set_version("basket", $version = 5); + } } static function uninstall(){ @@ -115,5 +219,6 @@ class basket_installer $db->query("DROP TABLE IF EXISTS {product_overrides}"); $db->query("DROP TABLE IF EXISTS {item_products}"); $db->query("DROP TABLE IF EXISTS {postage_bands}"); + $db->query("DROP TABLE IF EXISTS {orders}"); } } diff --git a/modules/basket/helpers/basket_theme.php b/modules/basket/helpers/basket_theme.php index 2c9ae671..1ad535e5 100644 --- a/modules/basket/helpers/basket_theme.php +++ b/modules/basket/helpers/basket_theme.php @@ -1,7 +1,7 @@ basket = Session_Basket::get(); - return $view->render(); + if (!basket::is_side_bar_only()) + { + $view = new View("basket.html"); + + $view->basket = Session_Basket::get(); + return $view->render(); + } + return ""; } static function admin_head($theme) { @@ -36,12 +41,15 @@ class basket_theme_Core { } } static function photo_top($theme){ - if ( product::isForSale($theme->item()->id)){ - $view = new View("add_to_basket.html"); + if (!basket::is_side_bar_only()) + { + if ( product::isForSale($theme->item()->id)){ + $view = new View("add_to_basket.html"); - $view->item = $theme->item(); + $view->item = $theme->item(); - return $view->render(); + return $view->render(); + } } return ""; } diff --git a/modules/basket/helpers/postage_band.php b/modules/basket/helpers/postage_band.php index 042215cb..ca679d53 100644 --- a/modules/basket/helpers/postage_band.php +++ b/modules/basket/helpers/postage_band.php @@ -1,7 +1,7 @@ where("name", "=", $name)->find(); + if ($postage->loaded()) { + throw new Exception("@todo postage already EXISTS $name"); + } + + $postage->name = $name; + $postage->flat_rate = $flatrate; + $postage->per_item = $peritemcost; + + $postage->save(); + return $postage; + } + /** * returns the array of postage bands * @return an array of postage bands diff --git a/modules/basket/helpers/product.php b/modules/basket/helpers/product.php index 3ac44884..a4a13c8c 100644 --- a/modules/basket/helpers/product.php +++ b/modules/basket/helpers/product.php @@ -1,7 +1,7 @@ "g-add-product-form")); + $form = new Forge("admin/product_lines/add_product", "", "post", array("id" => "gAddProductForm")); $group = $form->group("add_product")->label(t("Add Product")); - $group->input("name")->label(t("Name"))->id("g-product-name") + $group->input("name")->label(t("Name"))->id("gProductName") ->error_messages("in_use", t("There is already a product with that name")); $group->input("cost")->label(t("Cost"))->id("gCost"); - $group->input("description")->label(t("Description"))->id("g-description"); + $group->input("description")->label(t("Description"))->id("gDescription"); $group->dropdown("postage_band") ->label(t("Postage Band")) ->options(postage_band::getPostageArray()); $group->submit("")->value(t("Add Product")); + $product = ORM::factory("product"); return $form; } static function get_edit_form_admin($product) { + $form = new Forge("admin/product_lines/edit_product/$product->id", "", "post", - array("id" => "g-edit-product-form")); + array("id" => "gEditProductForm")); $group = $form->group("edit_product")->label(t("Edit Product")); - $group->input("name")->label(t("Name"))->id("g-product-name")->value($product->name); + $group->input("name")->label(t("Name"))->id("gProductName")->value($product->name); $group->inputs["name"]->error_messages( "in_use", t("There is already a product with that name")); - $group->input("cost")->label(t("Cost"))->id("g-cost")->value($product->cost); - $group->input("description")->label(t("Description"))->id("g-description")-> + $group->input("cost")->label(t("Cost"))->id("gCost")->value($product->cost); + $group->input("description")->label(t("Description"))->id("gDescription")-> value($product->description); $group->dropdown("postage_band") ->label(t("Postage Band")) @@ -55,17 +57,39 @@ class product_Core { static function get_delete_form_admin($product) { $form = new Forge("admin/product_lines/delete_product/$product->id", "", "post", - array("id" => "g-delete-product-form")); + array("id" => "gDeleteProductForm")); $group = $form->group("delete_product")->label( t("Are you sure you want to delete product %name?", array("name" => $product->name))); $group->submit("")->value(t("Delete product %name", array("name" => $product->name))); return $form; } + /** + * Create a new product + * + * @param string $name + * @param string $full_name + * @param string $password + * @return User_Model + */ + static function create($name, $cost, $description, $postage_band) { + $product = ORM::factory("product")->where("name", "=", $name)->find(); + if ($product->loaded()) { + throw new Exception("@todo USER_ALREADY_EXISTS $name"); + } + + $product->name = $name; + $product->cost = $cost; + $product->description = $description; + $product->postage_band_id = $postage_band; + $product->save(); + return $product; + } + static function getProductArray($id){ $producta = array(); // check for product override - $product_override = ORM::factory("product_override")->where('item_id', "=", $id)->find(); + $product_override = ORM::factory("product_override")->where('item_id', "=", $id)->find(); if (!$product_override->loaded()){ // no override found so check parents @@ -75,11 +99,12 @@ class product_Core { $parents = $item->parents(); foreach ($parents as $parent){ // check for product override - $product_override = ORM::factory("product_override")->where('item_id', "=", $parent->id)->find(); - if ($product_override->loaded()){ - break; + $temp_override = ORM::factory("product_override")->where('item_id', "=", $parent->id)->find(); + if ($temp_override ->loaded()){ + $product_override = $temp_override; + //break; } - } + } } $products = ORM::factory("product")->find_all(); @@ -89,8 +114,8 @@ class product_Core { if ($product_override->loaded()){ $show = !$product_override->none; $item_product = ORM::factory("item_product") - ->where('product_override_id', "=", $product_override->id) - ->where('product_id', "=", $product->id)->find(); + ->where('product_override_id', "=", $product_override->id) + ->where('product_id', "=", $product->id)->find(); if ($item_product->loaded()){ $cost = $item_product->cost; @@ -102,7 +127,7 @@ class product_Core { if ($show) { - $producta[$product->id] = $product->description." (".basket::formatMoney($cost).")"; + $producta[$product->id] = html::clean($product->description)." (".basket::formatMoneyForWeb($cost).")"; } } @@ -111,6 +136,8 @@ class product_Core { static function isForSale($id){ + try + { // check for product override $product_override = ORM::factory("product_override")->where('item_id', "=", $id)->find(); @@ -122,9 +149,10 @@ class product_Core { $parents = $item->parents(); foreach ($parents as $parent){ // check for product override - $product_override = ORM::factory("product_override")->where('item_id', "=", $parent->id)->find(); - if ($product_override->loaded()){ - break; + $temp_override = ORM::factory("product_override")->where('item_id', "=", $parent->id)->find(); + if ($temp_override ->loaded()){ + $product_override = $temp_override; + //break; } } } @@ -136,8 +164,8 @@ class product_Core { foreach ($products as $product){ $item_product = ORM::factory("item_product") - ->where('product_override_id', "=", $product_override->id) - ->where('product_id', "=", $product->id)->find(); + ->where('product_override_id', "=", $product_override->id) + ->where('product_id', "=", $product->id)->find(); if ($item_product->loaded()){ @@ -152,5 +180,10 @@ class product_Core { } else { return count($products) > 0; } + } + catch (Exception $e) + { + echo $e; + } } } \ No newline at end of file diff --git a/modules/basket/libraries/Paypal.php b/modules/basket/libraries/Paypal.php new file mode 100644 index 00000000..c18ee058 --- /dev/null +++ b/modules/basket/libraries/Paypal.php @@ -0,0 +1,330 @@ +add_field('business', 'somebody@domain.com'); + * $p->add_field('first_name', $_POST['first_name']); + * ... (add all your fields in the same manor) + * $p->submit_paypal_post(); + * + * To process an IPN, have your IPN processing file contain: + * + * $p = new paypal_class; + * if ($p->validate_ipn()) { + * ... (IPN is verified. Details are in the ipn_data() array) + * } + * + * + * In case you are new to paypal, here is some information to help you: + * + * 1. Download and read the Merchant User Manual and Integration Guide from + * http://www.paypal.com/en_US/pdf/integration_guide.pdf. This gives + * you all the information you need including the fields you can pass to + * paypal (using add_field() with this class) aswell as all the fields + * that are returned in an IPN post (stored in the ipn_data() array in + * this class). It also diagrams the entire transaction process. + * + * 2. Create a "sandbox" account for a buyer and a seller. This is just + * a test account(s) that allow you to test your site from both the + * seller and buyer perspective. The instructions for this is available + * at https://developer.paypal.com/ as well as a great forum where you + * can ask all your paypal integration questions. Make sure you follow + * all the directions in setting up a sandbox test environment, including + * the addition of fake bank accounts and credit cards. + * + ******************************************************************************* + */ + +class Paypal_Core { + + var $last_error; // holds the last error encountered + + var $ipn_response; // holds the IPN response from paypal + public $ipn_data = array(); // array contains the POST values for IPN + + var $fields = array(); // array holds the fields to submit to paypal + + + public function __construct() + { + // initialization constructor. Called when class is created. + + // sandbox paypal + + //$this->paypal_url = "https://www.sandbox.paypal.com/cgi-bin/webscr"; + //$this->secure_url = "ssl://www.sandbox.paypal.com"; + + // normal paypal + $this->paypal_url = "https://www.paypal.com/cgi-bin/webscr"; + $this->secure_url = "ssl://www.paypal.com"; + + $this->last_error = ''; + + //$this->ipn_log_file = Kohana::log_directory().Kohana::config('paypal.ipn_logfile'); + //$this->ipn_log = true; + $this->ipn_response = ''; + + // populate $fields array with a few default values. See the paypal + // documentation for a list of fields and their data types. These defaul + // values can be overwritten by the calling script. + + + } + + function add_field($field, $value) { + + // adds a key=>value pair to the fields array, which is what will be + // sent to paypal as POST variables. If the value is already in the + // array, it will be overwritten. + + $this->fields["$field"] = $value; + } + + public function process($session_basket, $return_url, $cancel_url, $notify_url){ + + $this->add_field('rm','2'); + $this->add_field('cmd','_cart'); + $this->add_field('upload','1'); + + $this->add_field('currency_code', basket::getCurrency()); + $this->add_field('business', basket::getPaypalAccount()); + + // IPN stuff + $this->add_field('return', $return_url); + $this->add_field('cancel_return', $cancel_url); + $this->add_field('notify_url', $notify_url); + + // postage + if ($session_basket->ispp()){ + $postage = $session_basket->postage_cost(); + if ($postage > 0) { + $this->add_field('shipping_1',$postage); + } + } + + // basket contents + $id = 1; + foreach ($session_basket->contents as $key => $basket_item){ + $this->add_field("item_name_$id", $basket_item->getCode()); + $this->add_field("amount_$id", $basket_item->cost_per); + $this->add_field("quantity_$id",$basket_item->quantity); + $id++; + } + + // shipping address + $this->add_field("payer_email", $session_basket->email); + $this->add_field("address_name", $session_basket->name); + $this->add_field("address_street", $session_basket->house." ".$session_basket->street); + $this->add_field("address_city", $session_basket->town); + $this->add_field("address_zip", $session_basket->postcode); + $this->add_field("contact_phone", $session_basket->phone); + + $string = "
paypal_url."\">\n"; + + foreach ($this->fields as $name => $value) { + $string = $string."\n"; + } + + $string = $string."
"; + return $string; + } + + function validate_ipn($key) { + + // parse the paypal URL + $url_parsed=parse_url($this->paypal_url); + + // generate the post string from the _POST vars aswell as load the + // _POST vars into an arry so we can play with them from the calling + // script. + $post_string = 'cmd=_notify-validate'; + foreach ($_POST as $field=>$value) { + $this->ipn_data["$field"] = $value; + $value = urlencode(stripslashes($value)); + $value = preg_replace('/(.*[^%^0^D])(%0A)(.*)/i','${1}%0D%0A${3}',$value); + $post_string .= '&'.$field.'='.$value; + } + + // open the connection to paypal + + $fp = fsockopen($this->secure_url,443,$err_num,$err_str,30); + if(!$fp) { + + // could not open the connection. If loggin is on, the error message + // will be in the log. + $this->last_error = "fsockopen error no. $errnum: $errstr"; + $this->log_ipn_results($key,false); + return false; + + } else { + + // Post the data back to paypal + fputs($fp, "POST ".$url_parsed['path']." HTTP/1.1\r\n"); + fputs($fp, "Host: ".$url_parsed['host']."\r\n"); + fputs($fp, "Content-type: application/x-www-form-urlencoded\r\n"); + + fputs($fp, "Content-length: ".strlen($post_string)."\r\n\r\n"); + //fputs($fp, "Connection: close\r\n\r\n"); + fputs($fp, $post_string . "\r\n\r\n"); + + // loop through the response from the server and append to variable + while(!feof($fp)) { + $this->ipn_response .= fgets($fp, 1024); + } + + fclose($fp); // close connection + + } + + if (stristr($this->ipn_response,"VERIFIED")===false) + { + // Invalid IPN transaction. Check the log for details. + $this->last_error = 'IPN Validation Failed. '.$url_parsed['host'].'\\'.$url_parsed['path']; + $this->log_ipn_results($key,false); + return false; + } + else{ + + // Valid IPN transaction. + + // check recievers e-mail + $business = basket::getPaypalAccount(); + + if ($this->ipn_data['receiver_email']!=$business) + { + $this->last_error = 'receivers e-mail did not match '.$business; + $this->log_ipn_results($key,false); + return false; + } + + // if confirmed check message has not been received already + if ($this->ipn_data['payment_status'] == "Completed"){ + + $message = ORM::factory("ipn_message") + ->where('key',"=",$key) + ->where('status',"=",'completed') + ->where('txn_id',"=",$this->ipn_data['txn_id'])->find(); + + if ($message->loaded()){ + $this->last_error = 'Message alread received.'; + $this->log_ipn_results($key,false); + return false; + } + } + + $this->log_ipn_results($key,true); + return true; + + } + + } + + function log_ipn_results($key, $success) { + + // Timestamp + $text = '['.date('m/d/Y g:i A').'] - '; + + $message = ORM::factory("ipn_message"); + $message->date = time(); + $message->key = $key; + $message->txn_id = $this->ipn_data['txn_id']; + $message->status = $this->ipn_data['payment_status']; + $message->success = $success; + + // Success or failure being logged? + if ($success) $text .= "SUCCESS!\n"; + else $text .= 'FAIL: '.$this->last_error."\n"; + + // Log the POST variables + $text .= "IPN POST Vars from Paypal:\n"; + foreach ($this->ipn_data as $key=>$value) { + $text .= "$key=$value \n"; + } + + // Log the response from the paypal server + $text .= "\nIPN Response from Paypal Server:\n ".$this->ipn_response; + + $message->text = $text; + $message->save(); + } + + function dump_fields() { + + // Used for debugging, this function will output all the field/value pairs + // that are currently defined in the instance of the class using the + // add_field() function. + + echo "

paypal_class->dump_fields() Output:

"; + echo " + + + + "; + + ksort($this->fields); + foreach ($this->fields as $key => $value) { + echo ""; + } + + echo "
Field NameValue
$key".urldecode($value)." 

"; + } +} + + + diff --git a/modules/basket/libraries/Session_Basket.php b/modules/basket/libraries/Session_Basket.php index ba32442b..c73cfe36 100644 --- a/modules/basket/libraries/Session_Basket.php +++ b/modules/basket/libraries/Session_Basket.php @@ -1,7 +1,7 @@ contents)){ foreach ($this->contents as $key => $item){ unset($this->contents[$key]); } } + $this->ppenabled = true; } + public function enablepp() + { + $this->ppenabled = true; + } + + public function disablepp() + { + $this->ppenabled = false; + } + + public function ispp(){ + return $this->ppenabled; + } + + private function create_key($product, $id){ return "$product _ $id"; } @@ -116,7 +134,7 @@ class Session_Basket_Core { $key = $this->create_key($product, $id); if (isset($this->contents[$key])){ - $this->contents[$key]->add($id, $quantity); + $this->contents[$key]->add($quantity); } else { $this->contents[$key] = new basket_item($product, $id, $quantity); diff --git a/modules/basket/models/ipn_message.php b/modules/basket/models/ipn_message.php new file mode 100644 index 00000000..c6f75ffa --- /dev/null +++ b/modules/basket/models/ipn_message.php @@ -0,0 +1,16 @@ +date); + } + + public function json_encode(){ + $toReturn = array( + 'id' => $this->id, + 'date' => $this->formatedTime(), + 'text' => text::convertText($this->text)); + return $toReturn; + } +} \ No newline at end of file diff --git a/modules/basket/models/item_product.php b/modules/basket/models/item_product.php index 9dd24218..e152ab19 100644 --- a/modules/basket/models/item_product.php +++ b/modules/basket/models/item_product.php @@ -1,7 +1,7 @@ -did." ".$this->name." ".$this->status(); + } + + public function status(){ + switch ($this->status){ + case 1: + return "Waiting Payment"; + case 2: + return "Payment Confirmed"; + case 20: + return "Complete"; + + default: + return "Unknown"; + } + } + + public function payment_method(){ + switch ($this->method){ + case 1: + return "through Paypal"; + case 2: + return "offline"; + + default: + return "Unknown"; + } + } +} diff --git a/modules/basket/models/postage_band.php b/modules/basket/models/postage_band.php index e4354f9c..83eb6e08 100644 --- a/modules/basket/models/postage_band.php +++ b/modules/basket/models/postage_band.php @@ -1,7 +1,7 @@ "length[1,32]"); - /** - * Specify our rules here so that we have access to the instance of this model. - */ - public function validate($array=null) { - if (!$array) { - $this->rules = array( - "name" => array("rules" => array("required", "length[1,32]"), - "callbacks" => array(array($this, "valid_name"))), - "flat_rate" => array("rules" => array("required", "decimal")), - "per_item" => array("rules" => array("required"))); + protected $has_many=array('products'); - } - - parent::validate($array); - } - - /** - * Validate the item name. It can't conflict with other names, can't contain slashes or - * trailing periods. - */ - public function valid_name(Validation $v, $field) { - $postage_band = ORM::factory("postage_band")->where("name", "=", $this->name)->find(); - if ($postage_band->loaded() && $postage_band->id != $this->id) { - $v->add_error("name", "in_use"); - } - } } diff --git a/modules/basket/models/product.php b/modules/basket/models/product.php index d215aa39..2bd6a59b 100644 --- a/modules/basket/models/product.php +++ b/modules/basket/models/product.php @@ -1,7 +1,7 @@ "length[1,32]", + "description" => "length[0,255]"); + protected $belongs_to=array('postage_band'); - /** - * Specify our rules here so that we have access to the instance of this model. - */ - public function validate($array=null) { - if (!$array) { - $this->rules = array( - "name" => array("rules" => array("required", "length[1,32]"), - "callbacks" => array(array($this, "valid_name"))), - "description" => array("rules" => array("required", "length[0,255]")), - "cost" => array("rules" => array("required", "decimal"))); - } - - parent::validate($array); - } - - /** - * Validate the item name. It can't conflict with other names, can't contain slashes or - * trailing periods. - */ - public function valid_name(Validation $v, $field) { - Kohana_Log::add("error",print_r("valid_name!",1)); - $product = ORM::factory("product")->where("name", "=", $this->name)->find(); - if ($product->loaded() && $product->id != $this->id) { - $v->add_error("name", "in_use"); - } - } } diff --git a/modules/basket/models/product_override.php b/modules/basket/models/product_override.php index e6b28a0c..e3e720fd 100644 --- a/modules/basket/models/product_override.php +++ b/modules/basket/models/product_override.php @@ -1,7 +1,7 @@ -
- id") ?>" - title="" - class="g-dialog-link"> - Add To Basket +id") ?>" title="" class="g-dialog-link"> +
\ No newline at end of file diff --git a/modules/basket/views/admin_configure.html.php b/modules/basket/views/admin_configure.html.php index 7ee7f09e..9960fe01 100644 --- a/modules/basket/views/admin_configure.html.php +++ b/modules/basket/views/admin_configure.html.php @@ -1,8 +1,7 @@
-

-

- -

- +

+

+

+
\ No newline at end of file diff --git a/modules/basket/views/admin_postage_bands.html.php b/modules/basket/views/admin_postage_bands.html.php index f52cd165..d79fe380 100644 --- a/modules/basket/views/admin_postage_bands.html.php +++ b/modules/basket/views/admin_postage_bands.html.php @@ -1,7 +1,7 @@ " - class="g-dialog-link g-button-link right ui-icon-left ui-state-default ui-corner-all" - title=""> + class="g-dialog-link g-button right ui-icon-left ui-state-default ui-corner-all" + title=""> @@ -31,44 +31,41 @@ -
- +
+
- + $postage_band): ?> - "> + "> + - - - + + id") ?>" + class="g-dialog-link g-button ui-state-default ui-corner-all ui-icon-left"> + - + + + -
name) ?> + + flat_rate) ?> - flat_rate) ?> - - per_item) ?> - - id") ?>" - open_text="" - class="g-panel-link g-button-link ui-state-default ui-corner-all ui-icon-left"> - - - + + per_item) ?> + + id") ?>" + open_text="" + class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left"> + - id") ?>" - class="g-dialog-link g-button-link ui-state-default ui-corner-all ui-icon-left"> - - - -
+
- + \ No newline at end of file diff --git a/modules/basket/views/admin_product_lines.html.php b/modules/basket/views/admin_product_lines.html.php index f1073211..f20f2a37 100644 --- a/modules/basket/views/admin_product_lines.html.php +++ b/modules/basket/views/admin_product_lines.html.php @@ -1,7 +1,7 @@ " - class="g-dialog-link g-button g-right ui-icon-left ui-state-default ui-corner-all" + class="g-dialog-link g-button right ui-icon-left ui-state-default ui-corner-all" title=""> @@ -42,12 +42,12 @@ $product): ?> - "> + "> name) ?> - cost) ?> + cost) ?> description) ?> @@ -57,11 +57,11 @@ - + id") ?>" open_text="" class="g-panel-link g-button ui-state-default ui-corner-all ui-icon-left"> - + id") ?>" class="g-dialog-link g-button ui-state-default ui-corner-all ui-icon-left"> diff --git a/modules/basket/views/admin_templates.html.php b/modules/basket/views/admin_templates.html.php new file mode 100644 index 00000000..263293c4 --- /dev/null +++ b/modules/basket/views/admin_templates.html.php @@ -0,0 +1,8 @@ + +
+

+

+ +

+ +
\ No newline at end of file diff --git a/modules/basket/views/basket-side-bar.html.php b/modules/basket/views/basket-side-bar.html.php new file mode 100644 index 00000000..d6ac00d7 --- /dev/null +++ b/modules/basket/views/basket-side-bar.html.php @@ -0,0 +1,42 @@ +page_type != 'basket'){ + if (basket::can_view_orders()){ + ?>
" title="">item(); + if ($item->is_photo() && product::isForSale($theme->item()->id)){ + ?>

+id") ?>" +title="">

+contents) && ($basket->size() > 0)) { + ?>
+

" title="">

- page_subtype != 'basket'): ?> + + page_type != 'basket'): ?> + + " + title="">View Orders + contents) && ($basket->size() > 0)): ?>
" diff --git a/modules/basket/views/checkout.html.php b/modules/basket/views/checkout.html.php index 395847e6..b9ceaa2d 100644 --- a/modules/basket/views/checkout.html.php +++ b/modules/basket/views/checkout.html.php @@ -1,7 +1,7 @@
- + +

Payment Details

-

After you have confirmed the order we will get in contact with you to arrange payment.

+ +
+ + +
+
diff --git a/modules/basket/views/confirm_order.html.php b/modules/basket/views/confirm_order.html.php index 2599041d..60ff14ac 100644 --- a/modules/basket/views/confirm_order.html.php +++ b/modules/basket/views/confirm_order.html.php @@ -1,7 +1,7 @@ -
+

Basket Summary

-
+
@@ -33,7 +33,8 @@ function so(){document.confirm.submit();} contents as $key => $prod_details): ?> - "> + "> + - + postage_cost();?> 0):?> - "> - + "> + - "> - + "> + +
getItem(); ?>
@@ -47,19 +48,20 @@ function so(){document.confirm.submit();} quantity) ?>
- cost)) ?> + cost) ?>
Postage and Packaging
ispp()?"":"style=\"text-decoration:line-through\""; ?>>Postage and Packagingispp()?"":"style=\"text-decoration:line-through\""; ?>>
Total Costcost() + $postage))?>
Total Costispp()?basket::formatMoneyForWeb($basket->cost() + $postage):basket::formatMoneyForWeb($basket->cost()); ?>
@@ -78,9 +80,10 @@ E-mail : email ?>
Telephone : phone ?>
-" class="g-left g-button ui-state-default ui-corner-all ui-icon-left"> +
diff --git a/modules/basket/views/order_complete.html.php b/modules/basket/views/order_complete.html.php index b38151e7..5f384732 100644 --- a/modules/basket/views/order_complete.html.php +++ b/modules/basket/views/order_complete.html.php @@ -1,7 +1,7 @@
+

Thankyou for your order

-You will be contacted soon to arrange payment and delivery. +method == Order_Model::PAYMENT_PAYPAL){ +?>Your order will be confirmed when Paypal has finished processing your order.$ordernumber, "total_cost"=>basket::formatMoneyForWeb($total_cost)));?>
\ No newline at end of file diff --git a/modules/basket/views/paypal_redirect.html.php b/modules/basket/views/paypal_redirect.html.php new file mode 100644 index 00000000..26a2438b --- /dev/null +++ b/modules/basket/views/paypal_redirect.html.php @@ -0,0 +1,4 @@ + +

Processing

If you are not automatically redirected to + paypal within 5 seconds Click Here.

+ diff --git a/modules/basket/views/pew1.html.php b/modules/basket/views/pew1.html.php new file mode 100644 index 00000000..c751f7cb --- /dev/null +++ b/modules/basket/views/pew1.html.php @@ -0,0 +1,16 @@ + + \ No newline at end of file diff --git a/modules/basket/views/pew2.html.php b/modules/basket/views/pew2.html.php new file mode 100644 index 00000000..41324d2d --- /dev/null +++ b/modules/basket/views/pew2.html.php @@ -0,0 +1,17 @@ + + \ No newline at end of file diff --git a/modules/basket/views/print_order.html.php b/modules/basket/views/print_order.html.php new file mode 100644 index 00000000..63598131 --- /dev/null +++ b/modules/basket/views/print_order.html.php @@ -0,0 +1,20 @@ + + + +Print Order + + + + + + + + + + + \ No newline at end of file diff --git a/modules/basket/views/view_basket.html.php b/modules/basket/views/view_basket.html.php index c213d4a2..891d2647 100644 --- a/modules/basket/views/view_basket.html.php +++ b/modules/basket/views/view_basket.html.php @@ -1,7 +1,7 @@ +
+
contents ) && count($basket->contents) > 0): ?> - - - - - " - class="g-right g-button ui-state-default ui-corner-all ui-icon-right"> - - - " - class="g-right g-button ui-state-default ui-corner-all ui-icon-right"> - - - -

- -

-
+ $(document).ready(function(){ + $("#pickup").click(function(){ + if (this.checked) + { + window.location = ""; + } + else + { + window.location = ""; + } + }); + }) + + + " + class="right g-button ui-state-default ui-corner-all ui-icon-right"> + + +
+
contents ) && count($basket->contents) > 0): ?> - +
@@ -58,12 +76,14 @@ contents as $key => $prod_details): ?> - "> + "> - "> - + "> + + + "> - "> - + + "> +
getItem(); ?>
+ <?= $item->title?> +
@@ -74,13 +94,9 @@ cost?> - cost)) ?> + cost); ?> - + " class="g-button ui-state-default ui-corner-all ui-icon-left"> @@ -90,34 +106,32 @@ postage_cost();?> 0):?> -
Postage and Packaging
ispp()?"":"style=\"text-decoration:line-through\""; ?>>Postage and Packagingispp()?"":"style=\"text-decoration:line-through\""; ?>> +
ispp()?"":"checked"; ?>/> Select if you wish to pick up the photos.
Total Cost
Total Costispp()?basket::formatMoneyForWeb($total + $postage):basket::formatMoneyForWeb($total)?>
+ Shopping Basket is Empty
+
\ No newline at end of file diff --git a/modules/basket/views/view_ipn.html.php b/modules/basket/views/view_ipn.html.php new file mode 100644 index 00000000..6c19e27f --- /dev/null +++ b/modules/basket/views/view_ipn.html.php @@ -0,0 +1,46 @@ + +

IPN Messages for title()?>

+">Back to orders +
+ + +
+

+
+ diff --git a/modules/basket/views/view_order.html.php b/modules/basket/views/view_order.html.php new file mode 100644 index 00000000..d735e26f --- /dev/null +++ b/modules/basket/views/view_order.html.php @@ -0,0 +1,18 @@ + +

title()?>

+Payment is payment_method()?>status==Order_Model::WAITING_PAYMENT){ + ?>
id)."?csrf=$csrf";?>">Confirm Order Payment status==Order_Model::PAYMENT_CONFIRMED){ + ?>
id)."?csrf=$csrf";?>">Confirm Order Delivery method==Order_Model::PAYMENT_PAYPAL){ + ?>
id);?>">View Paypal IPN Messages
+",$order->text);?> \ No newline at end of file diff --git a/modules/basket/views/view_orders.html.php b/modules/basket/views/view_orders.html.php new file mode 100644 index 00000000..a5c90e1c --- /dev/null +++ b/modules/basket/views/view_orders.html.php @@ -0,0 +1,67 @@ + +
+
+ + + + + + +
+
+
+ +
+

+
+ diff --git a/modules/gwtorganise/controllers/json_album.php b/modules/gwtorganise/controllers/json_album.php index 637df65a..5cf032f8 100644 --- a/modules/gwtorganise/controllers/json_album.php +++ b/modules/gwtorganise/controllers/json_album.php @@ -310,7 +310,7 @@ class Json_Album_Controller extends Controller { $i++; } - json::reply($toreturn); + print json_encode($toreturn); } @@ -322,7 +322,7 @@ class Json_Album_Controller extends Controller { $item = $this->p_rotate($item, $dir); - json::reply(self::child_json_encode($item)); + print json_encode(self::child_json_encode($item)); } public function resize_config(){ @@ -338,5 +338,4 @@ class Json_Album_Controller extends Controller { json::reply(array("resize" => false)); } } - -} \ No newline at end of file +}