Parent Directory
|
Revision Log
|
Revision Graph
Stop gap solution to #577424: make sure to validate the node even if the title is '0'.
| 1 | <?php |
| 2 | // $Id: cvs.module,v 1.233 2009/08/05 20:27:56 dww Exp $ |
| 3 | // $Name: $ |
| 4 | |
| 5 | /** |
| 6 | * @file |
| 7 | * Provides access to CVS commit logs. |
| 8 | * |
| 9 | * @internal |
| 10 | * commit 139 looks weird. Remove from both cvs_files and cvs_messages? |
| 11 | * some commits are done by user 'root' ? |
| 12 | */ |
| 13 | |
| 14 | // Status values for CVS accounts. Update _cvs_get_status_options() for any changes. |
| 15 | define('CVS_PENDING', 0); |
| 16 | define('CVS_APPROVED', 1); |
| 17 | define('CVS_DECLINED', 2); |
| 18 | define('CVS_QUEUED', 3); |
| 19 | define('CVS_DISABLED', 4); |
| 20 | define('CVS_MIN_PASS_LENGTH', 5); |
| 21 | define('CVS_LICENSE', 'GNU public license, version 2'); |
| 22 | define('CVS_LICENSE_LINK', 'http://www.gnu.org/licenses/old-licenses/gpl-2.0.html'); |
| 23 | |
| 24 | if (function_exists('drupal_get_path')) { |
| 25 | $path = drupal_get_path('module', 'cvs'); |
| 26 | if (file_exists("$path/cvs_local.inc")) { |
| 27 | require_once "$path/cvs_local.inc"; |
| 28 | } |
| 29 | } |
| 30 | |
| 31 | /** |
| 32 | * Implementation of hook_help(). |
| 33 | */ |
| 34 | function cvs_help($path, $arg) { |
| 35 | switch ($path) { |
| 36 | case 'cvs': |
| 37 | case 'admin/project/cvs-accounts': |
| 38 | case 'admin/project/cvs-repositories': |
| 39 | case 'admin/project/cvs-settings': |
| 40 | return t('CVS (Concurrent Versions System) is a code management system used by developers to collaborate and track modifications of code.'); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | /** |
| 45 | * Implementation of hook_menu(). |
| 46 | */ |
| 47 | function cvs_menu() { |
| 48 | global $base_url; |
| 49 | $items = array(); |
| 50 | |
| 51 | // User pages: |
| 52 | $access = 'access CVS messages'; |
| 53 | $admin_access = 'administer CVS'; |
| 54 | |
| 55 | $items['cvs'] = array( |
| 56 | 'title' => 'CVS messages', |
| 57 | 'page callback' => 'cvs_page', |
| 58 | 'access arguments' => array($access), |
| 59 | 'type' => MENU_SUGGESTED_ITEM, |
| 60 | ); |
| 61 | $items['cvs-application'] = array( |
| 62 | 'title' => 'CVS application form', |
| 63 | 'page callback' => 'cvs_application_page', |
| 64 | 'access arguments' => array($access), |
| 65 | 'type' => MENU_SUGGESTED_ITEM, |
| 66 | ); |
| 67 | |
| 68 | // autocomplete callback |
| 69 | $items['cvs/user/autocomplete'] = array( |
| 70 | 'title' => 'CVS user autocomplete', |
| 71 | 'page callback' => 'cvs_user_autocomplete', |
| 72 | 'access arguments' => array($access), |
| 73 | 'type' => MENU_CALLBACK, |
| 74 | ); |
| 75 | |
| 76 | // Admin pages: |
| 77 | |
| 78 | // If for some reason someone is using this module without |
| 79 | // project.module (which is technically legitimate, though hard to |
| 80 | // imagine), we need to define our own version of /admin/project |
| 81 | // so the rest of our admin pages all work. |
| 82 | if (!module_exists('project')) { |
| 83 | $items['admin/project'] = array( |
| 84 | 'title' => 'Project administration', |
| 85 | 'description' => 'Administrative interface for project management and related modules.', |
| 86 | 'page callback' => 'system_admin_menu_block_page', |
| 87 | 'file' => 'system.admin.inc', |
| 88 | 'file path' => drupal_get_path('module', 'system'), |
| 89 | 'access arguments' => array($admin_access), |
| 90 | 'type' => MENU_NORMAL_ITEM, |
| 91 | ); |
| 92 | } |
| 93 | |
| 94 | $items['admin/project/cvs-settings'] = array( |
| 95 | 'description' => 'Modify CVS management settings, such as how it integrates with projects on your site, the text used on the CVS account application form, and the default wording for emails sent when CVS accounts are approved or denied.', |
| 96 | 'title' => 'CVS settings', |
| 97 | 'page callback' => 'drupal_get_form', |
| 98 | 'page arguments' => array('cvs_settings_form'), |
| 99 | 'access arguments' => array($admin_access), |
| 100 | 'type' => MENU_NORMAL_ITEM, |
| 101 | ); |
| 102 | |
| 103 | // Accounts: |
| 104 | $items['admin/project/cvs-accounts'] = array( |
| 105 | 'title' => 'CVS accounts', |
| 106 | 'description' => 'Approve or deny requests from the <a href="'. $base_url .'/cvs-application">CVS application</a>, import CVS users from an existing CVSROOT/password file, or export a CVSROOT/passwd file to install in any of your CVS repositories.', |
| 107 | 'page callback' => 'cvs_account', |
| 108 | 'access arguments' => array($admin_access), |
| 109 | 'type' => MENU_NORMAL_ITEM, |
| 110 | ); |
| 111 | $items['admin/project/cvs-accounts/list'] = array( |
| 112 | 'title' => 'List', |
| 113 | 'page callback' => 'cvs_account', |
| 114 | 'access arguments' => array($admin_access), |
| 115 | 'type' => MENU_DEFAULT_LOCAL_TASK, |
| 116 | ); |
| 117 | $items['admin/project/cvs-accounts/import'] = array( |
| 118 | 'title' => 'Import', |
| 119 | 'page callback' => 'drupal_get_form', |
| 120 | 'page arguments' => array('cvs_account_import'), |
| 121 | 'access arguments' => array($admin_access), |
| 122 | 'type' => MENU_LOCAL_TASK, |
| 123 | 'weight' => 2, |
| 124 | ); |
| 125 | $items['admin/project/cvs-accounts/export'] = array( |
| 126 | 'title' => 'Export', |
| 127 | 'page callback' => 'cvs_account_export', |
| 128 | 'access arguments' => array($admin_access), |
| 129 | 'type' => MENU_LOCAL_TASK, |
| 130 | 'weight' => 3, |
| 131 | ); |
| 132 | $items['admin/project/cvs-accounts/status'] = array( |
| 133 | 'title' => 'Status', |
| 134 | 'page callback' => 'cvs_account_status', |
| 135 | 'access arguments' => array($admin_access), |
| 136 | 'type' => MENU_LOCAL_TASK, |
| 137 | 'weight' => 4, |
| 138 | ); |
| 139 | |
| 140 | // Repositories: |
| 141 | $items['admin/project/cvs-repositories'] = array( |
| 142 | 'title' => 'CVS repositories', |
| 143 | 'description' => 'Define and configure what CVS repositories are connected to your site, how CVS log messages should be saved, and how to integrate each repository with a source browsing tool such as ViewCVS.', |
| 144 | 'page callback' => 'cvs_repository', |
| 145 | 'access arguments' => array($admin_access), |
| 146 | 'type' => MENU_NORMAL_ITEM, |
| 147 | ); |
| 148 | $items['admin/project/cvs-repositories/list'] = array( |
| 149 | 'title' => 'List', |
| 150 | 'page callback' => 'cvs_repository', |
| 151 | 'access arguments' => array($admin_access), |
| 152 | 'type' => MENU_DEFAULT_LOCAL_TASK, |
| 153 | ); |
| 154 | $items['admin/project/cvs-repositories/add'] = array( |
| 155 | 'title' => 'Add repository', |
| 156 | 'page callback' => 'drupal_get_form', |
| 157 | 'page arguments' => array('cvs_repository_form'), |
| 158 | 'access arguments' => array($admin_access), |
| 159 | 'type' => MENU_LOCAL_TASK, |
| 160 | 'weight' => 2, |
| 161 | ); |
| 162 | $items['admin/project/cvs-repositories/edit'] = array( |
| 163 | 'title' => 'Edit repository', |
| 164 | 'page callback' => 'cvs_repository_edit', |
| 165 | 'access arguments' => array($admin_access), |
| 166 | 'type' => MENU_CALLBACK, |
| 167 | ); |
| 168 | $items['admin/project/cvs-repositories/delete'] = array( |
| 169 | 'title' => 'Delete', |
| 170 | 'page callback' => 'cvs_repository_delete', |
| 171 | 'access arguments' => array($admin_access), |
| 172 | 'type' => MENU_CALLBACK, |
| 173 | ); |
| 174 | $items['admin/project/cvs-repositories/fetch'] = array( |
| 175 | 'title' => 'Fetch log', |
| 176 | 'page callback' => 'cvs_repository_fetch', |
| 177 | 'access arguments' => array($admin_access), |
| 178 | 'type' => MENU_CALLBACK, |
| 179 | ); |
| 180 | |
| 181 | |
| 182 | // If the user has a CVS account, add a 'track CVS messages' tab to the tracker page. |
| 183 | $items['user/%user/track/code'] = array( |
| 184 | 'title' => 'Track code', |
| 185 | 'page callback' => 'cvs_account_tracker', |
| 186 | 'access callback' => 'cvs_account_tracker_access', |
| 187 | 'access arguments' => array(1), |
| 188 | 'type' => MENU_LOCAL_TASK, |
| 189 | 'weight' => 2, |
| 190 | ); |
| 191 | |
| 192 | $items['node/%node/cvs-access'] = array( |
| 193 | 'title' => 'CVS access', |
| 194 | 'page callback' => 'drupal_get_form', |
| 195 | 'page arguments' => array('cvs_project_access_form'), |
| 196 | 'access callback' => 'cvs_project_access_form_access', |
| 197 | 'access arguments' => array(1), |
| 198 | 'type' => MENU_LOCAL_TASK, |
| 199 | 'weight' => 4, |
| 200 | ); |
| 201 | $items['node/%node/cvs-access/delete/%user'] = array( |
| 202 | 'page callback' => 'drupal_get_form', |
| 203 | 'page arguments' => array('cvs_project_delete_access', 1, 4), |
| 204 | 'access callback' => 'cvs_project_access_form_access', |
| 205 | 'access arguments' => array(1), |
| 206 | 'type' => MENU_CALLBACK, |
| 207 | ); |
| 208 | $items['node/%project_node/committers'] = array( |
| 209 | 'title' => 'Committers', |
| 210 | 'page callback' => 'cvs_project_committers_page', |
| 211 | 'page arguments' => array(1), |
| 212 | 'type' => MENU_CALLBACK, |
| 213 | 'access callback' => 'node_access', |
| 214 | 'access arguments' => array('view', 1), |
| 215 | ); |
| 216 | // Redirect from the legacy URL to prevent link rot. |
| 217 | $items['project/developers/%project_node'] = array( |
| 218 | 'title' => 'Developers', |
| 219 | 'page callback' => 'cvs_project_developers_redirect', |
| 220 | 'page arguments' => array(2), |
| 221 | 'type' => MENU_CALLBACK, |
| 222 | 'access callback' => 'node_access', |
| 223 | 'access arguments' => array('view', 2), |
| 224 | ); |
| 225 | |
| 226 | return $items; |
| 227 | } |
| 228 | |
| 229 | function cvs_account_tracker_access($account) { |
| 230 | $result = db_query('SELECT uid, status FROM {cvs_accounts} WHERE uid = %d', $account->uid); |
| 231 | if ($cvs_account = db_fetch_object($result)) { |
| 232 | return user_access('access CVS messages') && $cvs_account->status == CVS_APPROVED; |
| 233 | } |
| 234 | |
| 235 | return FALSE; |
| 236 | } |
| 237 | |
| 238 | function cvs_user_edit_form_access($account) { |
| 239 | global $user; |
| 240 | $result = db_query('SELECT uid, status FROM {cvs_accounts} WHERE uid = %d', $account->uid); |
| 241 | if ($cvs_account = db_fetch_object($result)) { |
| 242 | return (!empty($user->uid) && $user->uid == $account->uid && $cvs_account->status == CVS_APPROVED) || user_access('administer CVS'); |
| 243 | } |
| 244 | |
| 245 | return FALSE; |
| 246 | } |
| 247 | |
| 248 | function cvs_project_access_form_access($node) { |
| 249 | global $user; |
| 250 | $result = db_query('SELECT uid FROM {cvs_accounts} WHERE uid = %d AND status = %d', $user->uid, CVS_APPROVED); |
| 251 | if ($cvs_account = db_fetch_object($result)) { |
| 252 | return $node->type == "project_project" && project_use_cvs($node) && |
| 253 | ($node->uid == $user->uid || user_access('administer nodes') |
| 254 | || user_access('administer CVS')); |
| 255 | } |
| 256 | |
| 257 | return FALSE; |
| 258 | } |
| 259 | |
| 260 | /** |
| 261 | * Implementation of hook_user(). |
| 262 | * |
| 263 | * Adds listing of CVS commits by project to the user profile page. |
| 264 | * |
| 265 | * Also, we need to hack this category in for the CVS edit subtab, since user |
| 266 | * module does try to have a tight control of management of these menu items, |
| 267 | * so we need to get it created through this hook and then altered by |
| 268 | * hook_menu_alter(). Drupal 7 should do better. |
| 269 | */ |
| 270 | function cvs_user($op, &$edit, &$account, $category = NULL) { |
| 271 | switch ($op) { |
| 272 | case 'view': |
| 273 | // Print a list of projects the specified user contributed to. |
| 274 | if (!empty($account->uid)) { |
| 275 | $result = db_query("SELECT DISTINCT(f.nid), n.title, COUNT(f.nid) AS commits FROM {cvs_files} f INNER JOIN {node} n ON n.status = %d AND n.nid = f.nid WHERE f.uid = %d GROUP BY f.nid, n.title ORDER BY commits DESC", 1, $account->uid); |
| 276 | $total = 0; |
| 277 | $projects = array(); |
| 278 | while ($project = db_fetch_object($result)) { |
| 279 | $project_link = l($project->title, 'node/'. $project->nid); |
| 280 | $projects[] = format_plural($project->commits, '!project (1 commit)', '!project (@count commits)', array('!project' => $project_link)); |
| 281 | $total += $project->commits; |
| 282 | } |
| 283 | if ($total > 0) { |
| 284 | $projects[] = format_plural($total, 'Total: 1 commit', 'Total: @count commits'); |
| 285 | } |
| 286 | if (!empty($projects)) { |
| 287 | $account->content['cvs'] = array( |
| 288 | '#type' => 'user_profile_category', |
| 289 | '#title' => t('Projects'), |
| 290 | '#weight' => 10, |
| 291 | '#attributes' => array('class' => 'cvs-project-user-commits'), |
| 292 | ); |
| 293 | $account->content['cvs']['items'] = array( |
| 294 | '#type' => 'user_profile_item', |
| 295 | '#value' => theme('item_list', $projects), |
| 296 | ); |
| 297 | } |
| 298 | } |
| 299 | break; |
| 300 | |
| 301 | case 'categories': |
| 302 | return array(array('name' => 'cvs', 'title' => t('CVS'), 'weight' => 3)); |
| 303 | |
| 304 | } |
| 305 | } |
| 306 | |
| 307 | /** |
| 308 | * Implementation of hook_menu_alter(). |
| 309 | * |
| 310 | * See why we need this hack in cvs_user(). |
| 311 | */ |
| 312 | function cvs_menu_alter(&$callbacks) { |
| 313 | $callbacks['user/%user_category/edit/cvs']['page callback'] = 'drupal_get_form'; |
| 314 | $callbacks['user/%user_category/edit/cvs']['page arguments'] = array('cvs_user_edit_form', 1); |
| 315 | $callbacks['user/%user_category/edit/cvs']['access callback'] = 'cvs_user_edit_form_access'; |
| 316 | $callbacks['user/%user_category/edit/cvs']['access arguments'] = array(1); |
| 317 | } |
| 318 | |
| 319 | /** |
| 320 | * Implementation of hook_perm(). |
| 321 | */ |
| 322 | function cvs_perm() { |
| 323 | return array('access CVS messages', 'administer CVS'); |
| 324 | } |
| 325 | |
| 326 | /** |
| 327 | * Implementation of hook_cron(). |
| 328 | */ |
| 329 | function cvs_cron() { |
| 330 | $result = db_query("SELECT * FROM {cvs_repositories} WHERE method = %d", 0); |
| 331 | while ($repo = db_fetch_object($result)) { |
| 332 | cvs_fetch_repository($repo); |
| 333 | } |
| 334 | } |
| 335 | |
| 336 | /** |
| 337 | * Implementation of hook_theme(). |
| 338 | */ |
| 339 | function cvs_theme() { |
| 340 | return array( |
| 341 | 'cvs_commit_message' => array( |
| 342 | 'arguments' => array('commit'), |
| 343 | ), |
| 344 | 'cvs_project_access_form' => array( |
| 345 | 'arguments' => array('form'), |
| 346 | ), |
| 347 | 'cvs_project_maintainer_list' => array( |
| 348 | 'arguments' => array('node', 'maintainers'), |
| 349 | ), |
| 350 | ); |
| 351 | } |
| 352 | |
| 353 | /** |
| 354 | * Form builder function for system settings. |
| 355 | */ |
| 356 | function cvs_settings_form(&$form_state) { |
| 357 | $strings = _cvs_get_strings(); |
| 358 | |
| 359 | $form['cvs_email_address'] = array( |
| 360 | '#type' => 'textfield', |
| 361 | '#title' => t('E-mail address'), |
| 362 | '#default_value' => variable_get('cvs_email_address', 'cvs@example.com'), |
| 363 | '#description' => t('The e-mail address of the CVS administrator.'), |
| 364 | ); |
| 365 | $form['cvs_use_file'] = array( |
| 366 | '#type' => 'radios', |
| 367 | '#title' => t("Use file to store log"), |
| 368 | '#default_value' => variable_get('cvs_use_file', 1), |
| 369 | '#options' => array(t('Disabled'), t('Enabled')), |
| 370 | '#description' => t('When enabled, this will store log messages in a temporary file to reduce memory consumption.'), |
| 371 | ); |
| 372 | $options = _cvs_get_repository_options('<' . t('none') . '>'); |
| 373 | $form['cvs_default_repo'] = array( |
| 374 | '#title' => t('Default CVS repository for projects'), |
| 375 | '#type' => 'radios', |
| 376 | '#options' => $options, |
| 377 | '#default_value' => variable_get('cvs_default_repo', 0), |
| 378 | '#description' => t('Choose the repository that should be used by default when projects are being edited'), |
| 379 | ); |
| 380 | $form['cvs_restrict_project_creation'] = array( |
| 381 | '#title' => t('Restrict project creation to users with CVS accounts'), |
| 382 | '#type' => 'checkbox', |
| 383 | '#default_value' => variable_get('cvs_restrict_project_creation', 1), |
| 384 | '#description' => t('If this box is checked, only users with CVS accounts will be allowed to create project nodes.'), |
| 385 | ); |
| 386 | if (module_exists('project') && project_use_taxonomy()) { |
| 387 | $form['type_validation'] = array( |
| 388 | '#title' => t('Validate %cvs_dir by %type', array('%cvs_dir' => t('CVS directory'), '%type' => t('Project type'))), |
| 389 | '#type' => 'fieldset', |
| 390 | ); |
| 391 | $form['type_validation']['cvs_directory_validate_by_type'] = array( |
| 392 | '#title' => t('Validate %cvs_dir using %type', array('%cvs_dir' => t('CVS directory'), '%type' => t('Project type'))), |
| 393 | '#type' => 'checkbox', |
| 394 | '#default_value' => variable_get('cvs_directory_validate_by_type', 1), |
| 395 | '#description' => t("If this box is checked, the first element of the path specified in the %cvs_dir field must match the selected %type for project nodes. This is a case insensitive comparison, and spaces in the %type field will be converted to hypens ('-') for the purpose of the comparison. However, if custom directories are specified in the fields below, those will be used for validation instead.", array('%cvs_dir' => t('CVS directory'), '%type' => t('Project type'))), |
| 396 | ); |
| 397 | $terms = taxonomy_get_tree(_project_get_vid()); |
| 398 | foreach ($terms as $i => $term) { |
| 399 | // Only use the first-level terms. |
| 400 | if ($term->depth == 0) { |
| 401 | $form['type_validation']['cvs_directory_tid_'. $term->tid] = array( |
| 402 | '#title' => t('Directory for %term_name', array('%term_name' => $term->name)), |
| 403 | '#type' => 'textfield', |
| 404 | '#default_value' => variable_get('cvs_directory_tid_'. $term->tid, ''), |
| 405 | ); |
| 406 | } |
| 407 | } |
| 408 | } |
| 409 | $form['cvs_validate_by_short_name'] = array( |
| 410 | '#title' => t('Validate %cvs_dir using %short_name', array('%cvs_dir' => t('CVS directory'), '%short_name' => t('Project short name'))), |
| 411 | '#type' => 'checkbox', |
| 412 | '#default_value' => variable_get('cvs_validate_by_short_name', 1), |
| 413 | '#description' => t("If this box is checked, the last element of the path specified in the %cvs_dir field must match the %short_name field for project nodes.", array('%cvs_dir' => t('CVS directory'), '%short_name' => t('Project short name'))), |
| 414 | ); |
| 415 | $form['cvs_directory_validate_dir_root_by_case'] = array( |
| 416 | '#title' => t('Ensure lowercase for first element of %cvs_dir', array('%cvs_dir' => t('CVS directory'))), |
| 417 | '#type' => 'checkbox', |
| 418 | '#default_value' => variable_get('cvs_directory_validate_dir_root_by_case', 1), |
| 419 | '#description' => t("If this box is checked, the first element of the path specified in the %cvs_dir field must be lowercase.", array('%cvs_dir' => t('CVS directory'))), |
| 420 | ); |
| 421 | $form['cvs_list_per_page'] = array( |
| 422 | '#title' => t('Number of CVS accounts listed per page'), |
| 423 | '#type' => 'textfield', |
| 424 | '#default_value' => variable_get('cvs_list_per_page', 20), |
| 425 | '#size' => 6, |
| 426 | '#description' => t('The number of users to display per page in admin list view.') |
| 427 | ); |
| 428 | $form['cvs_application_form'] = array( |
| 429 | '#title' => t('CVS application form strings'), |
| 430 | '#type' => 'fieldset', |
| 431 | '#collapsible' => TRUE, |
| 432 | '#collapsed' => TRUE |
| 433 | ); |
| 434 | $form['cvs_application_form']['cvs_message_anon'] = array( |
| 435 | '#title' => t('Message to anonymous users'), |
| 436 | '#type' => 'textarea', |
| 437 | '#default_value' => variable_get('cvs_message_anon', $strings['cvs_message_anon']), |
| 438 | '#description' => t('Message to show to anonymous users who are trying to apply for a CVS account'), |
| 439 | ); |
| 440 | $form['cvs_application_form']['cvs_message_auth'] = array( |
| 441 | '#title' => t('Message to authenticated users'), |
| 442 | '#type' => 'textarea', |
| 443 | '#default_value' => variable_get('cvs_message_auth', $strings['cvs_message_auth']), |
| 444 | '#description' => t('Message to show to authenticated users who are applying for a CVS account.'), |
| 445 | ); |
| 446 | $form['cvs_application_form']['cvs_motivation_description'] = array( |
| 447 | '#title' => t('Motivation message description'), |
| 448 | '#type' => 'textarea', |
| 449 | '#default_value' => variable_get('cvs_motivation_description', $strings['cvs_motivation_description']), |
| 450 | '#description' => t('Text to display below the motivation field of a CVS application.'), |
| 451 | ); |
| 452 | $form['cvs_email_form'] = array( |
| 453 | '#title' => t('CVS application e-mail messages'), |
| 454 | '#description' => t('The following messages are templates for e-mails messages |
| 455 | sent to users who have applied for a CVS account. The following variables are |
| 456 | substituted (where available) when the message is sent. |
| 457 | <ul> |
| 458 | <li>%account-name - The username of the applicant.</li> |
| 459 | <li>%user-account-url - The URL of the applicant\'s user page.</li> |
| 460 | <li>%manage-cvs-account-url : The URL where the user can manage his CVS account.</li> |
| 461 | <li>%cvs-admin-message : Additional guidelines specified by the CVS administrator.</li> |
| 462 | <li>%cvs-admin-name : Username of the CVS administrator.</li> |
| 463 | <li>%motivation-message : The motivation message of the applicant.</li> |
| 464 | <li>%client-information - The applicant\'s IP and browser related information.</li> |
| 465 | </ul>'), |
| 466 | '#type' => 'fieldset', |
| 467 | '#collapsible' => TRUE, |
| 468 | '#collapsed' => TRUE |
| 469 | ); |
| 470 | $form['cvs_email_form']['cvs_received_email'] = array( |
| 471 | '#title' => t('CVS application received e-mail message'), |
| 472 | '#type' => 'textarea', |
| 473 | '#default_value' => variable_get('cvs_received_email', $strings['cvs_received_email']), |
| 474 | '#description' => t('The message to send to users whose application has been received.'), |
| 475 | ); |
| 476 | $form['cvs_email_form']['cvs_new_application_email'] = array( |
| 477 | '#title' => t('CVS new application e-mail message'), |
| 478 | '#type' => 'textarea', |
| 479 | '#default_value' => variable_get('cvs_new_application_email', $strings['cvs_new_application_email']), |
| 480 | '#description' => t('The message sent to the administrator when a user has submitted an application.'), |
| 481 | ); |
| 482 | $form['cvs_email_form']['cvs_approved_email'] = array( |
| 483 | '#title' => t('CVS account approved e-mail message'), |
| 484 | '#type' => 'textarea', |
| 485 | '#default_value' => variable_get('cvs_approved_email', $strings['cvs_approved_email']), |
| 486 | '#description' => t('The message to send to users whose accounts have been approved.'), |
| 487 | ); |
| 488 | $form['cvs_email_form']['cvs_pending_email'] = array( |
| 489 | '#title' => t('CVS account pending e-mail message'), |
| 490 | '#type' => 'textarea', |
| 491 | '#default_value' => variable_get('cvs_pending_email', $strings['cvs_pending_email']), |
| 492 | '#description' => t('The message to send to users whose accounts cannot be approved yet.'), |
| 493 | ); |
| 494 | $form['cvs_email_form']['cvs_declined_email'] = array( |
| 495 | '#title' => t('CVS account declined e-mail message'), |
| 496 | '#type' => 'textarea', |
| 497 | '#default_value' => variable_get('cvs_declined_email', $strings['cvs_declined_email']), |
| 498 | '#description' => t('The message to send to users whose accounts have been declined.'), |
| 499 | ); |
| 500 | $form['cvs_email_form']['cvs_disabled_email'] = array( |
| 501 | '#title' => t('CVS account disabled e-mail message'), |
| 502 | '#type' => 'textarea', |
| 503 | '#default_value' => variable_get('cvs_disabled_email', $strings['cvs_disabled_email']), |
| 504 | '#description' => t('The message to send to users whose accounts have been disabled.'), |
| 505 | ); |
| 506 | |
| 507 | if (module_exists('project_release')) { |
| 508 | $form['cvs_message_new_release_branch'] = array( |
| 509 | '#title' => t('Message when new releases are added from a branch'), |
| 510 | '#type' => 'textarea', |
| 511 | '#default_value' => variable_get('cvs_message_new_release_branch', ''), |
| 512 | '#description' => t('Message to show to project maintainers when they add a new development snapshot release from a branch.'), |
| 513 | ); |
| 514 | $form['cvs_message_new_release_tag'] = array( |
| 515 | '#title' => t('Message when new releases are added from a tag'), |
| 516 | '#type' => 'textarea', |
| 517 | '#default_value' => variable_get('cvs_message_new_release_tag', ''), |
| 518 | '#description' => t('Message to show to project maintainers when they add a new official release from a tag.'), |
| 519 | ); |
| 520 | } |
| 521 | return system_settings_form($form); |
| 522 | } |
| 523 | |
| 524 | /** |
| 525 | * Implementation of hook_nodeapi(). |
| 526 | */ |
| 527 | function cvs_nodeapi(&$node, $op, $arg = NULL) { |
| 528 | if ($node->type == 'project_project') { |
| 529 | switch ($op) { |
| 530 | case 'load': |
| 531 | $result = db_query('SELECT * FROM {cvs_projects} WHERE nid = %d', $node->nid); |
| 532 | if ($project = db_fetch_object($result)) { |
| 533 | $node->cvs['repository'] = $project->rid; |
| 534 | $node->cvs['directory'] = $project->directory; |
| 535 | } |
| 536 | break; |
| 537 | case 'insert': |
| 538 | case 'update': |
| 539 | _cvs_directory_fix($node->cvs['directory']); |
| 540 | db_query('DELETE FROM {cvs_projects} WHERE nid = %d', $node->nid); |
| 541 | db_query("INSERT INTO {cvs_projects} (nid, rid, directory) VALUES (%d, %d, '%s')", $node->nid, $node->cvs['repository'], $node->cvs['directory']); |
| 542 | db_query("UPDATE {cvs_files} SET nid = %d WHERE rid = %d AND file LIKE '%s%%'", $node->nid, $node->cvs['repository'], $node->cvs['directory']); |
| 543 | break; |
| 544 | case 'validate': |
| 545 | if (strlen($node->title) > 0) { |
| 546 | $admin = user_access('administer projects'); |
| 547 | $project = !empty($node->nid) ? node_load($node->nid) : NULL; |
| 548 | if (!empty($node->cvs['repository']) && !db_result(db_query('SELECT rid FROM {cvs_repositories} WHERE rid = %d', $node->cvs['repository']))) { |
| 549 | form_set_error('cvs][repository', t('You must select a valid CVS repository.')); |
| 550 | } |
| 551 | if (!$admin && $project && $node->cvs['repository'] != $project->cvs['repository']) { |
| 552 | form_set_error('cvs][repository', t('You do not have permission to modify the CVS repository for this project.')); |
| 553 | } |
| 554 | if (empty($node->cvs['repository'])) { |
| 555 | // The rest of this validation only makes sense if we have |
| 556 | // a CVS repository for this project |
| 557 | if (!empty($node->cvs['directory'])) { |
| 558 | form_set_error('cvs][directory', t('You can not specify a CVS directory if there is no CVS repository for this project.')); |
| 559 | } |
| 560 | break; |
| 561 | } |
| 562 | _cvs_directory_fix($node->cvs['directory']); |
| 563 | if (!$node->cvs['directory']) { |
| 564 | form_set_error('cvs][directory', t('You have to specify a valid CVS directory.')); |
| 565 | } |
| 566 | else if (!preg_match('/^[a-zA-Z0-9\/_-]+$/', $node->cvs['directory'])) { |
| 567 | form_set_error('cvs][directory', t("The path of the CVS directory can only contain letters, numbers, slashes ('/'), hyphens ('-') and underscores ('_').")); |
| 568 | } |
| 569 | else if (preg_match('/\/\//', $node->cvs['directory'])) { |
| 570 | form_set_error('cvs][directory', t("The path of the CVS directory cannot contain two slashes next to each other '//'.")); |
| 571 | } |
| 572 | else if (db_result(db_query("SELECT nid FROM {cvs_projects} WHERE nid != %d AND rid = %d AND directory = '%s'", $node->nid, $node->cvs['repository'], $node->cvs['directory']))) { |
| 573 | form_set_error('cvs][directory', t('The specified CVS directory conflicts with that of an existing project.')); |
| 574 | } |
| 575 | else if (!$admin) { |
| 576 | $path_elems = explode('/', $node->cvs['directory']); |
| 577 | // Remove empty elements caused by the trailing and leading '/'. |
| 578 | $path_elems = array_filter($path_elems); |
| 579 | if (variable_get('cvs_directory_validate_dir_root_by_case', 1)) { |
| 580 | if ($path_elems[1] != drupal_strtolower($path_elems[1])) { |
| 581 | form_set_error('cvs][directory', t("The root of the CVS directory (%root) must be lowercase.", array('%root' => $path_elems[1]))); |
| 582 | } |
| 583 | } |
| 584 | if (project_use_taxonomy() && variable_get('cvs_directory_validate_by_type', 1)) { |
| 585 | $tree = taxonomy_get_term($node->project_type); |
| 586 | $cvs_dir_root = _cvs_dir_root($tree->name, $node->project_type); |
| 587 | if (drupal_strtolower($path_elems[1]) != $cvs_dir_root) { |
| 588 | form_set_error('cvs][directory', t("The root of the CVS directory (%root) does not match the selected project type (%type). By default, spaces in the type name are converted to hyphens in the path, but custom mappings can also be defined. Given the current project type, the first element of the directory path should be: %goal.", array('%root' => $path_elems[1], '%type' => $tree->name, '%goal' => $cvs_dir_root))); |
| 589 | } |
| 590 | } |
| 591 | if (variable_get('cvs_validate_by_short_name', 1)) { |
| 592 | $last_elem = array_pop($path_elems); |
| 593 | if ($last_elem != $node->project['uri']) { |
| 594 | form_set_error('cvs][directory', t("The last part of the CVS directory (%last) does not match the short project name (%short).", array('%last' => $last_elem, '%short' => $node->project['uri']))); |
| 595 | form_set_error('project][uri', t("The short project name (%short) does not match the last part of the CVS directory (%last).", array('%last' => $last_elem, '%short' => $node->project['uri']))); |
| 596 | } |
| 597 | } |
| 598 | } |
| 599 | } |
| 600 | break; |
| 601 | case 'delete': |
| 602 | db_query('DELETE FROM {cvs_projects} WHERE nid = %d', $node->nid); |
| 603 | break; |
| 604 | } |
| 605 | } |
| 606 | elseif ($node->type == 'project_release') { |
| 607 | switch ($op) { |
| 608 | case 'insert': |
| 609 | if (project_use_cvs($node->project)) { |
| 610 | if ($node->project_release['rebuild']) { |
| 611 | $msg = variable_get('cvs_message_new_release_branch', ''); |
| 612 | } |
| 613 | else { |
| 614 | $msg = variable_get('cvs_message_new_release_tag', ''); |
| 615 | } |
| 616 | if (!empty($msg)) { |
| 617 | drupal_set_message($msg); |
| 618 | } |
| 619 | } |
| 620 | break; |
| 621 | } |
| 622 | } |
| 623 | } |
| 624 | |
| 625 | /** |
| 626 | * Implementation of hook_form_alter(). |
| 627 | */ |
| 628 | function cvs_form_alter(&$form, &$form_state, $form_id) { |
| 629 | if ($form_id == 'project_project_node_form') { |
| 630 | cvs_alter_project_project_form($form, $form_state); |
| 631 | return; |
| 632 | } |
| 633 | if ($form_id == 'project_release_node_form') { |
| 634 | if (function_exists('cvs_local_alter_project_release_form')) { |
| 635 | cvs_local_alter_project_release_form($form, $form_state); |
| 636 | } |
| 637 | cvs_alter_project_release_form($form, $form_state); |
| 638 | return; |
| 639 | } |
| 640 | } |
| 641 | |
| 642 | /** |
| 643 | * Menu Callback: Display the CVS account edit form. |
| 644 | * Form builder function for cvs_user_edit_form() |
| 645 | */ |
| 646 | function cvs_user_edit_form(&$form_state, $account) { |
| 647 | global $user; |
| 648 | |
| 649 | $result = db_fetch_object(db_query("SELECT cvs_user, motivation, status FROM {cvs_accounts} WHERE uid = %d", $account->uid)); |
| 650 | $cvs_user = $result->cvs_user; |
| 651 | $cvs_status = $result->status; |
| 652 | $cvs_motivation = $result->motivation; |
| 653 | |
| 654 | $form['cvs'] = array( |
| 655 | '#type' => 'fieldset', |
| 656 | '#title' => t('CVS account settings'), |
| 657 | '#collapsible' => TRUE, |
| 658 | '#collapsed' => FALSE, |
| 659 | ); |
| 660 | if (user_access('administer CVS')) { |
| 661 | // Due to the workaround being used in hook_menu to allow CVS administrators |
| 662 | // access to the user's account/edit section, the page title is incorrect. |
| 663 | $account = user_load(array('uid' => $account->uid)); |
| 664 | drupal_set_title(check_plain($account->name)); |
| 665 | |
| 666 | $form['cvs']['cvs_user'] = array( |
| 667 | '#type' => 'textfield', |
| 668 | '#title' => t('CVS username'), |
| 669 | '#default_value' => $cvs_user, |
| 670 | '#size' => 30, |
| 671 | '#maxlength' => 64, |
| 672 | '#description' => t('The CVS username associated with this account. This field is used to link CVS messages to user accounts.'), |
| 673 | ); |
| 674 | $form['cvs']['cvs_pass'] = array( |
| 675 | '#type' => 'password_confirm', |
| 676 | '#title' => t('CVS password'), |
| 677 | '#description' => t('To change the current CVS password, enter the new password in both fields.'), |
| 678 | ); |
| 679 | $form['cvs']['motivation'] = array( |
| 680 | '#type' => 'item', |
| 681 | '#title' => t('Motivation message'), |
| 682 | '#value' => check_markup($cvs_motivation), |
| 683 | ); |
| 684 | $form['cvs']['cvs_status'] = array( |
| 685 | '#type' => 'radios', |
| 686 | '#title' => t('CVS status'), |
| 687 | '#default_value' => $cvs_status, |
| 688 | '#options' => _cvs_get_status_options(), |
| 689 | '#description' => t("You can change the status of the user's CVS account."), |
| 690 | ); |
| 691 | $form['cvs']['send_mail'] = array( |
| 692 | '#type' => 'checkbox', |
| 693 | '#title' => t('Inform the user by e-mail.'), |
| 694 | '#default_value' => 1, |
| 695 | ); |
| 696 | $form['cvs']['message'] = array( |
| 697 | '#type' => 'textarea', |
| 698 | '#title' => t('Reason/Message'), |
| 699 | '#cols' => 50, |
| 700 | '#rows' => 5, |
| 701 | '#description' => t('The message you want to send to the user. This can be the reason for declining the application or an additional message after approval (used in e-mail).'), |
| 702 | ); |
| 703 | } |
| 704 | elseif (strlen($cvs_user) && $account->uid == $user->uid) { |
| 705 | if($cvs_status) { |
| 706 | $form['cvs']['cvs_user'] = array( |
| 707 | '#type' => 'item', |
| 708 | '#title' => t('CVS username'), |
| 709 | '#value' => $cvs_user, |
| 710 | '#description' => t('Your CVS username. This field can only be edited by administrators and is used to link your CVS messages to your user account.'), |
| 711 | ); |
| 712 | $form['cvs']['cvs_pass'] = array( |
| 713 | '#type' => 'password_confirm', |
| 714 | '#title' => t('CVS password'), |
| 715 | '#description' => t('To change your current CVS password, enter the new password in both fields.'), |
| 716 | ); |
| 717 | } |
| 718 | else { |
| 719 | $form['cvs']['cvs_user'] = array( |
| 720 | '#type' => 'item', |
| 721 | '#title' => t('CVS username'), |
| 722 | '#value' => $cvs_user, |
| 723 | '#description' => t('Your CVS username associated with this account. Your CVS application has not been approved yet, it has been declined, or your account got blocked.'), |
| 724 | ); |
| 725 | } |
| 726 | } |
| 727 | else { |
| 728 | $form['cvs']['cvs_user'] = array( |
| 729 | '#type' => 'item', |
| 730 | '#title' => t('CVS username'), |
| 731 | '#value' => $cvs_user, |
| 732 | '#description' => t('The CVS username associated with this account.'), |
| 733 | ); |
| 734 | } |
| 735 | $form['cvs']['cvs_uid'] = array('#type' => 'value', '#value' => $account->uid); |
| 736 | $form['submit'] = array('#type' => 'submit', '#value' => t('Save')); |
| 737 | |
| 738 | return $form; |
| 739 | } |
| 740 | |
| 741 | /** |
| 742 | * Validate CVS user edit form submission. |
| 743 | */ |
| 744 | function cvs_user_edit_form_validate($form, &$form_state) { |
| 745 | if (isset($form_state['values']['cvs_user'])) { |
| 746 | // Check for duplicates: |
| 747 | $id = db_result(db_query("SELECT uid FROM {cvs_accounts} WHERE cvs_user = '%s' AND uid != %d", $form_state['values']['cvs_user'], $form_state['values']['cvs_uid'])); |
| 748 | if ($id != 0) { |
| 749 | form_set_error('cvs_user', t('The specified CVS username is already in use by user #!id.', array('!id' => $id))); |
| 750 | } |
| 751 | } |
| 752 | if (!empty($form_state['values']['cvs_pass']) && strlen($form_state['values']['cvs_pass']) < CVS_MIN_PASS_LENGTH) { |
| 753 | form_set_error('cvs_pass', t('The CVS password you have chosen is too short (it must be at least !min characters long).', array('!min' => CVS_MIN_PASS_LENGTH))); |
| 754 | } |
| 755 | } |
| 756 | |
| 757 | /** |
| 758 | * Process CVS user edit form submission. |
| 759 | */ |
| 760 | function cvs_user_edit_form_submit($form, &$form_state) { |
| 761 | global $user; |
| 762 | |
| 763 | $result = db_fetch_object(db_query("SELECT cvs_user, status FROM {cvs_accounts} WHERE uid = %d", $form_state['values']['cvs_uid'])); |
| 764 | $cvs_user = $result->cvs_user; |
| 765 | $cvs_status = $result->status; |
| 766 | |
| 767 | if (user_access('administer CVS') && isset($form_state['values']['cvs_status'])) { |
| 768 | if ($form_state['values']['cvs_status'] == CVS_QUEUED && $cvs_status == CVS_QUEUED) { |
| 769 | // The QUEUED status should only indicate the initial status of an |
| 770 | // application. Once it has been replied to, it should be set to PENDING. |
| 771 | // In case the administrator forgets to do this, do it automatically. |
| 772 | $form_state['values']['cvs_status'] = CVS_PENDING; |
| 773 | } |
| 774 | if (isset($form_state['values']['cvs_pass']) && strlen($form_state['values']['cvs_pass'])) { |
| 775 | db_query("UPDATE {cvs_accounts} SET cvs_user = '%s', status = %d, pass = '%s' WHERE uid = %d", $form_state['values']['cvs_user'], $form_state['values']['cvs_status'], crypt($form_state['values']['cvs_pass']), $form_state['values']['cvs_uid']); |
| 776 | } |
| 777 | else { |
| 778 | db_query("UPDATE {cvs_accounts} SET cvs_user = '%s', status = %d WHERE uid = %d", $form_state['values']['cvs_user'], $form_state['values']['cvs_status'], $form_state['values']['cvs_uid']); |
| 779 | } |
| 780 | db_query("UPDATE {cvs_messages} SET cvs_user = '%s' WHERE uid = %d", $form_state['values']['cvs_user'], $form_state['values']['cvs_uid']); |
| 781 | if ($form_state['values']['send_mail']) { |
| 782 | cvs_mail_user($form_state['values']['cvs_uid'], $form_state['values']['message']); |
| 783 | } |
| 784 | drupal_set_message(t('The CVS account %account has been updated successfully.', array('%account' => $form_state['values']['cvs_user']))); |
| 785 | $form_state['redirect'] = 'admin/project/cvs-accounts'; |
| 786 | } |
| 787 | elseif (strlen($cvs_user) && $form_state['values']['cvs_uid'] == $user->uid && isset($form_state['values']['cvs_pass']) && strlen($form_state['values']['cvs_pass'])) { |
| 788 | if($cvs_status) { |
| 789 | db_query("UPDATE {cvs_accounts} SET pass = '%s' WHERE uid = %d", crypt($form_state['values']['cvs_pass']), $form_state['values']['cvs_uid']); |
| 790 | drupal_set_message(t('Your CVS password has been updated successfully.')); |
| 791 | } |
| 792 | } |
| 793 | } |
| 794 | |
| 795 | /** |
| 796 | * Alters the project_project node form to add CVS integration |
| 797 | * @see cvs_form_alter |
| 798 | * |
| 799 | * PROJECT TODO: this whole function needs to be reviewed |
| 800 | * after the 6.x project* port. |
| 801 | */ |
| 802 | function cvs_alter_project_project_form(&$form, &$form_state) { |
| 803 | $node = $form['#node']; |
| 804 | $repositories = _cvs_get_repository_options(t('<none>')); |
| 805 | $form['cvs'] = array( |
| 806 | '#type' => 'fieldset', |
| 807 | '#title' => t('CVS integration'), |
| 808 | '#collapsible' => TRUE, |
| 809 | '#tree' => TRUE, |
| 810 | '#weight' => 4, |
| 811 | ); |
| 812 | $default_repo = isset($node->cvs['repository']) ? $node->cvs['repository'] : variable_get('cvs_default_repo', 0); |
| 813 | if (count($repositories) > 1) { |
| 814 | $form['cvs']['repository'] = array( |
| 815 | '#type' => 'select', |
| 816 | '#title' => t('Repository'), |
| 817 | '#default_value' => $default_repo, |
| 818 | '#options' => user_access('administer projects') ? $repositories : array($default_repo => $repositories[$default_repo]), |
| 819 | '#description' => t("Specify the project's CVS repository."), |
| 820 | ); |
| 821 | } |
| 822 | $form['cvs']['directory'] = array( |
| 823 | '#type' => 'textfield', |
| 824 | '#title' => t('CVS directory'), |
| 825 | '#default_value' => isset($node->cvs['directory']) ? $node->cvs['directory'] : '', |
| 826 | '#size' => 40, |
| 827 | '#maxlength' => 255, |
| 828 | '#description' => t("Specify the project's directory within the selected CVS repository. Directory names should start with a leading slash and end with a trailing slash, and must be unique for each project. For example: <code>/modules/foo/</code>, <code>/themes/foo/</code> or <code>/translations/foo/</code>. If there is no CVS repository associated with the project, this setting should be left blank."), |
| 829 | ); |
| 830 | if ($default_repo == 0 || !empty($node->cvs['directory'])) { |
| 831 | // If the default for the repository selector is <none> (either |
| 832 | // because the project has already been saved with 0 for the |
| 833 | // repository, or because that's the site-wide default), or if we |
| 834 | // already have the value for the CVS directory, we should hide |
| 835 | // these gory details by default. |
| 836 | $form['cvs']['#collapsed'] = TRUE; |
| 837 | } |
| 838 | } |
| 839 | |
| 840 | /** |
| 841 | * Alters the project_release node to add build tag UI |
| 842 | * @see cvs_form_alter |
| 843 | * |
| 844 | * PROJECT TODO: this whole function needs to be reviewed |
| 845 | * after the 6.x project* port. |
| 846 | */ |
| 847 | function cvs_alter_project_release_form(&$form, &$form_state) { |
| 848 | // If we're not adding it, call a separate method that just worries |
| 849 | // about how to alter the edit form, since the add form is so complex. |
| 850 | if (arg(1) != 'add') { |
| 851 | return cvs_alter_project_release_form_edit($form, $form_state); |
| 852 | } |
| 853 | |
| 854 | $project = $form['project']['#value']; |
| 855 | |
| 856 | // Check to see if this project has a repository set. If not, then don't |
| 857 | // alter the form so that the project can have releases just as if the |
| 858 | // cvs.module were not enabled at all. |
| 859 | if (!project_use_cvs($project)) { |
| 860 | return; |
| 861 | } |
| 862 | |
| 863 | if (!isset($project->project_release['releases'])) { |
| 864 | // This project has no releases, nothing to alter |
| 865 | return; |
| 866 | } |
| 867 | |
| 868 | $fields = array('version_major', 'version_minor', 'version_patch'); |
| 869 | |
| 870 | if (isset($form_state['cvs_tag'])) { |
| 871 | $tag_name = $form_state['cvs_tag']; |
| 872 | } |
| 873 | elseif (isset($form_state['values']['project_release']['tag'])) { |
| 874 | $tag_name = $form_state['values']['project_release']['tag']; |
| 875 | } |
| 876 | |
| 877 | if (!empty($tag_name)) { |
| 878 | $vid = _project_release_get_api_vid(); |
| 879 | if ($tag_name == 'HEAD') { |
| 880 | // Special case validation for the HEAD... |
| 881 | $tag = new stdClass(); |
| 882 | $tag->tag = 'HEAD'; |
| 883 | $tag->branch = 1; |
| 884 | $tag->nid = $project->nid; |
| 885 | |
| 886 | foreach ($fields as $field) { |
| 887 | if (isset($form_state['storage']['project_release'][$field])) { |
| 888 | $form_val = $form_state['storage']['project_release'][$field]; |
| 889 | if ($form_val !== '' && (is_numeric($form_val) || $form_val == 'x')) { |
| 890 | $version->$field = $form_val; |
| 891 | } |
| 892 | } |
| 893 | } |
| 894 | if (isset($form_state['storage']['project_release']['version_extra']) |
| 895 | && $form_state['storage']['project_release']['version_extra'] !== '') { |
| 896 | $version->version_extra = $form_state['storage']['project_release']['version_extra']; |
| 897 | } |
| 898 | if (isset($form['taxonomy'][$vid])) { |
| 899 | if (isset($form_state['storage']['project_release']['version_api_tid'])) { |
| 900 | $version_api_tid = $form_state['storage']['project_release']['version_api_tid']; |
| 901 | if (is_numeric($version_api_tid) && !empty($version_api_tid) && db_result(db_query('SELECT COUNT(*) FROM {term_data} WHERE tid = %d AND vid = %d', $version_api_tid, $vid))) { |
| 902 | $version->version_api_tid = $version_api_tid; |
| 903 | $indexes = form_get_options($form['taxonomy'][$vid], $version_api_tid); |
| 904 | $options = array(); |
| 905 | if ($indexes !== FALSE) { |
| 906 | foreach ($indexes as $index) { |
| 907 | $options[] = $form['taxonomy'][$vid]['#options'][$index]; |
| 908 | } |
| 909 | $form['taxonomy'][$vid]['#options'] = $options; |
| 910 | $form['taxonomy'][$vid]['#default_value'] = $version_api_tid; |
| 911 | } |
| 912 | } |
| 913 | } |
| 914 | } |
| 915 | |
| 916 | if (function_exists('cvs_local_version_is_valid')) { |
| 917 | $vers_is_valid = cvs_local_version_is_valid($version, $tag, $project); |
| 918 | } |
| 919 | else { |
| 920 | $vers_is_valid = isset($version); |
| 921 | } |
| 922 | if ($vers_is_valid) { |
| 923 | $version_str = project_release_get_version($version, $project); |
| 924 | } |
| 925 | else { |
| 926 | unset($version); |
| 927 | _cvs_alter_project_release_form_unset_all($form, array('taxonomy', 'project_release')); |
| 928 | $elements = element_children($form['taxonomy']); |
| 929 | $found_it = FALSE; |
| 930 | foreach ($elements as $element) { |
| 931 | if ($element != $vid) { |
| 932 | unset($form['taxonomy'][$element]); |
| 933 | } |
| 934 | else { |
| 935 | $found_it = TRUE; |
| 936 | } |
| 937 | } |
| 938 | if (!$found_it) { |
| 939 | // If we're not leaving the API selection element, unset the |
| 940 | // whole thing so we don't leave an empty fieldset. |
| 941 | unset($form['taxonomy']); |
| 942 | } |
| 943 | } |
| 944 | } |
| 945 | else { |
| 946 | $query = db_query("SELECT * FROM {cvs_tags} WHERE nid = %d AND tag = '%s'", $project->nid, $tag_name); |
| 947 | $tag = db_fetch_object($query); |
| 948 | if (!$tag) { |
| 949 | form_set_error('tag', t('The tag you selected does not exist for this project.')); |
| 950 | } |
| 951 | $query = db_query("SELECT nid FROM {project_release_nodes} WHERE pid = %d AND tag = '%s'", $project->nid, $tag_name); |
| 952 | if (db_result($query)) { |
| 953 | form_set_error('tag', t('The tag or branch you have selected is already in use by another release')); |
| 954 | } |
| 955 | $version = cvs_get_version_from_tag($tag, $project); |
| 956 | $version_str = project_release_get_version($version, $project); |
| 957 | } |
| 958 | unset($form['tag']); |
| 959 | $tags[$tag_name] = $tag_name; |
| 960 | $form['cvs_tag'] = array('#weight' => -4); |
| 961 | $form['cvs_tag']['project_release'] = array('#tree' => TRUE); |
| 962 | $form['cvs_tag']['project_release']['tag'] = array( |
| 963 | '#type' => 'select', |
| 964 | '#title' => $tag->branch ? t('CVS branch') : t('CVS tag'), |
| 965 | '#options' => $tags, |
| 966 | '#default_value' => $tag->tag, |
| 967 | '#required' => TRUE, |
| 968 | ); |
| 969 | $form['project_release']['rebuild'] = array( |
| 970 | '#type' => 'value', |
| 971 | '#value' => $tag->branch, |
| 972 | ); |
| 973 | |
| 974 | if (isset($version_str)) { |
| 975 | // Since this is the final page, turn this into a fieldset with |
| 976 | // all the nice float/clear goodness |
| 977 | $form['cvs_tag']['#type'] = 'fieldset'; |
| 978 | $form['cvs_tag']['#collapsible'] = TRUE; |
| 979 | $form['cvs_tag']['#title'] = t('Release identification'); |
| 980 | $form['cvs_tag']['#prefix'] = '<div class="version-elements">'; |
| 981 | $form['cvs_tag']['#suffix'] = '</div>'; |
| 982 | $form['cvs_tag']['#description'] = t('Now that the CVS tag has been selected, these can not be modified.'); |
| 983 | |
| 984 | // Display the version string so the user knows we've got it right. |
| 985 | $form['cvs_tag']['version'] = array( |
| 986 | '#type' => 'textfield', |
| 987 | '#title' => 'Version string', |
| 988 | '#default_value' => $version_str, |
| 989 | '#attributes' => array('readonly' => TRUE, 'style' => 'width:auto'), |
| 990 | '#required' => TRUE, |
| 991 | '#size' => 30, |
| 992 | '#maxlength' => 40, |
| 993 | ); |
| 994 | // Stash this in a form value so it'll make it through to validation |
| 995 | // where the title of the release node is set. |
| 996 | $form['cvs_tag']['project_release']['version'] = array( |
| 997 | '#type' => 'value', |
| 998 | '#value' => $version_str, |
| 999 | ); |
| 1000 | // Also stash it in form_state['storage'] so we preserve it through |
| 1001 | // multi-page, preview, and submit. |
| 1002 | $form_state['storage']['project_release']['version'] = $version_str; |
| 1003 | } |
| 1004 | if (isset($version)) { |
| 1005 | foreach (array_merge($fields, array('version_extra')) as $field) { |
| 1006 | if (isset($version->$field)) { |
| 1007 | $form_state['storage']['project_release'][$field] = $version->$field; |
| 1008 | } |
| 1009 | $form['project_release'][$field]['#access'] = FALSE; |
| 1010 | } |
| 1011 | // If we already know the version info, which includes the |
| 1012 | // compatibility taxonomy, so rip out all other taxonomy options. |
| 1013 | if (isset($form['taxonomy'][$vid])) { |
| 1014 | $tid = $version->version_api_tid; |
| 1015 | $indexes = form_get_options($form['taxonomy'][$vid], $tid); |
| 1016 | if ($indexes !== FALSE) { |
| 1017 | $options = array(); |
| 1018 | foreach ($indexes as $index) { |
| 1019 | $options[] = $form['taxonomy'][$vid]['#options'][$index]; |
| 1020 | } |
| 1021 | $form['taxonomy'][$vid]['#options'] = $options; |
| 1022 | $form['taxonomy'][$vid]['#default_value'] = $tid; |
| 1023 | } |
| 1024 | } |
| 1025 | $form['project_release']['#access'] = FALSE; |
| 1026 | $form['rel_id']['#access'] = FALSE; |
| 1027 | // $form['#pre_render'][] = 'cvs_project_release_form_pre_render'; |
| 1028 | // Add a submit handler to copy the version values from |
| 1029 |