Merge branch 'saas-dev' of https://github.com/sourcefabric/Airtime into saas-dev
This commit is contained in:
commit
b98f573531
|
@ -329,4 +329,49 @@ class Billing
|
|||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
}
|
||||
|
||||
public static function getInvoices()
|
||||
{
|
||||
Billing::ensureClientIdIsValid();
|
||||
$credentials = Billing::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getinvoices";
|
||||
$postfields["responsetype"] = "json";
|
||||
$postfields["userid"] = Application_Model_Preference::GetClientId();
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
|
||||
$invoices = array();
|
||||
if ($result["invoices"]) {
|
||||
$invoices = $result["invoices"]["invoice"];
|
||||
}
|
||||
return $invoices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks if the customer has any unpaid invoices and if so, returns
|
||||
* the ID of one of them. Returns 0 otherwise.
|
||||
*/
|
||||
public static function checkForUnpaidInvoice() {
|
||||
$invoices = self::getInvoices();
|
||||
$unpaidInvoice = 0;
|
||||
$unpaidInvoices = 0;
|
||||
foreach ($invoices as $invoice)
|
||||
{
|
||||
if ($invoice['status'] == 'Unpaid') {
|
||||
$unpaidInvoices += 1;
|
||||
$unpaidInvoice = $invoice;
|
||||
}
|
||||
}
|
||||
if ($unpaidInvoices > 0) {
|
||||
return $unpaidInvoice;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -21,6 +21,8 @@ class Application_Common_UsabilityHints
|
|||
|
||||
$userIsOnCalendarPage = false;
|
||||
$userIsOnAddMediaPage = false;
|
||||
$userIsOnShowbuilderPage = false;
|
||||
$userIsSuperAdmin = Application_Model_User::getCurrentUser()->isSuperAdmin();
|
||||
|
||||
// If $userPath is set the request came from AJAX so the user's
|
||||
// current location inside Airtime gets passed in to this function.
|
||||
|
@ -36,6 +38,11 @@ class Application_Common_UsabilityHints
|
|||
if (strpos(strtolower($userPath), 'schedule') !== false) {
|
||||
$userIsOnCalendarPage = true;
|
||||
}
|
||||
|
||||
if (strpos(strtolower($userPath), 'showbuilder') !== false) {
|
||||
$userIsOnShowbuilderPage = true;
|
||||
}
|
||||
|
||||
} else {
|
||||
// If $userPath is not set the request came from inside Airtime so
|
||||
// we can use Zend's Front Controller to get the user's current location.
|
||||
|
@ -48,6 +55,10 @@ class Application_Common_UsabilityHints
|
|||
if ($currentController == "plupload") {
|
||||
$userIsOnAddMediaPage = true;
|
||||
}
|
||||
|
||||
if ($currentController == 'showbuilder') {
|
||||
$userIsOnShowbuilderPage = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (self::zeroFilesUploaded()) {
|
||||
|
@ -92,10 +103,16 @@ class Application_Common_UsabilityHints
|
|||
"<a href=\"/schedule\">",
|
||||
"</a>");
|
||||
}
|
||||
} else {
|
||||
return "";
|
||||
} else if ($userIsOnShowbuilderPage && $userIsSuperAdmin) {
|
||||
$unpaidInvoice = Billing::checkForUnpaidInvoice();
|
||||
if ($unpaidInvoice != null) {
|
||||
$invoiceUrl = "/billing/invoice?invoiceid=" . $unpaidInvoice['id'];
|
||||
$amount = $unpaidInvoice['currencyprefix'] . $unpaidInvoice['total'];
|
||||
return _pro(sprintf("You have an unpaid invoice for %s due soon. <a href='%s'>Please pay it to keep your station on the air.</a>", $amount, $invoiceUrl));;
|
||||
}
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns true if no files have been uploaded.
|
||||
|
|
|
@ -283,26 +283,7 @@ class BillingController extends Zend_Controller_Action {
|
|||
$baseUrl = Application_Common_OsPath::getBaseDir();
|
||||
$this->view->headLink()->appendStylesheet($baseUrl.'css/billing.css?'.$CC_CONFIG['airtime_version']);
|
||||
|
||||
Billing::ensureClientIdIsValid();
|
||||
$credentials = Billing::getAPICredentials();
|
||||
|
||||
$postfields = array();
|
||||
$postfields["username"] = $credentials["username"];
|
||||
$postfields["password"] = md5($credentials["password"]);
|
||||
$postfields["action"] = "getinvoices";
|
||||
$postfields["responsetype"] = "json";
|
||||
$postfields["userid"] = Application_Model_Preference::GetClientId();
|
||||
|
||||
$query_string = "";
|
||||
foreach ($postfields AS $k=>$v) $query_string .= "$k=".urlencode($v)."&";
|
||||
|
||||
$result = Billing::makeRequest($credentials["url"], $query_string);
|
||||
|
||||
if ($result["invoices"]) {
|
||||
$this->view->invoices = $result["invoices"]["invoice"];;
|
||||
} else {
|
||||
$this->view->invoices = array();
|
||||
}
|
||||
$this->view->invoices = Billing::getInvoices();
|
||||
}
|
||||
|
||||
public function invoiceAction()
|
||||
|
@ -312,6 +293,4 @@ class BillingController extends Zend_Controller_Action {
|
|||
$invoice_id = $request->getParam('invoiceid');
|
||||
self::viewInvoice($invoice_id);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
|
|
@ -188,7 +188,7 @@ class Application_Form_BillingClient extends Zend_Form
|
|||
$passwordVerify->addValidator($notEmptyValidator);
|
||||
$this->addElement($passwordVerify);
|
||||
|
||||
$this->addElement('hash', 'csrf', array(
|
||||
$this->addElement('hash', 'csrf_client', array(
|
||||
'salt' => 'unique'
|
||||
));
|
||||
|
||||
|
|
|
@ -3,12 +3,7 @@ class Application_Form_BillingUpgradeDowngrade extends Zend_Form
|
|||
{
|
||||
public function init()
|
||||
{
|
||||
$csrf_namespace = new Zend_Session_Namespace('csrf_namespace');
|
||||
$csrf_element = new Zend_Form_Element_Hidden('csrf');
|
||||
$csrf_element->setValue($csrf_namespace->authtoken)->setRequired('true')->removeDecorator('HtmlTag')->removeDecorator('Label');
|
||||
$this->addElement($csrf_element);
|
||||
|
||||
$this->addElement('hash', 'csrf', array(
|
||||
$this->addElement('hash', 'csrf_upgrade', array( //Needs a unique ID (csrf_upgrade) so it doesn't conflict with other tokens in subforms
|
||||
'salt' => 'unique'
|
||||
));
|
||||
|
||||
|
|
|
@ -99,7 +99,7 @@ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
|
|||
<!--<div style="padding-bottom: 2px;">Disk Usage</div>-->
|
||||
<div class="disk_usage_progress_bar"></div>
|
||||
<div class="disk_usage_percent_in_use"><?php echo sprintf("%01.1fGB of %01.1fGB", $used/pow(2, 30), $total/pow(2, 30)); ?></div>
|
||||
<div class="disk_usage_used" style="width:<?php echo sprintf("%01.1f%%", $used/$total*100) ?>;"></div>
|
||||
<div class="disk_usage_used" style="width:<?php echo sprintf("%01.1f%%", min(100, $used/$total*100)) ?>;"></div>
|
||||
|
||||
<!--<div style="margin-top: 15px; font-size: 12px;">
|
||||
<?php //echo sprintf("%01.1fGB of %01.1fGB", $used/pow(2, 30), $total/pow(2, 30)); ?>
|
||||
|
|
|
@ -13,8 +13,13 @@ class Application_Model_Datatables
|
|||
$info = explode('~', $term);
|
||||
if ($dbname == 'utime' || $dbname == 'mtime' || $dbname == 'lptime') {
|
||||
|
||||
try {
|
||||
$input1 = ($info[0] != "") ? Application_Common_DateHelper::UserTimezoneStringToUTCString($info[0]) : null;
|
||||
$input2 = ($info[1] != "") ? Application_Common_DateHelper::UserTimezoneStringToUTCString($info[1]) : null;
|
||||
} catch (Exception $e) {
|
||||
$input1 = null;
|
||||
$input2 = null;
|
||||
}
|
||||
|
||||
} else if($dbname == 'bit_rate' || $dbname == 'sample_rate') {
|
||||
$input1 = isset($info[0])?doubleval($info[0]) * 1000:null;
|
||||
|
|
|
@ -955,6 +955,10 @@ class Application_Model_Scheduler
|
|||
$this->con->beginTransaction();
|
||||
|
||||
try {
|
||||
//Increase the transaction isolation level to prevent two concurrent requests from potentially resulting
|
||||
//in tracks scheduled at the same time.
|
||||
$this->con->exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
|
||||
|
||||
$this->validateMediaItems($mediaItems); //Check for missing files, etc.
|
||||
$this->validateRequest($scheduleItems, true);
|
||||
|
||||
|
@ -1005,6 +1009,9 @@ class Application_Model_Scheduler
|
|||
//$this->con->useDebug(true);
|
||||
|
||||
try {
|
||||
//Increase the transaction isolation level to prevent two concurrent requests from potentially resulting
|
||||
//in tracks scheduled at the same time.
|
||||
$this->con->exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
|
||||
|
||||
$this->validateItemMove($selectedItems, $afterItems[0]);
|
||||
$this->validateRequest($selectedItems);
|
||||
|
|
|
@ -850,6 +850,9 @@ SQL;
|
|||
$con = Propel::getConnection(CcPrefPeer::DATABASE_NAME);
|
||||
try {
|
||||
$con->beginTransaction();
|
||||
//It is extremely important that we increase the transaction isolation level, so that if two
|
||||
//requests cause the show schedule to be generated at the same time, one will be rolled back.
|
||||
$con->exec("SET TRANSACTION ISOLATION LEVEL SERIALIZABLE");
|
||||
|
||||
//UTC DateTime object
|
||||
$showsPopUntil = Application_Model_Preference::GetShowsPopulatedUntil();
|
||||
|
@ -862,7 +865,9 @@ SQL;
|
|||
$con->commit();
|
||||
} catch (Exception $e) {
|
||||
$con->rollBack();
|
||||
throw $e;
|
||||
//throw $e;
|
||||
Logging::warn("Did not create show instances due to transaction error. This is usually safe
|
||||
and caused by two concurrent transactions. " . $e->getMessage());
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -5,7 +5,7 @@ $topTextClass = "";
|
|||
if (array_key_exists("planupdated", $_GET))
|
||||
{
|
||||
$topText = _pro("<b>Thank you!</b> Your plan has been updated and you will be invoiced during your next billing cycle.");
|
||||
$topTextClass = "status-good";
|
||||
$topTextClass = "invoice-status-good";
|
||||
}
|
||||
else {
|
||||
$topText = _pro("Tip: To pay an invoice, click \"View Invoice\" and look for the \"Checkout\" button.");
|
||||
|
|
|
@ -274,7 +274,7 @@ echo($currentProduct["name"]);
|
|||
<form id="<?php echo $form->getId(); ?>" method="<?php echo $form->getMethod() ?>" action="<?php echo
|
||||
$form->getAction()?>" enctype="<?php echo $form->getEncType();?>">
|
||||
|
||||
<?php echo $form->csrf ?>
|
||||
<?php echo $form->csrf_upgrade ?>
|
||||
|
||||
<div id="plantype">
|
||||
<?php echo $form->newproductid ?>
|
||||
|
@ -353,6 +353,7 @@ echo($currentProduct["name"]);
|
|||
<div id="vaterror"></div>
|
||||
</div>
|
||||
<div class="clearfix"></div>
|
||||
<?php echo $billingForm->csrf_client ?>
|
||||
|
||||
<div>
|
||||
<div class="billing_checkbox">
|
||||
|
@ -379,7 +380,7 @@ echo($currentProduct["name"]);
|
|||
<b>Total:</b> <span id="total"></span>
|
||||
</div>
|
||||
|
||||
<input type="submit" class="btn right-floated" value="Submit Order" id="atpro_submitorder"></input>
|
||||
<input type="submit" class="btn right-floated" value="Submit Order" id="atpro_submitorder">
|
||||
<div class="clearfix"></div>
|
||||
</form>
|
||||
</div>
|
|
@ -47,7 +47,7 @@
|
|||
<div style="padding-bottom: 2px;">Storage</div>
|
||||
<div class="disk_usage_progress_bar"></div>
|
||||
<div class="disk_usage_percent_in_use"><?php echo sprintf("%01.1f%% ", $used/$total*100) . _("in use") ?></div>
|
||||
<div class="disk_usage_used" style="width:<?php echo sprintf("%01.1f%%", $used/$total*100) ?>;"></div>
|
||||
<div class="disk_usage_used" style="width:<?php echo sprintf("%01.1f%%", min(100, $used/$total*100)) ?>;"></div>
|
||||
|
||||
<div style="margin-top: 17px; font-size: 12px;"><?php echo sprintf("%01.1fGB of %01.1fGB", $used/pow(2, 30), $total/pow(2, 30)); ?></div>
|
||||
</div>
|
||||
|
|
|
@ -225,6 +225,14 @@
|
|||
color: #ff0000;
|
||||
}
|
||||
|
||||
.invoice-status-good {
|
||||
background: #e3ffc9 url(images/stream_status.png) no-repeat 10px 10px;
|
||||
border-color: #54b300;
|
||||
padding: 2px 12px 4px 32px;
|
||||
margin: 2px 1px 10px 0px;
|
||||
color: #330;
|
||||
}
|
||||
|
||||
/** This form is the separate one on the Billing Account Details page (BillingClient.php) */
|
||||
#clientdetails_form {
|
||||
width: 500px;
|
||||
|
|
|
@ -288,15 +288,13 @@ select {
|
|||
color:#ff5d1a;
|
||||
}
|
||||
.now-playing-block {
|
||||
/*width:35%;*/
|
||||
flex: 1 auto;
|
||||
flex: 1 0;
|
||||
background: url(images/masterpanel_spacer.png) no-repeat 0 0;
|
||||
margin-left: 152px;
|
||||
padding-left: 14px;
|
||||
}
|
||||
.show-block {
|
||||
/*width:30%;*/
|
||||
flex: 1 auto;
|
||||
flex: 1 0;
|
||||
}
|
||||
.text-row {
|
||||
height:30px;
|
||||
|
@ -3817,10 +3815,8 @@ hr {
|
|||
}
|
||||
|
||||
.disk_usage_progress_bar {
|
||||
position: absolute;
|
||||
left: 4px;
|
||||
right: 4px;
|
||||
/* width: 118px; */
|
||||
float: left;
|
||||
width: 100%;
|
||||
height: 13px;
|
||||
background: #444444;
|
||||
background: -moz-linear-gradient(top, #464646 0, #3e3e3e 100%);
|
||||
|
@ -3846,7 +3842,7 @@ hr {
|
|||
background: -webkit-gradient(linear, left top, left bottom, color-stop(0, #ff6f01), color-stop(100%, #bc5200));
|
||||
height:13px;
|
||||
z-index: 2;
|
||||
position:absolute;
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.dropdown-menu li > a:hover, .dropdown-menu li > a:focus, .dropdown-submenu:hover > a
|
||||
|
|
Loading…
Reference in New Issue