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 @@
+