diff --git a/password_policy.admin.inc b/password_policy.admin.inc index 775d64e..f0e183e 100644 --- a/password_policy.admin.inc +++ b/password_policy.admin.inc @@ -481,6 +481,76 @@ function password_policy_admin_form_submit($form, &$form_state) { drupal_goto('admin/config/people/password_policy/delete/' . $form_state['values']['pid']); } + _password_policy_admin_form_save_policy($form_state); + + $form_state['redirect'] = 'admin/config/people/password_policy/list'; +} + +/** + * Saves policy from submitted policy form. + */ +function _password_policy_admin_form_save_policy($form_state) { + $policy = _password_policy_admin_form_get_policy($form_state); + password_policy_save_policy($policy); + _password_policy_admin_form_set_saved_message($policy); +} + +/** + * Gets policy from submitted policy form. + * + * @param array $form_state + * Form state. + * + * @return array + * Policy array. + */ +function _password_policy_admin_form_get_policy(array $form_state) { + $form_values = $form_state['values']; + $policy = array( + 'name' => $form_values['name'], + 'description' => $form_values['description'], + 'constraints' => _password_policy_admin_form_get_constraints($form_state), + 'expiration' => $form_values['expiration'], + 'warning' => $form_values['warning'], + 'roles' => $form_values['roles'], + ); + if (isset($form_values['pid'])) { + // Editing an existing policy. Get pid. + $policy['pid'] = $form_values['pid']; + } + else { + // Adding a new policy. Disable by default. + $policy['enabled'] = 0; + } + + return $policy; +} + +/** + * Sets message indicating policy has been saved. + * + * @param array $policy + * Policy array. + */ +function _password_policy_admin_form_set_saved_message(array $policy) { + if (isset($policy['pid'])) { + drupal_set_message(t('Policy %name has been updated.', array('%name' => $policy['name']))); + } + else { + drupal_set_message(t('Policy %name has been created.', array('%name' => $policy['name']))); + } +} + +/** + * Gets constraints from submitted policy form. + * + * @param array $form_state + * Form state. + * + * @return array + * Constraints array. + */ +function _password_policy_admin_form_get_constraints(array $form_state) { $constraints = array(); foreach ($form_state['values'] as $key => $value) { // If we have no form value, then we have no constraint to set. @@ -492,52 +562,7 @@ function password_policy_admin_form_submit($form, &$form_state) { } } } - - $expiration = intval($form_state['values']['expiration']); - // If we have a pid, update, else save. - if (isset($form_state['values']['pid']) && $form_state['values']['pid']) { - db_update('password_policy') - ->fields(array( - 'name' => $form_state['values']['name'], - 'description' => $form_state['values']['description'], - 'constraints' => serialize($constraints), - 'expiration' => !empty($expiration) ? $expiration : 0, - 'warning' => str_replace(' ', '', $form_state['values']['warning']), - )) - ->condition('pid', $form_state['values']['pid']) - ->execute(); - drupal_set_message(t('Policy %name has been updated.', array('%name' => $form_state['values']['name']))); - watchdog('password_policy', 'Policy %name updated.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/config/people/password_policy/' . $form_state['values']['pid'] . '/edit')); - $pid = $form_state['values']['pid']; - db_delete('password_policy_role') - ->condition('pid', $pid) - ->execute(); - } - else { - $pid = db_insert('password_policy') - ->fields(array( - 'name' => $form_state['values']['name'], - 'description' => $form_state['values']['description'], - 'enabled' => 0, - 'constraints' => serialize($constraints), - 'expiration' => !empty($expiration) ? $expiration : 0, - 'warning' => str_replace(' ', '', $form_state['values']['warning']), - )) - ->execute(); - drupal_set_message(t('Policy %name has been created.', array('%name' => $form_state['values']['name']))); - watchdog('password_policy', 'New policy %name created.', array('%name' => $form_state['values']['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/config/people/password_policy/' . $pid . '/edit')); - } - - foreach (array_filter($form_state['values']['roles']) as $rid => $enabled) { - db_insert('password_policy_role') - ->fields(array( - 'pid' => $pid, - 'rid' => $rid, - )) - ->execute(); - } - - $form_state['redirect'] = 'admin/config/people/password_policy/list'; + return $constraints; } /** diff --git a/password_policy.features.inc b/password_policy.features.inc new file mode 100644 index 0000000..2f7a8fc --- /dev/null +++ b/password_policy.features.inc @@ -0,0 +1,89 @@ + 'slave')) + ->fetchAllKeyed(0, 0); +} + +/** + * Implements hook_features_export(). + */ +function password_policy_features_export($data, &$export, $module_name) { + $export['dependencies']['features'] = 'features'; + $export['dependencies']['password_policy'] = 'password_policy'; + + foreach ($data as $policy_name) { + $policy = password_policy_load_policy_by_name($policy_name); + + // Export roles to which policy applies. + foreach ($policy['roles'] as $rid) { + $role = user_role_load($rid); + $export['features']['user_role'][$role->name] = $role->name; + } + + $export['features']['password_policy'][$policy_name] = $policy_name; + } + + return $export; +} + +/** + * Implements hook_features_export_render(). + */ +function password_policy_features_export_render($module_name, $data, $export = NULL) { + $code = array(); + foreach ($data as $policy_name) { + $policy = password_policy_load_policy_by_name($policy_name); + if ($policy) { + $roles = array(); + foreach ($policy['roles'] as $rid) { + $role = user_role_load($rid); + $roles[] = $role->name; + } + $policy['roles'] = $roles; + unset($policy['pid']); + $code[$policy['name']] = $policy; + } + } + + $code = ' return ' . features_var_export($code, ' ') . ';'; + + return array('password_policy_features_default_policies' => $code); +} + +/** + * Implements hook_features_revert(). + */ +function password_policy_features_revert($module_name) { + password_policy_features_rebuild($module_name); +} + +/** + * Implements hook_features_rebuild(). + */ +function password_policy_features_rebuild($module_name) { + $saved_policies = module_invoke($module_name, 'password_policy_features_default_policies'); + foreach ($saved_policies as $policy) { + $roles = array(); + foreach ($policy['roles'] as $name) { + $role = user_role_load_by_name($name); + $roles[$role->rid] = $role->rid; + } + $policy['roles'] = $roles; + + $exists = password_policy_load_policy_by_name($policy['name']); + if ($exists) { + $policy['pid'] = $exists['pid']; + } + + password_policy_save_policy($policy); + } +} diff --git a/password_policy.module b/password_policy.module index e585b47..3cf6abd 100644 --- a/password_policy.module +++ b/password_policy.module @@ -186,22 +186,7 @@ function password_policy_drupal_goto_alter(&$path, &$options) { * A populated policy array or FALSE if not found. */ function password_policy_policy_load($pid) { - static $policies = array(); - - if (is_numeric($pid)) { - if (isset($policies[$pid])) { - return $policies[$pid]; - } - else { - $policy = _password_policy_load_policy_by_pid($pid); - if ($policy) { - $policy['constraints'] = unserialize($policy['constraints']); - $policies[$pid] = $policy; - return $policy; - } - } - } - return FALSE; + return _password_policy_load_policy_by_pid($pid); } /** @@ -1237,6 +1222,24 @@ function _password_policy_constraint_js($name, $constraint, $account) { } /****************************************************************************/ +/* Features integration */ +/****************************************************************************/ + +/** + * Implements hook_features_api(). + */ +function password_policy_features_api() { + return array( + 'password_policy' => array( + 'name' => 'Password Policy', + 'file' => drupal_get_path('module', 'password_policy') . '/password_policy.features.inc', + 'default_hook' => 'password_policy_features_default_policies', + 'features_source' => TRUE, + ), + ); +} + +/****************************************************************************/ /* Auxiliary functions */ /****************************************************************************/ @@ -1266,25 +1269,86 @@ function _password_policy_constraints() { /** * Loads the policy with the specified id. * + * Attempts to load the policy from a static cache variable. If not found, + * loads the policy from the database. + * * @param int $pid * The policy id. * * @return array|false - * A policy array, or FALSE if no policy was found. + * A populated policy array or FALSE if not found. */ function _password_policy_load_policy_by_pid($pid) { - $row = db_select('password_policy', 'p', array('target' => 'slave')) - ->fields('p') - ->condition('pid', $pid) - ->execute() - ->fetchAssoc(); + static $policies = array(); + + if (is_numeric($pid)) { + if (isset($policies[$pid])) { + return $policies[$pid]; + } + else { + $policy = _password_policy_load_policy_from_db(array('pid' => $pid)); + if ($policy) { + $policies[$pid] = $policy; + return $policy; + } + } + } + return FALSE; +} + +/** + * Loads the policy with the specified name. + * + * Attempts to load the policy from a static cache variable. If not found, + * loads the policy from the database. + * + * @param string $name + * The name of the policy. + * + * @return array|false + * A populated policy array or FALSE if not found. + */ +function password_policy_load_policy_by_name($name) { + static $policies = array(); + + if (isset($policies[$name])) { + return $policies[$name]; + } + else { + $policy = _password_policy_load_policy_from_db(array('name' => $name)); + if ($policy) { + $policies[$name] = $policy; + return $policy; + } + } + return FALSE; +} + +/** + * Loads the policy that meets the specified conditions from the database. + * + * @param array $conditions + * Associative array of conditions where keys are field names and values are + * field values. + * + * @return array|false + * A policy array or FALSE if no policy was found. + */ +function _password_policy_load_policy_from_db(array $conditions) { + $query = db_select('password_policy', 'p', array('target' => 'slave')) + ->fields('p'); + foreach ($conditions as $field => $value) { + $query->condition($field, $value); + } + $row = $query->execute()->fetchAssoc(); if ($row) { + $row['constraints'] = unserialize($row['constraints']); // Fetch roles. $row['roles'] = array(); $result = db_select('password_policy_role', 'p', array('target' => 'slave')) ->fields('p', array('rid')) - ->condition('pid', $pid) + ->condition('pid', $row['pid']) ->execute(); foreach ($result as $role) { $row['roles'][$role->rid] = $role->rid; @@ -1349,6 +1413,65 @@ function _password_policy_load_active_policy(array $roles) { } /** + * Saves a policy. + * + * @param array $policy + * A policy array. + */ +function password_policy_save_policy(array $policy) { + if (isset($policy['pid']) && $policy['pid']) { + $fields = array( + 'name' => $policy['name'], + 'description' => $policy['description'], + 'constraints' => serialize($policy['constraints']), + 'created' => isset($policy['created']) ? $policy['created'] : 0, + 'expiration' => !empty($policy['expiration']) ? $policy['expiration'] : 0, + 'warning' => str_replace(' ', '', $policy['warning']), + 'weight' => !empty($policy['weight']) ? $policy['weight'] : 0, + ); + // On policy edit form we have no 'enabled' param, so modify update query. + if (isset($policy['enabled'])) { + $fields += array( + 'enabled' => $policy['enabled'], + ); + } + db_update('password_policy') + ->fields($fields) + ->condition('pid', $policy['pid']) + ->execute(); + watchdog('password_policy', 'Policy %name updated.', array('%name' => $policy['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/config/people/password_policy/' . $policy['pid'] . '/edit')); + db_delete('password_policy_role') + ->condition('pid', $policy['pid']) + ->execute(); + $pid = $policy['pid']; + } + else { + $pid = db_insert('password_policy') + ->fields(array( + 'name' => $policy['name'], + 'description' => $policy['description'], + 'enabled' => $policy['enabled'], + 'constraints' => serialize($policy['constraints']), + 'created' => isset($policy['created']) ? $policy['created'] : 0, + 'expiration' => !empty($policy['expiration']) ? $policy['expiration'] : 0, + 'warning' => str_replace(' ', '', $policy['warning']), + 'weight' => !empty($policy['weight']) ? $policy['weight'] : 0, + )) + ->execute(); + watchdog('password_policy', 'New policy %name created.', array('%name' => $policy['name']), WATCHDOG_NOTICE, l(t('edit'), 'admin/config/people/password_policy/' . $pid . '/edit')); + } + + foreach (array_filter($policy['roles']) as $rid => $enabled) { + db_insert('password_policy_role') + ->fields(array( + 'pid' => $pid, + 'rid' => $rid, + )) + ->execute(); + } +} + +/** * Stores user password hash. * * @param int $uid