diff --git a/application/classes/auth/osb.php b/application/classes/auth/osb.php index e9ee4677..a4d28a46 100644 --- a/application/classes/auth/osb.php +++ b/application/classes/auth/osb.php @@ -258,7 +258,6 @@ class Auth_OSB extends Auth_ORM { $orm = ORM::factory($t) ->where($c,'=',$oldsess); - // @todo There must be a way that ORM can update multiple records with 1 SQL foreach ($orm->find_all() as $o) $o->set('session_id',session_id()) ->update(); diff --git a/application/classes/config.php b/application/classes/config.php index a306333b..d75320a7 100644 --- a/application/classes/config.php +++ b/application/classes/config.php @@ -45,7 +45,7 @@ class Config extends lnApp_Config { static $return = array(); if (! count($return)) - foreach (ORM::factory('module')->where('status','=',1)->find_all() as $mo) + foreach (ORM::factory('module')->list_active() as $mo) $return[$mo->name] = MODPATH.$mo->name; return $return; diff --git a/application/classes/controller/admin/account.php b/application/classes/controller/admin/account.php index 4907645f..18f51fb4 100644 --- a/application/classes/controller/admin/account.php +++ b/application/classes/controller/admin/account.php @@ -12,44 +12,20 @@ */ class Controller_Admin_Account extends Controller_TemplateDefault_Admin { protected $secure_actions = array( - 'autocomplete'=>FALSE, // @todo To Change + 'ajaxlist'=>FALSE, // @todo To Change 'list'=>TRUE, 'listlog'=>TRUE, ); - public function action_autocomplete() { + public function action_ajaxlist() { $return = array(); - $a = ORM::factory('account')->where('status','=',1); - if (isset($_REQUEST['term']) AND trim($_REQUEST['term'])) { - $t = $_REQUEST['term']; - - // @todo - Implement different search criteria, eg: @ by email, space for first/last, etc - if (FALSE) { - - // All search - } else { - $a = $a - ->where_open() - ->where('first_name','like','%'.$t.'%') - ->or_where('last_name','like','%'.$t.'%') - ->or_where('company','like','%'.$t.'%') - ->or_where('email','like','%'.$t.'%') - ->where_close(); - } - } - - // @todo The results should be limited so that users dont see what they shouldnt. - foreach ($a->find_all() as $ao) - array_push($return,array( - 'id'=>$ao->id, - 'label'=>sprintf('%s (%s)',$ao->name(),$ao->email), - 'value'=>$ao->id, - )); + if (isset($_REQUEST['term']) AND trim($_REQUEST['term'])) + $return += ORM::factory('account')->list_autocomplete($_REQUEST['term']); $this->auto_render = FALSE; $this->response->headers('Content-Type','application/json'); - $this->response->body(json_encode($return)); + $this->response->body(json_encode(array_values($return))); } /** diff --git a/application/classes/kohana.php b/application/classes/kohana.php index 9942d61e..811cd74d 100644 --- a/application/classes/kohana.php +++ b/application/classes/kohana.php @@ -18,8 +18,6 @@ class Kohana extends Kohana_Core { * unless each site has exactly the same modules enabled. * This is because Kohana::$file is cached with the enabled modules * and is not OSB multi-site aware. - * - * @todo It might be nice to cache the Kohana::$file site-aware for improved performance */ public static function shutdown_handler() { // If caching isnt enabled, we can skip this anyway diff --git a/application/classes/lnapp/controller/templatedefault.php b/application/classes/lnapp/controller/templatedefault.php index c4a9afa8..149fa50e 100644 --- a/application/classes/lnapp/controller/templatedefault.php +++ b/application/classes/lnapp/controller/templatedefault.php @@ -82,6 +82,11 @@ abstract class lnApp_Controller_TemplateDefault extends Controller_Template { return; } + $TEST = FALSE; + // Actions that start with ajax, should only be ajax + if (preg_match('/^ajax/',Request::current()->action()) AND ! Request::current()->is_ajax() AND ! $TEST) + die(); + parent::before(); // Check user auth and role diff --git a/application/classes/model/account.php b/application/classes/model/account.php index c78169fc..ae40d6ea 100644 --- a/application/classes/model/account.php +++ b/application/classes/model/account.php @@ -117,7 +117,7 @@ class Model_Account extends Model_Auth_UserDefault { // @todo This shouldnt really be required if ($result < 0) - $result = 0; + throw new Kohana_Exception($result); return $format ? Currency::display($result) : $result; } @@ -133,10 +133,6 @@ class Model_Account extends Model_Auth_UserDefault { return $alo->saved(); } - private function _where_active() { - return $this->where('status','=',TRUE); - } - public function list_active() { return $this->_where_active()->order_by('company,last_name,first_name')->find_all(); } @@ -158,10 +154,11 @@ class Model_Account extends Model_Auth_UserDefault { /** * Search for accounts matching a term */ - public function list_autocomplete($term,$index='id') { + public function list_autocomplete($term,$index='id',array $limit=array()) { $return = array(); $this->clear(); + $this->where_active(); $value = 'name(TRUE)'; // Build our where clause @@ -183,13 +180,20 @@ class Model_Account extends Model_Auth_UserDefault { $value = 'email'; } else { - $this->where('company','like','%'.$term.'%') + $this->where_open() + ->where('company','like','%'.$term.'%') ->or_where('first_name','like','%'.$term.'%') ->or_where('last_name','like','%'.$term.'%') - ->or_where('email','like','%'.$term.'%'); + ->or_where('email','like','%'.$term.'%') + ->where_close(); + } + + foreach ($limit as $w) { + list($k,$s,$v) = $w; + + $this->and_where($k,$s,$v); } - // @todo This should limit the results so that users dont see other users services. foreach ($this->find_all() as $o) $return[$o->$index] = array( 'value'=>$o->$index, diff --git a/application/classes/model/group.php b/application/classes/model/group.php index d9eaa366..a9fef7aa 100644 --- a/application/classes/model/group.php +++ b/application/classes/model/group.php @@ -47,7 +47,7 @@ class Model_Group extends Model_Auth_RoleDefault { if (! $this->loaded()) return $return; - foreach (ORM::factory('group')->where('status','=',1)->and_where('parent_id','=',$this)->find_all() as $go) { + foreach (ORM::factory('group')->where_active()->and_where('parent_id','=',$this)->find_all() as $go) { array_push($return,$go); $return = array_merge($return,$go->list_childgrps()); @@ -69,7 +69,7 @@ class Model_Group extends Model_Auth_RoleDefault { if (! $this->loaded()) return $return; - foreach (ORM::factory('group')->where('status','=',1)->and_where('id','=',$this->parent_id)->find_all() as $go) { + foreach (ORM::factory('group')->where_active()->and_where('id','=',$this->parent_id)->find_all() as $go) { array_push($return,$go); $return = array_merge($return,$go->list_parentgrps()); diff --git a/application/classes/orm.php b/application/classes/orm.php index 4d644008..274034e0 100644 --- a/application/classes/orm.php +++ b/application/classes/orm.php @@ -127,5 +127,14 @@ class ORM extends Kohana_ORM { ->where('site_id', '=', Config::siteid()) ->execute($this->_db)->get('records_found'); } + + protected function _where_active() { + return $this->where('status','=',TRUE); + } + + public function where_active() { + return $this->_where_active(); + } + } ?> diff --git a/application/classes/ormosb.php b/application/classes/ormosb.php index dbb46e99..d25a22f5 100644 --- a/application/classes/ormosb.php +++ b/application/classes/ormosb.php @@ -25,13 +25,14 @@ abstract class ORMOSB extends ORM { // Our attributes used in forms. protected $_form = array(); + // Rules to assist with site ID and getting next record ID for inserts. public function rules() { return array( 'id'=>array( - array('ORMOSB::get_next_id',array(':validation',':model',':field')), + array('ORMOSB::get_next_id',array(':model',':field')), ), 'site_id'=>array( - array('ORMOSB::set_site_id',array(':validation',':model',':field')), + array('ORMOSB::set_site_id',array(':model',':field')), ), ); } @@ -73,8 +74,7 @@ abstract class ORMOSB extends ORM { * @param array Validate object * @param string Primary Key */ - // @todo Do we need the $array? - public static function get_next_id(Validation $array,$model,$field) { + public static function get_next_id($model,$field) { if (! is_null($model->$field)) return TRUE; @@ -92,8 +92,10 @@ abstract class ORMOSB extends ORM { return TRUE; } - // @todo Do we need the $array? - public static function set_site_id(Validation $array,$model,$field) { + /** + * Set the site ID attribute for each row update + */ + public static function set_site_id($model,$field) { if (! is_null($model->$field)) return TRUE; @@ -209,14 +211,6 @@ abstract class ORMOSB extends ORM { return empty($mc[$key]) ? '' : $mc[$key]; } - protected function _where_active() { - return $this->where('status','=',TRUE); - } - - public function where_active() { - return $this->_where_active(); - } - public function list_active() { return $this->_where_active()->find_all(); } diff --git a/application/classes/period.php b/application/classes/period.php index a21b5d03..00f9d5a0 100644 --- a/application/classes/period.php +++ b/application/classes/period.php @@ -23,56 +23,57 @@ class Period { * @param boolean Show dates in 'Y-m-d' format * @return array */ - public static function details($type,$weekday=NULL,$start=NULL,$df=FALSE) { - // Our precision for the pro-rata percentage - $precision = 4; - // Make the period consistent, eg: Quarterly = Jan-Mar,Apr-Jun; HalfYearly = Jan-Jun,Jul-Dec - $strict = FALSE; - + public static function details($type,$weekday=NULL,$start=NULL,$df=FALSE,$strict=FALSE) { // Round the time integer to a whole day. if (is_null($start)) $start = strtotime('today'); else $start = strtotime(date('Y-m-d',$start)); + $inc_months = $used_months = 0; + switch ($type) { // Weekly - // @todo Make Weekly pro-rata to a day of the week case 0: - $period_end = $start+(86400*(7-1)); - return array('start'=>$start,'date'=>$start,'end'=>$period_end,'prorate'=>1); + if ($strict) + throw new Kohana_Exception('Strict doesnt work here'); - # Monthly + $period_start = is_null($weekday) ? $start : $start+86400*($weekday-date('w',$start)); + $period_end = $period_start+(86400*7); + + break; + + // Monthly case 1: + // NOTE: Strict doesnt do anything here. $inc_months = 1; break; - # Quarterly + // Quarterly case 2: - # @todo Make this configurable. - $strict = TRUE; $inc_months = 3; break; - # Half Yearly + // Half Yearly case 3: - # @todo Make this configurable. - $strict = TRUE; $inc_months = 6; break; - # Yearly + // Yearly case 4: $inc_months = 12; break; - # Biennial + // Biennial case 5: $inc_months = 24; break; - # Triennial + // Triennial case 6: + if ($strict) + throw new Kohana_Exception('Strict not implemented here'); + $inc_months = 36; break; @@ -80,21 +81,24 @@ class Period { return FALSE; } - // If workout a day of week we calculate to. + // Workout the period start day if (is_null($weekday)) - $weekday = date('d',$start); + $weekday = $strict ? 1 : date('d',$start); - $used_months = 0; - if ($strict && $type > 0 && $type < 5) - $used_months = $inc_months-(($inc_months-(date('n',$start)%$inc_months))%$inc_months+1); + // We only work our used_months for periods monthly or more. + if ($inc_months) { + if ($strict) + $used_months = $inc_months-(($inc_months-(date('n',$start)%$inc_months))%$inc_months+1); - $d = mktime(0,0,0,date('m',$start)-$used_months,$weekday,date('y',$start)); - if ($d <= $start) - $period_start = $d; - else - $period_start = mktime(0,0,0,date('m',$d)-1-$used_months,$weekday,date('y',$d)); + $d = mktime(0,0,0,date('m',$start)-$used_months,$weekday,date('y',$start)); + if ($d <= $start) + $period_start = $d; + else + $period_start = mktime(0,0,0,date('m',$d)-1-$used_months,$weekday,date('y',$d)); - $period_end = mktime(0,0,0,date('m',$period_start)+$inc_months,$weekday,date('y',$period_start)); + // Workout the period end + $period_end = mktime(0,0,0,date('m',$period_start)+$inc_months,$weekday,date('y',$period_start)); + } $total_time = $period_end-$period_start; $remain_time = $period_end-$start; @@ -104,21 +108,21 @@ class Period { $period_end -= 86400; $return = array( - 'start'=>$period_start, - 'start_time'=>$start, - 'date'=>$start, - 'end'=>$period_end, - 'end_time'=>$period_end, - 'weekday'=>$weekday, - 'prorata'=>round($remain_time/$total_time,$precision), - 'total_time'=>sprintf('%3.1f',$total_time/86400), - 'remain_time'=>sprintf('%3.1f',$remain_time/86400), - 'used_time'=>sprintf('%3.1f',$used_time/86400)); + 'start'=>$period_start, + 'start_time'=>$start, + 'date'=>$start, + 'end'=>$period_end, + 'end_time'=>$period_end, + 'weekday'=>$weekday, + 'prorata'=>round($remain_time/$total_time,4), + 'total_time'=>sprintf('%3.1f',$total_time/86400), + 'remain_time'=>sprintf('%3.1f',$remain_time/86400), + 'used_time'=>sprintf('%3.1f',$used_time/86400), + ); - // @todo Use the configured data format if ($df) foreach (array('start','date','end') as $key) - $return[$key] = date('Y-m-d',$return[$key]); + $return[$key] = Config::date($return[$key]); return $return; } diff --git a/application/classes/staticlistmodule.php b/application/classes/staticlistmodule.php index f0b7fe94..2bcb3791 100644 --- a/application/classes/staticlistmodule.php +++ b/application/classes/staticlistmodule.php @@ -49,7 +49,6 @@ abstract class StaticListModule extends StaticList { // Override our argument list as defined in parent list($name,$table,$default,$key,$value,$where,$addblank,$attributes) = func_get_args(); - // @todo - our query type should come from our configuration? $db = DB::select()->from($table); foreach ($where as $k=>$v) { diff --git a/modules/charge/classes/controller/admin/charge.php b/modules/charge/classes/controller/admin/charge.php index 0719ab65..869290ba 100644 --- a/modules/charge/classes/controller/admin/charge.php +++ b/modules/charge/classes/controller/admin/charge.php @@ -91,7 +91,7 @@ class Controller_Admin_Charge extends Controller_TemplateDefault_Admin { Script::add(array('type'=>'stdin','data'=>' $(document).ready(function() { $("input[name=account_id]").autocomplete({ - source: "'.URL::site('admin/account/autocomplete').'", + source: "'.URL::site('admin/account/ajaxlist').'", minLength: 2, change: function(event,ui) { // Send the request and update sub category dropdown @@ -100,7 +100,7 @@ class Controller_Admin_Charge extends Controller_TemplateDefault_Admin { data: "aid="+$(this).val(), dataType: "json", cache: false, - url: "'.URL::site('admin/service/autolist').'", + url: "'.URL::site('admin/service/ajaxlist').'", timeout: 2000, error: function() { alert("Failed to submit"); @@ -115,7 +115,7 @@ class Controller_Admin_Charge extends Controller_TemplateDefault_Admin { // Fill sub category select $.each(data, function(i, j){ - var row = ""; + var row = ""; $(row).appendTo("select[name=service_id]"); }); } diff --git a/modules/invoice/classes/model/invoice.php b/modules/invoice/classes/model/invoice.php index 5180f1ea..9e1e7063 100644 --- a/modules/invoice/classes/model/invoice.php +++ b/modules/invoice/classes/model/invoice.php @@ -577,7 +577,7 @@ class Model_Invoice extends ORMOSB { * @todo This should be optimised a little to return only invoices to send, instead of looking for them. */ public function list_tosend() { - return ORM::factory('invoice')->where('status','=',1)->where_open()->where('print_status','is',NULL)->or_where('print_status','!=',1)->where_close(); + return ORM::factory('invoice')->where_active()->where_open()->where('print_status','is',NULL)->or_where('print_status','!=',1)->where_close(); } public function html() { diff --git a/modules/payment/classes/controller/admin/payment.php b/modules/payment/classes/controller/admin/payment.php index ce107f26..dc31041f 100644 --- a/modules/payment/classes/controller/admin/payment.php +++ b/modules/payment/classes/controller/admin/payment.php @@ -16,15 +16,11 @@ class Controller_Admin_Payment extends Controller_TemplateDefault_Admin { 'addbulk'=>TRUE, 'list'=>TRUE, 'view'=>TRUE, - 'autocomplete'=>FALSE, + 'ajaxlist'=>FALSE, 'autoitemlist'=>FALSE, ); - public function action_autocomplete() { - // We are only available via an ajax call. - if (! Request::current()->is_ajax()) - die(); - + public function action_ajaxlist() { $return = array(); if (isset($_REQUEST['term']) AND trim($_REQUEST['term'])) { @@ -155,7 +151,7 @@ class Controller_Admin_Payment extends Controller_TemplateDefault_Admin { } }); $("input[name=account_id]").autocomplete({ - source: "'.URL::site('admin/payment/autocomplete').'", + source: "'.URL::site('admin/payment/ajaxlist').'", minLength: 2, change: function(event,ui) { // Send the request and update sub category dropdown diff --git a/modules/product/classes/controller/product/category.php b/modules/product/classes/controller/product/category.php index 10e87631..95aa3f5f 100644 --- a/modules/product/classes/controller/product/category.php +++ b/modules/product/classes/controller/product/category.php @@ -34,8 +34,7 @@ class Controller_Product_Category extends Controller_TemplateDefault { */ private function _get_categories() { return ORM::factory('product_category') - ->where('status','=',TRUE) - ->find_all(); + ->list_active(); } } ?> diff --git a/modules/service/classes/controller/admin/service.php b/modules/service/classes/controller/admin/service.php index 09b87952..3c5b7cad 100644 --- a/modules/service/classes/controller/admin/service.php +++ b/modules/service/classes/controller/admin/service.php @@ -13,7 +13,7 @@ class Controller_Admin_Service extends Controller_TemplateDefault_Admin { // @todo This "module" menu items should belong in the module dir. protected $secure_actions = array( - 'autolist'=>FALSE, // @todo To Change + 'ajaxlist'=>FALSE, // @todo To Change 'adslstat'=>TRUE, 'list'=>TRUE, 'listbycheckout'=>TRUE, @@ -31,23 +31,17 @@ class Controller_Admin_Service extends Controller_TemplateDefault_Admin { 'view'=>TRUE, ); - public function action_autolist() { + public function action_ajaxlist() { $return = array(); - $s = ORM::factory('service')->where_active(); - if (isset($_REQUEST['aid'])) - $s = $s->where('account_id','=',$_REQUEST['aid']); - - // @todo This should limit the results so that users dont see other users services. - foreach ($s->find_all() as $so) - array_push($return,array( - 'value'=>$so->id, - 'text'=>sprintf('%s: %s',$so->id,$so->service_name()), - )); + $return += ORM::factory('service')->list_autocomplete( + isset($_REQUEST['term']) ? $_REQUEST['term'] : '', + 'id', + isset($_REQUEST['aid']) ? array(array('account_id','=',$_REQUEST['aid'])) : array()); $this->auto_render = FALSE; $this->response->headers('Content-Type','application/json'); - $this->response->body(json_encode($return)); + $this->response->body(json_encode(array_values($return))); } /** @@ -84,7 +78,7 @@ class Controller_Admin_Service extends Controller_TemplateDefault_Admin { // @todo This needs to be configurable $go = ORM::factory('group',array('name'=>'Personal')); - foreach (ORM::factory('account')->where('status','=',1)->find_all() as $ao) + foreach (ORM::factory('account')->list_active() as $ao) if ($ao->has_any('group',array($go))) foreach ($ao->service->list_active() as $so) if (! $so->service_billing->checkout_plugin_id) diff --git a/modules/service/classes/controller/affiliate/service.php b/modules/service/classes/controller/affiliate/service.php index 328057d5..2d19717f 100644 --- a/modules/service/classes/controller/affiliate/service.php +++ b/modules/service/classes/controller/affiliate/service.php @@ -54,7 +54,7 @@ class Controller_Affiliate_Service extends Controller_TemplateDefault_Affiliate // @todo This needs to be configurable $go = ORM::factory('group',array('name'=>'Personal')); - foreach (ORM::factory('account')->where('status','=',1)->find_all() as $ao) + foreach (ORM::factory('account')->list_active() as $ao) if ($ao->has_any('group',array($go))) foreach ($this->filter($ao->service->list_active(),$this->ao->affiliate->id,'name()') as $so) if (! $so->service_billing->checkout_plugin_id) diff --git a/modules/service/classes/model/service.php b/modules/service/classes/model/service.php index 9c21b9cd..d047c739 100644 --- a/modules/service/classes/model/service.php +++ b/modules/service/classes/model/service.php @@ -143,6 +143,36 @@ class Model_Service extends ORMOSB { /** LIST FUNCTIONS **/ + /** + * Search for services matching a term + */ + public function list_autocomplete($term,$index='id',array $limit=array()) { + $return = array(); + + $this->clear(); + $this->where_active(); + $value = 'service_name()'; + + // Build our where clause + $this->where_open() + ->where('id','like','%'.$term.'%') + ->where_close(); + + foreach ($limit as $w) { + list($k,$s,$v) = $w; + + $this->and_where($k,$s,$v); + } + + foreach ($this->find_all() as $o) + $return[$o->$index] = array( + 'value'=>$o->$index, + 'label'=>sprintf('SVC %s: %s',$o->id,Table::resolve($o,$value)), + ); + + return $return; + } + public function list_bylistgroup($cat) { $result = array(); diff --git a/modules/statement/classes/controller/user/statement.php b/modules/statement/classes/controller/user/statement.php index 61a7a95a..4b3a1ff1 100644 --- a/modules/statement/classes/controller/user/statement.php +++ b/modules/statement/classes/controller/user/statement.php @@ -27,7 +27,7 @@ class Controller_User_Statement extends Controller_TemplateDefault_User { $ta[$i]['payment'] = $o; } - foreach ($this->ao->invoice->where('status','!=',0)->find_all() as $o) { + foreach ($this->ao->invoice->list_active() as $o) { $i = count($ta); $ta[$i]['time'] = $o->date_orig; $ta[$i]['invoice'] = $o;