From 81ceafbfbd3632ce5afc6b27a54f8b03d92fbb76 Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 12 Jun 2014 17:54:20 -0400 Subject: [PATCH 01/47] whmcs client form --- airtime_mvc/application/configs/ACL.php | 6 +- .../controllers/BillingController.php | 58 ++++++ .../application/forms/BillingPurchase.php | 180 ++++++++++++++++++ .../application/layouts/scripts/layout.phtml | 4 +- .../views/scripts/billing/index.phtml | 1 + .../views/scripts/billing/purchase.phtml | 4 + 6 files changed, 250 insertions(+), 3 deletions(-) create mode 100644 airtime_mvc/application/controllers/BillingController.php create mode 100644 airtime_mvc/application/forms/BillingPurchase.php create mode 100644 airtime_mvc/application/views/scripts/billing/index.phtml create mode 100644 airtime_mvc/application/views/scripts/billing/purchase.phtml diff --git a/airtime_mvc/application/configs/ACL.php b/airtime_mvc/application/configs/ACL.php index 842778065..b52904b7a 100644 --- a/airtime_mvc/application/configs/ACL.php +++ b/airtime_mvc/application/configs/ACL.php @@ -29,7 +29,8 @@ $ccAcl->add(new Zend_Acl_Resource('library')) ->add(new Zend_Acl_Resource('audiopreview')) ->add(new Zend_Acl_Resource('webstream')) ->add(new Zend_Acl_Resource('locale')) - ->add(new Zend_Acl_Resource('upgrade')); + ->add(new Zend_Acl_Resource('upgrade')) + ->add(new Zend_Acl_Resource('billing')); /** Creating permissions */ $ccAcl->allow('G', 'index') @@ -54,7 +55,8 @@ $ccAcl->allow('G', 'index') ->allow('A', 'listenerstat') ->allow('A', 'user') ->allow('A', 'systemstatus') - ->allow('A', 'preference'); + ->allow('A', 'preference') + ->allow('A', 'billing'); $aclPlugin = new Zend_Controller_Plugin_Acl($ccAcl); diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php new file mode 100644 index 000000000..9a339426b --- /dev/null +++ b/airtime_mvc/application/controllers/BillingController.php @@ -0,0 +1,58 @@ +view->form = $form; + //$this->view->html = $this->view->render('billing/purchase.phtml'); + } + + public static function getClientDetails() + { + try { + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "getclientsdetails"; + $postfields["stats"] = true; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 1822; + $postfields["responsetype"] = "json"; + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, $url); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 5); //Aggressive 5 second timeout + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + $jsondata = curl_exec($ch); + if (curl_error($ch)) { + //die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch)); + throw new Exception("WHMCS server down or invalid request."); + } + curl_close($ch); + + $arr = json_decode($jsondata, true); + return $arr["client"]; + } catch (Exception $e) { + Logging::info($e->getMessage()); + } + } +} \ No newline at end of file diff --git a/airtime_mvc/application/forms/BillingPurchase.php b/airtime_mvc/application/forms/BillingPurchase.php new file mode 100644 index 000000000..dfb0c1201 --- /dev/null +++ b/airtime_mvc/application/forms/BillingPurchase.php @@ -0,0 +1,180 @@ +setDecorators(array( + array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ + $client = BillingController::getClientDetails(); + + $notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator(); + $emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator(); + + $firstname = new Zend_Form_Element_Text('firstname'); + $firstname->setLabel(_('First Name:')) + ->setValue($client["firstname"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($firstname); + + $lastname = new Zend_Form_Element_Text('lastname'); + $lastname->setLabel(_('Last Name:')) + ->setValue($client["lastname"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($lastname); + + $companyname = new Zend_Form_Element_Text('companyname'); + $companyname->setLabel(_('Company Name:')) + ->setValue($client["companyname"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($companyname); + + $email = new Zend_Form_Element_Text('email'); + $email->setLabel(_('Email Address:')) + ->setValue($client["email"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->setAttrib('readonly', 'readonly') + ->addValidator($emailValidator) + ->addFilter('StringTrim'); + $this->addElement($email); + + $address1 = new Zend_Form_Element_Text('address1'); + $address1->setLabel(_('Address 1:')) + ->setValue($client["address1"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($address1); + + $address2 = new Zend_Form_Element_Text('address2'); + $address2->setLabel(_('Address 2:')) + ->setValue($client["address2"]) + ->setAttrib('class', 'input_text') + ->addFilter('StringTrim'); + $this->addElement($address2); + + $city = new Zend_Form_Element_Text('city'); + $city->setLabel(_('City:')) + ->setValue($client["city"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($city); + + //TODO: get list from whmcs? + $state = new Zend_Form_Element_Text('state'); + $state->setLabel(_('State/Region:')) + ->setValue($client["state"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($state); + + $postcode = new Zend_Form_Element_Text('postcode'); + $postcode->setLabel(_('Zip Code:')) + ->setValue($client["postcode"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($postcode); + + $locale = new Zend_Locale('en_US'); + $countries = $locale->getTranslationList('Territory', 'en', 2); + asort($countries, SORT_LOCALE_STRING); + + $country = new Zend_Form_Element_Select('country'); + $country->setLabel(_('Country:')) + ->setValue($client["country"]) + ->setAttrib('class', 'input_text') + ->setMultiOptions($countries) + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($country); + + $phonenumber = new Zend_Form_Element_Text('phonenumber'); + $phonenumber->setLabel(_('Phone Number:')) + ->setValue($client["phonenumber"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($phonenumber); + + //TODO: get list from whmcs + $securityqid = new Zend_Form_Element_Text('securityqid'); + $securityqid->setLabel(_('Please choose a security question:')) + ->setValue($client["securityqid"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($securityqid); + + $securityqans = new Zend_Form_Element_Text('securityqans'); + $securityqans->setLabel(_('Please enter an answer:')) + ->setValue($client["securityqans"]) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($securityqans); + + foreach ($client["customfields"] as $field) { + if ($field["id"] == 7) { + $vatvalue = $field["value"]; + } elseif ($field["id"] == 71) { + $subscribevalue = $field["value"]; + } + } + + $vat = new Zend_Form_Element_Text('vat'); + $vat->setLabel(_('VAT/Tax ID (EU only)')) + ->setValue($vatvalue) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($vat); + + $subscribe = new Zend_Form_Element_Checkbox('subscribe'); + $subscribe->setLabel(_('Subscribe to Sourcefabric newsletter')) + ->setValue($subscribevalue) + ->setAttrib('class', 'input_text') + ->setRequired(true) + ->addValidator($notEmptyValidator) + ->addFilter('StringTrim'); + $this->addElement($subscribe); + + $password = new Zend_Form_Element_Password('whmcspassword'); + $password->setLabel(_('Password:')); + $password->setAttrib('class', 'input_text'); + $password->setRequired(true); + $password->addFilter('StringTrim'); + $password->addValidator($notEmptyValidator); + $this->addElement($password); + + $passwordVerify = new Zend_Form_Element_Password('whmcspasswordVerify'); + $passwordVerify->setLabel(_('Verify Password:')); + $passwordVerify->setAttrib('class', 'input_text'); + $passwordVerify->setRequired(true); + $passwordVerify->addFilter('StringTrim'); + $passwordVerify->addValidator($notEmptyValidator); + $this->addElement($passwordVerify); + } +} \ No newline at end of file diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index fc46df5c4..ec5008736 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -24,7 +24,9 @@
diff --git a/airtime_mvc/application/views/scripts/billing/index.phtml b/airtime_mvc/application/views/scripts/billing/index.phtml new file mode 100644 index 000000000..30d74d258 --- /dev/null +++ b/airtime_mvc/application/views/scripts/billing/index.phtml @@ -0,0 +1 @@ +test \ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/billing/purchase.phtml b/airtime_mvc/application/views/scripts/billing/purchase.phtml new file mode 100644 index 000000000..b5d116fe7 --- /dev/null +++ b/airtime_mvc/application/views/scripts/billing/purchase.phtml @@ -0,0 +1,4 @@ +
+successMessage ?> +form ?> +
\ No newline at end of file From d39f7548cd4a6c2aea1de4f60780d3284a28bfc0 Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 12 Jun 2014 17:58:02 -0400 Subject: [PATCH 02/47] un-hardcoded client id --- airtime_mvc/application/controllers/BillingController.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 9a339426b..106f475aa 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -27,8 +27,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($password); $postfields["action"] = "getclientsdetails"; $postfields["stats"] = true; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1822; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["responsetype"] = "json"; $query_string = ""; From 1f4c8b755d04def5f1625f849ddc10c96d43dd4a Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 17 Jun 2014 12:47:08 -0400 Subject: [PATCH 03/47] Created a separate view for upgrades and client info --- .../controllers/BillingController.php | 157 +++++++++++++++++- ...{BillingPurchase.php => BillingClient.php} | 30 ++-- .../forms/BillingUpgradeDowngrade.php | 49 ++++++ .../application/layouts/scripts/layout.phtml | 2 +- .../billing/{purchase.phtml => client.phtml} | 1 - .../views/scripts/billing/upgrade.phtml | 6 + 6 files changed, 224 insertions(+), 21 deletions(-) rename airtime_mvc/application/forms/{BillingPurchase.php => BillingClient.php} (85%) create mode 100644 airtime_mvc/application/forms/BillingUpgradeDowngrade.php rename airtime_mvc/application/views/scripts/billing/{purchase.phtml => client.phtml} (74%) create mode 100644 airtime_mvc/application/views/scripts/billing/upgrade.phtml diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 106f475aa..29048f543 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -7,32 +7,172 @@ class BillingController extends Zend_Controller_Action { } - public function purchaseAction() + public function upgradeAction() { - $form = new Application_Form_BillingPurchase(); - $this->view->form = $form; - //$this->view->html = $this->view->render('billing/purchase.phtml'); + $request = $this->getRequest(); + $form = new Application_Form_BillingUpgradeDowngrade(); + if ($request->isPost()) { + $formData = $request->getPost(); + + /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ + $url = "https://account.sourcefabric.com/includes/api.php"; + $username = "api_access"; + $password = "raditional69203"; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "upgradeproduct"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 1846; + //TODO: do not hardcode + //$postfields["serviceid"] = self::getClientInstanceId(); + $postfields["serviceid"] = "1678"; + $postfields["type"] = "product"; + $postfields["newproductid"] = $formData["newproductid"]; + $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; + $postfields["paymentmethod"] = $formData["paymentmethod"]; + $postfields["responsetype"] = "json"; + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + //$result = $this->makeRequest($url, $query_string); + //$invoiceUrl = "https://account.sourcefabric.com/viewinvoice.php?id=".$result["invoiceid"]; + $whmcsurl = "https://account.sourcefabric.com/dologin.php"; + $autoauthkey = "MabIttEtkac2"; + $timestamp = time(); //whmcs timezone? + $client = self::getClientDetails(); + $email = $client["email"]; + $hash = sha1($email.$timestamp.$autoauthkey); + $goto="viewinvoice.php?id=5108"; + $this->_redirect($whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); + + } else { + $this->view->form = $form; + } + } + + public function clientAction() + { + $request = $this->getRequest(); + $form = new Application_Form_BillingClient(); + if ($request->isPost()) { + $formData = $request->getPost(); + + /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ + $url = "https://account.sourcefabric.com/includes/api.php"; + $username = "api_access"; + $password = "raditional69203"; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "updateclient"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 1846; + $postfields = array_merge($postfields, $formData); + unset($postfields["password2verify"]); + unset($postfields["submit"]); + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $result = $this->makeRequest($url, $query_string); + Logging::info($result); + } else { + $this->view->form = $form; + } + } + + //TODO: this does not return a service id. why? + private static function getClientInstanceId() + { + /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ + $url = "https://account.sourcefabric.com/includes/api.php"; + $username = "api_access"; + $password = "raditional69203"; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "getclientsproducts"; + $postfields["responsetype"] = "json"; + $postfields["clientid"] = 1846; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $result = self::makeRequest($url, $query_string); + Logging::info($result); + } + + public static function getProducts() + { + /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ + $url = "https://account.sourcefabric.com/includes/api.php"; + $username = "api_access"; + $password = "raditional69203"; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "getproducts"; + $postfields["responsetype"] = "json"; + $postfields["gid"] = "15"; + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $result = self::makeRequest($url, $query_string); + return $result["products"]["product"]; } public static function getClientDetails() { try { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ + $url = "https://account.sourcefabric.com/includes/api.php"; + $username = "api_access"; + $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; $postfields["password"] = md5($password); $postfields["action"] = "getclientsdetails"; $postfields["stats"] = true; - $postfields["clientid"] = Application_Model_Preference::GetClientId(); + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 1846; $postfields["responsetype"] = "json"; $query_string = ""; foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + $arr = self::makeRequest($url, $query_string); + return $arr["client"]; + } catch (Exception $e) { + Logging::info($e->getMessage()); + } + } + + private static function makeRequest($url, $query_string) { + try { $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, $url); curl_setopt($ch, CURLOPT_POST, 1); @@ -48,8 +188,7 @@ class BillingController extends Zend_Controller_Action { } curl_close($ch); - $arr = json_decode($jsondata, true); - return $arr["client"]; + return json_decode($jsondata, true); } catch (Exception $e) { Logging::info($e->getMessage()); } diff --git a/airtime_mvc/application/forms/BillingPurchase.php b/airtime_mvc/application/forms/BillingClient.php similarity index 85% rename from airtime_mvc/application/forms/BillingPurchase.php rename to airtime_mvc/application/forms/BillingClient.php index dfb0c1201..a56086c9a 100644 --- a/airtime_mvc/application/forms/BillingPurchase.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -1,13 +1,14 @@ setDecorators(array( array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ $client = BillingController::getClientDetails(); + Logging::info($client); $notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator(); $emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator(); @@ -116,14 +117,18 @@ class Application_Form_BillingPurchase extends Zend_Form ->addFilter('StringTrim'); $this->addElement($phonenumber); - //TODO: get list from whmcs - $securityqid = new Zend_Form_Element_Text('securityqid'); + /*$securityqid = new Zend_Form_Element_Select('securityqid'); $securityqid->setLabel(_('Please choose a security question:')) ->setValue($client["securityqid"]) ->setAttrib('class', 'input_text') ->setRequired(true) - ->addValidator($notEmptyValidator) - ->addFilter('StringTrim'); + ->setMultiOptions(array( + "1" => _("What is the name of your favorite childhood friend?"), + "3" => _("What school did you attend for sixth grade?"), + "4" => _("In what city did you meet your spouse/significant other?"), + "5" => _("What street did you live on in third grade?"), + "6" => _("What is the first name of the boy or girl that you first kissed?"), + "7" => _("In what city or town was your first job?"))); $this->addElement($securityqid); $securityqans = new Zend_Form_Element_Text('securityqans'); @@ -133,7 +138,7 @@ class Application_Form_BillingPurchase extends Zend_Form ->setRequired(true) ->addValidator($notEmptyValidator) ->addFilter('StringTrim'); - $this->addElement($securityqans); + $this->addElement($securityqans);*/ foreach ($client["customfields"] as $field) { if ($field["id"] == 7) { @@ -143,7 +148,7 @@ class Application_Form_BillingPurchase extends Zend_Form } } - $vat = new Zend_Form_Element_Text('vat'); + $vat = new Zend_Form_Element_Text('customfield7'); $vat->setLabel(_('VAT/Tax ID (EU only)')) ->setValue($vatvalue) ->setAttrib('class', 'input_text') @@ -152,7 +157,7 @@ class Application_Form_BillingPurchase extends Zend_Form ->addFilter('StringTrim'); $this->addElement($vat); - $subscribe = new Zend_Form_Element_Checkbox('subscribe'); + $subscribe = new Zend_Form_Element_Checkbox('customfield71'); $subscribe->setLabel(_('Subscribe to Sourcefabric newsletter')) ->setValue($subscribevalue) ->setAttrib('class', 'input_text') @@ -161,7 +166,7 @@ class Application_Form_BillingPurchase extends Zend_Form ->addFilter('StringTrim'); $this->addElement($subscribe); - $password = new Zend_Form_Element_Password('whmcspassword'); + $password = new Zend_Form_Element_Password('password2'); $password->setLabel(_('Password:')); $password->setAttrib('class', 'input_text'); $password->setRequired(true); @@ -169,12 +174,17 @@ class Application_Form_BillingPurchase extends Zend_Form $password->addValidator($notEmptyValidator); $this->addElement($password); - $passwordVerify = new Zend_Form_Element_Password('whmcspasswordVerify'); + $passwordVerify = new Zend_Form_Element_Password('password2verify'); $passwordVerify->setLabel(_('Verify Password:')); $passwordVerify->setAttrib('class', 'input_text'); $passwordVerify->setRequired(true); $passwordVerify->addFilter('StringTrim'); $passwordVerify->addValidator($notEmptyValidator); $this->addElement($passwordVerify); + + $submit = new Zend_Form_Element_Submit("submit"); + $submit->setIgnore(true) + ->setLabel(_("Save")); + $this->addElement($submit); } } \ No newline at end of file diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php new file mode 100644 index 000000000..905482943 --- /dev/null +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -0,0 +1,49 @@ + $p) { + $productPrices[$p["name"]] = array( + "monthly" => $p["pricing"]["USD"]["monthly"], + "annualy" => $p["pricing"]["USD"]["annually"] + ); + $productTypes[$p["pid"]] = $p["name"]; + } + + //$currentPlanType = ucfirst(Application_Model_Preference::GetPlanLevel()); + $currentPlanType = "Hobbyist"; + if (($key = array_search($currentPlanType, $productTypes)) !== false) { + unset($productTypes[$key]); + } + + $pid = new Zend_Form_Element_Radio('newproductid'); + $pid->setLabel(_('Plan type:')) + ->setMultiOptions($productTypes) + ->setValue(26); + $this->addElement($pid); + + $billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle'); + $billingcycle->setLabel(_('Billing cycle:')) + ->setMultiOptions(array('monthly' => 'monthly', 'annually' => 'annually')) + ->setValue('monthly'); + $this->addElement($billingcycle); + + $paymentmethod = new Zend_Form_Element_Radio('paymentmethod'); + $paymentmethod->setLabel(_('Payment method:')) + ->setMultiOptions(array( + 'paypal' => _('PayPal'), + 'tco' => _('Credit Card via 2Checkout'))) + ->setValue('paypal'); + $this->addElement($paymentmethod); + + $submit = new Zend_Form_Element_Submit("submit"); + $submit->setIgnore(true) + ->setLabel(_("Save")); + $this->addElement($submit); + } +} diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index ec5008736..6fef87157 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -24,7 +24,7 @@
  • - >Buy Now  + >Upgrade  >escape($this->loggedInAs()); ?> | >
  • diff --git a/airtime_mvc/application/views/scripts/billing/purchase.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml similarity index 74% rename from airtime_mvc/application/views/scripts/billing/purchase.phtml rename to airtime_mvc/application/views/scripts/billing/client.phtml index b5d116fe7..d3850cfc2 100644 --- a/airtime_mvc/application/views/scripts/billing/purchase.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,4 +1,3 @@
    -successMessage ?> form ?>
    \ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml new file mode 100644 index 000000000..d22807b64 --- /dev/null +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -0,0 +1,6 @@ +
    +successMessage ?> +
    Plan Level:
    +form ?> +



    +
    \ No newline at end of file From dc583a6e4148872ef3574e78e1bd1003149b78a1 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 17 Jun 2014 17:07:33 -0400 Subject: [PATCH 04/47] Messing around with AutoAuth for whmcs Client form wasn't getting populated with new values after a save - fixed --- airtime_mvc/application/controllers/BillingController.php | 7 +++++-- airtime_mvc/application/forms/BillingClient.php | 1 - 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 29048f543..a24416a96 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -42,13 +42,15 @@ class BillingController extends Zend_Controller_Action { //$result = $this->makeRequest($url, $query_string); //$invoiceUrl = "https://account.sourcefabric.com/viewinvoice.php?id=".$result["invoiceid"]; + $whmcsurl = "https://account.sourcefabric.com/dologin.php"; $autoauthkey = "MabIttEtkac2"; $timestamp = time(); //whmcs timezone? $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); - $goto="viewinvoice.php?id=5108"; + //$goto="viewinvoice.php?id=5108"; + $goto = "clientarea.php"; $this->_redirect($whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); } else { @@ -85,7 +87,8 @@ class BillingController extends Zend_Controller_Action { foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($url, $query_string); - Logging::info($result); + $form = new Application_Form_BillingClient(); + $this->view->form = $form; } else { $this->view->form = $form; } diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index a56086c9a..c278afc23 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -8,7 +8,6 @@ class Application_Form_BillingClient extends Zend_Form /*$this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ $client = BillingController::getClientDetails(); - Logging::info($client); $notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator(); $emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator(); From 7f6fc7770ac568ee926aa7bc86d3b86f6be76ed1 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Tue, 17 Jun 2014 17:40:55 -0400 Subject: [PATCH 05/47] Added Super Admin role and WHMCS login --- airtime_mvc/application/configs/ACL.php | 5 +- .../controllers/LoginController.php | 1 - .../controllers/UserController.php | 4 +- .../controllers/WhmcsLoginController.php | 176 ++++++++++++++++++ .../controllers/plugins/Acl_plugin.php | 3 +- airtime_mvc/application/forms/AddUser.php | 4 +- airtime_mvc/application/models/Preference.php | 2 +- airtime_mvc/public/js/airtime/user/user.js | 11 +- 8 files changed, 197 insertions(+), 9 deletions(-) create mode 100644 airtime_mvc/application/controllers/WhmcsLoginController.php diff --git a/airtime_mvc/application/configs/ACL.php b/airtime_mvc/application/configs/ACL.php index 842778065..e4b884e6e 100644 --- a/airtime_mvc/application/configs/ACL.php +++ b/airtime_mvc/application/configs/ACL.php @@ -7,13 +7,15 @@ $ccAcl = new Zend_Acl(); $ccAcl->addRole(new Zend_Acl_Role('G')) ->addRole(new Zend_Acl_Role('H'), 'G') ->addRole(new Zend_Acl_Role('P'), 'H') - ->addRole(new Zend_Acl_Role('A'), 'P'); + ->addRole(new Zend_Acl_Role('A'), 'P') + ->addRole(new Zend_Acl_Role('S'), 'A'); $ccAcl->add(new Zend_Acl_Resource('library')) ->add(new Zend_Acl_Resource('index')) ->add(new Zend_Acl_Resource('user')) ->add(new Zend_Acl_Resource('error')) ->add(new Zend_Acl_Resource('login')) + ->add(new Zend_Acl_Resource('whmcs-login')) ->add(new Zend_Acl_Resource('playlist')) ->add(new Zend_Acl_Resource('plupload')) ->add(new Zend_Acl_Resource('schedule')) @@ -34,6 +36,7 @@ $ccAcl->add(new Zend_Acl_Resource('library')) /** Creating permissions */ $ccAcl->allow('G', 'index') ->allow('G', 'login') + ->allow('G', 'whmcs-login') ->allow('G', 'error') ->allow('G', 'user', 'edit-user') ->allow('G', 'showbuilder') diff --git a/airtime_mvc/application/controllers/LoginController.php b/airtime_mvc/application/controllers/LoginController.php index ee4ced5e4..311b000eb 100644 --- a/airtime_mvc/application/controllers/LoginController.php +++ b/airtime_mvc/application/controllers/LoginController.php @@ -16,7 +16,6 @@ class LoginController extends Zend_Controller_Action Application_Model_Locale::configureLocalization($request->getcookie('airtime_locale', 'en_CA')); if (Zend_Auth::getInstance()->hasIdentity()) { - $this->_redirect('Showbuilder'); } diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php index fad0277db..30963ae98 100644 --- a/airtime_mvc/application/controllers/UserController.php +++ b/airtime_mvc/application/controllers/UserController.php @@ -62,7 +62,9 @@ class UserController extends Zend_Controller_Action if ($formData['password'] != "xxxxxx") { $user->setPassword($formData['password']); } - $user->setType($formData['type']); + if (array_key_exists('type', $formData)) { + $user->setType($formData['type']); + } $user->setEmail($formData['email']); $user->setCellPhone($formData['cell_phone']); $user->setSkype($formData['skype']); diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php new file mode 100644 index 000000000..5b05d40c6 --- /dev/null +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -0,0 +1,176 @@ +getRequest(); + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $username = "admin"; + $email = $_POST["email"]; + $password = $_POST["password"]; + + Application_Model_Locale::configureLocalization($request->getcookie('airtime_locale', 'en_CA')); + if (Zend_Auth::getInstance()->hasIdentity()) + { + $this->_redirect('Showbuilder'); + } + + $authAdapter = new WHMCS_Auth_Adapter($username, $email, $password); + + $auth = Zend_Auth::getInstance(); + $result = $auth->authenticate($authAdapter); + if ($result->isValid()) { + //all info about this user from the login table omit only the password + //$userInfo = $authAdapter->getResultRowObject(null, 'password'); + + //the default storage is a session with namespace Zend_Auth + /* + [id] => 1 + [login] => admin + [pass] => hashed password + [type] => A + [first_name] => + [last_name] => + [lastlogin] => + [lastfail] => + [skype_contact] => + [jabber_contact] => + [email] => asdfasdf@asdasdf.com + [cell_phone] => + [login_attempts] => 0 + */ + + //Zend_Auth already does this for us, it's not needed: + //$authStorage = $auth->getStorage(); + //$authStorage->write($result->getIdentity()); //$userInfo); + + //set the user locale in case user changed it in when logging in + //$locale = $form->getValue('locale'); + //Application_Model_Preference::SetUserLocale($locale); + + $this->_redirect('Showbuilder'); + } + else { + echo("Sorry, that username or password was incorrect."); + } + + return; + } +} + +class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { + private $username; + private $password; + private $email; + + function __construct($username, $email, $password) { + $this->username = $username; + $this->password = $password; + $this->email = $email; + $this->identity = null; + } + + function authenticate() { + if (!$this->validateCredentialsWithWHMCS($this->email, $this->password)) + { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); + } + + $identity = array(); + + //TODO: Get identity of the first admin user! + + /* + $identity["id"] = 1; + $identity["type"] = "S"; + $identity["login"] = $this->username; //admin"; + $identity["email"] = $this->email;*/ + $identity = $this->getSuperAdminIdentity(); + if (is_null($identity)) { + Logging::error("No super admin user found"); + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null); + } + $identity = (object)$identity; //Convert the array into an stdClass object + + try { + return new Zend_Auth_Result(Zend_Auth_Result::SUCCESS, $identity); + } catch (Exception $e) { + // exception occured + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE, null); + } + } + + private function getSuperAdminIdentity() + { + $firstSuperAdminUser = CcSubjsQuery::create() + ->filterByDbType('S') + ->orderByDbId() + ->findOne(); + if (!$firstSuperAdminUser) { + //If there's no super admin users, get the first regular admin user! + $firstSuperAdminUser = CcSubjsQuery::create() + ->filterByDbType('A') + ->orderByDbId() + ->findOne(); + if (!$firstSuperAdminUser) { + return null; + } + } + $identity["id"] = $firstSuperAdminUser->getDbId(); + $identity["type"] = "S"; //Super Admin + $identity["login"] = $firstSuperAdminUser->getDbLogin(); + $identity["email"] = $this->email; + return $identity; + } + + private function validateCredentialsWithWHMCS($email, $password) + { + $client_postfields = array(); + $client_postfields["username"] = $_SERVER['WHMCS_USERNAME']; //WHMCS API username + $client_postfields["password"] = md5($_SERVER['WHMCS_PASSWORD']); //WHMCS API password + $client_postfields["action"] ="validatelogin"; + $client_postfields["responsetype"] = "json"; + + $client_postfields["email"] = $email; + $client_postfields["password2"] = $password; + + $query_string = ""; + foreach ($client_postfields as $k => $v) $query_string .= "$k=".urlencode($v)."&"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, WHMCS_API_URL); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_FAILONERROR, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + $jsondata = curl_exec($ch); + if (curl_error($ch)) { + die(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); + //die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch)); + } + curl_close($ch); + + $arr = json_decode($jsondata, true); # Decode JSON String + + if ($arr["result"] != "success") { + return false; + } + + return true; + } +} \ No newline at end of file diff --git a/airtime_mvc/application/controllers/plugins/Acl_plugin.php b/airtime_mvc/application/controllers/plugins/Acl_plugin.php index c5dc4b9f4..bfacdeb09 100644 --- a/airtime_mvc/application/controllers/plugins/Acl_plugin.php +++ b/airtime_mvc/application/controllers/plugins/Acl_plugin.php @@ -117,8 +117,7 @@ class Zend_Controller_Plugin_Acl extends Zend_Controller_Plugin_Abstract return; } - if (in_array($controller, array("api", "auth", "locale", "upgrade"))) { - + if (in_array($controller, array("api", "auth", "locale", "upgrade", 'whmcs-login'))) { $this->setRoleName("G"); } elseif (!Zend_Auth::getInstance()->hasIdentity()) { diff --git a/airtime_mvc/application/forms/AddUser.php b/airtime_mvc/application/forms/AddUser.php index 1d3835ae7..09d5216c1 100644 --- a/airtime_mvc/application/forms/AddUser.php +++ b/airtime_mvc/application/forms/AddUser.php @@ -95,9 +95,9 @@ class Application_Form_AddUser extends Zend_Form "G" => _("Guest"), "H" => _("DJ"), "P" => _("Program Manager"), - "A" => _("Admin") + "A" => _("Admin"), )); - $select->setRequired(true); + $select->setRequired(false); $this->addElement($select); $saveBtn = new Zend_Form_Element_Button('save_user'); diff --git a/airtime_mvc/application/models/Preference.php b/airtime_mvc/application/models/Preference.php index cfed23b1c..24d61e066 100644 --- a/airtime_mvc/application/models/Preference.php +++ b/airtime_mvc/application/models/Preference.php @@ -6,7 +6,7 @@ class Application_Model_Preference { private static function getUserId() - { + { //pass in true so the check is made with the autoloader //we need this check because saas calls this function from outside Zend if (!class_exists("Zend_Auth", true) || !Zend_Auth::getInstance()->hasIdentity()) { diff --git a/airtime_mvc/public/js/airtime/user/user.js b/airtime_mvc/public/js/airtime/user/user.js index 71f9eed6e..3473e1acf 100644 --- a/airtime_mvc/public/js/airtime/user/user.js +++ b/airtime_mvc/public/js/airtime/user/user.js @@ -23,6 +23,12 @@ function populateForm(entries){ $('#password').val(""); $('#passwordVerify').val(""); } + if (entries.login === 'admin') + { + $('#type').attr('disabled', '1'); + } else { + $('#type').removeAttr('disabled'); + } } function rowClickCallback(row_id){ @@ -57,6 +63,9 @@ function rowCallback( nRow, aData, iDisplayIndex ){ } else if ( aData['type'] == "P" ) { $('td:eq(3)', nRow).html( $.i18n._('Program Manager') ); + } else if ( aData['type'] == "S" ) + { + $('td:eq(3)', nRow).html( $.i18n._('Super Admin') ); } return nRow; @@ -183,7 +192,7 @@ $(document).ready(function() { var newUser = {login:"", first_name:"", last_name:"", type:"G", id:""}; - $('#add_user_button').live('click', function(){populateForm(newUser)}); + $('#add_user_button').live('click', function(){populateForm(newUser);}); $('#save_user').live('click', function(){ var data = $('#user_form').serialize(); From 70a7410b1a0e1d7c5f64cb5d9caa87253469d0fe Mon Sep 17 00:00:00 2001 From: drigato Date: Wed, 18 Jun 2014 10:42:50 -0400 Subject: [PATCH 06/47] Remove key --- airtime_mvc/application/controllers/BillingController.php | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index a24416a96..044926734 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -44,13 +44,12 @@ class BillingController extends Zend_Controller_Action { //$invoiceUrl = "https://account.sourcefabric.com/viewinvoice.php?id=".$result["invoiceid"]; $whmcsurl = "https://account.sourcefabric.com/dologin.php"; - $autoauthkey = "MabIttEtkac2"; + $autoauthkey = ""; $timestamp = time(); //whmcs timezone? $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); - //$goto="viewinvoice.php?id=5108"; - $goto = "clientarea.php"; + $goto="viewinvoice.php?id=5108"; $this->_redirect($whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); } else { From b12d88ddf79f0a53e36c0af267791e0972f29a07 Mon Sep 17 00:00:00 2001 From: drigato Date: Wed, 18 Jun 2014 11:03:26 -0400 Subject: [PATCH 07/47] Fix a whoopsies --- .../application/controllers/BillingController.php | 10 ---------- 1 file changed, 10 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 044926734..8085c7d12 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -19,8 +19,6 @@ class BillingController extends Zend_Controller_Action { $password = $_SERVER["WHMCS_PASSWORD"]; $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ $url = "https://account.sourcefabric.com/includes/api.php"; - $username = "api_access"; - $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; @@ -69,8 +67,6 @@ class BillingController extends Zend_Controller_Action { $password = $_SERVER["WHMCS_PASSWORD"]; $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ $url = "https://account.sourcefabric.com/includes/api.php"; - $username = "api_access"; - $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; @@ -101,8 +97,6 @@ class BillingController extends Zend_Controller_Action { $password = $_SERVER["WHMCS_PASSWORD"]; $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ $url = "https://account.sourcefabric.com/includes/api.php"; - $username = "api_access"; - $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; @@ -126,8 +120,6 @@ class BillingController extends Zend_Controller_Action { $password = $_SERVER["WHMCS_PASSWORD"]; $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ $url = "https://account.sourcefabric.com/includes/api.php"; - $username = "api_access"; - $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; @@ -151,8 +143,6 @@ class BillingController extends Zend_Controller_Action { $password = $_SERVER["WHMCS_PASSWORD"]; $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ $url = "https://account.sourcefabric.com/includes/api.php"; - $username = "api_access"; - $password = "raditional69203"; $postfields = array(); $postfields["username"] = $username; From 971e81756c05263389c0c6fab9ee940516299cd4 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 18 Jun 2014 18:27:16 -0400 Subject: [PATCH 08/47] Added ability to login directly with WHMCS credentials (on Airtime login screen) --- .../controllers/LoginController.php | 24 ++++-- .../controllers/WhmcsLoginController.php | 77 ++++++++++++++++++- 2 files changed, 95 insertions(+), 6 deletions(-) diff --git a/airtime_mvc/application/controllers/LoginController.php b/airtime_mvc/application/controllers/LoginController.php index 311b000eb..f5c6a01d0 100644 --- a/airtime_mvc/application/controllers/LoginController.php +++ b/airtime_mvc/application/controllers/LoginController.php @@ -1,5 +1,7 @@ _redirect('Showbuilder'); } else { - $message = _("Wrong username or password provided. Please try again."); - Application_Model_Subjects::increaseLoginAttempts($username); - Application_Model_LoginAttempts::increaseAttempts($_SERVER['REMOTE_ADDR']); - $form = new Application_Form_Login(); - $error = true; + $email = $form->getValue('username'); + $authAdapter = new WHMCS_Auth_Adapter("admin", $email, $password); + $auth = Zend_Auth::getInstance(); + $result = $auth->authenticate($authAdapter); + if ($result->isValid()) { + //set the user locale in case user changed it in when logging in + Application_Model_Preference::SetUserLocale($locale); + + $this->_redirect('Showbuilder'); + } + else { + $message = _("Wrong username or password provided. Please try again."); + Application_Model_Subjects::increaseLoginAttempts($username); + Application_Model_LoginAttempts::increaseAttempts($_SERVER['REMOTE_ADDR']); + $form = new Application_Form_Login(); + $error = true; + } } } } diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index 5b05d40c6..44d866be6 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -17,7 +17,7 @@ class WhmcsLoginController extends Zend_Controller_Action $this->view->layout()->disableLayout(); $this->_helper->viewRenderer->setNoRender(true); - $username = "admin"; + $username = "admin"; //This is just for appearance in your session. It shows up in the corner of the Airtime UI. $email = $_POST["email"]; $password = $_POST["password"]; @@ -87,6 +87,10 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); } + if (!$this->verifyClientSubdomainOwnership()) + { + return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); + } $identity = array(); @@ -173,4 +177,75 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { return true; } + + function verifyClientSubdomainOwnership() + { + $client_postfields = array(); + $client_postfields["username"] = $_SERVER['WHMCS_USERNAME']; + $client_postfields["password"] = md5($_SERVER['WHMCS_PASSWORD']); + $client_postfields["action"] ="getclientsproducts"; + $client_postfields["responsetype"] = "json"; + + $client_postfields["clientid"] = Application_Model_Preference::GetClientId(); + //$client_postfields["stats"] = "true"; + + $query_string = ""; + foreach ($client_postfields as $k => $v) $query_string .= "$k=".urlencode($v)."&"; + + $ch = curl_init(); + curl_setopt($ch, CURLOPT_URL, WHMCS_API_URL); + curl_setopt($ch, CURLOPT_POST, 1); + curl_setopt($ch, CURLOPT_TIMEOUT, 30); + curl_setopt($ch, CURLOPT_FAILONERROR, 1); + curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); + curl_setopt($ch, CURLOPT_POSTFIELDS, $query_string); + curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0); + curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0); + $jsondata = curl_exec($ch); + if (curl_error($ch)) { + die(curl_getinfo($ch, CURLINFO_EFFECTIVE_URL)); + //die("Connection Error: ".curl_errno($ch).' - '.curl_error($ch)); + } + curl_close($ch); + + $arr = json_decode($jsondata, true); # Decode JSON String + //$client_id = $arr["clientid"]; + //print_r($arr); + if ($arr["result"] != "success") { + die("Sorry, that email address or password was incorrect."); + } + + $doesAirtimeProductExist = false; + $isAirtimeAccountSuspended = true; + $airtimeProduct = null; + + foreach ($arr["products"] as $product) + { + if (strpos($product[0]["groupname"], "Airtime") === FALSE) + { + //Ignore non-Airtime products + continue; + } + else + { + if ($product[0]["status"] === "Active") { + $airtimeProduct = $product[0]; + $subdomain = ''; + + foreach ($airtimeProduct['customfields']['customfield'] as $customField) + { + if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME) + { + $subdomain = $customField['value']; + if ($subdomain . ".airtime.pro" === $_SERVER['SERVER_NAME']) + { + return true; + } + } + } + } + } + } + return false; + } } \ No newline at end of file From 81699b3c6527afc7b39511af15be1421c8155a7f Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 18 Jun 2014 18:42:55 -0400 Subject: [PATCH 09/47] Fixed missing constant --- airtime_mvc/application/controllers/WhmcsLoginController.php | 1 + 1 file changed, 1 insertion(+) diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index 44d866be6..d1f3705de 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -1,6 +1,7 @@ Date: Wed, 18 Jun 2014 20:20:08 -0400 Subject: [PATCH 10/47] Fixed bad client ID / subdomain check in WhmcsLoginController --- .../controllers/WhmcsLoginController.php | 25 +++++++++++++------ 1 file changed, 17 insertions(+), 8 deletions(-) diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index d1f3705de..abb31019f 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -84,11 +84,12 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { } function authenticate() { - if (!$this->validateCredentialsWithWHMCS($this->email, $this->password)) + list($credentialsValid, $clientId) = $this->validateCredentialsWithWHMCS($this->email, $this->password)) + if (!$credentialsValid) { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); } - if (!$this->verifyClientSubdomainOwnership()) + if (!$this->verifyClientSubdomainOwnership($clientId)) { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); } @@ -139,7 +140,8 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { $identity["email"] = $this->email; return $identity; } - + + //Returns an array! Read the code carefully: private function validateCredentialsWithWHMCS($email, $password) { $client_postfields = array(); @@ -173,21 +175,28 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { $arr = json_decode($jsondata, true); # Decode JSON String if ($arr["result"] != "success") { - return false; + return array(false, -1); } + $clientId = $arr["userid"]; - return true; + return array(true, $clientId); } - function verifyClientSubdomainOwnership() + function verifyClientSubdomainOwnership($clientId) { + //Do a quick safety check to ensure the client ID we're authenticating + //matches up to the owner of this instance. + if ($clientId != Application_Model_Preference::GetClientId()) + { + return false; + } $client_postfields = array(); $client_postfields["username"] = $_SERVER['WHMCS_USERNAME']; $client_postfields["password"] = md5($_SERVER['WHMCS_PASSWORD']); $client_postfields["action"] ="getclientsproducts"; $client_postfields["responsetype"] = "json"; - $client_postfields["clientid"] = Application_Model_Preference::GetClientId(); + $client_postfields["clientid"] = $clientId; //$client_postfields["stats"] = "true"; $query_string = ""; @@ -238,7 +247,7 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME) { $subdomain = $customField['value']; - if ($subdomain . ".airtime.pro" === $_SERVER['SERVER_NAME']) + if (($subdomain . ".airtime.pro") === $_SERVER['SERVER_NAME']) { return true; } From 29e9182fcdbed355b6374bc19e12734893d8efe0 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 18 Jun 2014 20:22:13 -0400 Subject: [PATCH 11/47] Fixed syntax error... grumble grumble --- airtime_mvc/application/controllers/WhmcsLoginController.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index abb31019f..0f0e327de 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -84,7 +84,7 @@ class WHMCS_Auth_Adapter implements Zend_Auth_Adapter_Interface { } function authenticate() { - list($credentialsValid, $clientId) = $this->validateCredentialsWithWHMCS($this->email, $this->password)) + list($credentialsValid, $clientId) = $this->validateCredentialsWithWHMCS($this->email, $this->password); if (!$credentialsValid) { return new Zend_Auth_Result(Zend_Auth_Result::FAILURE_CREDENTIAL_INVALID, null); From 540b9167a1d4c76835b7ba611191abf52af474ae Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 19 Jun 2014 07:10:30 -0400 Subject: [PATCH 12/47] Invoice action --- .../controllers/BillingController.php | 41 +++++++++++-------- 1 file changed, 25 insertions(+), 16 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 8085c7d12..59d8f21a0 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -14,11 +14,10 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); - /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ - $url = "https://account.sourcefabric.com/includes/api.php"; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; $postfields = array(); $postfields["username"] = $username; @@ -42,11 +41,12 @@ class BillingController extends Zend_Controller_Action { //$invoiceUrl = "https://account.sourcefabric.com/viewinvoice.php?id=".$result["invoiceid"]; $whmcsurl = "https://account.sourcefabric.com/dologin.php"; - $autoauthkey = ""; + $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; $timestamp = time(); //whmcs timezone? $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); + //$goto = "viewinvoice.php?id=".$result["invoiceid"]; $goto="viewinvoice.php?id=5108"; $this->_redirect($whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); @@ -62,11 +62,10 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); - /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ - $url = "https://account.sourcefabric.com/includes/api.php"; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; $postfields = array(); $postfields["username"] = $username; @@ -89,14 +88,26 @@ class BillingController extends Zend_Controller_Action { } } + public function invoiceAction() + { + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $username = $_SERVER["WHMCS_USERNAME"]; + $password = $_SERVER["WHMCS_PASSWORD"]; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + + $postfields = array(); + $postfields["username"] = $username; + $postfields["password"] = md5($password); + $postfields["action"] = "updateclient"; + } + //TODO: this does not return a service id. why? private static function getClientInstanceId() { - /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ - $url = "https://account.sourcefabric.com/includes/api.php"; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; $postfields = array(); $postfields["username"] = $username; @@ -115,11 +126,10 @@ class BillingController extends Zend_Controller_Action { public static function getProducts() { - /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ - $url = "https://account.sourcefabric.com/includes/api.php"; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; $postfields = array(); $postfields["username"] = $username; @@ -138,11 +148,10 @@ class BillingController extends Zend_Controller_Action { public static function getClientDetails() { try { - /*$accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; + $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey;*/ - $url = "https://account.sourcefabric.com/includes/api.php"; + $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; $postfields = array(); $postfields["username"] = $username; From 40f2796972037b4fb7fe52477e1118f479f29be8 Mon Sep 17 00:00:00 2001 From: drigato Date: Thu, 19 Jun 2014 16:55:01 -0400 Subject: [PATCH 13/47] Created an invoice view Some refactoring Some validation --- .../controllers/BillingController.php | 111 ++++++++++++------ .../application/forms/BillingClient.php | 12 +- .../forms/BillingUpgradeDowngrade.php | 7 +- .../views/scripts/billing/invoice.phtml | 0 .../views/scripts/billing/invoices.phtml | 9 ++ 5 files changed, 94 insertions(+), 45 deletions(-) create mode 100644 airtime_mvc/application/views/scripts/billing/invoice.phtml create mode 100644 airtime_mvc/application/views/scripts/billing/invoices.phtml diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 59d8f21a0..189aa28f6 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -12,49 +12,66 @@ class BillingController extends Zend_Controller_Action { $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); if ($request->isPost()) { + //$formData = $form->getValues(); $formData = $request->getPost(); - - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; - - $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); - $postfields["action"] = "upgradeproduct"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; - //TODO: do not hardcode - //$postfields["serviceid"] = self::getClientInstanceId(); - $postfields["serviceid"] = "1678"; - $postfields["type"] = "product"; - $postfields["newproductid"] = $formData["newproductid"]; - $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; - $postfields["paymentmethod"] = $formData["paymentmethod"]; - $postfields["responsetype"] = "json"; - - $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - - //$result = $this->makeRequest($url, $query_string); - //$invoiceUrl = "https://account.sourcefabric.com/viewinvoice.php?id=".$result["invoiceid"]; - - $whmcsurl = "https://account.sourcefabric.com/dologin.php"; - $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; - $timestamp = time(); //whmcs timezone? - $client = self::getClientDetails(); - $email = $client["email"]; - $hash = sha1($email.$timestamp.$autoauthkey); - //$goto = "viewinvoice.php?id=".$result["invoiceid"]; - $goto="viewinvoice.php?id=5108"; - $this->_redirect($whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); - + if ($form->isValid($formData)) { + + $credentials = self::getAPICredentials(); + + $postfields = array(); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); + $postfields["action"] = "upgradeproduct"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 1846; + //TODO: do not hardcode + //$postfields["serviceid"] = self::getClientInstanceId(); + $postfields["serviceid"] = "1678"; + $postfields["type"] = "product"; + $postfields["newproductid"] = $formData["newproductid"]; + $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; + $postfields["paymentmethod"] = $formData["paymentmethod"]; + $postfields["responsetype"] = "json"; + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + //update client info + + + //$result = $this->makeRequest($credentials["url"], $query_string); + //self::viewInvoice($result["invoiceid"]); + self::viewInvoice(5108); + } else { + $this->view->form = $form; + } } else { $this->view->form = $form; } } + private static function getAPICredentials() + { + return array( + "access_key" => $_SERVER["WHMCS_ACCESS_KEY"], + "username" => $_SERVER["WHMCS_USERNAME"], + "password" => $_SERVER["WHMCS_PASSWORD"], + "url" => "https://account.sourcefabric.com/includes/api.php?accesskey=".$_SERVER["WHMCS_ACCESS_KEY"], + ); + } + + private static function viewInvoice($invoice_id) + { + $whmcsurl = "https://account.sourcefabric.com/dologin.php"; + $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; + $timestamp = time(); //whmcs timezone? + $client = self::getClientDetails(); + $email = $client["email"]; + $hash = sha1($email.$timestamp.$autoauthkey); + $goto = "viewinvoice.php?id=".$invoice_id; + header("Location: ".$whmcsurl."?email=$email×tamp=$timestamp&hash=$hash&goto=$goto"); + } + public function clientAction() { $request = $this->getRequest(); @@ -88,7 +105,7 @@ class BillingController extends Zend_Controller_Action { } } - public function invoiceAction() + public function invoicesAction() { $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; $username = $_SERVER["WHMCS_USERNAME"]; @@ -98,7 +115,23 @@ class BillingController extends Zend_Controller_Action { $postfields = array(); $postfields["username"] = $username; $postfields["password"] = md5($password); - $postfields["action"] = "updateclient"; + $postfields["action"] = "getinvoices"; + $postfields["responsetype"] = "json"; + $postfields["userid"] = 1846; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $result = self::makeRequest($url, $query_string); + $this->view->invoices = $result["invoices"]["invoice"]; + } + + public function invoiceAction() + { + $request = $this->getRequest(); + $invoice_id = $request->getParam('invoiceid'); + self::viewInvoice($invoice_id); } //TODO: this does not return a service id. why? diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index c278afc23..2b889a52e 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -116,7 +116,7 @@ class Application_Form_BillingClient extends Zend_Form ->addFilter('StringTrim'); $this->addElement($phonenumber); - /*$securityqid = new Zend_Form_Element_Select('securityqid'); + $securityqid = new Zend_Form_Element_Select('securityqid'); $securityqid->setLabel(_('Please choose a security question:')) ->setValue($client["securityqid"]) ->setAttrib('class', 'input_text') @@ -137,7 +137,7 @@ class Application_Form_BillingClient extends Zend_Form ->setRequired(true) ->addValidator($notEmptyValidator) ->addFilter('StringTrim'); - $this->addElement($securityqans);*/ + $this->addElement($securityqans); foreach ($client["customfields"] as $field) { if ($field["id"] == 7) { @@ -151,8 +151,8 @@ class Application_Form_BillingClient extends Zend_Form $vat->setLabel(_('VAT/Tax ID (EU only)')) ->setValue($vatvalue) ->setAttrib('class', 'input_text') - ->setRequired(true) - ->addValidator($notEmptyValidator) + //->setRequired(true) + //->addValidator($notEmptyValidator) ->addFilter('StringTrim'); $this->addElement($vat); @@ -168,6 +168,7 @@ class Application_Form_BillingClient extends Zend_Form $password = new Zend_Form_Element_Password('password2'); $password->setLabel(_('Password:')); $password->setAttrib('class', 'input_text'); + $password->setValue("xxxxxx"); $password->setRequired(true); $password->addFilter('StringTrim'); $password->addValidator($notEmptyValidator); @@ -176,8 +177,11 @@ class Application_Form_BillingClient extends Zend_Form $passwordVerify = new Zend_Form_Element_Password('password2verify'); $passwordVerify->setLabel(_('Verify Password:')); $passwordVerify->setAttrib('class', 'input_text'); + $passwordVerify->setValue("xxxxxx"); $passwordVerify->setRequired(true); $passwordVerify->addFilter('StringTrim'); + //$passwordVerify->addValidator($notEmptyValidator); + $passwordVerify->addValidator('Identical', false, array('token' => 'password2')); $passwordVerify->addValidator($notEmptyValidator); $this->addElement($passwordVerify); diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php index 905482943..8a7d8a084 100644 --- a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -41,9 +41,12 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form ->setValue('paypal'); $this->addElement($paymentmethod); - $submit = new Zend_Form_Element_Submit("submit"); + /*$submit = new Zend_Form_Element_Submit("submit"); $submit->setIgnore(true) ->setLabel(_("Save")); - $this->addElement($submit); + $this->addElement($submit);*/ + + $client = new Application_Form_BillingClient(); + $this->addSubForm($client, 'billing_client_info'); } } diff --git a/airtime_mvc/application/views/scripts/billing/invoice.phtml b/airtime_mvc/application/views/scripts/billing/invoice.phtml new file mode 100644 index 000000000..e69de29bb diff --git a/airtime_mvc/application/views/scripts/billing/invoices.phtml b/airtime_mvc/application/views/scripts/billing/invoices.phtml new file mode 100644 index 000000000..ed1f13a74 --- /dev/null +++ b/airtime_mvc/application/views/scripts/billing/invoices.phtml @@ -0,0 +1,9 @@ +
    +invoices as $invoice) {?> + + + +
    \ No newline at end of file From faa12c80652233766f5c9ae83441109cda93872d Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Fri, 20 Jun 2014 13:36:06 -0400 Subject: [PATCH 14/47] Super Admin edit page points to billing now * Also prevent super admin from being deleted --- airtime_mvc/application/configs/constants.php | 1 + .../application/controllers/UserController.php | 10 +++++++++- airtime_mvc/application/models/User.php | 7 ++++++- .../views/scripts/form/edit-user.phtml | 2 +- .../views/scripts/user/add-user.phtml | 3 +++ airtime_mvc/public/js/airtime/user/user.js | 18 ++++++++++++------ 6 files changed, 32 insertions(+), 9 deletions(-) diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 34f8cab41..9e2563d0f 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -41,6 +41,7 @@ define('UI_MDATA_VALUE_FORMAT_STREAM' , 'live stream'); //User types define('UTYPE_HOST' , 'H'); define('UTYPE_ADMIN' , 'A'); +define('UTYPE_SUPERADMIN' , 'S'); define('UTYPE_GUEST' , 'G'); define('UTYPE_PROGRAM_MANAGER' , 'P'); diff --git a/airtime_mvc/application/controllers/UserController.php b/airtime_mvc/application/controllers/UserController.php index 30963ae98..f28917e9e 100644 --- a/airtime_mvc/application/controllers/UserController.php +++ b/airtime_mvc/application/controllers/UserController.php @@ -63,7 +63,9 @@ class UserController extends Zend_Controller_Action $user->setPassword($formData['password']); } if (array_key_exists('type', $formData)) { - $user->setType($formData['type']); + if ($formData['type'] != UTYPE_SUPERADMIN) { //Don't allow any other user to be promoted to Super Admin + $user->setType($formData['type']); + } } $user->setEmail($formData['email']); $user->setCellPhone($formData['cell_phone']); @@ -189,6 +191,12 @@ class UserController extends Zend_Controller_Action } $user = new Application_Model_User($delId); + + // Don't allow super admins to be deleted. + if ($user->isSuperAdmin()) + { + return; + } # Take care of the user's files by either assigning them to somebody # or deleting them all diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php index 8a1008577..dc1cd49c8 100644 --- a/airtime_mvc/application/models/User.php +++ b/airtime_mvc/application/models/User.php @@ -49,7 +49,12 @@ class Application_Model_User { return $this->isUserType(UTYPE_ADMIN); } - + + public function isSuperAdmin() + { + return $this->isUserType(UTYPE_SUPERADMIN); + } + public function canSchedule($p_showId) { $type = $this->getType(); diff --git a/airtime_mvc/application/views/scripts/form/edit-user.phtml b/airtime_mvc/application/views/scripts/form/edit-user.phtml index 1cf55dba4..b26d87499 100644 --- a/airtime_mvc/application/views/scripts/form/edit-user.phtml +++ b/airtime_mvc/application/views/scripts/form/edit-user.phtml @@ -157,7 +157,7 @@
- +
diff --git a/airtime_mvc/application/views/scripts/user/add-user.phtml b/airtime_mvc/application/views/scripts/user/add-user.phtml index a85744a46..b58607a89 100644 --- a/airtime_mvc/application/views/scripts/user/add-user.phtml +++ b/airtime_mvc/application/views/scripts/user/add-user.phtml @@ -26,6 +26,9 @@ +
successMessage ?>
diff --git a/airtime_mvc/public/js/airtime/user/user.js b/airtime_mvc/public/js/airtime/user/user.js index 3473e1acf..f3a414b66 100644 --- a/airtime_mvc/public/js/airtime/user/user.js +++ b/airtime_mvc/public/js/airtime/user/user.js @@ -4,6 +4,17 @@ function populateForm(entries){ $('.errors').remove(); $('.success').remove(); + if (entries.type === 'S') + { + $("#user_details").hide(); + $("#user_details_superadmin_message").show(); + $('#type').attr('disabled', '1'); + } else { + $("#user_details").show(); + $("#user_details_superadmin_message").hide(); + $('#type').removeAttr('disabled'); + } + $('#user_id').val(entries.id); $('#login').val(entries.login); $('#first_name').val(entries.first_name); @@ -23,12 +34,6 @@ function populateForm(entries){ $('#password').val(""); $('#passwordVerify').val(""); } - if (entries.login === 'admin') - { - $('#type').attr('disabled', '1'); - } else { - $('#type').removeAttr('disabled'); - } } function rowClickCallback(row_id){ @@ -66,6 +71,7 @@ function rowCallback( nRow, aData, iDisplayIndex ){ } else if ( aData['type'] == "S" ) { $('td:eq(3)', nRow).html( $.i18n._('Super Admin') ); + $('td:eq(4)', nRow).html(""); //Disable deleting the super admin } return nRow; From 01bf2883e5d59d298da846d54388a3163ce3eebf Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 20 Jun 2014 15:00:28 -0400 Subject: [PATCH 15/47] Save client info on upgrade --- .../controllers/BillingController.php | 34 +++++++++++++++---- .../views/scripts/billing/upgrade.phtml | 4 ++- 2 files changed, 30 insertions(+), 8 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 189aa28f6..91a06b80d 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -15,7 +15,6 @@ class BillingController extends Zend_Controller_Action { //$formData = $form->getValues(); $formData = $request->getPost(); if ($form->isValid($formData)) { - $credentials = self::getAPICredentials(); $postfields = array(); @@ -33,15 +32,36 @@ class BillingController extends Zend_Controller_Action { $postfields["paymentmethod"] = $formData["paymentmethod"]; $postfields["responsetype"] = "json"; - $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + $upgrade_query_string = ""; + foreach ($postfields AS $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info + $clientfields = array(); + $clientfields["username"] = $credentials["username"]; + $clientfields["password"] = md5($credentials["password"]); + $clientfields["action"] = "updateclient"; + //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); + $clientfields["clientid"] = 1846; + $clientfields["responsetype"] = "json"; + unset($formData["newproductid"]); + unset($formData["newproductbillingcycle"]); + unset($formData["paymentmethod"]); + unset($formData["action"]); + $clientfields = array_merge($clientfields, $formData); + unset($clientfields["password2verify"]); + unset($clientfields["submit"]); + $client_query_string = ""; + foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; - - //$result = $this->makeRequest($credentials["url"], $query_string); - //self::viewInvoice($result["invoiceid"]); - self::viewInvoice(5108); + $result = $this->makeRequest($credentials["url"], $client_query_string); + if ($result["result"] == "error") { + $this->view->errorMessage = "An error occurred and we could not upgrade your account. Please contact support for help"; + $this->view->form = $form; + } else { + //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); + //self::viewInvoice($result["invoiceid"]); + self::viewInvoice(5108); + } } else { $this->view->form = $form; } diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index d22807b64..6d40d3b0d 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -1,5 +1,7 @@
-successMessage ?> +errorMessage)) {?> +
errorMessage ?>
+
Plan Level:
form ?>



From 1e1dc1dd03daabaa6a9dd6654a0eccab8e93df13 Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 20 Jun 2014 16:31:26 -0400 Subject: [PATCH 16/47] Validation Refactoring --- .../controllers/BillingController.php | 117 ++++++++++-------- .../views/scripts/billing/client.phtml | 5 + 2 files changed, 71 insertions(+), 51 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 91a06b80d..50af88b03 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -55,7 +55,7 @@ class BillingController extends Zend_Controller_Action { $result = $this->makeRequest($credentials["url"], $client_query_string); if ($result["result"] == "error") { - $this->view->errorMessage = "An error occurred and we could not upgrade your account. Please contact support for help"; + $this->setErrorMessage(); $this->view->form = $form; } else { //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); @@ -70,10 +70,27 @@ class BillingController extends Zend_Controller_Action { } } + private function setErrorMessage($msg=null) + { + if (!is_null($msg)) { + $this->view->errorMessage = $msg; + } else { + $this->view->errorMessage = "An error occurred and we could not update your account. Please contact support for help."; + } + } + + private function setSuccessMessage($msg=null) + { + if (!is_null($msg)) { + $this->view->successMessage = $msg; + } else { + $this->view->successMessage = "Your account has been updated."; + } + } + private static function getAPICredentials() { return array( - "access_key" => $_SERVER["WHMCS_ACCESS_KEY"], "username" => $_SERVER["WHMCS_USERNAME"], "password" => $_SERVER["WHMCS_PASSWORD"], "url" => "https://account.sourcefabric.com/includes/api.php?accesskey=".$_SERVER["WHMCS_ACCESS_KEY"], @@ -98,28 +115,37 @@ class BillingController extends Zend_Controller_Action { $form = new Application_Form_BillingClient(); if ($request->isPost()) { $formData = $request->getPost(); + if ($form->isValid($formData)) { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; - - $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); - $postfields["action"] = "updateclient"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; - $postfields = array_merge($postfields, $formData); - unset($postfields["password2verify"]); - unset($postfields["submit"]); - - $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - - $result = $this->makeRequest($url, $query_string); - $form = new Application_Form_BillingClient(); - $this->view->form = $form; + $credentials = self::getAPICredentials(); + + $postfields = array(); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); + $postfields["action"] = "updateclient"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = 18460000000; + $postfields["responsetype"] = "json"; + $postfields = array_merge($postfields, $formData); + unset($postfields["password2verify"]); + unset($postfields["submit"]); + + $query_string = ""; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + $result = $this->makeRequest($credentials["url"], $query_string); + + if ($result["result"] == "error") { + $this->setErrorMessage(); + } else { + $form = new Application_Form_BillingClient(); + $this->setSuccessMessage(); + } + + $this->view->form = $form; + } else { + $this->view->form = $form; + } } else { $this->view->form = $form; } @@ -127,14 +153,11 @@ class BillingController extends Zend_Controller_Action { public function invoicesAction() { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + $credentials = self::getAPICredentials(); $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getinvoices"; $postfields["responsetype"] = "json"; $postfields["userid"] = 1846; @@ -143,7 +166,7 @@ class BillingController extends Zend_Controller_Action { $query_string = ""; foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - $result = self::makeRequest($url, $query_string); + $result = self::makeRequest($credentials["url"], $query_string); $this->view->invoices = $result["invoices"]["invoice"]; } @@ -157,14 +180,11 @@ class BillingController extends Zend_Controller_Action { //TODO: this does not return a service id. why? private static function getClientInstanceId() { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + $credentials = self::getAPICredentials(); $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsproducts"; $postfields["responsetype"] = "json"; $postfields["clientid"] = 1846; @@ -173,42 +193,37 @@ class BillingController extends Zend_Controller_Action { $query_string = ""; foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - $result = self::makeRequest($url, $query_string); + $result = self::makeRequest($credentials["url"], $query_string); Logging::info($result); } public static function getProducts() { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + $credentials = self::getAPICredentials(); $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getproducts"; $postfields["responsetype"] = "json"; + //gid is the Airtime product group id on whmcs $postfields["gid"] = "15"; $query_string = ""; foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - $result = self::makeRequest($url, $query_string); + $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; } public static function getClientDetails() { try { - $accessKey = $_SERVER["WHMCS_ACCESS_KEY"]; - $username = $_SERVER["WHMCS_USERNAME"]; - $password = $_SERVER["WHMCS_PASSWORD"]; - $url = "https://account.sourcefabric.com/includes/api.php?accesskey=" . $accessKey; + $credentials = self::getAPICredentials(); $postfields = array(); - $postfields["username"] = $username; - $postfields["password"] = md5($password); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsdetails"; $postfields["stats"] = true; //$postfields["clientid"] = Application_Model_Preference::GetClientId(); @@ -218,7 +233,7 @@ class BillingController extends Zend_Controller_Action { $query_string = ""; foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; - $arr = self::makeRequest($url, $query_string); + $arr = self::makeRequest($credentials["url"], $query_string); return $arr["client"]; } catch (Exception $e) { Logging::info($e->getMessage()); diff --git a/airtime_mvc/application/views/scripts/billing/client.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml index d3850cfc2..980288c81 100644 --- a/airtime_mvc/application/views/scripts/billing/client.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,3 +1,8 @@
+errorMessage)) {?> +
errorMessage ?>
+successMessage)) {?> +
successMessage ?>
+ form ?>
\ No newline at end of file From 4179123ce04a50264de10e4466efb672b2ed4ca7 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Fri, 20 Jun 2014 16:41:48 -0400 Subject: [PATCH 17/47] Set up CORS for microsite autologin after signup --- .../application/controllers/LoginController.php | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/airtime_mvc/application/controllers/LoginController.php b/airtime_mvc/application/controllers/LoginController.php index f5c6a01d0..0ddb17d2d 100644 --- a/airtime_mvc/application/controllers/LoginController.php +++ b/airtime_mvc/application/controllers/LoginController.php @@ -15,6 +15,16 @@ class LoginController extends Zend_Controller_Action $request = $this->getRequest(); + //Allow AJAX requests from www.airtime.pro. We use this to automatically login users + //after they sign up from the microsite. + $response = $this->getResponse()->setHeader('Access-Control-Allow-Origin', '*'); + $origin = $request->getHeader('Origin'); + if (($origin != "") && (!in_array($origin, array("http://www.airtime.pro", "https://www.airtime.pro")))) + { + //Don't allow CORS from other domains to prevent XSS. + throw new Zend_Controller_Action_Exception('Forbidden', 403); + } + Application_Model_Locale::configureLocalization($request->getcookie('airtime_locale', 'en_CA')); if (Zend_Auth::getInstance()->hasIdentity()) { From f6a4a9d0d09c79f5076d9779e83191420fcaecca Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 20 Jun 2014 16:54:05 -0400 Subject: [PATCH 18/47] Removed invalid client id - for testing purposes --- airtime_mvc/application/controllers/BillingController.php | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 50af88b03..3747b2ee7 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -54,6 +54,7 @@ class BillingController extends Zend_Controller_Action { foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $client_query_string); + Logging::info($result); if ($result["result"] == "error") { $this->setErrorMessage(); $this->view->form = $form; @@ -124,7 +125,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 18460000000; + $postfields["clientid"] = 1846; $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); From 5d0ea2d01540e3aeb0618be28d2866c882925db6 Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 20 Jun 2014 17:25:05 -0400 Subject: [PATCH 19/47] Add billing section to main menu --- airtime_mvc/application/configs/ACL.php | 2 +- .../application/configs/navigation.php | 28 +++++++++++++++++++ .../application/layouts/scripts/layout.phtml | 2 +- 3 files changed, 30 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/application/configs/ACL.php b/airtime_mvc/application/configs/ACL.php index fe0c5b425..ff65a9192 100644 --- a/airtime_mvc/application/configs/ACL.php +++ b/airtime_mvc/application/configs/ACL.php @@ -59,7 +59,7 @@ $ccAcl->allow('G', 'index') ->allow('A', 'user') ->allow('A', 'systemstatus') ->allow('A', 'preference') - ->allow('A', 'billing'); + ->allow('S', 'billing'); $aclPlugin = new Zend_Controller_Plugin_Acl($ccAcl); diff --git a/airtime_mvc/application/configs/navigation.php b/airtime_mvc/application/configs/navigation.php index f3149f146..87314135a 100644 --- a/airtime_mvc/application/configs/navigation.php +++ b/airtime_mvc/application/configs/navigation.php @@ -134,6 +134,34 @@ $pages = array( 'resource' => 'dashboard' ) ) + ), + array( + 'label' => _('Billing'), + 'uri' => '#', + 'resource' => 'billing', + 'pages' => array( + array( + 'label' => _('Account Details'), + 'module' => 'default', + 'controller' => 'billing', + 'action' => 'client', + 'resource' => 'billing' + ), + array( + 'label' => _('Account Plans'), + 'module' => 'default', + 'controller' => 'billing', + 'action' => 'upgrade', + 'resource' => 'billing' + ), + array( + 'label' => _('View Invocices'), + 'module' => 'default', + 'controller' => 'billing', + 'action' => 'invoices', + 'resource' => 'billing' + ) + ) ) ); diff --git a/airtime_mvc/application/layouts/scripts/layout.phtml b/airtime_mvc/application/layouts/scripts/layout.phtml index 6fef87157..ce67531c1 100644 --- a/airtime_mvc/application/layouts/scripts/layout.phtml +++ b/airtime_mvc/application/layouts/scripts/layout.phtml @@ -24,7 +24,7 @@
  • - >Upgrade  + >escape($this->loggedInAs()); ?> | >
  • From 25e4036d2f422fd5161a5488535274c478a74ad8 Mon Sep 17 00:00:00 2001 From: drigato Date: Fri, 20 Jun 2014 17:29:56 -0400 Subject: [PATCH 20/47] typo --- airtime_mvc/application/configs/navigation.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/configs/navigation.php b/airtime_mvc/application/configs/navigation.php index 87314135a..5b7e4e049 100644 --- a/airtime_mvc/application/configs/navigation.php +++ b/airtime_mvc/application/configs/navigation.php @@ -155,7 +155,7 @@ $pages = array( 'resource' => 'billing' ), array( - 'label' => _('View Invocices'), + 'label' => _('View Invoices'), 'module' => 'default', 'controller' => 'billing', 'action' => 'invoices', From 0eab0c609b94b6dee2cb24e416a7c2e86c67cb0b Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Fri, 20 Jun 2014 17:43:20 -0400 Subject: [PATCH 21/47] Permissions fixes for Super Admin users --- airtime_mvc/application/controllers/LibraryController.php | 8 ++++---- .../application/controllers/ScheduleController.php | 8 ++++---- .../application/controllers/WebstreamController.php | 2 +- airtime_mvc/application/models/Block.php | 2 +- airtime_mvc/application/models/Playlist.php | 2 +- airtime_mvc/application/models/StoredFile.php | 2 +- airtime_mvc/application/models/User.php | 5 +++-- airtime_mvc/application/models/airtime/CcSubjs.php | 2 +- 8 files changed, 16 insertions(+), 15 deletions(-) diff --git a/airtime_mvc/application/controllers/LibraryController.php b/airtime_mvc/application/controllers/LibraryController.php index 41ab24eaa..42699e9bc 100644 --- a/airtime_mvc/application/controllers/LibraryController.php +++ b/airtime_mvc/application/controllers/LibraryController.php @@ -83,7 +83,7 @@ class LibraryController extends Zend_Controller_Action $obj = new $objInfo['className']($obj_sess->id); $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); if ($isAdminOrPM || $obj->getCreatorId() == $userInfo->id) { $this->view->obj = $obj; @@ -186,7 +186,7 @@ class LibraryController extends Zend_Controller_Action //Open a jPlayer window and play the audio clip. $menu["play"] = array("name"=> _("Preview"), "icon" => "play", "disabled" => false); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $obj_sess = new Zend_Session_Namespace(UI_PLAYLISTCONTROLLER_OBJ_SESSNAME); @@ -302,7 +302,7 @@ class LibraryController extends Zend_Controller_Action $mediaItems = $this->_getParam('media', null); $user = Application_Model_User::getCurrentUser(); - //$isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + //$isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $files = array(); $playlists = array(); @@ -418,7 +418,7 @@ class LibraryController extends Zend_Controller_Action public function editFileMdAction() { $user = Application_Model_User::getCurrentUser(); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $request = $this->getRequest(); diff --git a/airtime_mvc/application/controllers/ScheduleController.php b/airtime_mvc/application/controllers/ScheduleController.php index a430e15e5..ec385f167 100644 --- a/airtime_mvc/application/controllers/ScheduleController.php +++ b/airtime_mvc/application/controllers/ScheduleController.php @@ -104,7 +104,7 @@ class ScheduleController extends Zend_Controller_Action $this->createShowFormAction(true); $user = Application_Model_User::getCurrentUser(); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { $this->view->preloadShowForm = true; } @@ -133,7 +133,7 @@ class ScheduleController extends Zend_Controller_Action { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $editable = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $editable = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); $calendar_interval = Application_Model_Preference::GetCalendarTimeScale(); Logging::info($calendar_interval); @@ -191,7 +191,7 @@ class ScheduleController extends Zend_Controller_Action $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { try { $show = new Application_Model_Show($showId); } catch (Exception $e) { @@ -586,7 +586,7 @@ class ScheduleController extends Zend_Controller_Action { $user = Application_Model_User::getCurrentUser(); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { $id = $this->_getParam('id'); try { diff --git a/airtime_mvc/application/controllers/WebstreamController.php b/airtime_mvc/application/controllers/WebstreamController.php index 8eb9a2ac5..1d94923c3 100644 --- a/airtime_mvc/application/controllers/WebstreamController.php +++ b/airtime_mvc/application/controllers/WebstreamController.php @@ -88,7 +88,7 @@ class WebstreamController extends Zend_Controller_Action public function isAuthorized($webstream_id) { $user = Application_Model_User::getCurrentUser(); - if ($user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { + if ($user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER))) { return true; } diff --git a/airtime_mvc/application/models/Block.php b/airtime_mvc/application/models/Block.php index babef06a5..8ea3593b1 100644 --- a/airtime_mvc/application/models/Block.php +++ b/airtime_mvc/application/models/Block.php @@ -1038,7 +1038,7 @@ SQL; { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); // get only the files from the blocks // we are about to delete diff --git a/airtime_mvc/application/models/Playlist.php b/airtime_mvc/application/models/Playlist.php index 7a7573d2a..90baaf621 100644 --- a/airtime_mvc/application/models/Playlist.php +++ b/airtime_mvc/application/models/Playlist.php @@ -987,7 +987,7 @@ SQL; { $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); // get only the files from the playlists // we are about to delete diff --git a/airtime_mvc/application/models/StoredFile.php b/airtime_mvc/application/models/StoredFile.php index e30851e26..8031ba5c4 100644 --- a/airtime_mvc/application/models/StoredFile.php +++ b/airtime_mvc/application/models/StoredFile.php @@ -379,7 +379,7 @@ SQL; $userInfo = Zend_Auth::getInstance()->getStorage()->read(); $user = new Application_Model_User($userInfo->id); - $isAdminOrPM = $user->isUserType(array(UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); + $isAdminOrPM = $user->isUserType(array(UTYPE_SUPERADMIN, UTYPE_ADMIN, UTYPE_PROGRAM_MANAGER)); if (!$isAdminOrPM && $this->getFileOwnerId() != $user->getId()) { throw new FileNoPermissionException(); } diff --git a/airtime_mvc/application/models/User.php b/airtime_mvc/application/models/User.php index dc1cd49c8..14bb9491d 100644 --- a/airtime_mvc/application/models/User.php +++ b/airtime_mvc/application/models/User.php @@ -60,8 +60,9 @@ class Application_Model_User $type = $this->getType(); $result = false; - if ($type === UTYPE_ADMIN || - $type === UTYPE_PROGRAM_MANAGER || + if ($this->isAdmin() || + $this->isSuperAdmin() || + $this->isPM() || self::isHostOfShow($p_showId)) { $result = true; } diff --git a/airtime_mvc/application/models/airtime/CcSubjs.php b/airtime_mvc/application/models/airtime/CcSubjs.php index 78fd56d9e..9cba6165e 100644 --- a/airtime_mvc/application/models/airtime/CcSubjs.php +++ b/airtime_mvc/application/models/airtime/CcSubjs.php @@ -15,7 +15,7 @@ class CcSubjs extends BaseCcSubjs { public function isAdminOrPM() { - return $this->type === UTYPE_ADMIN || $this->type === UTYPE_PROGRAM_MANAGER; + return $this->type === UTYPE_ADMIN === UTYPE_SUPERADMIN || $this->type === UTYPE_ADMIN || $this->type === UTYPE_PROGRAM_MANAGER; } public function isHostOfShow($showId) From 9a84bdfda1cdffec6255191ac4fe1a624228041d Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Fri, 20 Jun 2014 17:44:30 -0400 Subject: [PATCH 22/47] Fixed syntax error --- airtime_mvc/application/models/airtime/CcSubjs.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/models/airtime/CcSubjs.php b/airtime_mvc/application/models/airtime/CcSubjs.php index 9cba6165e..7fe6289f1 100644 --- a/airtime_mvc/application/models/airtime/CcSubjs.php +++ b/airtime_mvc/application/models/airtime/CcSubjs.php @@ -15,7 +15,7 @@ class CcSubjs extends BaseCcSubjs { public function isAdminOrPM() { - return $this->type === UTYPE_ADMIN === UTYPE_SUPERADMIN || $this->type === UTYPE_ADMIN || $this->type === UTYPE_PROGRAM_MANAGER; + return $this->type === UTYPE_SUPERADMIN || $this->type === UTYPE_ADMIN || $this->type === UTYPE_PROGRAM_MANAGER; } public function isHostOfShow($showId) From 18e7707d8fde752737dce121e46766aa9a59bca3 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Fri, 20 Jun 2014 18:10:59 -0400 Subject: [PATCH 23/47] Trying to fix my commit again --- .../public/js/airtime/schedule/full-calendar-functions.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js index a178159ca..01b1096d5 100644 --- a/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js +++ b/airtime_mvc/public/js/airtime/schedule/full-calendar-functions.js @@ -35,7 +35,7 @@ function makeTimeStamp(date){ function dayClick(date, allDay, jsEvent, view){ // The show from will be preloaded if the user is admin or program manager. // Hence, if the user if DJ then it won't open anything. - if(userType == "A" || userType == "P"){ + if(userType == "S" || userType == "A" || userType == "P"){ var now, today, selected, chosenDate, chosenTime; now = adjustDateToServerDate(new Date(), serverTimezoneOffset); @@ -163,7 +163,7 @@ function viewDisplay( view ) { if(($("#add-show-form").length == 1) && ($("#add-show-form").css('display')=='none') && ($('.fc-header-left > span').length == 5)) { //userType is defined in bootstrap.php, and is derived from the currently logged in user. - if(userType == "A" || userType == "P"){ + if(userType == "S" || userType == "A" || userType == "P"){ makeAddShowButton(); } } From 6302e3b3359afcfc1108735b1645bf33ca06c33d Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Mon, 23 Jun 2014 13:24:28 -0400 Subject: [PATCH 24/47] Fix CORS with Chrome --- .../application/controllers/LoginController.php | 10 +++++++++- 1 file changed, 9 insertions(+), 1 deletion(-) diff --git a/airtime_mvc/application/controllers/LoginController.php b/airtime_mvc/application/controllers/LoginController.php index 0ddb17d2d..7c18f5dc6 100644 --- a/airtime_mvc/application/controllers/LoginController.php +++ b/airtime_mvc/application/controllers/LoginController.php @@ -17,9 +17,17 @@ class LoginController extends Zend_Controller_Action //Allow AJAX requests from www.airtime.pro. We use this to automatically login users //after they sign up from the microsite. + //Chrome sends the Origin header for all requests, so we whitelist the webserver's hostname as well. $response = $this->getResponse()->setHeader('Access-Control-Allow-Origin', '*'); $origin = $request->getHeader('Origin'); - if (($origin != "") && (!in_array($origin, array("http://www.airtime.pro", "https://www.airtime.pro")))) + if (($origin != "") && + (!in_array($origin, + array("http://www.airtime.pro", + "https://www.airtime.pro", + "http://" . $_SERVER['SERVER_NAME'], + "https://" . $_SERVER['SERVER_NAME'] + )) + )) { //Don't allow CORS from other domains to prevent XSS. throw new Zend_Controller_Action_Exception('Forbidden', 403); From 806525e28c287e63e24e0b5e6bb0e1f8a3757364 Mon Sep 17 00:00:00 2001 From: drigato Date: Mon, 23 Jun 2014 17:04:23 -0400 Subject: [PATCH 25/47] Fetch service id from whmcs api for upgrades --- .../controllers/BillingController.php | 58 +++++++++++++------ 1 file changed, 40 insertions(+), 18 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 3747b2ee7..34590a3e1 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -21,11 +21,12 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - //TODO: do not hardcode - //$postfields["serviceid"] = self::getClientInstanceId(); - $postfields["serviceid"] = "1678"; + + $postfields["serviceid"] = self::getClientServiceId(); + $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -33,15 +34,17 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $upgrade_query_string = ""; - foreach ($postfields AS $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; + //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; + $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); @@ -51,17 +54,22 @@ class BillingController extends Zend_Controller_Action { unset($clientfields["password2verify"]); unset($clientfields["submit"]); $client_query_string = ""; - foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; + foreach ($clientfields as $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $client_query_string); - Logging::info($result); + if ($result["result"] == "error") { $this->setErrorMessage(); $this->view->form = $form; } else { - //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); - //self::viewInvoice($result["invoiceid"]); - self::viewInvoice(5108); + $result = $this->makeRequest($credentials["url"], $upgrade_query_string); + if ($result["result"] == "error") { + Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed. - ".$result["message"]); + $this->setErrorMessage(); + $this->view->form = $form; + } else { + self::viewInvoice($result["invoiceid"]); + } } } else { $this->view->form = $form; @@ -102,7 +110,7 @@ class BillingController extends Zend_Controller_Action { { $whmcsurl = "https://account.sourcefabric.com/dologin.php"; $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; - $timestamp = time(); //whmcs timezone? + $timestamp = time(); $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); @@ -124,15 +132,17 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; + //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; + $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $query_string); @@ -165,7 +175,7 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); $this->view->invoices = $result["invoices"]["invoice"]; @@ -178,9 +188,10 @@ class BillingController extends Zend_Controller_Action { self::viewInvoice($invoice_id); } - //TODO: this does not return a service id. why? - private static function getClientInstanceId() + private static function getClientServiceId() { + $service_id = null; + $credentials = self::getAPICredentials(); $postfields = array(); @@ -192,10 +203,21 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); - Logging::info($result); + if (empty($result["products"])) { + Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed - Could not find service id"); + } else { + foreach ($result["products"]["product"] as $product) { + if (array_key_exists("groupname", $product) && $product["groupname"] == "Airtime") { + $service_id = $product["id"]; + } + break; + } + } + + return $service_id; } public static function getProducts() @@ -211,7 +233,7 @@ class BillingController extends Zend_Controller_Action { $postfields["gid"] = "15"; $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; @@ -232,7 +254,7 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $query_string = ""; - foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $arr = self::makeRequest($credentials["url"], $query_string); return $arr["client"]; From 73724bdd042f2fe9c4be2f90c36f6a4292c86054 Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 12:46:11 -0400 Subject: [PATCH 26/47] Custom fields were not saving --- .../application/controllers/BillingController.php | 7 +++++-- airtime_mvc/application/forms/BillingClient.php | 10 ++++++---- 2 files changed, 11 insertions(+), 6 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 34590a3e1..92592ccab 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -125,13 +125,16 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { - + $credentials = self::getAPICredentials(); $postfields = array(); $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; + + $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); + unset($formData["customfields"]); //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; @@ -140,7 +143,7 @@ class BillingController extends Zend_Controller_Action { $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); - + $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index 2b889a52e..d0cb60729 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -140,15 +140,16 @@ class Application_Form_BillingClient extends Zend_Form $this->addElement($securityqans); foreach ($client["customfields"] as $field) { - if ($field["id"] == 7) { + if ($field["id"] == "7") { $vatvalue = $field["value"]; - } elseif ($field["id"] == 71) { + } elseif ($field["id"] == "71") { $subscribevalue = $field["value"]; } } - $vat = new Zend_Form_Element_Text('customfield7'); + $vat = new Zend_Form_Element_Text("7"); $vat->setLabel(_('VAT/Tax ID (EU only)')) + ->setBelongsTo('customfields') ->setValue($vatvalue) ->setAttrib('class', 'input_text') //->setRequired(true) @@ -156,9 +157,10 @@ class Application_Form_BillingClient extends Zend_Form ->addFilter('StringTrim'); $this->addElement($vat); - $subscribe = new Zend_Form_Element_Checkbox('customfield71'); + $subscribe = new Zend_Form_Element_Checkbox('71'); $subscribe->setLabel(_('Subscribe to Sourcefabric newsletter')) ->setValue($subscribevalue) + ->setBelongsTo('customfields') ->setAttrib('class', 'input_text') ->setRequired(true) ->addValidator($notEmptyValidator) From 5d69ba5f91cb6d0da5675d6ac1a885c9dd5abf5a Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 12:51:02 -0400 Subject: [PATCH 27/47] Custom fields were not saving --- airtime_mvc/application/controllers/BillingController.php | 3 +++ 1 file changed, 3 insertions(+) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 92592ccab..4ade2cd6f 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -45,6 +45,9 @@ class BillingController extends Zend_Controller_Action { //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; + $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); + unset($formData["customfields"]); + $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); From 8c205924233de8efa4ea86c991fb122993494583 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Tue, 24 Jun 2014 15:52:43 -0400 Subject: [PATCH 28/47] Start of form customization for billing --- .../controllers/BillingController.php | 72 ++++++----------- .../application/forms/BillingClient.php | 2 +- .../forms/BillingUpgradeDowngrade.php | 11 ++- .../views/scripts/billing/upgrade.phtml | 80 ++++++++++++++++++- airtime_mvc/public/css/billing.css | 33 ++++++++ 5 files changed, 144 insertions(+), 54 deletions(-) create mode 100644 airtime_mvc/public/css/billing.css diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 4ade2cd6f..6cb18550d 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -9,6 +9,10 @@ class BillingController extends Zend_Controller_Action { public function upgradeAction() { + $CC_CONFIG = Config::getConfig(); + $baseUrl = Application_Common_OsPath::getBaseDir(); + $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); if ($request->isPost()) { @@ -21,12 +25,11 @@ class BillingController extends Zend_Controller_Action { $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - - $postfields["serviceid"] = self::getClientServiceId(); - + //TODO: do not hardcode + //$postfields["serviceid"] = self::getClientInstanceId(); + $postfields["serviceid"] = "1678"; $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -34,20 +37,15 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $upgrade_query_string = ""; - foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; - //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["clientid"] = 1846; - - $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); - unset($formData["customfields"]); - $clientfields["responsetype"] = "json"; unset($formData["newproductid"]); unset($formData["newproductbillingcycle"]); @@ -57,22 +55,17 @@ class BillingController extends Zend_Controller_Action { unset($clientfields["password2verify"]); unset($clientfields["submit"]); $client_query_string = ""; - foreach ($clientfields as $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; + foreach ($clientfields AS $k=>$v) $client_query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $client_query_string); - + Logging::info($result); if ($result["result"] == "error") { $this->setErrorMessage(); $this->view->form = $form; } else { - $result = $this->makeRequest($credentials["url"], $upgrade_query_string); - if ($result["result"] == "error") { - Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed. - ".$result["message"]); - $this->setErrorMessage(); - $this->view->form = $form; - } else { - self::viewInvoice($result["invoiceid"]); - } + //$result = $this->makeRequest($credentials["url"], $upgrade_query_string); + //self::viewInvoice($result["invoiceid"]); + self::viewInvoice(5108); } } else { $this->view->form = $form; @@ -113,7 +106,7 @@ class BillingController extends Zend_Controller_Action { { $whmcsurl = "https://account.sourcefabric.com/dologin.php"; $autoauthkey = $_SERVER["WHMCS_AUTOAUTH_KEY"]; - $timestamp = time(); + $timestamp = time(); //whmcs timezone? $client = self::getClientDetails(); $email = $client["email"]; $hash = sha1($email.$timestamp.$autoauthkey); @@ -128,27 +121,22 @@ class BillingController extends Zend_Controller_Action { if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { - + $credentials = self::getAPICredentials(); $postfields = array(); $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "updateclient"; - - $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); - unset($formData["customfields"]); - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["clientid"] = 1846; - $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); unset($postfields["password2verify"]); unset($postfields["submit"]); - + $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = $this->makeRequest($credentials["url"], $query_string); @@ -181,7 +169,7 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); $this->view->invoices = $result["invoices"]["invoice"]; @@ -194,10 +182,9 @@ class BillingController extends Zend_Controller_Action { self::viewInvoice($invoice_id); } - private static function getClientServiceId() + //TODO: this does not return a service id. why? + private static function getClientInstanceId() { - $service_id = null; - $credentials = self::getAPICredentials(); $postfields = array(); @@ -209,21 +196,10 @@ class BillingController extends Zend_Controller_Action { //$postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); - if (empty($result["products"])) { - Logging::info($_SERVER['HTTP_HOST']." - Account upgrade failed - Could not find service id"); - } else { - foreach ($result["products"]["product"] as $product) { - if (array_key_exists("groupname", $product) && $product["groupname"] == "Airtime") { - $service_id = $product["id"]; - } - break; - } - } - - return $service_id; + Logging::info($result); } public static function getProducts() @@ -239,7 +215,7 @@ class BillingController extends Zend_Controller_Action { $postfields["gid"] = "15"; $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; @@ -260,7 +236,7 @@ class BillingController extends Zend_Controller_Action { $postfields["responsetype"] = "json"; $query_string = ""; - foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $arr = self::makeRequest($credentials["url"], $query_string); return $arr["client"]; diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index d0cb60729..8ade507f2 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -4,7 +4,7 @@ require_once 'Zend/Locale.php'; class Application_Form_BillingClient extends Zend_Form { public function init() - { + { /*$this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ $client = BillingController::getClientDetails(); diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php index 8a7d8a084..10f2b8be7 100644 --- a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -6,7 +6,7 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $productPrices = array(); $productTypes = array(); $products = BillingController::getProducts(); - + foreach ($products as $k => $p) { $productPrices[$p["name"]] = array( "monthly" => $p["pricing"]["USD"]["monthly"], @@ -18,23 +18,26 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form //$currentPlanType = ucfirst(Application_Model_Preference::GetPlanLevel()); $currentPlanType = "Hobbyist"; if (($key = array_search($currentPlanType, $productTypes)) !== false) { - unset($productTypes[$key]); + //unset($productTypes[$key]); } $pid = new Zend_Form_Element_Radio('newproductid'); $pid->setLabel(_('Plan type:')) ->setMultiOptions($productTypes) + ->setRequired(true) ->setValue(26); - $this->addElement($pid); - + $this->addElement($pid); + $billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle'); $billingcycle->setLabel(_('Billing cycle:')) ->setMultiOptions(array('monthly' => 'monthly', 'annually' => 'annually')) + ->setRequired(true) ->setValue('monthly'); $this->addElement($billingcycle); $paymentmethod = new Zend_Form_Element_Radio('paymentmethod'); $paymentmethod->setLabel(_('Payment method:')) + ->setRequired(true) ->setMultiOptions(array( 'paypal' => _('PayPal'), 'tco' => _('Credit Card via 2Checkout'))) diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index 6d40d3b0d..c111765b5 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -1,8 +1,86 @@ +form; + $form->setAttrib('id', 'upgrade-downgrade'); +?>
    +

    Account Plans

    +
    +pricing grid here +
    errorMessage)) {?>
    errorMessage ?>
    Plan Level:
    -form ?> + + + +
    + +
    + newproductid ?> +
    +
    + newproductbillingcycle ?> +
    +
    + paymentmethod ?> +
    + +
    + getSubform("billing_client_info") ?> +
    + firstname?> +
    +
    + lastname?> +
    +
    + companyname?> +
    +
    + email?> +
    +
    + address1?> +
    +
    + address2?> +
    +
    + city?> +
    +
    + state?> +
    +
    + postcode?> +
    +
    + country?> +
    +
    + phonenumber?> +
    +
    + securityqid?> +
    +
    + securityqans?> +
    +
    + getElement("7"); ?> +
    +
    + getElement("71"); ?> +
    +
    + password2?> +
    +
    + password2verify?> +
    + +




    \ No newline at end of file diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css new file mode 100644 index 000000000..da9ab49be --- /dev/null +++ b/airtime_mvc/public/css/billing.css @@ -0,0 +1,33 @@ +@CHARSET "UTF-8"; + +#upgrade-downgrade dl +{ + width: 300px; +} + +#upgrade-downgrade dt, #upgrade-downgrade dd +{ + margin: 0px; +} + +#upgrade-downgrade dd +{ + margin-bottom: 10px; +} + +#plantype +{ + float: left; + +} + +#billingcycle +{ + float: left; +} + +#paymentmethod +{ + float: left; + +} \ No newline at end of file From bfb5631105600311caf8f9e412ebf3c693b51f0c Mon Sep 17 00:00:00 2001 From: drigato Date: Tue, 24 Jun 2014 16:23:23 -0400 Subject: [PATCH 29/47] Removed hardcoded client ids. Added a function that calculates vat and adds it to an invoice --- .../controllers/BillingController.php | 74 +++++++++++++++---- 1 file changed, 61 insertions(+), 13 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index 4ade2cd6f..5406ffee5 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -12,7 +12,15 @@ class BillingController extends Zend_Controller_Action { $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); if ($request->isPost()) { - //$formData = $form->getValues(); + + /* + * TODO: determine if VAT shoould be charged on the invoice or not. + * We'll need to check if a VAT number was supplied in the form and if so, + * validate it somehow. We'll also need to make sure the country given is + * in the EU + */ + $apply_vat = false; + $formData = $request->getPost(); if ($form->isValid($formData)) { $credentials = self::getAPICredentials(); @@ -22,8 +30,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "upgradeproduct"; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["serviceid"] = self::getClientServiceId(); @@ -37,13 +44,13 @@ class BillingController extends Zend_Controller_Action { foreach ($postfields as $k=>$v) $upgrade_query_string .= "$k=".urlencode($v)."&"; //update client info + $clientfields = array(); $clientfields["username"] = $credentials["username"]; $clientfields["password"] = md5($credentials["password"]); $clientfields["action"] = "updateclient"; - //$clientfields["clientid"] = Application_Model_Preference::GetClientId(); - $clientfields["clientid"] = 1846; + $clientfields["clientid"] = Application_Model_Preference::GetClientId(); $clientfields["customfields"] = base64_encode(serialize($formData["customfields"])); unset($formData["customfields"]); @@ -71,6 +78,9 @@ class BillingController extends Zend_Controller_Action { $this->setErrorMessage(); $this->view->form = $form; } else { + if ($apply_vat) { + $this->addVatToInvoice($result["invoiceid"]); + } self::viewInvoice($result["invoiceid"]); } } @@ -82,6 +92,47 @@ class BillingController extends Zend_Controller_Action { } } + private function addVatToInvoice($invoice_id) + { + $credentials = self::getAPICredentials(); + + //First we need to get the invoice details: sub total, and total + //so we can calcuate the amount of VAT to add + $invoicefields = array(); + $invoicefields["username"] = $credentials["username"]; + $invoicefields["password"] = md5($credentials["password"]); + $invoicefields["action"] = "getinvoice"; + $invoicefields["invoiceid"] = $invoice_id; + $invoicefields["responsetype"] = "json"; + + $invoice_query_string = ""; + foreach ($invoicefields as $k=>$v) $invoice_query_string .= "$k=".urlencode($v)."&"; + + //TODO: error checking + $result = $this->makeRequest($credentials["url"], $invoice_query_string); + + $vat_rate = 19.00; + $vat_amount = $result["subtotal"] * ($vat_rate/100); + $invoice_total = $result["total"] + $vat_amount; + + //Second, update the invoice with the VAT amount and updated total + $postfields = array(); + $postfields["username"] = $credentials["username"]; + $postfields["password"] = md5($credentials["password"]); + $postfields["action"] = "updateinvoice"; + $postfields["invoiceid"] = $invoice_id; + $postfields["tax"] = "$vat_amount"; + $postfields["taxrate"] = "$vat_rate"; + $postfields["total"] = "$invoice_total"; + $postfields["responsetype"] = "json"; + + $query_string = ""; + foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; + + //TODO: error checking + $result = $this->makeRequest($credentials["url"], $query_string); + } + private function setErrorMessage($msg=null) { if (!is_null($msg)) { @@ -139,8 +190,7 @@ class BillingController extends Zend_Controller_Action { $postfields["customfields"] = base64_encode(serialize($formData["customfields"])); unset($formData["customfields"]); - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["responsetype"] = "json"; $postfields = array_merge($postfields, $formData); @@ -177,13 +227,13 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getinvoices"; $postfields["responsetype"] = "json"; - $postfields["userid"] = 1846; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; $result = self::makeRequest($credentials["url"], $query_string); + $this->view->invoices = $result["invoices"]["invoice"]; } @@ -205,8 +255,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsproducts"; $postfields["responsetype"] = "json"; - $postfields["clientid"] = 1846; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $query_string = ""; foreach ($postfields as $k=>$v) $query_string .= "$k=".urlencode($v)."&"; @@ -255,8 +304,7 @@ class BillingController extends Zend_Controller_Action { $postfields["password"] = md5($credentials["password"]); $postfields["action"] = "getclientsdetails"; $postfields["stats"] = true; - //$postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["clientid"] = 1846; + $postfields["clientid"] = Application_Model_Preference::GetClientId(); $postfields["responsetype"] = "json"; $query_string = ""; From d92e5197e1afc92c599531b38d15a40087f340e2 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 25 Jun 2014 18:58:54 -0400 Subject: [PATCH 30/47] Design and overhaul of Account Plans screen * Basically working now except for VAT calculation * Includes pricing grid, basic total calculation * Revamped layout * Implemented getting the service ID in BillingController.php --- airtime_mvc/application/Bootstrap.php | 1 + airtime_mvc/application/configs/constants.php | 6 + .../controllers/BillingController.php | 71 +++++- .../controllers/WhmcsLoginController.php | 3 - .../application/forms/BillingClient.php | 4 +- .../forms/BillingUpgradeDowngrade.php | 18 +- .../views/scripts/billing/client.phtml | 1 + .../views/scripts/billing/upgrade.phtml | 225 +++++++++++++++--- .../views/scripts/partialviews/trialBox.phtml | 2 +- airtime_mvc/public/css/billing.css | 113 ++++++++- 10 files changed, 393 insertions(+), 51 deletions(-) diff --git a/airtime_mvc/application/Bootstrap.php b/airtime_mvc/application/Bootstrap.php index fc9f6c7e4..d66c680c5 100644 --- a/airtime_mvc/application/Bootstrap.php +++ b/airtime_mvc/application/Bootstrap.php @@ -14,6 +14,7 @@ require_once "DateHelper.php"; require_once "OsPath.php"; require_once "Database.php"; require_once "Timezone.php"; +require_once "Auth.php"; require_once __DIR__.'/forms/helpers/ValidationTypes.php'; require_once __DIR__.'/controllers/plugins/RabbitMqPlugin.php'; require_once __DIR__.'/controllers/plugins/Maintenance.php'; diff --git a/airtime_mvc/application/configs/constants.php b/airtime_mvc/application/configs/constants.php index 9e2563d0f..69ce78d19 100644 --- a/airtime_mvc/application/configs/constants.php +++ b/airtime_mvc/application/configs/constants.php @@ -64,3 +64,9 @@ define('UI_BLOCK_SESSNAME', 'BLOCK');*/ define('SOUNDCLOUD_NOT_UPLOADED_YET' , -1); define('SOUNDCLOUD_PROGRESS' , -2); define('SOUNDCLOUD_ERROR' , -3); + + +//WHMCS integration +define("WHMCS_API_URL", "https://account.sourcefabric.com/includes/api.php"); +define("SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME", "Choose your domain"); + diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index ffe90234f..e8aeea0f5 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -12,6 +12,7 @@ class BillingController extends Zend_Controller_Action { $CC_CONFIG = Config::getConfig(); $baseUrl = Application_Common_OsPath::getBaseDir(); $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + BillingController::ensureClientIdIsValid(); $request = $this->getRequest(); $form = new Application_Form_BillingUpgradeDowngrade(); @@ -35,7 +36,7 @@ class BillingController extends Zend_Controller_Action { $postfields["action"] = "upgradeproduct"; $postfields["clientid"] = Application_Model_Preference::GetClientId(); - $postfields["serviceid"] = self::getClientServiceId(); + $postfields["serviceid"] = self::getClientInstanceId(); $postfields["type"] = "product"; $postfields["newproductid"] = $formData["newproductid"]; $postfields["newproductbillingcycle"] = $formData["newproductbillingcycle"]; @@ -175,6 +176,7 @@ class BillingController extends Zend_Controller_Action { { $request = $this->getRequest(); $form = new Application_Form_BillingClient(); + BillingController::ensureClientIdIsValid(); if ($request->isPost()) { $formData = $request->getPost(); if ($form->isValid($formData)) { @@ -218,6 +220,7 @@ class BillingController extends Zend_Controller_Action { public function invoicesAction() { + BillingController::ensureClientIdIsValid(); $credentials = self::getAPICredentials(); $postfields = array(); @@ -237,6 +240,7 @@ class BillingController extends Zend_Controller_Action { public function invoiceAction() { + BillingController::ensureClientIdIsValid(); $request = $this->getRequest(); $invoice_id = $request->getParam('invoiceid'); self::viewInvoice($invoice_id); @@ -259,10 +263,52 @@ class BillingController extends Zend_Controller_Action { $result = self::makeRequest($credentials["url"], $query_string); Logging::info($result); + + if ($_SERVER['SERVER_NAME'] == "airtime.localhost") { + return "1384"; + } + //This code must run on airtime.pro for it to work... it's trying to match + //the server's hostname with the client subdomain. + foreach ($result["products"] as $product) + { + if (strpos($product[0]["groupname"], "Airtime") === FALSE) + { + //Ignore non-Airtime products + continue; + } + else + { + if ($product[0]["status"] === "Active") { + $airtimeProduct = $product[0]; + $subdomain = ''; + + foreach ($airtimeProduct['customfields']['customfield'] as $customField) + { + if ($customField['name'] === SUBDOMAIN_WHMCS_CUSTOM_FIELD_NAME) + { + $subdomain = $customField['value']; + if (($subdomain . ".airtime.pro") === $_SERVER['SERVER_NAME']) + { + return $airtimeProduct['id']; + } + } + } + } + } + } + throw new Exception("Unable to match subdomain to a service ID"); } public static function getProducts() { + //Making this static to cache the products during a single HTTP request. + //This saves us roundtrips to WHMCS if getProducts() is called multiple times. + static $result = array(); + if (!empty($result)) + { + return $result["products"]["product"]; + } + $credentials = self::getAPICredentials(); $postfields = array(); @@ -279,6 +325,21 @@ class BillingController extends Zend_Controller_Action { $result = self::makeRequest($credentials["url"], $query_string); return $result["products"]["product"]; } + + public static function getProductPricesAndTypes() + { + $products = BillingController::getProducts(); + + foreach ($products as $k => $p) { + $productPrices[$p["name"]] = array( + "monthly" => $p["pricing"]["USD"]["monthly"], + "annually" => $p["pricing"]["USD"]["annually"] + ); + $productTypes[$p["pid"]] = $p["name"] . " ($" . $productPrices[$p['name']]['monthly'] . "/mo)"; + } + return array($productPrices, $productTypes); + } + public static function getClientDetails() { @@ -325,4 +386,12 @@ class BillingController extends Zend_Controller_Action { Logging::info($e->getMessage()); } } + + private static function ensureClientIdIsValid() + { + if (Application_Model_Preference::GetClientId() == null) + { + throw new Exception("Invalid client ID: " . Application_Model_Preference::GetClientId()); + } + } } \ No newline at end of file diff --git a/airtime_mvc/application/controllers/WhmcsLoginController.php b/airtime_mvc/application/controllers/WhmcsLoginController.php index 0f0e327de..2f78ce5ed 100644 --- a/airtime_mvc/application/controllers/WhmcsLoginController.php +++ b/airtime_mvc/application/controllers/WhmcsLoginController.php @@ -1,8 +1,5 @@ setLabel(_('Company Name:')) ->setValue($client["companyname"]) ->setAttrib('class', 'input_text') - ->setRequired(true) + ->setRequired(false) ->addValidator($notEmptyValidator) ->addFilter('StringTrim'); $this->addElement($companyname); @@ -85,7 +85,7 @@ class Application_Form_BillingClient extends Zend_Form $this->addElement($state); $postcode = new Zend_Form_Element_Text('postcode'); - $postcode->setLabel(_('Zip Code:')) + $postcode->setLabel(_('Zip Code / Postal Code:')) ->setValue($client["postcode"]) ->setAttrib('class', 'input_text') ->setRequired(true) diff --git a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php index 10f2b8be7..b89136689 100644 --- a/airtime_mvc/application/forms/BillingUpgradeDowngrade.php +++ b/airtime_mvc/application/forms/BillingUpgradeDowngrade.php @@ -4,17 +4,9 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form public function init() { $productPrices = array(); - $productTypes = array(); - $products = BillingController::getProducts(); - - foreach ($products as $k => $p) { - $productPrices[$p["name"]] = array( - "monthly" => $p["pricing"]["USD"]["monthly"], - "annualy" => $p["pricing"]["USD"]["annually"] - ); - $productTypes[$p["pid"]] = $p["name"]; - } - + $productTypes = array(); + list($productPrices, $productTypes) = BillingController::getProductPricesAndTypes(); + //$currentPlanType = ucfirst(Application_Model_Preference::GetPlanLevel()); $currentPlanType = "Hobbyist"; if (($key = array_search($currentPlanType, $productTypes)) !== false) { @@ -30,7 +22,7 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $billingcycle = new Zend_Form_Element_Radio('newproductbillingcycle'); $billingcycle->setLabel(_('Billing cycle:')) - ->setMultiOptions(array('monthly' => 'monthly', 'annually' => 'annually')) + ->setMultiOptions(array('monthly' => 'Monthly', 'annually' => 'Annually')) ->setRequired(true) ->setValue('monthly'); $this->addElement($billingcycle); @@ -50,6 +42,8 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form $this->addElement($submit);*/ $client = new Application_Form_BillingClient(); + $client->removeElement("password2"); + $client->removeElement("password2verify"); $this->addSubForm($client, 'billing_client_info'); } } diff --git a/airtime_mvc/application/views/scripts/billing/client.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml index 980288c81..a38b8f685 100644 --- a/airtime_mvc/application/views/scripts/billing/client.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,4 +1,5 @@
    +

    Account Details

    errorMessage)) {?>
    errorMessage ?>
    successMessage)) {?> diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index c111765b5..8a482ea80 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -1,19 +1,162 @@ form; $form->setAttrib('id', 'upgrade-downgrade'); + ?> -
    -

    Account Plans

    + + +
    +

    +

    -pricing grid here + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    HobbyistStarterPlusPremium
    1 Stream + 2 Streams + 2 Streams + 3 Streams +
    64kbps Stream Quality + 64kbps and 128kbps Stream Quality + 64kbps and 196kbps Stream Quality + 64kbps, 128kbps, and 196kbps Stream Quality +
    5 Listeners + 40 Listeners per stream + 100 Listeners per stream + 500 Listeners per stream +
    2GB Storage + 5GB Storage + 30GB Storage + 150GB Storage +
    Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support + Live Chat, Ticket, Email, Forum Support +
    + Save 15% if paid annually + Save 15% if paid annually + Save 15% if paid annually +
    + + + +
    -errorMessage)) {?> -
    errorMessage ?>
    - -
    Plan Level:
    - - + +

    Current Plan: +

    +

    Choose a plan:

    @@ -23,36 +166,51 @@ pricing grid here
    newproductbillingcycle ?>
    -
    - paymentmethod ?> +
    + Save 15% on annual plans (Hobbyist plan excluded). +
    +
    +
    Total:
    + +
    + Plus VAT if you are an EU resident without a valid VAT number.
    -
    +

    Enter your payment details:

    + errorMessage)) {?> +
    errorMessage ?>
    + + + getSubform("billing_client_info") ?> -
    +
    firstname?>
    -
    +
    lastname?>
    -
    +
    +
    companyname?>
    -
    +
    email?>
    -
    +
    +
    address1?>
    -
    +
    address2?> -
    -
    +
    +
    +
    city?>
    -
    +
    state?>
    +
    postcode?>
    @@ -68,19 +226,30 @@ pricing grid here
    securityqans?>
    +

    VAT will be added to your invoice if you are an EU resident without a valid VAT number.

    +
    getElement("7"); ?>
    +
    +
    - getElement("71"); ?> + getElement("71"); ?> +
    + getElement("71")->renderViewHelper(); ?> +
    + getElement("71")->renderLabel(); ?>
    -
    - password2?> +
    + +

    After submitting your order, you will be redirected to an invoice with payment buttons.

    -
    - password2verify?> +
    + paymentmethod ?>
    - + +
    + +
    -



    \ No newline at end of file diff --git a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml index 691d2983a..c0abffc89 100644 --- a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml +++ b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml @@ -6,7 +6,7 @@
    diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css index da9ab49be..c34e8ad49 100644 --- a/airtime_mvc/public/css/billing.css +++ b/airtime_mvc/public/css/billing.css @@ -1,5 +1,28 @@ @CHARSET "UTF-8"; +.billing-panel +{ + width: 400px; + margin: 0 auto; + margin-bottom: 30px; +} + +#upgrade-downgrade +{ + border: 0px solid #000; + margin: 0 auto; + color: #000; +} + +#upgrade-downgrade label +{ + color: rgb(28,28,28); +} +#upgrade-downgrade label.disabled +{ + color: rgb(108,108,108); +} + #upgrade-downgrade dl { width: 300px; @@ -15,19 +38,101 @@ margin-bottom: 10px; } +.pricing-grid table +{ + border-spacing: 0px; + border-collapse: separate; + border: 1px solid #777; + width: 600px; + margin-left: -100px; + /*background-color: #555;*/ + table-layout: fixed; + margin-top: 20px; + margin-bottom: 20px; + box-shadow: 0px 5px 5px rgba(0,0,0,0.5); +} + +.pricing-grid td, .pricing-grid th +{ + border-bottom: 1px solid #999; + border-right: 1px solid #bbb; + background-color: #ccc; + padding: 10px; +} + +.pricing-grid th +{ + border-top-left-radius: 5px; + border-top-right-radius: 5px; + border: 0px; +} + + +.pricing-grid tr.price td +{ + text-align: right; + background-color: #ddd; + font-weight: bold; +} + +#current_plan +{ + text-align: center; +} + #plantype { - float: left; - + float: left; } #billingcycle { float: left; + margin-left: 30px; +} + +#billingcycle_disclaimer +{ + float: left; + margin-left: 30px; + width: 200px; +} + +#vat_disclaimer +{ + text-align: right; + font-size: 0.9em; + margin-bottom: 30px; +} + +#total_box +{ + text-align: right; + margin-top: 30px; + margin-bottom: 10px; + border: 1px solid #777; + background: #ccc; + padding: 5px; } #paymentmethod { - float: left; - +} + +.billing_col1, .billing_col2 +{ + float: left; + margin-right: 10px; +} + +.billing_checkbox +{ + float: left; + margin-right: 5px; + margin-bottom: 10px; +} + +#upgrade-downgrade input[type=submit] +{ + float: right; } \ No newline at end of file From fce6116d604626ba1bbe4347acc543b50b4c10ee Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 25 Jun 2014 20:01:14 -0400 Subject: [PATCH 31/47] Made the invoices view nice! --- .../controllers/BillingController.php | 8 +++++ .../views/scripts/billing/client.phtml | 4 +-- .../views/scripts/billing/invoices.phtml | 23 ++++++++++--- airtime_mvc/public/css/billing.css | 33 +++++++++++++++++++ 4 files changed, 61 insertions(+), 7 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index e8aeea0f5..e5049d449 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -174,6 +174,10 @@ class BillingController extends Zend_Controller_Action { public function clientAction() { + $CC_CONFIG = Config::getConfig(); + $baseUrl = Application_Common_OsPath::getBaseDir(); + $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + $request = $this->getRequest(); $form = new Application_Form_BillingClient(); BillingController::ensureClientIdIsValid(); @@ -220,6 +224,10 @@ class BillingController extends Zend_Controller_Action { public function invoicesAction() { + $CC_CONFIG = Config::getConfig(); + $baseUrl = Application_Common_OsPath::getBaseDir(); + $this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']); + BillingController::ensureClientIdIsValid(); $credentials = self::getAPICredentials(); diff --git a/airtime_mvc/application/views/scripts/billing/client.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml index a38b8f685..5b89d280b 100644 --- a/airtime_mvc/application/views/scripts/billing/client.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,5 +1,5 @@ -
    -

    Account Details

    +
    +

    Billing Account Details

    errorMessage)) {?>
    errorMessage ?>
    successMessage)) {?> diff --git a/airtime_mvc/application/views/scripts/billing/invoices.phtml b/airtime_mvc/application/views/scripts/billing/invoices.phtml index ed1f13a74..d143441cc 100644 --- a/airtime_mvc/application/views/scripts/billing/invoices.phtml +++ b/airtime_mvc/application/views/scripts/billing/invoices.phtml @@ -1,9 +1,22 @@ -
    +
    +

    Invoices

    +

    and look for the \"Checkout\" button.")?>

    + + + + + + + invoices as $invoice) {?> - + + + + + + - + +
    Date IssuedDue DateLinkStatus
    ">View Invoice">
    \ No newline at end of file diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css index c34e8ad49..9aaada3e3 100644 --- a/airtime_mvc/public/css/billing.css +++ b/airtime_mvc/public/css/billing.css @@ -135,4 +135,37 @@ #upgrade-downgrade input[type=submit] { float: right; +} + +#invoices_table +{ + margin: 0 auto; + border-spacing: 0px; + border-collapse: separate; + border: 1px solid #777; + /*background-color: #555;*/ + table-layout: fixed; + margin-top: 20px; + margin-bottom: 35px; + background: #ccc; +} + +#invoices_table tbody tr th +{ + border: 0px; +} + +#invoices_table .header +{ + box-shadow: 0px 2px 2px rgba(0,0,0,0.5); +} + +#invoices_table tr +{ + border: 1px solid #555; +} + +#invoices_table .unpaid +{ + color: #ff0000; } \ No newline at end of file From b36967a6905b3a99042ff617cbc7bc10120e0ac6 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 25 Jun 2014 20:32:41 -0400 Subject: [PATCH 32/47] Nicer auto-styling for the Billing Details form --- .../application/forms/BillingClient.php | 1 + .../views/scripts/billing/client.phtml | 5 +++++ airtime_mvc/public/css/billing.css | 18 ++++++++++++++++++ 3 files changed, 24 insertions(+) diff --git a/airtime_mvc/application/forms/BillingClient.php b/airtime_mvc/application/forms/BillingClient.php index 716bc36fd..5e6a2c252 100644 --- a/airtime_mvc/application/forms/BillingClient.php +++ b/airtime_mvc/application/forms/BillingClient.php @@ -8,6 +8,7 @@ class Application_Form_BillingClient extends Zend_Form /*$this->setDecorators(array( array('ViewScript', array('viewScript' => 'form/billing-purchase.phtml'))));*/ $client = BillingController::getClientDetails(); + $this->setAttrib("id", "clientdetails_form"); $notEmptyValidator = Application_Form_Helper_ValidationTypes::overrideNotEmptyValidator(); $emailValidator = Application_Form_Helper_ValidationTypes::overrideEmailAddressValidator(); diff --git a/airtime_mvc/application/views/scripts/billing/client.phtml b/airtime_mvc/application/views/scripts/billing/client.phtml index 5b89d280b..e57fb140b 100644 --- a/airtime_mvc/application/views/scripts/billing/client.phtml +++ b/airtime_mvc/application/views/scripts/billing/client.phtml @@ -1,3 +1,8 @@ +form->getElement("submit")->setAttrib("class", "right-align"); +$this->form->getElement("country")->setAttrib("class", "right-align"); +$this->form->getElement("securityqid")->setAttrib("class", "right-align"); +?>

    Billing Account Details

    errorMessage)) {?> diff --git a/airtime_mvc/public/css/billing.css b/airtime_mvc/public/css/billing.css index 9aaada3e3..88498a88f 100644 --- a/airtime_mvc/public/css/billing.css +++ b/airtime_mvc/public/css/billing.css @@ -168,4 +168,22 @@ #invoices_table .unpaid { color: #ff0000; +} + +/** This form is the separate one on the Billing Account Details page (BillingClient.php) */ +#clientdetails_form dt { + float: left; + clear: both; + width: 50%; + margin-bottom: 10px; +} +#clientdetails_form dd { + float: left; + margin-left: 0px; + margin-bottom: 10px; +} +#clientdetails_form .right-align +{ + /*text-align: right;*/ + width: 100%; } \ No newline at end of file From 94bbd3c8a59d158b56a481699abb7c572a679ad0 Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Wed, 25 Jun 2014 20:36:08 -0400 Subject: [PATCH 33/47] Don't open trialbox My Account link in new window --- .../application/views/scripts/partialviews/trialBox.phtml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml index c0abffc89..18873ce00 100644 --- a/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml +++ b/airtime_mvc/application/views/scripts/partialviews/trialBox.phtml @@ -6,7 +6,7 @@
    From 18c828defd0025bdd9981907981887a164cb450d Mon Sep 17 00:00:00 2001 From: Albert Santoni Date: Thu, 26 Jun 2014 17:31:34 -0400 Subject: [PATCH 34/47] Finished up VAT validation for Plans page --- .../controllers/BillingController.php | 144 +++++++++++++++++- .../views/scripts/billing/upgrade.phtml | 137 +++++++++++++++-- airtime_mvc/public/css/billing.css | 39 ++++- 3 files changed, 297 insertions(+), 23 deletions(-) diff --git a/airtime_mvc/application/controllers/BillingController.php b/airtime_mvc/application/controllers/BillingController.php index e5049d449..e5feb47b6 100644 --- a/airtime_mvc/application/controllers/BillingController.php +++ b/airtime_mvc/application/controllers/BillingController.php @@ -1,7 +1,18 @@ _helper->getHelper('AjaxContext'); + $ajaxContext->addActionContext('vat-validator', 'json') + ->addActionContext('is-country-in-eu', 'json') + ->initContext(); + } + public function indexAction() { @@ -24,12 +35,13 @@ class BillingController extends Zend_Controller_Action { * validate it somehow. We'll also need to make sure the country given is * in the EU */ - $apply_vat = false; - + $formData = $request->getPost(); if ($form->isValid($formData)) { $credentials = self::getAPICredentials(); + $apply_vat = BillingController::checkIfVatShouldBeApplied($formData["customfields"]["7"], $formData["country"]); + $postfields = array(); $postfields["username"] = $credentials["username"]; $postfields["password"] = md5($credentials["password"]); @@ -91,6 +103,124 @@ class BillingController extends Zend_Controller_Action { $this->view->form = $form; } } + + + public function isCountryInEuAction() + { + // Disable the view and the layout + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $request = $this->getRequest(); + if (!$request->isPost()) { + throw new Exception("Must POST data to isCountryInEuAction."); + } + $formData = $request->getPost(); + + //Set the return JSON value + $this->_helper->json(array("result"=>BillingController::isCountryInEU($formData["country"]))); + } + + public function vatValidatorAction() + { + // Disable the view and the layout + $this->view->layout()->disableLayout(); + $this->_helper->viewRenderer->setNoRender(true); + + $request = $this->getRequest(); + if (!$request->isPost()) { + throw new Exception("Must POST data to vatValidatorAction."); + } + $formData = $request->getPost(); + + $vatNumber = trim($formData["vatnumber"]); + if (empty($vatNumber)) { + $this->_helper->json(array("result"=>false)); + } + + //Set the return JSON value + $this->_helper->json(array("result"=>BillingController::checkIfVatShouldBeApplied($vatNumber, $formData["country"]))); + } + + /** + * @return True if VAT should be applied to the order, false otherwise. + */ + private static function checkIfVatShouldBeApplied($vatNumber, $countryCode) + { + if ($countryCode === 'UK') { + $countryCode = 'GB'; //VIES database has it as GB + } + //We don't charge you VAT if you're not in the EU + if (!BillingController::isCountryInEU($countryCode)) + { + return false; + } + + //So by here, we know you're in the EU. + + //No VAT number? Then we charge you VAT. + if (empty($vatNumber)) { + return true; + } + //Check if VAT number is valid + return BillingController::validateVATNumber($vatNumber, $countryCode); + } + + private static function isCountryInEU($countryCode) + { + $euCountryCodes = array('BE', 'BG', 'CZ', 'DK', 'DE', 'EE', 'IE', 'EL', 'ES', 'FR', + 'HR', 'IT', 'CY', 'LV', 'LT', 'LU', 'HU', 'MT', 'NL', 'AT', + 'PL', 'PT', 'RO', 'SI', 'SK', 'FI', 'SE', 'UK', 'GB'); + + if (!in_array($countryCode, $euCountryCodes)) { + return false; + } + return true; + } + + /** + * Check if an EU VAT number is valid, using the EU VIES validation web API. + * + * @param string $vatNumber - A VAT identifier (number), with or without the two letter country code at the + * start (either one works) . + * @param string $countryCode - A two letter country code + * @return boolean true if the VAT number is valid, false otherwise. + */ + private static function validateVATNumber($vatNumber, $countryCode) + { + $vatNumber = str_replace(array(' ', '.', '-', ',', ', '), '', trim($vatNumber)); + + //If the first two letters are a country code, use that as the country code and remove those letters. + $firstTwoCharacters = substr($vatNumber, 0, 2); + if (preg_match("/[a-zA-Z][a-zA-Z]/", $firstTwoCharacters) === 1) { + $countryCode = strtoupper($firstTwoCharacters); //The country code from the VAT number overrides your country. + $vatNumber = substr($vatNumber, 2); + } + $client = new SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl"); + + if($client){ + $params = array('countryCode' => $countryCode, 'vatNumber' => $vatNumber); + try{ + $r = $client->checkVat($params); + if($r->valid == true){ + // VAT-ID is valid + return true; + } else { + // VAT-ID is NOT valid + return false; + } + } catch(SoapFault $e) { + Logging::error('VIES EU VAT validation error: '.$e->faultstring); + return false; + } + } else { + // Connection to host not possible, europe.eu down? + Logging::error('VIES EU VAT validation error: Host unreachable'); + return false; + } + return false; + } + private function addVatToInvoice($invoice_id) { @@ -111,8 +241,7 @@ class BillingController extends Zend_Controller_Action { //TODO: error checking $result = $this->makeRequest($credentials["url"], $invoice_query_string); - $vat_rate = 19.00; - $vat_amount = $result["subtotal"] * ($vat_rate/100); + $vat_amount = $result["subtotal"] * (VAT_RATE/100); $invoice_total = $result["total"] + $vat_amount; //Second, update the invoice with the VAT amount and updated total @@ -254,7 +383,6 @@ class BillingController extends Zend_Controller_Action { self::viewInvoice($invoice_id); } - //TODO: this does not return a service id. why? private static function getClientInstanceId() { $credentials = self::getAPICredentials(); @@ -272,11 +400,15 @@ class BillingController extends Zend_Controller_Action { $result = self::makeRequest($credentials["url"], $query_string); Logging::info($result); + //XXX: Debugging / local testing if ($_SERVER['SERVER_NAME'] == "airtime.localhost") { return "1384"; } + //This code must run on airtime.pro for it to work... it's trying to match - //the server's hostname with the client subdomain. + //the server's hostname with the client subdomain. Once it finds a match + //between the product and the server's hostname/subdomain, then it + //returns the ID of that product (aka. the service ID of an Airtime instance) foreach ($result["products"] as $product) { if (strpos($product[0]["groupname"], "Airtime") === FALSE) diff --git a/airtime_mvc/application/views/scripts/billing/upgrade.phtml b/airtime_mvc/application/views/scripts/billing/upgrade.phtml index 8a482ea80..e0792d523 100644 --- a/airtime_mvc/application/views/scripts/billing/upgrade.phtml +++ b/airtime_mvc/application/views/scripts/billing/upgrade.phtml @@ -4,9 +4,14 @@ ?>