Index: language/en_us/plugin.php =================================================================== --- language/en_us/plugin.php (revision 0) +++ language/en_us/plugin.php (revision 0) @@ -0,0 +1,21 @@ + 'Plugin', + 'plugins' => 'Plugins', + 'list of plugins' => 'List of available plugins', + 'update plugins' => 'Update plugins', + + 'activated' => 'Activated', + 'deactivated' => 'De-activated', + 'what to do with data' => 'What do you want to do with the module associated data?', + 'delete data' => 'Purge ', + 'keep data' => 'Keep', + 'no plugins found' => 'No plugins found', + 'plugin activation failed' => 'Plugins failed to activate: %s', + 'plugins updated' => 'Plugins updated', + + ); // array + +?> Index: language/en_us/project_interface.php =================================================================== --- language/en_us/project_interface.php (revision 162) +++ language/en_us/project_interface.php (working copy) @@ -73,8 +73,8 @@ 'can manage milestones' => 'Manage milestones', 'can upload files' => 'Upload files', 'can manage files' => 'Manage files', - 'can assign to owners' => 'Assign tasks to members of owner company', - 'can assign to other' => 'Assign tasks to members of other clients', + 'can assign tasks to owner company' => 'Assign tasks to members of owner company', + 'can assign tasks to other clients' => 'Assign tasks to members of other clients', 'add by' => 'added by', 'edit by' => 'updated by', Index: init.php =================================================================== --- init.php (revision 162) +++ init.php (working copy) @@ -123,6 +123,21 @@ benchmark_timer_set_marker('Init application'); } // if + // here we will load plugin helper file + require_once 'plugins.php'; + + // Set plugin manager timer... + if (Env::isDebugging()) { + benchmark_timer_set_marker('Plugin Manager loaded'); + } // if + + require_once 'permissions.php'; + + // Set permission manager timer... + if (Env::isDebugging()) { + benchmark_timer_set_marker('Permission Manager loaded'); + } // if + // We need to call application.php after the routing is executed because // some of the application classes may need CONTROLLER, ACTION or $_GET // data collected by the matched route Index: application/plugins/empty.txt =================================================================== Index: application/permissions.php =================================================================== --- application/permissions.php (revision 0) +++ application/permissions.php (revision 0) @@ -0,0 +1,29 @@ +init(); + /* + * Convenience function for instance of PermissionManager used by hooks throughout + */ + function permission_manager() { + return PermissionManager::instance(); + } + + function add_permission($source, $permission_to_add) { + permission_manager()->addPermission($source,$permission_to_add); + } + + function remove_permission($source, $permission_to_remove) { + permission_manager()->removePermission($source,$permission_to_add); + } + + function remove_permission_source($source) { + permission_manager()->removeSource($source); + } +?> \ No newline at end of file Index: application/helpers/tabbednavigation.php =================================================================== --- application/helpers/tabbednavigation.php (revision 162) +++ application/helpers/tabbednavigation.php (working copy) @@ -7,7 +7,10 @@ * @return array */ function tabbed_navigation_items() { - return TabbedNavigation::instance()->getItems(); + // PLUGIN HOOK + return plugin_manager()->apply_filters('tabbed_navigation_items', + TabbedNavigation::instance()->getItems()); + // PLUGIN HOOK } // tabbed_navigation_items /** Index: application/helpers/application.php =================================================================== --- application/helpers/application.php (revision 162) +++ application/helpers/application.php (working copy) @@ -84,8 +84,8 @@ $logged_user = logged_user(); - $can_assign_to_owners = $logged_user->isMemberOfOwnerCompany() || $logged_user->getProjectPermission($project, ProjectUsers::CAN_ASSIGN_TO_OWNERS); - $can_assign_to_other = $logged_user->isMemberOfOwnerCompany() || $logged_user->getProjectPermission($project, ProjectUsers::CAN_ASSIGN_TO_OTHER); + $can_assign_to_owners = $logged_user->isMemberOfOwnerCompany() || $logged_user->getProjectPermission($project, PermissionManager::CAN_ASSIGN_TO_OWNERS); + $can_assign_to_other = $logged_user->isMemberOfOwnerCompany() || $logged_user->getProjectPermission($project, PermissionManager::CAN_ASSIGN_TO_OTHER); $grouped_users = $project->getUsers(true); Index: application/helpers/company_website.php =================================================================== --- application/helpers/company_website.php (revision 162) +++ application/helpers/company_website.php (working copy) @@ -51,6 +51,10 @@ get_url('dashboard', 'my_tasks') )); + // PLUGIN HOOK + plugin_manager()->do_action('add_dashboard_tab'); + // PLUGIN HOOK + tabbed_navigation_set_selected($selected); } // dashboard_tabbed_navigation @@ -86,6 +90,7 @@ define('ADMINISTRATION_TAB_CONFIGURATION', 'config'); define('ADMINISTRATION_TAB_TOOLS', 'tools'); define('ADMINISTRATION_TAB_UPGRADE', 'upgrade'); + define('ADMINISTRATION_TAB_PLUGINS', 'plugins'); /** * Prepare administration tabbed navigation @@ -135,6 +140,16 @@ lang('upgrade'), get_url('administration', 'upgrade') )); + add_tabbed_navigation_item(new TabbedNavigationItem( + ADMINISTRATION_TAB_PLUGINS, + lang('plugins'), + get_url('administration','plugins') + )); + + // PLUGIN HOOK + plugin_manager()->do_action('add_administration_tab'); + // PLUGIN HOOK + tabbed_navigation_set_selected($selected); } // administration_tabbed_navigation @@ -177,6 +192,11 @@ lang('my account'), get_url('account', 'index') )); + + // PLUGIN HOOK + plugin_manager()->do_action('add_my_account_tab'); + // PLUGIN HOOK + tabbed_navigation_set_selected($selected); } // account_tabbed_navigation Index: application/helpers/project_website.php =================================================================== --- application/helpers/project_website.php (revision 162) +++ application/helpers/project_website.php (working copy) @@ -78,6 +78,11 @@ lang('people'), get_url('project', 'people') )); + + // PLUGIN HOOK + plugin_manager()->do_action('add_project_tab'); + // PLUGIN HOOK + tabbed_navigation_set_selected($selected); } // dashboard_tabbed_navigation Index: application/models/PluginManager.class.php =================================================================== --- application/models/PluginManager.class.php (revision 0) +++ application/models/PluginManager.class.php (revision 0) @@ -0,0 +1,179 @@ +included = array(); + $this->filter_table = array(); + $activated_plugins = Plugins::getActivatedPlugins(); + + // now load each plugin + foreach(array_keys($activated_plugins) as $name) { + include_once 'plugins/'.$name.'/init.php'; + } // foreach + + // TODO : cleanup up old activated plugins without valid file?? + + } else { + PluginManager::instance()->init(); + } // if + } // init + + function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + if ( isset($this->filter_table[$tag][$priority]) ) { + foreach($this->filter_table[$tag][$priority] as $filter) { + if ( $filter['function'] == $function_to_add ) { + return false; + } // if + } // foreach + } // if + $this->filter_table[$tag][$priority][] = array('function'=>$function_to_add, + 'accepted_args'=>$accepted_args); + return true; + } // add_filter + + function remove_filter($tag, $function_to_remove, $priority = 10) { + $toret = false; + + if ( isset($this->filter_table[$tag][$priority]) ) { + foreach($this->filter_table[$tag][$priority] as $filter) { + if ( $filter['function'] != $function_to_remove ) { + $new_function_list[] = $filter; + } else { + $toret = true; + } // if + } // foreach + $this->filter_table[$tag][$priority] = $new_function_list; + } // if + return $toret; + } // remove_filter + + function do_action($tag,$arg='') { + + if ( !isset($this->filter_table[$tag]) ) { + return; + } else { + ksort($this->filter_table[$tag]); + } // if + + $args = array(); + if ( is_array($arg) && 1 == count($arg) && is_object($arg[0]) ) { + $args[] =& $arg[0]; + } else { + $args[] = $arg; + } // if + + for ( $a = 2; $a < func_num_args(); $a++ ) { + $args[] = func_get_arg($a); + } // for + + foreach ($this->filter_table[$tag] as $priority => $functions) { + if ( !is_null($functions) ) { + foreach($functions as $f) { + call_user_func_array($f['function'], array_slice($args, 0, (int)$f['accepted_args'])); + } // foreach + } // if + } // foreach + } // do_action + + function apply_filters($tag,$value) { + $args = func_get_args(); + + if ( !isset($this->filter_table[$tag]) ) { + return $value; + } else { + ksort($this->filter_table[$tag]); + } // if + + foreach ($this->filter_table[$tag] as $priority => $functions) { + if ( !is_null($functions) ) { + foreach($functions as $f) { + $args[1] = $value; + $value = call_user_func_array($f['function'], array_slice($args, 1,(int)$f['accepted_args'])); + } // foreach + } // if + } // foreach + return $value; + } // apply_filters + + function useHelper($plugin_name, $helper) { + $helper_file = APPLICATION_PATH . "/plugins/$plugin_name/helpers/$helper.php"; + + // If we have it include, else throw exception + if (is_file($helper_file)) { + include_once $helper_file; + return true; + } else { + throw new FileDnxError($helper_file, "Helper '$helper' for plugin '$plugin_name' does not exists (expected location '$helper_file')"); + } // if + } // useHelper + + /** + * Use specific library. This function will look in plugin directory. + * If it doesn't find requested library class, then LibraryDnxError + * will be raised + * + * @access public + * @param string $library Library name + * @return null + * @throws LibraryDnxError + */ + static function useLibrary($plugin_name, $library) { + $library_path = APPLICATION_PATH . "/plugins/$plugin_name/library/$library/"; + if (file_exists($library_path) && is_dir($library_path)) { + // Call init library file if it exists + $library_init_file = $library_path . $library . '.php'; + if (is_file($library_init_file)) { + include_once $library_init_file; + } // if + return true; + } // if + + throw new LibraryDnxError($library); + } // useLibrary + + /** + * Return single PluginManager instance + * + * @access public + * @param void + * @return PluginManager + */ + static function instance() { + static $instance; + if (!($instance instanceof PluginManager )) { + $instance = new PluginManager(); + } // if + return $instance; + } // instance +} +?> Index: application/models/application_logs/ApplicationLogs.class.php =================================================================== --- application/models/application_logs/ApplicationLogs.class.php (revision 162) +++ application/models/application_logs/ApplicationLogs.class.php (working copy) @@ -130,19 +130,62 @@ $private_filter = $include_private ? 1 : 0; $silent_filter = $include_silent ? 1 : 0; - return self::findAll(array( + $all_logs = self::findAll(array( 'conditions' => array('`is_private` <= ? AND `is_silent` <= ? AND `project_id` = (?)', $private_filter, $silent_filter, $project->getId()), 'order' => '`created_on` DESC', 'limit' => $limit, 'offset' => $offset, )); // findAll + + + return ApplicationLogs::filterLogs($all_logs); + } // getProjectLogs + + /** + * Exclude logs from uninstaller plugins + * + * @param Project $project + * @param boolean $include_private + * @param boolean $include_silent + * @param integer $limit + * @param integer $offset + * @return array + */ + static function filterLogs($all_logs) { + if ($all_logs==NULL) return; + $filtered_logs = array(); + //Only show logs related to installed applications + foreach ($all_logs as $log) + { + if ($log->getObject()==NULL) continue; + //Search the string 'plugins' in the file path containing the class, if false is a core application else is a plugin + if (strpos($GLOBALS['autoloader_classes'][strtoupper(get_class($log->getObject()))], 'plugins') == false) + { + //the class is a core application + $filtered_logs[]=$log; + } + else + { + //the class comes from a plugin + //so we need to filter logs from uninstalled plugins + $plugin_name = strtolower(get_class($log->getObject()->manager())); + $plugin = Plugins::findOne(array('conditions'=>array('`name` = ?', $plugin_name))); + if($plugin->isInstalled()) $filtered_logs[] = $log; + } + + } + return $filtered_logs; + + } // filterLogs + + /** * Return overall (for dashboard or RSS) * * This function will return array of application logs that match the function arguments. Entries can be filtered by - * type (prvivate, silent), projects (if $project_ids is array, if NULL project ID is ignored). Result set can be + * type (private, silent), projects (if $project_ids is array, if NULL project ID is ignored). Result set can be * also limited using $limit and $offset params * * @param boolean $include_private @@ -162,12 +205,14 @@ $conditions = array('`is_private` <= ? AND `is_silent` <= ?', $private_filter, $silent_filter); } // if - return self::findAll(array( + $all_logs = self::findAll(array( 'conditions' => $conditions, 'order' => '`created_on` DESC', 'limit' => $limit, 'offset' => $offset, )); // findAll + + return ApplicationLogs::filterLogs($all_logs); } // getOverallLogs /** Index: application/models/project_user_permissions/ProjectUserPermission.class.php =================================================================== --- application/models/project_user_permissions/ProjectUserPermission.class.php (revision 0) +++ application/models/project_user_permissions/ProjectUserPermission.class.php (revision 0) @@ -0,0 +1,13 @@ + Index: application/models/project_user_permissions/base/BaseProjectUserPermission.class.php =================================================================== --- application/models/project_user_permissions/base/BaseProjectUserPermission.class.php (revision 0) +++ application/models/project_user_permissions/base/BaseProjectUserPermission.class.php (revision 0) @@ -0,0 +1,97 @@ +getColumnValue('project_id'); + } // getProjectId() + + /** + * Set value of 'project_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setProjectId($value) { + return $this->setColumnValue('project_id', $value); + } // setProjectId() + + /** + * Return value of 'user_id' field + * + * @access public + * @param void + * @return integer + */ + function getUserId() { + return $this->getColumnValue('user_id'); + } // getUserId() + + /** + * Set value of 'user_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setUserId($value) { + return $this->setColumnValue('user_id', $value); + } // setUserId() + + /** + * Return value of 'permission_id' field + * + * @access public + * @param void + * @return integer + */ + function getPermissionId() { + return $this->getColumnValue('permission_id'); + } // getPermissionId() + + /** + * Set value of 'permission_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setPermissionId($value) { + return $this->setColumnValue('permission_id', $value); + } // setPermissionId() + + /** + * Return manager instance + * + * @access protected + * @param void + * @return ProjectUsers + */ + function manager() { + if (!($this->manager instanceof ProjectUserPermissions)) { + $this->manager = ProjectUserPermissions::instance(); + } + return $this->manager; + } // manager + + } // BaseProjectUserPermission + +?> Index: application/models/project_user_permissions/base/BaseProjectUserPermissions.class.php =================================================================== --- application/models/project_user_permissions/base/BaseProjectUserPermissions.class.php (revision 0) +++ application/models/project_user_permissions/base/BaseProjectUserPermissions.class.php (revision 0) @@ -0,0 +1,239 @@ + Column type map + * + * @var array + * @static + */ + static private $columns = array('user_id' => DATA_TYPE_INTEGER, 'project_id' => DATA_TYPE_INTEGER, 'permission_id' => DATA_TYPE_INTEGER); + + /** + * Construct + * + * @return BaseProjectUserPermissions + */ + function __construct() { + parent::__construct('ProjectUserPermission', 'project_user_permissions', true); + } // __construct + + // ------------------------------------------------------- + // Description methods + // ------------------------------------------------------- + + /** + * Return array of object columns + * + * @access public + * @param void + * @return array + */ + function getColumns() { + return array_keys(self::$columns); + } // getColumns + + /** + * Return column type + * + * @access public + * @param string $column_name + * @return string + */ + function getColumnType($column_name) { + if (isset(self::$columns[$column_name])) { + return self::$columns[$column_name]; + } else { + return DATA_TYPE_STRING; + } // if + } // getColumnType + + /** + * Return array of PK columns. If only one column is PK returns its name as string + * + * @access public + * @param void + * @return array or string + */ + function getPkColumns() { + return array ( + 0 => 'project_id', + 1 => 'user_id', + 2 => 'permission_id' +); + } // getPkColumns + + /** + * Return name of first auto_incremenent column if it exists + * + * @access public + * @param void + * @return string + */ + function getAutoIncrementColumn() { + return NULL; + } // getAutoIncrementColumn + + // ------------------------------------------------------- + // Finders + // ------------------------------------------------------- + + /** + * Do a SELECT query over database with specified arguments + * + * @access public + * @param array $arguments Array of query arguments. Fields: + * + * - one - select first row + * - conditions - additional conditions + * - order - order by string + * - offset - limit offset, valid only if limit is present + * - limit + * + * @return one or ProjectUserPermissions objects + * @throws DBQueryError + */ + function find($arguments = null) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::find($arguments); + } else { + return ProjectUserPermissions::instance()->find($arguments); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->find($arguments); + } // if + } // find + + /** + * Find all records + * + * @access public + * @param array $arguments + * @return one or ProjectUserPermissions objects + */ + function findAll($arguments = null) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::findAll($arguments); + } else { + return ProjectUserPermissions::instance()->findAll($arguments); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->findAll($arguments); + } // if + } // findAll + + /** + * Find one specific record + * + * @access public + * @param array $arguments + * @return ProjectUser + */ + function findOne($arguments = null) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::findOne($arguments); + } else { + return ProjectUserPermissions::instance()->findOne($arguments); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->findOne($arguments); + } // if + } // findOne + + /** + * Return object by its PK value + * + * @access public + * @param mixed $id + * @param boolean $force_reload If true cache will be skipped and data will be loaded from database + * @return ProjectUser + */ + function findById($id, $force_reload = false) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::findById($id, $force_reload); + } else { + return ProjectUserPermissions::instance()->findById($id, $force_reload); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->findById($id, $force_reload); + } // if + } // findById + + /** + * Return number of rows in this table + * + * @access public + * @param string $conditions Query conditions + * @return integer + */ + function count($condition = null) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::count($condition); + } else { + return ProjectUserPermissions::instance()->count($condition); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->count($condition); + } // if + } // count + + /** + * Delete rows that match specific conditions. If $conditions is NULL all rows from table will be deleted + * + * @access public + * @param string $conditions Query conditions + * @return boolean + */ + function delete($condition = null) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::delete($condition); + } else { + return ProjectUserPermissions::instance()->delete($condition); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->delete($condition); + } // if + } // delete + + /** + * This function will return paginated result. Result is an array where first element is + * array of returned object and second populated pagination object that can be used for + * obtaining and rendering pagination data using various helpers. + * + * Items and pagination array vars are indexed with 0 for items and 1 for pagination + * because you can't use associative indexing with list() construct + * + * @access public + * @param array $arguments Query argumens (@see find()) Limit and offset are ignored! + * @param integer $items_per_page Number of items per page + * @param integer $current_page Current page number + * @return array + */ + function paginate($arguments = null, $items_per_page = 10, $current_page = 1) { + if (isset($this) && instance_of($this, 'ProjectUserPermissions')) { + return parent::paginate($arguments, $items_per_page, $current_page); + } else { + return ProjectUserPermissions::instance()->paginate($arguments, $items_per_page, $current_page); + //$instance =& ProjectUserPermissions::instance(); + //return $instance->paginate($arguments, $items_per_page, $current_page); + } // if + } // paginate + + /** + * Return manager instance + * + * @return ProjectUserPermissions + */ + function instance() { + static $instance; + if (!instance_of($instance, 'ProjectUserPermissions')) { + $instance = new ProjectUserPermissions(); + } // if + return $instance; + } // instance + + } // BaseProjectUserPermissions + +?> Index: application/models/project_user_permissions/ProjectUserPermissions.class.php =================================================================== --- application/models/project_user_permissions/ProjectUserPermissions.class.php (revision 0) +++ application/models/project_user_permissions/ProjectUserPermissions.class.php (revision 0) @@ -0,0 +1,25 @@ +permissions_cache) && isset($this->permissions_cache[$project_user])) { + return $this->permissions_cache[$project_user]; + } + $permissions = array(); + $pups = ProjectUserPermissions::findAll(array('conditions' => '`project_id` = '.$project_user->getProjectId().' and `user_id` = '.$project_user->getUserId())); + if (is_array($pups)) { + foreach ($pups as $pup) { + $permissions[] = Permissions::getPermissionString($pup->getPermissionId()); + } + } //if + $this->permissions_cache[$project_user] = $permissions; + return $permissions; + } //getPermissionsForProjectUser +} // ProjectUserPermissions +?> Index: application/models/users/User.class.php =================================================================== --- application/models/users/User.class.php (revision 162) +++ application/models/users/User.class.php (working copy) @@ -184,7 +184,7 @@ * * @param Project $project * @param string $permission Name of the field where the permission value is stored. There are set of constants - * in ProjectUser that hold field names (ProjectUser::CAN_MANAGE_MESSAGES ...) + * in ProjectUser that hold field names (PermissionManager::CAN_MANAGE_MESSAGES ...) * @return boolean */ function hasProjectPermission(Project $project, $permission, $use_cache = true) { @@ -201,17 +201,68 @@ } // if return false; } // if + + $value = in_array($permission,$project_user->getPermissions()) ? true : false; + if ($use_cache) { + $this->project_permissions_cache[$project->getId()][$permission] = $value; + } // if + return $value; + } // hasProjectPermission + + /** + * Return project permission for specific user if he is on project. In case of any error $default is returned + * + * @access public + * @param Project $project + * @param string $permission Permission name + * @param boolean $default Default value + * @return boolean + */ + function getProjectPermission(Project $project, $permission, $default = false) { + static $valid_permissions = null; + if (is_null($valid_permissions)) { + $valid_permissions = array_keys(PermissionManager::getPermissionsText()); + } // if - $getter_method = 'get' . Inflector::camelize($permission); - $project_user_methods = get_class_methods('ProjectUser'); + if (!in_array($permission, $valid_permissions)) { + return $default; + } // if - $value = in_array($getter_method, $project_user_methods) ? $project_user->$getter_method() : false; - + $project_user = ProjectUsers::findById(array('project_id' => $project->getId(), 'user_id' => $this->getId())); + if (!($project_user instanceof ProjectUser)) { + if ($use_cache) { + $this->project_permissions_cache[$project->getId()][$permission] = false; + } // if + return $default; + } // if + + $value = in_array($permission,$project_user->getPermissions()) ? true : false; if ($use_cache) { $this->project_permissions_cache[$project->getId()][$permission] = $value; + } // if + return $value; + } // getProjectPermission + + function setProjectPermission(Project $project, $permissionString, $value) { + $permission_id = Permissions::getPermissionId($permissionString); + if (!isset($permission_id) || !$permission_id) { + return false; } - return $value; - } // hasProjectPermission + $pup = ProjectUserPermissions::findOne(array('conditions' => '`project_id` = '.$project->getId().' and `user_id` = '.$this->getId().' and `permission_id` = '.$permission_id)); + if ($value == 1) { + if (!isset($pup) || !($pup instanceof ProjectUserPermission)) { + $pup = new ProjectUserPermission(); + $pup->setProjectId($project->getId()); + $pup->setUserId($this->getId()); + } //if + $pup->setPermissionId($permission_id); + $pup->save(); + } else { + if (isset($pup) && ($pup instanceOf ProjectUserPermission)) { + $pup->delete(); + } // if + } // if + } // setProjectPermission /** * This function will check if this user have all project permissions @@ -221,7 +272,7 @@ * @return boolean */ function hasAllProjectPermissions(Project $project, $use_cache = true) { - $permissions = ProjectUsers::getPermissionColumns(); + $permissions = array_keys(PermissionManager::getPermissionsText()); if (is_array($permissions)) { foreach ($permissions as $permission) { if (!$this->hasProjectPermission($project, $permission, $use_cache)) { @@ -750,37 +801,6 @@ return ($this->getCompanyId() == $company->getId()) && $this->getIsAdmin(); } // isCompanyAdmin - /** - * Return project permission for specific user if he is on project. In case of any error $default is returned - * - * @access public - * @param Project $project - * @param string $permission Permission name - * @param boolean $default Default value - * @return boolean - */ - function getProjectPermission(Project $project, $permission, $default = false) { - static $valid_permissions = null; - if (is_null($valid_permissions)) { - $valid_permissions = ProjectUsers::getPermissionColumns(); - } // if - - if (!in_array($permission, $valid_permissions)) { - return $default; - } // if - - $project_user = ProjectUsers::findById(array( - 'project_id' => $project->getId(), - 'user_id' => $this->getId() - )); // findById - if (!($project_user instanceof ProjectUser)) { - return $default; - } // if - - $getter = 'get' . Inflector::camelize($permission); - return $project_user->$getter(); - } // getProjectPermission - // --------------------------------------------------- // URLs // --------------------------------------------------- Index: application/models/project_milestones/ProjectMilestone.class.php =================================================================== --- application/models/project_milestones/ProjectMilestone.class.php (revision 162) +++ application/models/project_milestones/ProjectMilestone.class.php (working copy) @@ -263,7 +263,7 @@ * @return boolean */ function canManage(User $user) { - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_MILESTONES); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_MILESTONES); } // canManage /** @@ -300,7 +300,7 @@ if ($user->isAdministrator()) { return true; } - return $user->getProjectPermission($project, ProjectUsers::CAN_MANAGE_MILESTONES); + return $user->getProjectPermission($project, PermissionManager::CAN_MANAGE_MILESTONES); } // canAdd /** Index: application/models/PermissionManager.class.php =================================================================== --- application/models/PermissionManager.class.php (revision 0) +++ application/models/PermissionManager.class.php (revision 0) @@ -0,0 +1,108 @@ +init(); + } // if + } + + /** + * Return single PermissionManager instance + * + * @access public + * @param void + * @return PluginManager + */ + static function instance() { + static $instance; + if (!($instance instanceof PermissionManager )) { + $instance = new PermissionManager(); + } // if + return $instance; + } // instance + + /* + * Get the localized permission text for displaying to the user + * @return array mapping the permission string to the localized text for that permission string + * + */ + function getPermissionsText() { + $permText = array(); + $permsBySource = Permissions::getPermissionsBySource(); + foreach ($permsBySource as $source => $permissions) { + foreach ($permissions as $permission) { + $text = split(' ',$permission[0],2); + if (count($text) == 2) { + $plang = "can ".$text[0]." ".$source." ".$text[1]; + } else { + $plang = "can ".$text[0]." ".$source; + } // if + $permText[$source."-".preg_replace('/ /','_',$permission[0])] = lang($plang); + } // foreach + } // foreach + return $permText; + } //getPermissionsText + + /* + * Add a permission source,name combination to the database + * + */ + static function addPermission($source,$name) { + if (Permissions::findOne(array('conditions' => "`source` = '".$source."' and `permission` = '".$name."'"))) { + return false; // permission already exists + } + $permission = new Permission(); + $permission->setSource($source); + $permission->setName($name); + return $permission->save(); + } //addPermission + + /* + * Remove a permission source,name combination from the database + * + */ + static function removePermission($source,$name) { + $permission = Permissions::findOne(array('conditions' => "`source` = '".$source."' and `permission` = '".$name."'")); + if (isset($permission) && $permission instanceof Permission) { + $permission->delete(); + return true; // permission already exists + } + return false; // permission does not exist + } + + /* + * Remove all permissions from the specified source from the database + * + */ + static function removeSource($source) { + $permissions = Permissions::findAll(array('conditions' => "`source` = '".$source."'")); + if (is_array($permissions)) { + foreach ($permissions as $permission) { + $permission->delete(); + } + return true; // permission already exists + } + return false; // permission source does not exist + } + +} +?> \ No newline at end of file Index: application/models/ProjectDataObject.class.php =================================================================== --- application/models/ProjectDataObject.class.php (revision 162) +++ application/models/ProjectDataObject.class.php (working copy) @@ -220,7 +220,7 @@ return false; } if ($this->isNew()) { - return $user->getProjectPermission($project, ProjectUsers::CAN_UPLOAD_FILES); + return $user->getProjectPermission($project, PermissionManager::CAN_UPLOAD_FILES); } else { return $this->canEdit($user); } // if Index: application/models/plugins/Plugin.class.php =================================================================== --- application/models/plugins/Plugin.class.php (revision 0) +++ application/models/plugins/Plugin.class.php (revision 0) @@ -0,0 +1,12 @@ + Index: application/models/plugins/base/BasePlugin.class.php =================================================================== --- application/models/plugins/base/BasePlugin.class.php (revision 0) +++ application/models/plugins/base/BasePlugin.class.php (revision 0) @@ -0,0 +1,96 @@ +getColumnValue('plugin_id'); + } // getPluginId() + + /** + * Set value of 'plugin_id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setPluginId($value) { + return $this->setColumnValue('plugin_id', $value); + } // setPluginId() + + /** + * Return value of 'name' field + * + * @access public + * @param void + * @return integer + */ + function getName() { + return $this->getColumnValue('name'); + } // getName() + + /** + * Set value of 'name' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setName($value) { + return $this->setColumnValue('name', $value); + } // setName() + + /** + * Tell if a plugin is installed + * + * @access public + * @return boolean + */ + function isInstalled() + { + return $this->getColumnValue('installed'); + } + + /** + * Set the value of installed property + * + * @access public + * @return boolean + */ + function setInstalled($value) + { + return $this->setColumnValue('installed', $value); + } + + /** + * Return manager instance + * + * @access protected + * @param void + * @return Plugins + */ + function manager() { + if (!($this->manager instanceof Plugins)) { + $this->manager = Plugins::instance(); + } + return $this->manager; + } // manager + + } // BasePlugin + +?> Index: application/models/plugins/base/BasePlugins.class.php =================================================================== --- application/models/plugins/base/BasePlugins.class.php (revision 0) +++ application/models/plugins/base/BasePlugins.class.php (revision 0) @@ -0,0 +1,234 @@ + Column type map + * + * @var array + * @static + */ + static private $columns = array('plugin_id' => DATA_TYPE_INTEGER, 'name' => DATA_TYPE_STRING, 'installed' => DATA_TYPE_BOOLEAN); + + /** + * Construct + * + * @return BasePlugins + */ + function __construct() { + parent::__construct('Plugin', 'plugins', true); + } // __construct + + // ------------------------------------------------------- + // Description methods + // ------------------------------------------------------- + + /** + * Return array of object columns + * + * @access public + * @param void + * @return array + */ + function getColumns() { + return array_keys(self::$columns); + } // getColumns + + /** + * Return column type + * + * @access public + * @param string $column_name + * @return string + */ + function getColumnType($column_name) { + if (isset(self::$columns[$column_name])) { + return self::$columns[$column_name]; + } else { + return DATA_TYPE_STRING; + } // if + } // getColumnType + + /** + * Return array of PK columns. If only one column is PK returns its name as string + * + * @access public + * @param void + * @return array or string + */ + function getPkColumns() { + return 'plugin_id'; + } // getPkColumns + + /** + * Return name of first auto_incremenent column if it exists + * + * @access public + * @param void + * @return string + */ + function getAutoIncrementColumn() { + return 'plugin_id'; + } // getAutoIncrementColumn + + // ------------------------------------------------------- + // Finders + // ------------------------------------------------------- + + /** + * Do a SELECT query over database with specified arguments + * + * @access public + * @param array $arguments Array of query arguments. Fields: + * + * - one - select first row + * - conditions - additional conditions + * - order - order by string + * - offset - limit offset, valid only if limit is present + * - limit + * + * @return one or Plugins objects + * @throws DBQueryError + */ + function find($arguments = null) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::find($arguments); + } else { + return Plugins::instance()->find($arguments); + //$instance =& Plugins::instance(); + //return $instance->find($arguments); + } // if + } // find + + /** + * Find all records + * + * @access public + * @param array $arguments + * @return one or Plugins objects + */ + function findAll($arguments = null) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::findAll($arguments); + } else { + return Plugins::instance()->findAll($arguments); + //$instance =& Plugins::instance(); + //return $instance->findAll($arguments); + } // if + } // findAll + + /** + * Find one specific record + * + * @access public + * @param array $arguments + * @return Plugin + */ + function findOne($arguments = null) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::findOne($arguments); + } else { + return Plugins::instance()->findOne($arguments); + //$instance =& Plugins::instance(); + //return $instance->findOne($arguments); + } // if + } // findOne + + /** + * Return object by its PK value + * + * @access public + * @param mixed $id + * @param boolean $force_reload If true cache will be skipped and data will be loaded from database + * @return Plugin + */ + function findById($id, $force_reload = false) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::findById($id, $force_reload); + } else { + return Plugins::instance()->findById($id, $force_reload); + //$instance =& Plugins::instance(); + //return $instance->findById($id, $force_reload); + } // if + } // findById + + /** + * Return number of rows in this table + * + * @access public + * @param string $conditions Query conditions + * @return integer + */ + function count($condition = null) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::count($condition); + } else { + return Plugins::instance()->count($condition); + //$instance =& Plugins::instance(); + //return $instance->count($condition); + } // if + } // count + + /** + * Delete rows that match specific conditions. If $conditions is NULL all rows from table will be deleted + * + * @access public + * @param string $conditions Query conditions + * @return boolean + */ + function delete($condition = null) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::delete($condition); + } else { + return Plugins::instance()->delete($condition); + //$instance =& Plugins::instance(); + //return $instance->delete($condition); + } // if + } // delete + + /** + * This function will return paginated result. Result is an array where first element is + * array of returned object and second populated pagination object that can be used for + * obtaining and rendering pagination data using various helpers. + * + * Items and pagination array vars are indexed with 0 for items and 1 for pagination + * because you can't use associative indexing with list() construct + * + * @access public + * @param array $arguments Query argumens (@see find()) Limit and offset are ignored! + * @param integer $items_per_page Number of items per page + * @param integer $current_page Current page number + * @return array + */ + function paginate($arguments = null, $items_per_page = 10, $current_page = 1) { + if (isset($this) && instance_of($this, 'Plugins')) { + return parent::paginate($arguments, $items_per_page, $current_page); + } else { + return Plugins::instance()->paginate($arguments, $items_per_page, $current_page); + //$instance =& Plugins::instance(); + //return $instance->paginate($arguments, $items_per_page, $current_page); + } // if + } // paginate + + /** + * Return manager instance + * + * @return Plugins + */ + function instance() { + static $instance; + if (!instance_of($instance, 'Plugins')) { + $instance = new Plugins(); + } // if + return $instance; + } // instance + + } // Plugins + +?> Index: application/models/plugins/Plugins.class.php =================================================================== --- application/models/plugins/Plugins.class.php (revision 0) +++ application/models/plugins/Plugins.class.php (revision 0) @@ -0,0 +1,84 @@ + $conditions + )); + foreach((array)$plugins as $plugin) { + if( array_key_exists($plugin->getName(),$results) ) { + $results[$plugin->getName()] = $plugin->getPluginId(); + } else { + // TODO : remove from DB here?? + } + } + + return $results; + + } // getAllPlugins + + /** + * Return array of all activated plugins based on plugin files on filesystem + * + * @param none + * @return array + */ + static function getActivatedPlugins() { + + $results = Plugins::getAllPlugins(); + + foreach($results as $name => $id) { + if( '-' == $id ) + unset($results[$name]); + } + + return $results; + + } // getActivatedPlugins + + /** + * Return array of all activated plugins + * + * @param none + * @return array + */ + static function getNamesFromDB() { + $names = array(); + $plugins = Plugins::findAll(array()); // findAll + if (is_array($plugins)) { + foreach ($plugins as $plugin) { + $names[] = $plugin->getName(); + } // foreach + } // if + return $names; + } // getActivatedPlugins + + } // Plugins + +?> Index: application/models/project_folders/ProjectFolder.class.php =================================================================== --- application/models/project_folders/ProjectFolder.class.php (revision 162) +++ application/models/project_folders/ProjectFolder.class.php (working copy) @@ -127,7 +127,7 @@ if (!$user->isProjectUser($this->getProject())) { return false; } - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_FILES); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_FILES); } // canManage /** @@ -151,7 +151,7 @@ if (!$user->isProjectUser($project)) { return false; } - return $user->getProjectPermission($project, ProjectUsers::CAN_MANAGE_FILES); + return $user->getProjectPermission($project, PermissionManager::CAN_MANAGE_FILES); } // canAdd /** Index: application/models/project_users/ProjectUser.class.php =================================================================== --- application/models/project_users/ProjectUser.class.php (revision 162) +++ application/models/project_users/ProjectUser.class.php (working copy) @@ -7,7 +7,17 @@ * @http://www.projectpier.org/ */ class ProjectUser extends BaseProjectUser { + + private $permissions = array(); + function getPermissions() { + if (count($this->permissions) == 0) { + $this->permissions = ProjectUserPermissions::getPermissionsForProjectUser($this); + } + return $this->permissions; + + } // getPermissions + } // ProjectUser ?> Index: application/models/project_users/ProjectUsers.class.php =================================================================== --- application/models/project_users/ProjectUsers.class.php (revision 162) +++ application/models/project_users/ProjectUsers.class.php (working copy) @@ -8,15 +8,6 @@ */ class ProjectUsers extends BaseProjectUsers { - /** All available user permissions **/ - const CAN_MANAGE_MESSAGES = 'can_manage_messages'; - const CAN_MANAGE_TASKS = 'can_manage_tasks'; - const CAN_MANAGE_MILESTONES = 'can_manage_milestones'; - const CAN_UPLOAD_FILES = 'can_upload_files'; - const CAN_MANAGE_FILES = 'can_manage_files'; - const CAN_ASSIGN_TO_OWNERS = 'can_assign_to_owners'; - const CAN_ASSIGN_TO_OTHER = 'can_assign_to_other'; - /** * Return all users that are involved in specific project * @@ -109,45 +100,7 @@ static function clearByUser(User $user) { return self::delete(array('`user_id` = ?', $user->getId())); } // clearByUser - - /** - * This function will return array of permission columns in table. Permission column name is - * used as permission ID in rest of the script - * - * @access public - * @param void - * @return array - */ - function getPermissionColumns() { - return array( - self::CAN_MANAGE_MESSAGES, - self::CAN_MANAGE_TASKS, - self::CAN_MANAGE_MILESTONES, - self::CAN_UPLOAD_FILES, - self::CAN_MANAGE_FILES, - self::CAN_ASSIGN_TO_OWNERS, - self::CAN_ASSIGN_TO_OTHER, - ); // array - } // getPermissionColumns - - /** - * Return permission name => permission text array - * - * @param void - * @return array - */ - static function getNameTextArray() { - return array( - ProjectUsers::CAN_MANAGE_MESSAGES => lang('can manage messages'), - ProjectUsers::CAN_MANAGE_TASKS => lang('can manage tasks'), - ProjectUsers::CAN_MANAGE_MILESTONES => lang('can manage milestones'), - ProjectUsers::CAN_UPLOAD_FILES => lang('can upload files'), - ProjectUsers::CAN_MANAGE_FILES => lang('can manage files'), - ProjectUsers::CAN_ASSIGN_TO_OWNERS => lang('can assign to owners'), - ProjectUsers::CAN_ASSIGN_TO_OTHER => lang('can assign to other'), - ); // array - } // getNameTextArray - + } // ProjectUsers ?> Index: application/models/project_users/base/BaseProjectUsers.class.php =================================================================== --- application/models/project_users/base/BaseProjectUsers.class.php (revision 162) +++ application/models/project_users/base/BaseProjectUsers.class.php (working copy) @@ -14,7 +14,7 @@ * @var array * @static */ - static private $columns = array('project_id' => DATA_TYPE_INTEGER, 'user_id' => DATA_TYPE_INTEGER, 'created_on' => DATA_TYPE_DATETIME, 'created_by_id' => DATA_TYPE_INTEGER, 'can_manage_messages' => DATA_TYPE_BOOLEAN, 'can_manage_tasks' => DATA_TYPE_BOOLEAN, 'can_manage_milestones' => DATA_TYPE_BOOLEAN, 'can_upload_files' => DATA_TYPE_BOOLEAN, 'can_manage_files' => DATA_TYPE_BOOLEAN, 'can_assign_to_owners' => DATA_TYPE_BOOLEAN, 'can_assign_to_other' => DATA_TYPE_BOOLEAN); + static private $columns = array('project_id' => DATA_TYPE_INTEGER, 'user_id' => DATA_TYPE_INTEGER, 'created_on' => DATA_TYPE_DATETIME, 'created_by_id' => DATA_TYPE_INTEGER); /** * Construct Index: application/models/project_files/ProjectFile.class.php =================================================================== --- application/models/project_files/ProjectFile.class.php (revision 162) +++ application/models/project_files/ProjectFile.class.php (working copy) @@ -396,7 +396,7 @@ if (!$user->isProjectUser($this->getProject())) { return false; } // if - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_FILES); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_FILES); } // canManage /** @@ -410,7 +410,7 @@ if (!$user->isProjectUser($project)) { return false; } // if - return $user->getProjectPermission($project, ProjectUsers::CAN_UPLOAD_FILES); + return $user->getProjectPermission($project, PermissionManager::CAN_UPLOAD_FILES); } // canUpload /** Index: application/models/project_messages/ProjectMessage.class.php =================================================================== --- application/models/project_messages/ProjectMessage.class.php (revision 162) +++ application/models/project_messages/ProjectMessage.class.php (working copy) @@ -206,7 +206,7 @@ if (!$user->isProjectUser($this->getProject())) { return false; } // if - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_MESSAGES); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_MESSAGES); } // canManage /** @@ -240,7 +240,7 @@ if ($user->isAdministrator()) { return true; // administrator } // if - return $user->getProjectPermission($project, ProjectUsers::CAN_MANAGE_MESSAGES); + return $user->getProjectPermission($project, PermissionManager::CAN_MANAGE_MESSAGES); } // canAdd /** Index: application/models/project_file_revisions/ProjectFileRevision.class.php =================================================================== --- application/models/project_file_revisions/ProjectFileRevision.class.php (revision 162) +++ application/models/project_file_revisions/ProjectFileRevision.class.php (working copy) @@ -284,7 +284,7 @@ if (!$user->isProjectUser($this->getProject())) { return false; } - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_FILES); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_FILES); } // canManage /** Index: application/models/project_task_lists/ProjectTaskList.class.php =================================================================== --- application/models/project_task_lists/ProjectTaskList.class.php (revision 162) +++ application/models/project_task_lists/ProjectTaskList.class.php (working copy) @@ -382,7 +382,7 @@ * @return boolean */ function canManage(User $user) { - return $user->getProjectPermission($this->getProject(), ProjectUsers::CAN_MANAGE_TASKS); + return $user->getProjectPermission($this->getProject(), PermissionManager::CAN_MANAGE_TASKS); } // canManage /** @@ -412,7 +412,7 @@ if ($user->isAccountOwner()) { return true; } // if - return $user->getProjectPermission($project, ProjectUsers::CAN_MANAGE_TASKS); + return $user->getProjectPermission($project, PermissionManager::CAN_MANAGE_TASKS); } // canAdd /** Index: application/models/permissions/Permission.class.php =================================================================== --- application/models/permissions/Permission.class.php (revision 0) +++ application/models/permissions/Permission.class.php (revision 0) @@ -0,0 +1,13 @@ + Index: application/models/permissions/Permissions.class.php =================================================================== --- application/models/permissions/Permissions.class.php (revision 0) +++ application/models/permissions/Permissions.class.php (revision 0) @@ -0,0 +1,70 @@ +getId()] = array($permission->getSource(),$permission->getName()); + } // foreach + } // if + return $map; + } // getAllPermissions + + static function getPermission($permission_id) { + //$permission = Permissions::findOne(array('conditions' => '`id` = '.$permission_id)); + $permission = Permissions::findById($permission_id); + return $permission; + } // getPermission + + /* + * Gets the permission (source,permission) combination as a string. + * @return string in format "source-permission_name_with_underscores" + */ + static function getPermissionString($permission_id) { + $permission = Permissions::findById($permission_id); + return $permission->getSource()."-".preg_replace('/ /','_',$permission->getName()); + } // getPermissionString + + static function getPermissionsBySource() { + $sources = array(); + $permissions = Permissions::findAll(); //findAll + if (is_array($permissions)) { + foreach ($permissions as $permission) { + if (!isset($sources[$permission->getSource()])) { + $sources[$permission->getSource()] = array(); + } // if + $sources[$permission->getSource()][] = array($permission->getName(),$permission->getId()); + } // foreach + } // if + return $sources; + } // getSources + + static function getPermissionId($permission_string) { + $index = strrpos($permission_string,'-'); + $source = substr($permission_string,0,$index); + $name = substr($permission_string,$index+1); + $name = preg_replace('/_/',' ',$name); + $permission = Permissions::findOne(array('conditions' => "`source` = '".$source."' and `permission` = '".$name."'")); + if (isset($permission)) { + return $permission->getId(); + } // if + return false; + } // getPermissionId + + } // Permissions + +?> Index: application/models/permissions/base/BasePermissions.class.php =================================================================== --- application/models/permissions/base/BasePermissions.class.php (revision 0) +++ application/models/permissions/base/BasePermissions.class.php (revision 0) @@ -0,0 +1,219 @@ + Column type map + * + * @var array + * @static + */ + static private $columns = array('id' => DATA_TYPE_INTEGER, 'source' => DATA_TYPE_STRING, 'permission' => DATA_TYPE_STRING); + + /** + * Construct + * + * @return BasePermissions + */ + function __construct() { + parent::__construct('Permission', 'permissions', true); + } // __construct + + // ------------------------------------------------------- + // Description methods + // ------------------------------------------------------- + + /** + * Return array of object columns + * + * @access public + * @param void + * @return array + */ + function getColumns() { + return array_keys(self::$columns); + } // getColumns + + /** + * Return column type + * + * @access public + * @param string $column_name + * @return string + */ + function getColumnType($column_name) { + if (isset(self::$columns[$column_name])) { + return self::$columns[$column_name]; + } else { + return DATA_TYPE_STRING; + } // if + } // getColumnType + + /** + * Return array of PK columns. If only one column is PK returns its name as string + * + * @access public + * @param void + * @return array or string + */ + function getPkColumns() { + return 'id'; + } // getPkColumns + + /** + * Return name of first auto_incremenent column if it exists + * + * @access public + * @param void + * @return string + */ + function getAutoIncrementColumn() { + return 'id'; + } // getAutoIncrementColumn + + // ------------------------------------------------------- + // Finders + // ------------------------------------------------------- + + /** + * Do a SELECT query over database with specified arguments + * + * @access public + * @param array $arguments Array of query arguments. Fields: + * + * - one - select first row + * - conditions - additional conditions + * - order - order by string + * - offset - limit offset, valid only if limit is present + * - limit + * + * @return one or Permissions objects + * @throws DBQueryError + */ + function find($arguments = null) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::find($arguments); + } else { + return Permissions::instance()->find($arguments); + } // if + } // find + + /** + * Find all records + * + * @access public + * @param array $arguments + * @return one or Permissions objects + */ + function findAll($arguments = null) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::findAll($arguments); + } else { + return Permissions::instance()->findAll($arguments); + } // if + } // findAll + + /** + * Find one specific record + * + * @access public + * @param array $arguments + * @return Permission + */ + function findOne($arguments = null) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::findOne($arguments); + } else { + return Permissions::instance()->findOne($arguments); + } // if + } // findOne + + /** + * Return object by its PK value + * + * @access public + * @param mixed $id + * @param boolean $force_reload If true cache will be skipped and data will be loaded from database + * @return Permission + */ + function findById($id, $force_reload = false) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::findById($id, $force_reload); + } else { + return Permissions::instance()->findById($id, $force_reload); + } // if + } // findById + + /** + * Return number of rows in this table + * + * @access public + * @param string $conditions Query conditions + * @return integer + */ + function count($condition = null) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::count($condition); + } else { + return Permissions::instance()->count($condition); + } // if + } // count + + /** + * Delete rows that match specific conditions. If $conditions is NULL all rows from table will be deleted + * + * @access public + * @param string $conditions Query conditions + * @return boolean + */ + function delete($condition = null) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::delete($condition); + } else { + return Permissions::instance()->delete($condition); + } // if + } // delete + + /** + * This function will return paginated result. Result is an array where first element is + * array of returned object and second populated pagination object that can be used for + * obtaining and rendering pagination data using various helpers. + * + * Items and pagination array vars are indexed with 0 for items and 1 for pagination + * because you can't use associative indexing with list() construct + * + * @access public + * @param array $arguments Query argumens (@see find()) Limit and offset are ignored! + * @param integer $items_per_page Number of items per page + * @param integer $current_page Current page number + * @return array + */ + function paginate($arguments = null, $items_per_page = 10, $current_page = 1) { + if (isset($this) && instance_of($this, 'Permissions')) { + return parent::paginate($arguments, $items_per_page, $current_page); + } else { + return Permissions::instance()->paginate($arguments, $items_per_page, $current_page); + } // if + } // paginate + + /** + * Return manager instance + * + * @return Permissions + */ + function instance() { + static $instance; + if (!instance_of($instance, 'Permissions')) { + $instance = new Permissions(); + } // if + return $instance; + } // instance + + } // Permissions + +?> Index: application/models/permissions/base/BasePermission.class.php =================================================================== --- application/models/permissions/base/BasePermission.class.php (revision 0) +++ application/models/permissions/base/BasePermission.class.php (revision 0) @@ -0,0 +1,97 @@ +getColumnValue('id'); + } // getId() + + /** + * Set value of 'id' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setId($value) { + return $this->setColumnValue('id', $value); + } // setId() + + /** + * Return value of 'source' field + * + * @access public + * @param void + * @return integer + */ + function getSource() { + return $this->getColumnValue('source'); + } // getSource() + + /** + * Set value of 'source' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setSource($value) { + return $this->setColumnValue('source', $value); + } // setSource() + + /** + * Return value of 'permission' field + * + * @access public + * @param void + * @return integer + */ + function getName() { + return $this->getColumnValue('permission'); + } // getName() + + /** + * Set value of 'permission' field + * + * @access public + * @param integer $value + * @return boolean + */ + function setName($value) { + return $this->setColumnValue('permission', $value); + } // setName() + + /** + * Return manager instance + * + * @access protected + * @param void + * @return Permissions + */ + function manager() { + if (!($this->manager instanceof Permissions)) { + $this->manager = Permissions::instance(); + } + return $this->manager; + } // manager + + } // BasePermission + +?> Index: application/controllers/AdministrationController.class.php =================================================================== --- application/controllers/AdministrationController.class.php (revision 162) +++ application/controllers/AdministrationController.class.php (working copy) @@ -245,6 +245,83 @@ } // try } // if } // tool_mass_mailer + + function plugins() { + + $plugins = Plugins::getAllPlugins(); + tpl_assign('plugins',$plugins); + + } // index + + function update_plugins() { + + $plugins = array_var($_POST,'plugins'); + $reference = Plugins::getAllPlugins(); + $errors = array(); + foreach($plugins as $name => $yes_no) { + //If it is not a plugin continue + $plugin_file_path = APPLICATION_PATH.'/plugins/'.$name.'/init.php'; + if (!file_exists($plugin_file_path)) continue; + // get existing id + $id = $reference[$name]; + $nicename = ucwords(str_replace('_',' ',$name)); + if($yes_no && '-' == $id) { + try { + //Check if plugin exists in database + $plugin = Plugins::findOne(array('conditions' => array('`name` = ?', $name))); + if ($plugin == NULL) $plugin = new Plugin(); + $plugin->setName($name); + $plugin->setInstalled(true); + + DB::beginWork(); + // get the file loaded here + include_once($plugin_file_path); + + // get activation routine ready + $activate = $name.'_activate'; + if( function_exists($activate) ) { + $activate(); + } + + // save to db now + $plugin->save(); + DB::commit(); + } catch(Exception $e) { + DB::rollback(); + $errors[] = $nicename.' ('.$e->getMessage().')'; + } + } + elseif(!$yes_no && '-' != $id) { + try + { + $plugin = Plugins::findById($id); + DB::beginWork(); + $deactivate = $name.'_deactivate'; + if( function_exists($deactivate) ) + { + //Check if user choose to purge data + if ($plugins[$name."_data"]=="0") + $deactivate(true); + else + $deactivate(); + } + $plugin->setInstalled(false); + $plugin->save(); + DB::commit(); + } catch(Exception $e) { + DB::rollback(); + $errors[] = $nicename.' ('.$e->getMessage().')'; + } + } + } + + if( count($errors) ) + flash_error(lang('plugin activation failed', implode(", ",$errors))); + else + flash_error(lang('plugins updated')); + $this->redirectTo('administration','plugins'); + + } // update } // AdministrationController Index: application/controllers/AccountController.class.php =================================================================== --- application/controllers/AccountController.class.php (revision 162) +++ application/controllers/AccountController.class.php (working copy) @@ -226,7 +226,7 @@ $this->redirectToReferer($company->getViewUrl()); } // if - $permissions = ProjectUsers::getNameTextArray(); + $permissions = PermissionManager::getPermissionsText(); $redirect_to = array_var($_GET, 'redirect_to'); if ((trim($redirect_to)) == '' || !is_valid_url($redirect_to)) { @@ -255,10 +255,9 @@ } // if foreach ($permissions as $permission => $permission_text) { - $permission_value = array_var($_POST, 'project_permission_' . $project->getId() . '_' . $permission) == 'checked'; - - $setter = 'set' . Inflector::camelize($permission); - $relation->$setter($permission_value); + $permission_value = array_var($_POST, 'project_permission_' . $project->getId() . '_' . $permission) == 'checked'; + + $user->setProjectPermission($project,$permission,$permission_value); } // foreach $relation->save(); @@ -274,6 +273,7 @@ $this->redirectToUrl($redirect_to); } // if } // update_permissions + /** * Edit logged user avatar Index: application/controllers/PluginController.class.php =================================================================== --- application/controllers/PluginController.class.php (revision 0) +++ application/controllers/PluginController.class.php (revision 0) @@ -0,0 +1,64 @@ + + * folder). + * + * @author Brett Edgar (True Digital Security, Inc.) + * @version 1.0 + * @http://www.projectpier.org/ + */ +abstract class PluginController extends ApplicationController { + var $plugin_name; + var $libraries; + /** + * Add application level constroller + * + * @param void + * @return null + */ + function __construct($name ) { + parent::__construct(); + $this->plugin_name = $name; + $this->libraries = array(); + } // __construct + + /** + * Add one or many helpers + * + * @param string $helper This param can be array of helpers + * @return null + */ + function addPluginHelper($helper) { + $args = func_get_args(); + if (!is_array($args)) { + return false; + } // if + + foreach ($args as $helper) { + if (!in_array($helper, $this->helpers)) { + if (PluginManager::useHelper($this->plugin_name,$helper)) { + $this->helpers[] = $helper; + }// if + } // if + } // foreach + + return true; + } // addHelper + + function addPluginLibrary($library) { + if (isset($this->libraries[$library]) && $this->libraries[$library]) { + return true; + } // if + + if (PluginManager::useLibrary($this->plugin_name,$library)) { + $this->libraries[] = $library; + } // if + } + +} // PluginController + +?> Index: application/controllers/ProjectController.class.php =================================================================== --- application/controllers/ProjectController.class.php (revision 162) +++ application/controllers/ProjectController.class.php (working copy) @@ -142,7 +142,7 @@ tpl_assign('project_companies', active_project()->getCompanies()); tpl_assign('user_projects', logged_user()->getProjects()); - $permissions = ProjectUsers::getNameTextArray(); + $permissions = PermissionManager::getPermissionsText(); tpl_assign('permissions', $permissions); $companies = array(owner_company()); @@ -194,10 +194,9 @@ // Owner company members have all permissions $permission_value = $company->isOwner() ? true : array_var($_POST, 'project_user_' . $user_id . '_' . $permission) == 'checked'; - - $setter = 'set' . Inflector::camelize($permission); - $project_user->$setter($permission_value); - + + $user = Users::findById($project_user->getUserId()); + $user->setProjectPermission(active_project(),$permission,$permission_value); } // if $project_user->save(); @@ -257,7 +256,7 @@ DB::beginWork(); $project->save(); - $permissions = ProjectUsers::getPermissionColumns(); + $permissions = array_keys(PermissionManager::getPermissionsText()); $auto_assign_users = owner_company()->getAutoAssignUsers(); // We are getting the list of auto assign users. If current user is not in the list @@ -282,7 +281,8 @@ $project_user->setUserId($user->getId()); if (is_array($permissions)) { foreach ($permissions as $permission) { - $project_user->setColumnValue($permission, true); + $user = Users::findById($project_user->getUserId()); + $user->setProjectPermission(active_project(),$permission,true); } } // if $project_user->save(); Index: application/controllers/UserController.class.php =================================================================== --- application/controllers/UserController.class.php (revision 162) +++ application/controllers/UserController.class.php (working copy) @@ -64,7 +64,7 @@ } // if $projects = $company->getProjects(); - $permissions = ProjectUsers::getNameTextArray(); + $permissions = PermissionManager::getPermissionsText(); tpl_assign('user', $user); tpl_assign('company', $company); @@ -107,8 +107,7 @@ foreach ($permissions as $permission => $permission_text) { $permission_value = array_var($user_data, 'project_permission_' . $project->getId() . '_' . $permission) == 'checked'; - $setter = 'set' . Inflector::camelize($permission); - $relation->$setter($permission_value); + $this->setProjectPermission($project,$permission,$permission_value); } // foreach $relation->save(); Index: application/plugins.php =================================================================== --- application/plugins.php (revision 0) +++ application/plugins.php (revision 0) @@ -0,0 +1,50 @@ +init(); + /* + * Convenience function for instance of PluginManager used by hooks throughout + */ + function plugin_manager() { + return PluginManager::instance(); + } + /* + * Convenience functions for plugin writers + */ + function add_action($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + return plugin_manager()->add_filter($tag,$function_to_add,$priority,$accepted_args); + } + function add_filter($tag, $function_to_add, $priority = 10, $accepted_args = 1) { + return plugin_manager()->add_filter($tag,$function_to_add,$priority,$accepted_args); + } + function remove_action($tag, $function_to_remove, $priority = 10) { + return plugin_manager()->remove_filter($tag,$function_to_remove,$priority); + } + function remove_filter($tag, $function_to_remove, $priority = 10) { + return plugin_manager()->remove_filter($tag,$function_to_remove,$priority); + } + +?> Index: application/views/administration/plugins.php =================================================================== --- application/views/administration/plugins.php (revision 0) +++ application/views/administration/plugins.php (revision 0) @@ -0,0 +1,67 @@ + + + +