Permalink
Browse files

0.8.6

  • Loading branch information...
1 parent d3a096d commit 5ab906c88eb7e8457a453c8407b927a380556ff8 @phpfreak committed Sep 6, 2011
Showing 788 changed files with 50,028 additions and 2,617 deletions.
View
@@ -0,0 +1,116 @@
+A. Plugins
+----------
+Plugins are installed in the <pp_root>/application/plugins folder.
+All plugin files are contained under this directory. The subdirectory
+structure should look like this, omitting what is not necessary:
+<plugin_name>
+ |-<plugin_name>/models
+ |-<plugin_name>/views
+ |-<plugin_name>/controllers
+ |-<plugin_name>/helpers
+ |-<plugin_name>/library
+ |-<plugin_name>/language
+ |- init.php
+
+The standard in the development team is to use plural for a plugin name.
+
+The plugin architecture supports both actions and filters. The
+difference between these is a matter of input; all actions on the same
+hook receive the same input regardless of order, filters receive
+modified input from previous filters on the same hook. These actions
+and filters are currently defined:
+
+I. Action
+ a. add_dashboard_tab
+ b. add_administration_tab
+ c. add_my_account_tab
+ d. add_project_tab
+ e. project_overview_page_actions
+ f. add_my_tasks_tab
+
+II. Filters
+ a. tabbed_navigation_items
+
+Plugins should implement an 'init.php' file in the root of the
+<pp_root>/application/plugins/<plugin_name>/ folder. Currently, the
+methods that must be implemented are:
+<plugin_name>_activate(): run anything necessary to activate the
+ plugin. Example: verify and/or add database tables and inital data
+<plugin_name>_deactivate($purge): run anything necessary to
+ de-activate the plugin. If the $purge argument is true, purge
+ all data related to the plugin. Example: delete database tables
+ and remove all permissions associated with this plugin.
+
+The function plugin_active(<plugin_name>) should be used in views and elsewhere
+to test if a plugin is active and change behaviour accordingly.
+
+Future work:
+
+Backup
+<plugin_name>_backup(args): do anything to backup data under the given backup_id
+<plugin_name>_restore(args): do anything to restore data from the given backup_id
+<plugin_name>_forget(args): do anything to delete the backup data under the given backup_id
+
+Args is an array with a least 1 key and value: backup_id => <integer>
+Optional keys: project_id => <integer>, company_id => <integer>, client_id => <integer>
+
+Stylesheets
+Stylesheets and JavaScript needs to be deployed manually in the themes directories.
+A solution is needed to support stylesheets, images and JavaScript local to the plugin.
+
+Configuration
+Currently configuration is implemented by manipulating the configuration tables and
+reusing the standard configuration pages. See tickets for an example.
+The original plugin developer mentioned a method <plugin_name>_configure_url()
+which would return a link constructed with the PP built-in get_url() function
+to a configuration page for the plugin. Not sure if it is still needed.
+
+
+
+B. Permissions
+--------------
+
+Permissions can be added to and removed from the system using the
+functions found in <pp_root>/application/permissions.php. The
+"source" of a permission is the plugin name. The "permission" is a
+short string description. Note that the base ProjectDataObject class,
+which all models inherit from, defines methods for canView()
+canEdit(), canAdd(), and canDelete(). Deletion is traditionally
+acceptable only for administrators, but if a plugin implements
+per-object ACLs, this permission can be assigned to individual users.
+In addition, any number of other functions can be implemented to allow
+for more fine-grained permissions.
+
+The default (built-in) permissions are:
+Source | Permission
+-----------+-------------------------
+files | manage
+files | upload
+milestones | manage
+messages | manage
+tasks | manage
+tasks | assign to other clients
+tasks | assign to owner company
+tickets | manage
+projects | manage
+milestones | change status
+
+For plugins that are implementing a new "Tab" on projects, the plugin
+should implement at least one permission called 'view'. The plugin's
+init.php file should include a line like
+"add_action('add_project_tab','<name of a callback function>')". The
+callback function should check the 'view' permission for the plugin
+based on the current user and project and add the tab *only* if the
+user has the appropriate permission. This will avoid cluttering the
+project interface with unnecessary tabs.
+
+--
+
+All the source files for deactivated plugins should be excluded from the AutoLoader.
+
+The Plugin system should gracefully deactivate (perhaps only temporarily) any missing plugins.
+
+I really like the WP plugin mechanism that identifies plugins by a description section. Maybe this system could include an "identity.xml" or "identity.txt" to help describe the plugin to the user. Fields would include Plugin Name, Version, Homepage, Description, Author, etc. It could also include an Upgrade URL in preparation for future automated plugin installation/upgrades. (Define the tag now, so authors will include it for the future.)
+
+Anyone have ideas on how to handle errant plugins? If a plugin causes problems, the user should have simple problem resolution options. One idea comes to mind: A "PP safe mode" URL (administrators only) where all plugins are disabled and the admin can disable plugins. It could be linked from the login screen (which might be designated a "plugin free zone").
+
@@ -8,49 +8,59 @@
* @version 1.0
* @http://www.projectpier.org/
*/
-
+ trace(__FILE__, 'begin');
define('FILE_STORAGE_FILE_SYSTEM', 'fs');
define('FILE_STORAGE_MYSQL', 'mysql');
-
+ define('TOKEN_COOKIE_NAME', 'pp086b2' . TABLE_PREFIX);
+ //$installation_root = config_option('installation_root', dirname($_SERVER['PHP_SELF']) );
+ $path=$_SERVER['PHP_SELF'];
+ $path=substr($path, 0, strpos($path, 'index.php'));
+ $installation_root = $path;
+ define('ROOT_URL', $installation_root);
+
// Init flash!
Flash::instance();
- Localization::instance()->loadSettings(DEFAULT_LOCALIZATION, ROOT . '/language');
- include_once APPLICATION_PATH . '/functions.php';
-
+ $language = config_option('installation_base_language', 'en_us');
+ if (isset($_SESSION['language'])) {
+ $language = $_SESSION['language'];
+ }
+ Localization::instance()->loadSettings($language, ROOT . '/language');
+
try {
+ trace(__FILE__, 'CompanyWebsite::init()');
CompanyWebsite::init();
if (config_option('upgrade_check_enabled', false)) {
VersionChecker::check(false);
} // if
-
if (config_option('file_storage_adapter', 'mysql') == FILE_STORAGE_FILE_SYSTEM) {
+ trace(__FILE__, 'CompanyWebsite::init() - use file storage');
FileRepository::setBackend(new FileRepository_Backend_FileSystem(FILES_DIR));
} else {
+ trace(__FILE__, 'CompanyWebsite::init() - use mysql storage');
FileRepository::setBackend(new FileRepository_Backend_MySQL(DB::connection()->getLink(), TABLE_PREFIX));
} // if
PublicFiles::setRepositoryPath(ROOT . '/public/files');
if (trim(PUBLIC_FOLDER) == '') {
PublicFiles::setRepositoryUrl(with_slash(ROOT_URL) . 'files');
} else {
- PublicFiles::setRepositoryUrl(with_slash(ROOT_URL) . 'public/files');
+ PublicFiles::setRepositoryUrl(with_slash(ROOT_URL) . PUBLIC_FOLDER . '/files');
} // if
// Owner company or administrator doen't exist? Let the user create them
} catch(OwnerCompanyDnxError $e) {
Env::executeAction('access', 'complete_installation');
} catch(AdministratorDnxError $e) {
- Env::executeAction('access', 'complete_installation');
-
+ Env::executeAction('access', 'complete_installation');
// Other type of error? We need to break here
} catch(Exception $e) {
+ trace(__FILE__, '- catch '.$e.__toString());
if (Env::isDebugging()) {
Env::dumpError($e);
} else {
Logger::log($e, Logger::FATAL);
Env::executeAction('error', 'system');
} // if
} // if
-
-?>
+?>
@@ -18,7 +18,12 @@ function __construct() {
parent::__construct();
$this->setLayout('dialog');
- $this->addHelper('form', 'breadcrumbs', 'pageactions', 'tabbednavigation', 'company_website', 'project_website');
+ $this->addHelper('form');
+ $this->addHelper('breadcrumbs');
+ $this->addHelper('pageactions');
+ $this->addHelper('tabbednavigation');
+ $this->addHelper('company_website');
+ $this->addHelper('project_website');
} // __construct
/**
@@ -28,9 +33,10 @@ function __construct() {
* @return null
*/
function login() {
- $this->addHelper('form');
-
+ trace(__FILE__,'login()');
+
if (function_exists('logged_user') && (logged_user() instanceof User)) {
+ trace(__FILE__, 'login() - redirectTo(dashboard) because already logged in' );
$this->redirectTo('dashboard');
} // if
@@ -73,7 +79,9 @@ function login() {
} // if
try {
+ trace(__FILE__,"login() - logUserIn($username, $remember)");
CompanyWebsite::instance()->logUserIn($user, $remember);
+ if (isset($_POST['loginLanguage'])) $_SESSION['language'] = $_POST['loginLanguage'];
} catch(Exception $e) {
tpl_assign('error', new Error(lang('invalid login data')));
$this->render();
@@ -101,10 +109,11 @@ function login() {
if (!count($ref_params)) {
$ref_params = null;
}
-
if ($ref_controller && $ref_action) {
+ trace(__FILE__, "login() - redirectTo($ref_controller, $ref_action, $ref_params)" );
$this->redirectTo($ref_controller, $ref_action, $ref_params);
} else {
+ trace(__FILE__, 'login() - redirectTo(dashboard)' );
$this->redirectTo('dashboard');
} // if
} // if
@@ -119,7 +128,11 @@ function login() {
*/
function logout() {
CompanyWebsite::instance()->logUserOut();
- $this->redirectTo('access', 'login');
+ if(($lrp = config_option('logout_redirect_page')) != false && $lrp != 'default') {
+ $this->redirectToUrl($lrp);
+ } else {
+ $this->redirectTo('access', 'login');
+ }
} // logout
/**
@@ -132,7 +145,7 @@ function forgot_password() {
$your_email = trim(array_var($_POST, 'your_email'));
tpl_assign('your_email', $your_email);
- if (array_var($_POST, 'submited') == 'submited') {
+ if (array_var($_POST, 'submitted') == 'submitted') {
if (!is_valid_email($your_email)) {
tpl_assign('error', new InvalidEmailAddressError($your_email, lang('invalid email address')));
$this->render();
@@ -156,6 +169,18 @@ function forgot_password() {
} // forgot_password
/**
+ * Clear cookies
+ *
+ * @access public
+ * @param void
+ * @return null
+ */
+ function clear_cookies() {
+ CompanyWebsite::instance()->logUserOut();
+ $this->redirectTo('access', 'login');
+ } // logout
+
+ /**
* Finish the installation - create owner company and administrator
*
* @param void
@@ -169,7 +194,7 @@ function complete_installation() {
$form_data = array_var($_POST, 'form');
tpl_assign('form_data', $form_data);
- if (array_var($form_data, 'submited') == 'submited') {
+ if (array_var($form_data, 'submitted') == 'submitted') {
try {
$admin_password = trim(array_var($form_data, 'admin_password'));
$admin_password_a = trim(array_var($form_data, 'admin_password_a'));
@@ -71,14 +71,18 @@ function edit_profile() {
'email' => $user->getEmail(),
'display_name' => $user->getDisplayName(),
'title' => $user->getTitle(),
+ 'homepage' => $user->getHomepage(),
'office_number' => $user->getOfficeNumber(),
'fax_number' => $user->getFaxNumber(),
'mobile_number' => $user->getMobileNumber(),
'home_number' => $user->getHomeNumber(),
'timezone' => $user->getTimezone(),
'is_admin' => $user->getIsAdmin(),
'auto_assign' => $user->getAutoAssign(),
+ 'use_LDAP' => $user->getUseLDAP(),
+ 'use_gravatar' => $user->getUseGravatar(),
'company_id' => $user->getCompanyId(),
+ 'can_manage_projects' => $user->canManageProjects() ? '1' : '0',
); // array
if (is_array($im_types)) {
@@ -101,8 +105,16 @@ function edit_profile() {
try {
DB::beginWork();
+ if (config_option('check_email_unique', '1')=='1') {
+ if (!$user->validateUniquenessOf('email')) {
+ throw new Error(lang('email address is already used'));
+ }
+ }
$user->setFromAttributes($user_data);
$user->save();
+
+ $granted = (trim(array_var($user_data, 'can_manage_projects')) == '1') ? 1 : 0;
+ $user->setPermission(PermissionManager::CAN_MANAGE_PROJECTS, $granted);
$user->clearImValues();
@@ -226,7 +238,7 @@ function update_permissions() {
$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)) {
@@ -241,32 +253,24 @@ function update_permissions() {
if (array_var($_POST, 'submitted') == 'submitted') {
DB::beginWork();
+ ProjectUsers::clearByUser($user);
foreach ($projects as $project) {
- $relation = ProjectUsers::findById(array(
- 'project_id' => $project->getId(),
- 'user_id' => $user->getId(),
- )); // findById
-
- if (array_var($_POST, 'project_permissions_' . $project->getId()) == 'checked') {
- if (!($relation instanceof ProjectUser)) {
- $relation = new ProjectUser();
- $relation->setProjectId($project->getId());
- $relation->setUserId($user->getId());
- } // 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);
- } // foreach
-
+ $permission_count = 0;
+ $permission_all = array_var($_POST, 'project_permissions_'.$project->getId().'_all') == 'checked' ;
+ foreach ($permissions as $permission_name => $permission_text) {
+ $permission_value = ($permission_all || array_var($_POST, 'project_permission_' . $project->getId() . '_' . $permission_name) == 'checked');
+ if ($permission_value) {
+ $permission_count++;
+ }
+ $user->setProjectPermission($project, $permission_name, $permission_value);
+ } // foreach
+
+ if ($permission_count>0) {
+ $relation = new ProjectUser();
+ $relation->setProjectId($project->getId());
+ $relation->setUserId($user->getId());
$relation->save();
- } else {
- if ($relation instanceof ProjectUser) {
- $relation->delete();
- } // if
- } // if
+ }
} // if
DB::commit();
Oops, something went wrong.

0 comments on commit 5ab906c

Please sign in to comment.