Major work to domain and hosting

Minor updates for ADSL services
Updates to Sort::MAsort()
Move core OSB items under application/
Moved ACCOUNT functions under application
Minor updates to task
This commit is contained in:
Deon George
2011-09-28 16:46:22 +10:00
parent 147d035e46
commit 130a87aa9a
199 changed files with 1536 additions and 10742 deletions

View File

@@ -0,0 +1,259 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Auth driver.
*
* @package OSB
* @subpackage Account
* @category Auth
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Auth_OSB extends Auth_ORM {
/**
* OSB authentication is controlled via database queries.
*
* This method can be used to test two situations:
* 1) Is the user logged in? ($role == FALSE)
* 2) Can the user run the current controller->action ($role == TRUE)
*
* @param boolean If authentication should be done for this module:method (ie: controller:action).
* @return boolean
*/
public function logged_in($role = NULL, $debug = NULL) {
$status = FALSE;
// Get the user from the session
$user = $this->get_user(FALSE);
// If we are not a valid user object, then we are not logged in
if (is_object($user) AND $user instanceof Model_Account AND $user->loaded()) {
if (Config::sitemode() == Kohana::DEVELOPMENT && Kohana::config('config.site_debug'))
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>Kohana::debug(array('user'=>$user->username,'r'=>$role))));
if (! empty($role)) {
// Get the module details
$mo = ORM::factory('module',array('name'=>Request::current()->controller()));
if (! $mo->loaded() OR ! $mo->status) {
SystemMessage::add(array(
'title'=>'Module is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Module not defined: %s',Request::current()->controller()),
));
} else {
if (Request::current()->directory())
$method_name = sprintf('%s_%s',Request::current()->directory(),Request::current()->action());
else
$method_name = Request::current()->action();
// Get the method number
$mmo = ORM::factory('module_method',array('module_id'=>$mo->id,'name'=>$method_name));
if (! $mmo->loaded()) {
SystemMessage::add(array(
'title'=>'Method is not defined or active in the Database',
'type'=>'warning',
'body'=>sprintf('Method not defined: %s for %s',Request::current()->action(),$mo->name),
));
} else {
// If the role has the authorisation to run the method
$gmo = ORM::factory('group_method')
->where('method_id','=',$mmo->id);
$roles = '';
foreach ($gmo->find_all() as $gm) {
$roles .= ($roles ? '|' : '').$gm->group->name;
// $gm->group->id == 0 means all users.
if ($gm->group->id == 0 OR $user->has_any('group',$gm->group->list_childgrps(TRUE))) {
$status = TRUE;
$roles = '';
break;
}
}
if (! $status) {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'User is not authorised in Database',
'type'=>'debug',
'body'=>sprintf('Role(s) checked: %s<br/>User: %s</br>Module: %s<br/>Method: %s',$roles,$user->username,$mo->name,$mmo->name),
));
}
}
}
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'Debug',
'type'=>'debug',
'body'=>sprintf('A-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Role: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
$user->username,Request::current()->controller(),Request::current()->action(),$role,$status,$debug)));
// There is no role, so the method should be allowed to run as anonymous
} else {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array(
'title'=>'Debug',
'type'=>'debug',
'body'=>sprintf('B-User: <b>%s</b>, Module: <b>%s</b>, Method: <b>%s</b>, Status: <b>%s</b>, Data: <b>%s</b>',
$user->username,Request::current()->controller(),Request::current()->action(),'No Role Default Access',$debug)));
$status = TRUE;
}
// Check and see if we have a token to login and run the method
} elseif ((! empty($_REQUEST['token']) AND $token = $_REQUEST['token']) OR $token=Session::instance()->get('token')) {
if ($user=$this->_get_token_user($token) AND $user !== FALSE)
$status = TRUE;
} else {
if (Config::sitemode() == Kohana::DEVELOPMENT)
SystemMessage::add(array('title'=>'Debug','type'=>'debug','body'=>'No user logged in'));
}
return $status;
}
/**
* Gets the currently logged in user from the session.
* Returns FALSE if no user is currently logged in.
*
* @param boolean Check token users too
* @return mixed
*/
public function get_user($tokenuser=TRUE) {
$user = parent::get_user();
// If we are not logged in, see if there is token for the usre
if ($tokenuser AND $user === FALSE AND $token=Session::instance()->get('token')) {
$user = $this->_get_token_user($token);
}
return $user;
}
/**
* Get the user that a token applies to
*
* This will check that the token is valid (not expired and for the request)
*
* @param $token The token
* @return mixed The user
*/
private function _get_token_user($token) {
$mmto = ORM::factory('module_method_token',array('token'=>$token));
$user = FALSE;
if ($mmto->loaded()) {
if ($mmto->date_expire < time()) {
SystemMessage::add(array(
'title'=>_('Token Not Valid'),
'type'=>'warning',
'body'=>_('Token expired')));
Session::instance()->delete('token');
$mmto->delete();
} else {
// Check that the token is for this URI
$mo = ORM::factory('module',array('name'=>Request::current()->controller()));
$mmo = ORM::factory('module_method',
array('name'=>Request::current()->directory() ? sprintf('%s_%s',Request::current()->directory(),Request::current()->action()) : Request::current()->action()));
// Ignore the token if this is not the right method.
if ($mmo->id == $mmto->method_id) {
// @todo Implement single use tokens
Session::instance()->set('token',$token);
$user = ORM::factory('account',$mmto->account_id);
}
}
}
return $user;
}
/**
* Logs a user in.
*
* @param string username
* @param string password
* @param boolean enable autologin
* @return boolean
*/
protected function _login($user, $password, $remember)
{
if ( ! is_object($user))
{
$username = $user;
// Load the user
$user = ORM::factory('account');
$user->where($user->unique_key($username), '=', $username)->find();
}
// If the passwords match, perform a login
if ($user->status AND $user->has_any('group',ORM::factory('group',array('name'=>'Registered Users'))->list_childgrps(TRUE)) AND $user->password === $password)
{
if ($remember === TRUE)
{
// Create a new autologin token
$token = ORM::factory('user_token');
// Set token data
$token->user_id = $user->id;
$token->expires = time() + $this->_config['lifetime'];
$token->save();
// Set the autologin cookie
Cookie::set('authautologin', $token->token, $this->_config['lifetime']);
}
// Record our session ID, we may need to update our DB when we get a new ID
$oldsess = session_id();
// Finish the login
$this->complete_login($user);
// Do we need to update databases with our new sesion ID
// @todo figure out where this is best to go
$session_change_trigger = array('cart'=>'session_id');
if (count($session_change_trigger) AND (session_id() != $oldsess)) {
foreach ($session_change_trigger as $t => $c) {
if (Config::moduleexist($c)) {
$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();
}
}
}
return TRUE;
}
// Login failed
return FALSE;
}
/**
* Determine if a user is authorised to view an account
*
* @param integer Account ID
*
* @return boolean TRUE if authorised, FALSE if not.
*/
public function authorised($aid,$afid=NULL) {
return (($ao = $this->get_user()) AND $ao->loaded() AND ($aid == $ao->id OR $ao->isAdmin() OR (! is_null($afid) AND $afid == $ao->affiliate->id))) ? TRUE : FALSE;
}
}
?>

View File

@@ -1,14 +1,14 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class is for access company informaiton.
* This class is for access company information.
*
* @package OSB
* @subpackage Page
* @subpackage System
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Company {
public static function instance() {

View File

@@ -1,5 +1,15 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class is for access system configuration.
*
* @package OSB
* @subpackage Config
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Config extends lnApp_Config {
// Our setup object
public $so;
@@ -28,18 +38,18 @@ class Config extends lnApp_Config {
* Our available modules are defined in the DB (along with method
* security).
*/
public static function appmodules() {
$modules = array();
$module_table = 'module';
public static function modules() {
static $return = array();
if (class_exists('Model_'.ucfirst($module_table))) {
$mo = ORM::factory($module_table)->where('status','=',1)->find_all()->as_array();
if (! count($return))
foreach (ORM::factory('module')->where('status','=',1)->find_all() as $mo)
$return[$mo->name] = MODPATH.$mo->name;
foreach ($mo as $o)
$modules[$o->name] = MODPATH.$o->name;
}
return $return;
}
return $modules;
public static function moduleexist($module) {
return array_key_exists($module,static::modules()) ? TRUE : FALSE;
}
}
?>

View File

@@ -0,0 +1,16 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides account management
*
* @package lnApp
* @subpackage Page/Account
* @category Controllers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
* @also [logout]
*/
class Controller_Account extends Controller_TemplateDefault {
}
?>

View File

@@ -32,7 +32,8 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault {
'due_date'=>array('label'=>'Due Date'),
'account->name()'=>array('label'=>'Account'),
'account->display("status")'=>array('label'=>'Active'),
'id()'=>array('label'=>'ID'),
'id'=>array('label'=>'ID','url'=>'user/invoice/view/'),
'total_amt'=>array('label'=>'Total','class'=>'right'),
'due(TRUE)'=>array('label'=>'Amount Due','class'=>'right'),
),
array('page'=>TRUE)),
@@ -49,7 +50,8 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault {
'due_date'=>array('label'=>'Due Date'),
'account->name()'=>array('label'=>'Account'),
'account->display("status")'=>array('label'=>'Active'),
'id()'=>array('label'=>'ID'),
'id'=>array('label'=>'ID','url'=>'user/invoice/view/'),
'total_amt'=>array('label'=>'Total','class'=>'right'),
'due(TRUE)'=>array('label'=>'Amount Due','class'=>'right'),
),
array('page'=>TRUE)),
@@ -60,13 +62,14 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault {
Block_Sub::add(array(
'title'=>'Invoices Due',
'body'=>Table::display(
$o->list_due($t),
$o->list_due(),
25,
array(
'due_date'=>array('label'=>'Due Date'),
'account->name()'=>array('label'),
'account->display("status")'=>array('label'=>'Active'),
'id()'=>array('label'=>'ID'),
'id'=>array('label'=>'ID','url'=>'user/invoice/view/'),
'total_amt'=>array('label'=>'Total','class'=>'right'),
'due(TRUE)'=>array('label'=>'Amount Due','class'=>'right'),
),
array('show_other'=>'due()')),
@@ -83,9 +86,10 @@ class Controller_Admin_Welcome extends Controller_TemplateDefault {
$o->list_unapplied(),
25,
array(
'id'=>array('label'=>'ID'),
'date_payment'=>array('label'=>'Pay Date'),
'account->name()'=>array('label'=>'Account'),
'account->display("status")'=>array('label'=>'Active'),
'id'=>array('label'=>'ID','url'=>'user/payment/view/'),
'total_amt'=>array('label'=>'Total','class'=>'right'),
'balance(TRUE)'=>array('label'=>'Balance','class'=>'right'),
),

View File

@@ -152,6 +152,15 @@ abstract class Controller_lnApp_TemplateDefault extends Controller_Template {
$this->meta->title = Kohana::Config('config.appname');
$this->template->title = '';
// Language
$this->meta->language = Config::instance()->so->language_id;
// Copyright
$this->meta->copywrite = Config::instance()->so->site_name;
// Copyright
$this->meta->description = sprintf('%s::%s',$this->request->controller(),$this->request->action());
// Style Sheets Properties
$this->meta->styles = Style::factory();

View File

@@ -39,7 +39,7 @@ class Controller_TemplateDefault extends Controller_lnApp_TemplateDefault {
}
private function _cart() {
if (! class_exists('cart') OR ! Cart::instance()->contents()->reset(FALSE)->count_all())
if (! Config::moduleexist('cart') OR ! class_exists('cart') OR ! Cart::instance()->contents()->reset(FALSE)->count_all())
return '';
return Cart::instance()->cart_block();

View File

@@ -11,5 +11,20 @@
* @license http://dev.leenooks.net/license.html
*/
class Controller_TemplateDefault_Affiliate extends Controller_TemplateDefault_User {
/**
* This will filter a search query to only return the affiliates
*/
protected function filter($o,$af,$sort='account->name()',$afid='affiliate_id') {
$result = array();
foreach ($o as $x)
if ($x->$afid == $af)
array_push($result,$x);
if ($sort)
Sort::MAsort($result,$sort);
return $result;
}
}
?>

View File

@@ -35,7 +35,7 @@ class Controller_Tree extends Controller_lnApp_Tree {
if ($mmo->menu_display AND empty($modules[$mmo->module_id]))
$modules[$mmo->module_id] = $mmo->module;
Sort::masort($modules,'name');
Sort::MAsort($modules,'name');
foreach ($modules as $id => $mo)
if (! $mo->parent_id)
@@ -52,7 +52,7 @@ class Controller_Tree extends Controller_lnApp_Tree {
if ($user->has_any('group',$gmo->list_childgrps(TRUE)))
$methods[$mmo->id] = $mmo;
Sort::masort($modules,'name');
Sort::MASort($modules,'name');
foreach ($methods as $id => $mmo) {
if (preg_match('/_/',$mmo->name)) {

View File

@@ -0,0 +1,111 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides User Account Update functions
*
* @package OSB
* @subpackage Account
* @category Controllers/User
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Controller_User_Account extends Controller_TemplateDefault_User {
protected $secure_actions = array(
'edit'=>TRUE,
'resetpassword'=>TRUE,
);
public function action_resetpassword() {
// @todo Fix this next logic, since matches_ifset is not being called when the value is on the form, but empty
if (empty($_POST['password_confirm']))
$_POST['password_confirm'] = ' ';
// Store our new values
$this->ao->values($_POST);
// Run validation and save
if ($this->ao->changed())
if ($this->ao->check()) {
SystemMessage::add(array(
'title'=>_('Record updated'),
'type'=>'info',
'body'=>_('Your account record has been updated.')
));
$this->ao->save();
// Log the password reset
$this->ao->log('Password reset');
Request::current()->redirect('login');
} else {
$output = '';
foreach ($this->ao->validation()->errors('forms/login') as $field => $error)
$output .= sprintf('<li><b>%s</b> %s</li>',$field,$error);
if ($output)
$output = sprintf('<ul>%s</ul>',$output);
SystemMessage::add(array(
'title'=>_('Record NOT updated'),
'type'=>'error',
'body'=>_('Your updates didnt pass validation.').'<br/>'.$output,
));
}
else
SystemMessage::add(array(
'title'=>_('Record NOT updated'),
'type'=>'info',
'body'=>_('Your account has NOT been updated.')
));
Block::add(array(
'title'=>_('Password Reset'),
'body'=>View::factory('account/password_reset')
->set('record',$this->ao),
));
}
/**
* Show a product
*/
public function action_edit() {
// Store our new values
$this->ao->values($_POST);
// Run validation and save
if ($this->ao->changed())
if ($this->ao->check()) {
SystemMessage::add(array(
'title'=>_('Record updated'),
'type'=>'info',
'body'=>_('Your account record has been updated.')
));
$this->ao->save();
} else {
$output = '';
foreach ($this->ao->validation()->errors('forms/login') as $field => $error)
$output .= sprintf('<li><b>%s</b> %s</li>',$field,$error);
if ($output)
$output = sprintf('<ul>%s</ul>',$output);
SystemMessage::add(array(
'title'=>_('Record NOT updated'),
'type'=>'error',
'body'=>_('Your updates didnt pass validation.').'<br/>'.$output,
));
}
Block::add(array(
'title'=>sprintf('%s: %s - %s',_('Account Edit'),$this->ao->accnum(),$this->ao->name(TRUE)),
'body'=>View::factory('account/user/edit')
->set('record',$this->ao),
));
}
}
?>

View File

@@ -0,0 +1,21 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class provides Country routines
*
* @package OSB
* @subpackage Cart
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Country {
public static function icon($cid) {
// @todo alt character should be country specific
// @todo This doesnt correctly get the right 3 character country code - it should be obtained from a join with country/currency
return HTML::image(sprintf('media/img/country/%s.gif',StaticList_Module::record('country','two_code','id',$cid)),array('alt'=>'$','style'=>'border: 0px;'));
return sprintf('media/img/country/%s.gif',StaticList_Module::record('country','three_code','id',$cid));
}
}
?>

View File

@@ -0,0 +1,18 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This is class is for all page attributes.
*
* @package OSB
* @category Helpers
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Currency {
public static function display($amount) {
// @todo $cid and therefore precision should come from a global session value.
return Num::format($amount,2,TRUE);
}
}
?>

View File

@@ -92,7 +92,7 @@ abstract class lnApp_Config extends Kohana_Config {
* Show a date using a site configured format
*/
public static function date($date) {
return date(Kohana::config('config.date_format'),$date);
return $date ? date(Kohana::config('config.date_format'),$date) : '&gtNot Set&lt';
}
/**

View File

@@ -20,75 +20,64 @@ class lnApp_Sort {
* @param boolean Whether to reverse sort.
* @return array Sorted multi demension array.
*/
public static function masort(&$data,$sortby,$rev=0) {
// if the array to sort is null or empty
if (! $data)
public static function MAsort(&$data,$sortby,$rev=0) {
// if the array to sort is null or empty, or our sortby is bad
if (! preg_match('/^[a-zA-Z0-9_]+(\([a-zA-Z0-9_,]*\))?$/',$sortby) || ! $data)
return;
$code = "\$c=0;\n";
$code = '$c=0;';
foreach (explode(',',$sortby) as $key) {
$code .= "if (is_object(\$a) || is_object(\$b)) {\n";
$code .= 'if (is_object($a) || is_object($b)) {';
foreach (array('a','b') as $x) {
$code .= 'if (is_array($'.$x.'->'.$key.')) {';
$code .= 'asort($'.$x.'->'.$key.');';
$code .= '$x'.$x.' = array_shift($'.$x.'->'.$key.');';
$code .= '} else';
$code .= '$x'.$x.' = $'.$x.'->'.$key.';';
}
$code .= " if (is_array(\$a->$key)) {\n";
$code .= " asort(\$a->$key);\n";
$code .= " \$aa = array_shift(\$a->$key);\n";
$code .= " } else\n";
$code .= " \$aa = \$a->$key;\n";
$code .= " if (is_array(\$b->$key)) {\n";
$code .= " asort(\$b->$key);\n";
$code .= " \$bb = array_shift(\$b->$key);\n";
$code .= " } else\n";
$code .= " \$bb = \$b->$key;\n";
$code .= " if (\$aa != \$bb)";
$code .= 'if ($xa != $xb)';
if ($rev)
$code .= " return (\$aa < \$bb ? 1 : -1);\n";
$code .= 'return ($xa < $xb ? 1 : -1);';
else
$code .= " return (\$aa > \$bb ? 1 : -1);\n";
$code .= 'return ($xa > $xb ? 1 : -1);';
$code .= "} else {\n";
$code .= '} else {';
$code .= " \$a = array_change_key_case(\$a);\n";
$code .= " \$b = array_change_key_case(\$b);\n";
foreach (array('a','b') as $x)
$code .= '$'.$x.' = array_change_key_case($'.$x.');';
$key = strtolower($key);
$code .= " if ((! isset(\$a['$key'])) && isset(\$b['$key'])) return 1;\n";
$code .= " if (isset(\$a['$key']) && (! isset(\$b['$key']))) return -1;\n";
$code .= 'if ((! isset($a[\''.$key.'\'])) && isset($b[\''.$key.'\'])) return 1;';
$code .= 'if (isset($a[\''.$key.'\']) && (! isset($b[\''.$key.'\']))) return -1;';
$code .= " if ((isset(\$a['$key'])) && (isset(\$b['$key']))) {\n";
$code .= " if (is_array(\$a['$key'])) {\n";
$code .= " asort(\$a['$key']);\n";
$code .= " \$aa = array_shift(\$a['$key']);\n";
$code .= " } else\n";
$code .= " \$aa = \$a['$key'];\n";
$code .= 'if ((isset($a[\''.$key.'\'])) && (isset($b[\''.$key.'\']))) {';
foreach (array('a','b') as $x) {
$code .= 'if (is_array($'.$x.'[\''.$key.'\'])) {';
$code .= 'asort($'.$x.'[\''.$key.'\']);';
$code .= '$x'.$x.' = array_shift($'.$x.'[\''.$key.'\']);';
$code .= '} else';
$code .= '$x'.$x.' = $'.$x.'[\''.$key.'\'];';
}
$code .= " if (is_array(\$b['$key'])) {\n";
$code .= " asort(\$b['$key']);\n";
$code .= " \$bb = array_shift(\$b['$key']);\n";
$code .= " } else\n";
$code .= " \$bb = \$b['$key'];\n";
$code .= " if (\$aa != \$bb)\n";
$code .= " if (is_numeric(\$aa) && is_numeric(\$bb)) {\n";
$code .= 'if ($xa != $xb)';
$code .= 'if (is_numeric($xa) && is_numeric($xb)) {';
if ($rev)
$code .= " return (\$aa < \$bb ? 1 : -1);\n";
$code .= 'return ($xa < $xb ? 1 : -1);';
else
$code .= " return (\$aa > \$bb ? 1 : -1);\n";
$code .= 'return ($xa > $xb ? 1 : -1);';
$code .= " } else {\n";
$code .= '} else {';
if ($rev)
$code .= " if ( (\$c = strcasecmp(\$bb,\$aa)) != 0 ) return \$c;\n";
$code .= 'if (($c = strcasecmp($xb,$xa)) != 0) return $c;';
else
$code .= " if ( (\$c = strcasecmp(\$aa,\$bb)) != 0 ) return \$c;\n";
$code .= 'if (($c = strcasecmp($xa,$xb)) != 0) return $c;';
$code .= " }\n";
$code .= " }\n";
$code .= "}\n";
$code .= '}}}';
}
$code .= 'return $c;';

View File

@@ -201,7 +201,7 @@ $(document).ready(function() {
break;
}
if ($pag OR ($i++ < $rows)) {
if ($pag OR ($i++ < $rows) OR is_null($rows)) {
foreach (array_keys($cols) as $col)
$td[$col]['value'] = Table::resolve($do,$col);

View File

@@ -0,0 +1,127 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Account extends Model_Auth_UserDefault {
// Relationships
protected $_has_many = array(
'user_tokens' => array('model' => 'user_token'),
'email_log' => array('far_key'=>'id'),
'group' => array('through' => 'account_group'),
'invoice' => array('far_key'=>'id'),
'payment'=>array('far_key'=>'id'),
'service' => array('far_key'=>'id'),
);
protected $_has_one = array(
'affiliate' => array('far_key'=>'id'),
);
protected $_display_filters = array(
'date_orig'=>array(
array('Config::date',array(':value')),
),
'date_last'=>array(
array('Config::date',array(':value')),
),
'status'=>array(
array('StaticList_YesNo::display',array(':value')),
),
);
/**
* Return an account name
*/
public function name($withcompany=FALSE) {
if ($withcompany)
return sprintf('%s %s (%s)',$this->first_name,$this->last_name,$this->company);
else
return sprintf('%s %s',$this->first_name,$this->last_name);
}
public function accnum() {
return sprintf('%02s-%04s',Config::siteid(),$this->id);
}
public function title($name) {
return StaticList_Title::form($name,$this->title);
}
public function currency($name) {
return StaticListModule::form($name,'currency',$this->currency_id,'id','name',array());
}
public function country($name) {
return StaticListModule::form($name,'country',$this->country_id,'id','name',array());
}
public function language($name) {
// @todo To setup
return 'en';
}
/**
* Get the groups that an account belongs to
*/
public function groups() {
return $this->group->find_all();
}
public function isAdmin() {
// @todo Define admins in the config file or DB
$admins = array(ORM::factory('group',array('name'=>'Root')));
return $this->has('group',$admins);
}
/**
* Get a list of all invoices for this account
*/
public function invoices() {
return $this->invoice->distinct('id')->find_all();
}
/**
* Get a list of due invoices for this account
*
* @param int Date (in secs) to only retrieve invoices prior to this date
*/
public function invoices_due($date=NULL) {
$return = array();
foreach ($this->invoices() as $io)
if ((is_null($date) OR $io->date_orig < $date) AND $io->due())
$return[$io->id] = $io;
return $return;
}
/**
* Calculate the total of invoices due for this account
*/
public function invoices_due_total($date=NULL,$format=FALSE) {
$result = 0;
foreach ($this->invoices_due($date) as $io)
$result += $io->due();
return $format ? Currency::display($result) : $result;
}
public function log($message) {
// Log the logout
$alo = ORM::factory('account_log');
$alo->account_id = $this->id;
$alo->ip = $_SERVER['REMOTE_ADDR'];
$alo->details = $message;
$alo->save();
return $alo->saved();
}
}
?>

View File

@@ -0,0 +1,24 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* This class supports Account Login Logging
*
* @package OSB
* @subpackage Account
* @category Models
* @author Deon George
* @copyright (c) 2010 Open Source Billing
* @license http://dev.osbill.net/license.html
*/
class Model_Account_Log extends ORMOSB {
protected $_belongs_to = array(
'account'=>array(),
);
protected $_display_filters = array(
'date_orig'=>array(
array('Config::datetime',array(':value')),
),
);
}
?>

View File

@@ -0,0 +1,13 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Auth_RoleDefault extends Model_Auth_Role {
}
?>

View File

@@ -0,0 +1,83 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Auth_UserDefault extends Model_Auth_User {
// Validation rules
public function rules() {
return array(
'username' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 32)),
),
'password' => array(
array('not_empty'),
array('min_length', array(':value', 5)),
array('max_length', array(':value', 32)),
),
'email' => array(
array('not_empty'),
array('min_length', array(':value', 4)),
array('max_length', array(':value', 127)),
array('email'),
),
// @todo To test
'password_confirm' => array(
array('matches_ifset', array(':validation', 'password', 'password_confirm')),
),
);
}
// Validation callbacks
// @todo _callbacks no longer used
protected $_callbacks = array(
'username' => array('username_available'),
'email' => array('email_available'),
);
// Columns to ignore
protected $_ignored_columns = array('password_confirm');
/*
* Complete our login
*
* For some database logins, we may not want to record the user last login
* details in the repository, so we just override that parent function
* here.
*
* We can also do some other post-login actions here.
* @todo Maybe we can do our session update here.
*/
public function complete_login() {
return $this->log('Logged In');
}
/**
* Test to see if a record has been changed
*/
public function changed() {
return ! (empty($this->_changed));
}
/**
* Debug function to see that has() finds
* @todo This function could be removed
*/
public function has_list($alias, $model) {
// Return list of matches
return DB::select()
->from($this->_has_many[$alias]['through'])
->where($this->_has_many[$alias]['foreign_key'], '=', $this->pk())
->where($this->_has_many[$alias]['far_key'], '=', $model->pk())
->execute($this->_db)
->as_array();
}
}
?>

View File

@@ -0,0 +1,15 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Country Model
*
* @package OSB
* @subpackage Modules
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Country extends ORMOSB {
}
?>

View File

@@ -0,0 +1,84 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* @package lnApp
* @subpackage Auth
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Group extends Model_Auth_RoleDefault {
// Relationships
protected $_has_many = array(
'account'=>array('through'=>'account_group'),
'module_method'=>array('through'=>'group_method','far_key'=>'method_id'),
);
protected $_sorting = array(
'name'=>'ASC',
);
// Validation rules
protected $_rules = array(
'name' => array(
'not_empty' => NULL,
'min_length' => array(4),
'max_length' => array(32),
),
'description' => array(
'max_length' => array(255),
),
);
protected $_display_filters = array(
'status'=>array(
array('StaticList_YesNo::display',array(':value')),
),
);
/**
* This function will, given a group, list all of the children that
* are also related to this group, in the group heirarchy.
*/
public function list_childgrps($incParent=FALSE) {
$return = array();
if (! $this->loaded())
return $return;
foreach (ORM::factory('group')->where('status','=',1)->and_where('parent_id','=',$this)->find_all() as $go) {
array_push($return,$go);
$return = array_merge($return,$go->list_childgrps());
}
if ($incParent)
array_push($return,$this);
return $return;
}
/**
* This function will, given a group, list all of the parent that
* are also related to this group, in the group heirarchy.
*/
public function list_parentgrps($incParent=FALSE) {
$return = array();
if (! $this->loaded())
return $return;
foreach (ORM::factory('group')->where('status','=',1)->and_where('id','=',$this->parent_id)->find_all() as $go) {
array_push($return,$go);
$return = array_merge($return,$go->list_parentgrps());
}
if ($incParent)
array_push($return,$this);
return $return;
}
}
?>

View File

@@ -0,0 +1,21 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
/**
* OSB Setup Model
*
* This module must remain in applications/ as it is used very early in the
* OSB initialisation.
*
* @package OSB
* @subpackage Modules
* @category Models
* @author Deon George
* @copyright (c) 2010 Deon George
* @license http://dev.leenooks.net/license.html
*/
class Model_Setup extends ORMOSB {
protected $_has_one = array(
'country'=>array('foreign_key'=>'id','far_key'=>'country_id'),
);
}
?>

View File

@@ -1,4 +1,4 @@
<?php defined('SYSPATH') or die('No direct access allowed.');
class sort extends lnApp_Sort {}
class Sort extends lnApp_Sort {}
?>