diff --git a/application/classes/Config.php b/application/classes/Config.php index 7e8fcae..243e41d 100644 --- a/application/classes/Config.php +++ b/application/classes/Config.php @@ -38,8 +38,8 @@ class Config extends Kohana_Config { return Config::$_instance; } - public static function Copywrite() { - return '(c) 2014 Deon George'; + public static function Copywrite($html=FALSE) { + return ($html ? '©' : '(c)').' 2014 Deon George'; } public static function version() { diff --git a/application/classes/Controller/Admin/Module.php b/application/classes/Controller/Admin/Module.php new file mode 100644 index 0000000..646afba --- /dev/null +++ b/application/classes/Controller/Admin/Module.php @@ -0,0 +1,187 @@ +TRUE, + 'edit'=>TRUE, + 'list'=>TRUE, + ); + + protected function _classes($dir,$class,$array=NULL,$key='') { + $result = array(); + + if (is_null($array)) { + $key = 'classes/Controller'; + $array = Arr::get(Kohana::list_files('classes'),$key); + } + + if (! $class) + return array_keys($array); + + if (! $dir) { + if (! empty($array[$key.'/'.$class])) + $result = Arr::merge($result,$this->_classes('','',$array[$key.'/'.$class],$key.'/'.$class)); + + if (! empty($array[$key.'/'.$class.'.php'])) + array_push($result,$key.'/'.$class); + + } else { + if (! empty($array[$key.'/'.$dir])) + $result = Arr::merge($result,$this->_classes('',$class,$array[$key.'/'.$dir],$key.'/'.$dir)); + + if (! empty($array[$key.'/'.$dir.'/'.$class.'.php'])) + array_push($result,$key.'/'.$dir.'/'.$class); + } + + foreach ($result as $k=>$v) + $result[$k] = str_replace('.php','',str_replace('/','_',preg_replace('/^classes\//','',$v))); + + return $result; + } + + /** + * Get the list of methods for a class + */ + protected function _methods($class) { + $class = Kohana::classname($class); + // Get a list of methods this module has + $methods = $secure_actions = $auth_required = array(); + + // List of classes where all our methods are, including this one. + $classes = URL::$method_directory; + array_unshift($classes,''); + + foreach ($classes as $c) { + $x = URL::dir($c); + $cp = $this->_classes($x,$class); + + foreach ($cp as $cn) + if (class_exists($cn)) { + $sc = preg_replace(sprintf('/^Controller_%s%s_?/',$x ? $x.'_' : '',$class),'',$cn); + $r = new ReflectionClass($cn); + + $rdp = $r->getDefaultProperties(); + $secure_actions[$cn] = $rdp['secure_actions']; + $auth_required[$cn] = $rdp['auth_required']; + + foreach ($r->getMethods() as $method) + if ($method->class == $cn AND preg_match('/^action_/',$method->name)) + array_push($methods,str_replace('action_',strtolower($x.($sc ? '_'.$sc : '').':'),$method->name)); + } + } + + return array('methods'=>$methods,'secure_actions'=>$secure_actions,'auth_required'=>$auth_required); + } + + /** + * Edit a Module Configuration + */ + public function action_edit() { + $id = $this->request->param('id'); + $mo = ORM::factory('Module',$id); + + $methods = array(); + + if (! $mo->loaded()) { + SystemMessage::factory() + ->title(_('Invalid Module ID')) + ->type('error') + ->body(sprintf(_('Module with ID %s doesnt appear to exist?'),$id)); + + HTTP::redirect(URL::link('admin','module/list')); + } + + $mm = $this->_methods($mo->name); + $methods['exist'] = array(); + foreach ($mo->module_method->find_all() as $mmo) { + if (in_array($mmo->name,$mm['methods'])) { + $k = array_search($mmo->name,$mm['methods']); + unset($mm['methods'][$k]); + + $mmo->status('INDB'); + } else + $mmo->status('ORPHAN'); + + if (! empty($mm['secure_actions'][$mmo->controller()][$mmo->method()])) + unset($mm['secure_actions'][$mmo->controller()][$mmo->method()]); + + array_push($methods['exist'],$mmo); + } + + $methods['missing'] = array(); + foreach ($mm['methods'] as $k=>$method) { + $mmo = ORM::factory('Module_Method'); + $mmo->module_id = $mo->id; + $mmo->name = $method; + + if (! empty($mm['auth_required'][$mmo->controller()]) AND $mm['auth_required'][$mmo->controller()]) + $mmo->status('MISSING'); + + array_push($methods['missing'],$mmo); + } + + Block::factory() + ->title(sprintf('%s: %s ',_('Defined Module Methods For'),$mo->display('name'))) + ->title_icon('icon-cog') + ->body(Table::factory() + ->data($methods['exist']) + ->columns(array( + 'id'=>'ID', + 'name'=>'Name', + 'notes'=>'Notes', + 'menu_display'=>'Menu', + 'status()'=>'Status', + )) + ->prepend(array( + 'id'=>array('url'=>URL::link('admin','module_method/edit/')), + )) + ); + + Block::factory() + ->title(sprintf('%s: %s ',_('Missing Module Methods For'),$mo->display('name'))) + ->title_icon('icon-exclamation-sign') + ->body(Table::factory() + ->data($methods['missing']) + ->columns(array( + 'name'=>'Name', + 'status()'=>'Status', + )) + ->prepend(array( + 'name'=>array('url'=>URL::link('admin','module_method/add/'.$mo->id.'/')), + )) + ); + } + + /** + * List our installed modules + */ + public function action_list() { + Block::factory() + ->title('Defined Modules') + ->title_icon('icon-cog') + ->body(Table::factory() + ->data(ORM::factory('Module')->where('parent_id','is',NULL)->find_all()) + ->jssort(TRUE) + ->columns(array( + 'id'=>'ID', + 'name'=>'Name', + 'notes'=>'Notes', + 'status'=>'Active', + 'external'=>'External', + )) + ->prepend(array( + 'id'=>array('url'=>URL::link('admin','module/edit/')), + )) + ); + } +} +?> diff --git a/application/classes/Controller/Admin/Module/Method.php b/application/classes/Controller/Admin/Module/Method.php new file mode 100644 index 0000000..c674c51 --- /dev/null +++ b/application/classes/Controller/Admin/Module/Method.php @@ -0,0 +1,109 @@ +request->param('id'); + $method = $this->request->param('sid'); + + $mo = ORM::factory('Module',$id); + $mm = $this->_methods($mo->name); + + if (! $mo->loaded() OR ! in_array($method,$mm['methods'])) + HTTP::redirect(URL::link('admin','module/list')); + + if ($_POST) { + $mmo = $mo->module_method; + $mmo->name = $method; + $mmo->module_id = $mo->id; + $mmo->values($_POST); + + if (! $this->save($mmo)) + throw HTTP_Exception::factory(501,'Unable to save data :post',array(':post'=>serialize($_POST))); + + HTTP::redirect(URL::link('admin','module/edit/'.$mo->id)); + } + + Block::factory() + ->title(sprintf(_('Add Method (%s) to Database for (%s)'),strtoupper($method),strtoupper($mo->name))) + ->title_icon('icon-plus-sign') + ->type('form-horizontal') + ->body(View::factory('module/method/admin/add') + ->set('name',$method) + ->set('o',$mo) + ); + } + + /** + * Edit a Module Configuration + */ + public function action_edit() { + $id = $this->request->param('id'); + $mmo = ORM::factory('Module_Method',$id); + + if (! $mmo->loaded()) { + SystemMessage::factory() + ->title(_('Invalid Method ID')) + ->type('error') + ->body(sprintf(_('Method with ID %s doesnt appear to exist?'),$id)); + + HTTP::redirect(URL::link('admin','module/list')); + } + + if ($_POST) { + $mmo->values($_POST); + + if (! $this->save($mmo)) + throw HTTP_Exception::factory(501,'Unable to save data :post',array(':post'=>serialize($_POST))); + + foreach (ORM::factory('Group')->find_all() as $go) { + // If the group was defined and no longer + if ($mmo->has('group',$go) AND (! isset($_POST['groups']) OR ! in_array($go->id,$_POST['groups']))) { + $gmo = ORM::factory('Group_Method',array('method_id'=>$mmo->id,'group_id'=>$go->id)); + + if (! $gmo->delete()) + SystemMessage::factory() + ->title(_('Unable to DELETE Group Method')) + ->type('error') + ->body(sprintf(_('Unable to delete Group Method for method %s and group %s'),$mmo->name,$go->name)); + + // If the group was not defined and now is + } elseif (! $mmo->has('group',$go) AND isset($_POST['groups']) AND in_array($go->id,$_POST['groups'])) { + $gmo = ORM::factory('Group_Method') + ->values(array( + 'method_id'=>$mmo->id, + 'group_id'=>$go->id, + )); + + if (! $this->save($gmo)) + SystemMessage::factory() + ->title(_('Unable to SAVE Group Method')) + ->type('error') + ->body(sprintf(_('Unable to save Group Method for method %s and group %s'),$mmo->name,$go->name)); + } + } + + HTTP::redirect(URL::link('admin','module/edit/'.$mmo->module_id)); + } + + Block::factory() + ->title(sprintf(_('Configure access to method (%s::%s)'),$mmo->controller(),$mmo->method())) + ->title_icon('icon-plus-sign') + ->type('form') + ->body(View::factory('module/method/admin/edit') + ->set('o',$mmo) + ); + } +} +?> diff --git a/application/classes/Controller/Module.php b/application/classes/Controller/Module.php new file mode 100644 index 0000000..a58989a --- /dev/null +++ b/application/classes/Controller/Module.php @@ -0,0 +1,14 @@ + diff --git a/application/classes/Controller/TemplateDefault.php b/application/classes/Controller/TemplateDefault.php new file mode 100644 index 0000000..fa8bdc1 --- /dev/null +++ b/application/classes/Controller/TemplateDefault.php @@ -0,0 +1,46 @@ +save(); + + } catch (ORM_Validation_Exception $e) { + SystemMessage::factory() + ->title('Record NOT updated') + ->type('error') + ->body(join('
',array_values($e->errors('models')))); + + return FALSE; + } + } + + protected function setup(array $config_items=array()) { + $mo = ORM::factory('Module',array('name'=>Request::current()->controller())); + if (! $mo->loaded()) + throw HTTP_Exception::factory(501,'Unknown module :module',array(':module'=>Request::current()->controller())); + + if ($_POST AND isset($_POST['module_config'][$mo->id])) + Config::instance()->module_config($mo->name,$_POST['module_config'][$mo->id])->save(); + + if ($config_items) { + Block::factory() + ->title('Update Module Configuration') + ->title_icon('icon-wrench') + ->type('form-horizontal') + ->body(View::factory('setup/admin/module')->set('o',Company::instance()->so())->set('mid',$mo->id)); + } + } +} +?> diff --git a/application/classes/Controller/Welcome.php b/application/classes/Controller/Welcome.php index 95f0470..9e82ace 100644 --- a/application/classes/Controller/Welcome.php +++ b/application/classes/Controller/Welcome.php @@ -1,6 +1,7 @@ load('config')->appname) diff --git a/application/classes/Model/Group/Method.php b/application/classes/Model/Group/Method.php new file mode 100644 index 0000000..0899fbb --- /dev/null +++ b/application/classes/Model/Group/Method.php @@ -0,0 +1,25 @@ +array(), + ); + protected $_belongs_to = array( + 'group'=>array(), + ); + + // This module doesnt keep track of column updates automatically + protected $_created_column = FALSE; + protected $_updated_column = FALSE; +} +?> diff --git a/application/classes/Model/Module/Method.php b/application/classes/Model/Module/Method.php new file mode 100644 index 0000000..5c9be86 --- /dev/null +++ b/application/classes/Model/Module/Method.php @@ -0,0 +1,91 @@ +array(), + ); + protected $_has_one = array( + 'record_id'=>array(), + ); + protected $_has_many = array( + 'group'=>array('through'=>'group_method','foreign_key'=>'method_id') + ); + + protected $_sorting = array( + 'name'=>'ASC', + ); + + protected $_nullifempty = array( + 'menu_display', + ); + + protected $status; + + public function controller_sub() { + return substr_count($this->name,'_') ? substr($this->name,($x=strpos($this->name,'_')),strpos($this->name,':')-$x) : ''; + } + + public function controller() { + return Kohana::classname(sprintf('Controller%s_%s',($this->directory() ? '_' : '').$this->directory(),$this->module->name).$this->controller_sub()); + } + + public function directory() { + return substr($this->name,0,substr_count($this->name,'_') ? strpos($this->name,'_') : strpos($this->name,':')); + } + + public function method() { + return substr($this->name,strpos($this->name,':')+1); + } + + /** + * Get our Module_Method object for this request + */ + public function request_mmo(Request $ro) { + list($c,$x) = substr_count($ro->controller(),'_') ? explode('_',$ro->controller(),2) : array($ro->controller(),''); + + $mo = ORM::factory('Module',array('name'=>$c)); + + if ($mo->loaded() AND $mo->active) { + $method = strtolower($ro->directory() ? sprintf('%s:%s',$ro->directory() ? $ro->directory().($x ? '_'.$x : '') : $ro->action(),$ro->action()) : $ro->action()); + + // Get the method number + $mmo = $mo->module_method + ->where('name','=',$method) + ->find(); + + if ($mmo->loaded()) + return $mmo; + } + } + + public function status($status=NULL) { + if ($status) + $this->status = $status; + + return $this->status; + } + + public function url() { + if (! preg_match('/:/',$this->name)) + return NULL; + + list($type,$action) = preg_split('/:/',$this->name,2); + + return URL::link($this->directory(),$this->module->name.$this->controller_sub().'/'.$action); + } +} +?> diff --git a/application/classes/ORM.php b/application/classes/ORM.php index 4dc5fc9..7420c1b 100644 --- a/application/classes/ORM.php +++ b/application/classes/ORM.php @@ -154,19 +154,19 @@ abstract class ORM extends lnApp_ORM { * Function help to find records that are active */ public function list_active($active=TRUE) { - $x=($active ? $this->_where_active() : $this); + $x=($active ? $this->where_active() : $this); return $x->find_all(); } public function list_count($active=TRUE) { - $x=($active ? $this->_where_active() : $this); + $x=($active ? $this->where_active() : $this); return $x->find_all()->count(); } public function where_active() { - return $this->where('active','=',TRUE); + return $this->where($this->_table_name.'.active','=',TRUE); } public function where_authorised(Model_Account $ao=NULL,$aid='account_id') { diff --git a/application/classes/Request.php b/application/classes/Request.php new file mode 100644 index 0000000..f881439 --- /dev/null +++ b/application/classes/Request.php @@ -0,0 +1,28 @@ +request_mmo($this)); + } +} +?> diff --git a/application/classes/URL.php b/application/classes/URL.php index 4bee911..08e28a7 100644 --- a/application/classes/URL.php +++ b/application/classes/URL.php @@ -13,6 +13,7 @@ class URL extends lnApp_URL { // Our method paths for different functions public static $method_directory = array( 'admin'=>'a', + 'director'=>'d', 'committee'=>'c', 'user'=>'u', ); @@ -25,7 +26,10 @@ class URL extends lnApp_URL { case 'admin': $result[$k] = array('name'=>'Administrator','icon'=>'icon-globe'); break; - case 'committe': $result[$k] = array('name'=>'Reseller','icon'=>'icon-th-list'); + case 'director': $result[$k] = array('name'=>'Director','icon'=>'icon-th-list'); + break; + + case 'committee': $result[$k] = array('name'=>'Committee','icon'=>'icon-th-list'); break; case 'user': $result[$k] = array('name'=>Auth::instance()->get_user()->name(),'icon'=>'icon-user'); diff --git a/application/config/config.php b/application/config/config.php index 77eb350..dc1264d 100644 --- a/application/config/config.php +++ b/application/config/config.php @@ -3,6 +3,7 @@ return array ( 'appname' => 'Membership Database', + 'method_security' => TRUE, 'session_change_trigger'=>array( // Updates to tables to make when our session ID is changed ), 'theme' => 'focusbusiness', diff --git a/application/views/module/method/admin/add.php b/application/views/module/method/admin/add.php new file mode 100644 index 0000000..f4508cd --- /dev/null +++ b/application/views/module/method/admin/add.php @@ -0,0 +1,16 @@ +
+
+ Add Method + + 'Method','disabled','class'=>'col-sm-5')); ?> + 'Description','placeholder'=>'Method Description','class'=>'col-sm-7')); ?> + 'Menu Title','placeholder'=>'Menu Title','class'=>'col-sm-7')); ?> +
+ +
+
+ + +
+
+
diff --git a/application/views/module/method/admin/edit.php b/application/views/module/method/admin/edit.php new file mode 100644 index 0000000..510d172 --- /dev/null +++ b/application/views/module/method/admin/edit.php @@ -0,0 +1,42 @@ +
+
+ Method Details + + notes,array('label'=>'Description','placeholder'=>'Method Description','xclass'=>'col-md-5')); ?> + menu_display,array('label'=>'Menu Title','placeholder'=>'Menu Title','xclass'=>'col-md-5')); ?> + +
+
+ +
+
+ Method Security + + + + + + + + + + + find_all() as $go) : ?> + + + + + + + + +
MethodNotesGroup ActiveMethod Enable
id,TRUE),$go->display('name')); ?>display('notes'); ?>display('active'); ?>id,$o->has('group',$go)); ?>
+
+ +
+
+ + +
+
+