├── fserver.context.inc ├── fserver.css ├── fserver.drush.inc ├── fserver.features.content.inc ├── fserver.features.inc ├── fserver.features.menu_links.inc ├── fserver.info ├── fserver.install ├── fserver.js ├── fserver.module ├── fserver.strongarm.inc ├── fserver.views.inc ├── fserver.views_default.inc ├── tests └── fserver.test └── views ├── fserver-updatexml.tpl.php ├── fserver_handler_field_mdhash.inc ├── fserver_handler_field_release_tag.inc ├── fserver_handler_sort_release_tag.inc ├── fserver_plugin_style_updatexml.inc └── theme.inc /fserver.context.inc: -------------------------------------------------------------------------------- 1 | disabled = FALSE; /* Edit this to true to make a default context disabled initially */ 10 | $context->api_version = 3; 11 | $context->name = 'fserver-section-project'; 12 | $context->description = ''; 13 | $context->tag = ''; 14 | $context->conditions = array( 15 | 'node' => array( 16 | 'values' => array( 17 | 'fserver_project' => 'fserver_project', 18 | 'fserver_distro' => 'fserver_distro', 19 | ), 20 | 'options' => array( 21 | 'node_form' => 0, 22 | ), 23 | ), 24 | ); 25 | $context->reactions = array( 26 | 'block' => array( 27 | 'blocks' => array( 28 | 'views-fserver_releases-block_1' => array( 29 | 'module' => 'views', 30 | 'delta' => 'fserver_releases-block_1', 31 | 'region' => 'content', 32 | 'weight' => 0, 33 | ), 34 | ), 35 | ), 36 | ); 37 | $context->condition_mode = 0; 38 | 39 | $export['fserver-section-project'] = $context; 40 | return $export; 41 | } 42 | -------------------------------------------------------------------------------- /fserver.css: -------------------------------------------------------------------------------- 1 | div#edit-field-fserver-api-value-wrapper, 2 | div#edit-field-fserver-versionmajor-value-wrapper, 3 | div#edit-field-fserver-versionpatch-value-wrapper, 4 | div#edit-field-fserver-versionextra-0-value-wrapper { 5 | div#edit-field-fserver-versionextratype-value-wrapper { 6 | div#edit-field-fserver-versionextranum-value-wrapper { 7 | float: left; 8 | margin-right: 1em; 9 | } 10 | div#edit-field-fserver-recommended-value-wrapper { 11 | clear: both; 12 | } 13 | ul#fserver-release-info, 14 | ul#fserver-release-info li { 15 | list-style: none; 16 | background: 0; 17 | margin: 0; 18 | padding: 0; 19 | } -------------------------------------------------------------------------------- /fserver.drush.inc: -------------------------------------------------------------------------------- 1 | 'Determine the packaging status of a project.', 26 | ); 27 | $items['fserver-package'] = array( 28 | 'description' => 'Update packaging for a project.', 29 | ); 30 | $items['fserver-distro'] = array( 31 | 'description' => 'Update packaging for a distribution.', 32 | ); 33 | return $items; 34 | } 35 | 36 | /** 37 | * Implementation of hook_drush_help(). 38 | */ 39 | function fserver_drush_help($section) { 40 | switch ($section) { 41 | case 'drush:fserver-status': 42 | return dt("Determine the packaging status of a project."); 43 | case 'drush:fserver-package': 44 | return dt("Update packaging for a project."); 45 | case 'drush:fserver-distro': 46 | return dt("Package a new Drupal distribution from a distribution node."); 47 | } 48 | } 49 | 50 | /** 51 | * Package new releases for a specified project or all. 52 | */ 53 | function drush_fserver_package() { 54 | if (!drush_get_option('uri') && !drush_get_option('l')) { 55 | drush_die('You must use the --uri option to specify the location of this site.'); 56 | } 57 | 58 | $projects = _fserver_drush_get_projects(); 59 | 60 | // Filter the project list by the argument. 61 | $args = func_get_args(); 62 | $arg = array_shift($args); 63 | if (!empty($arg)) { 64 | if (isset($projects[$arg])) { 65 | $projects = array($arg => $projects[$arg]); 66 | } 67 | else { 68 | drush_die('The project '. $arg .' could not be found.'); 69 | } 70 | } 71 | 72 | $rows = array(); 73 | foreach ($projects as $project) { 74 | $new_tags = $project->get_new_tags(); 75 | if (!empty($new_tags)) { 76 | foreach ($new_tags as $tag_id => $tag) { 77 | $release = $project->create_release($tag_id); 78 | $rows[] = array($project->node->title, $tag_id, $release->field_fserver_file[0]['filename']); 79 | } 80 | } 81 | } 82 | if (!empty($rows)) { 83 | array_unshift($rows, array(dt('Project'), dt('Release'), dt('Filename'))); 84 | drush_print_table($rows, TRUE); 85 | } 86 | else { 87 | drush_print(dt('All projects are up to date. No packages were created.')); 88 | } 89 | } 90 | 91 | /** 92 | * Display project packaging status. 93 | */ 94 | function drush_fserver_status() { 95 | $projects = _fserver_drush_get_projects(); 96 | 97 | // Filter the project list by the argument. 98 | $args = func_get_args(); 99 | $arg = array_shift($args); 100 | if (!empty($arg)) { 101 | if (isset($projects[$arg])) { 102 | $projects = array($arg => $projects[$arg]); 103 | } 104 | else { 105 | drush_die('The project '. $arg .' could not be found.'); 106 | } 107 | } 108 | 109 | $rows = array(array(dt('Method'), dt('Project'), dt('New tags'))); 110 | foreach ($projects as $project) { 111 | $new_tags = $project->get_new_tags(); 112 | $rows[] = array( 113 | $project->method, 114 | $project->node->title, 115 | !empty($new_tags) ? implode(', ',array_keys($new_tags)) : dt("Up to date"), 116 | ); 117 | } 118 | drush_print_table($rows, TRUE); 119 | } 120 | 121 | /** 122 | * Retrieve all fserver projects from the DB. 123 | */ 124 | function _fserver_drush_get_projects() { 125 | static $projects; 126 | if (!isset($projects)) { 127 | $projects = array(); 128 | $result = db_query("SELECT nid, title FROM {node} WHERE type = 'fserver_project' AND status = 1"); 129 | while ($row = db_fetch_object($result)) { 130 | $node = node_load($row->nid); 131 | $project = new FserverProject($node, $node->field_fserver_name[0]['value'], $node->field_fserver_method[0]['value'], $node->field_fserver_repository[0]['value']); 132 | $projects[$project->name] = $project; 133 | } 134 | } 135 | return $projects; 136 | } 137 | 138 | /** 139 | * Project class. Contains helpful methods for detecting tags, packaging, etc. 140 | */ 141 | class FserverProject { 142 | var $node, $name, $method, $repository; 143 | 144 | /** 145 | * We will store the backend object here. 146 | */ 147 | var $backend; 148 | 149 | /** 150 | * Constructor. 151 | */ 152 | function __construct($node, $name, $method, $repository) { 153 | $this->node = $node; 154 | $this->name = $name; 155 | $this->method = $method; 156 | $this->repository = $repository; 157 | 158 | // We try to create a backend for us to user later: 159 | $method_class = 'FserverProject_' . $this->method; 160 | if (class_exists($method_class)) { 161 | $this->backend = new $method_class($this); 162 | } 163 | } 164 | 165 | /** 166 | * Initialize a working copy for this project. 167 | */ 168 | function init_wc() { 169 | if (isset($this->backend)) { 170 | $this->backend->init_wc(); 171 | } 172 | } 173 | 174 | /** 175 | * Get new tags that have no corresponding release nodes. 176 | */ 177 | function get_new_tags() { 178 | $new_tags = array(); 179 | $releases = $this->get_releases(); 180 | foreach ($this->get_tags() as $tag_id => $tag) { 181 | if (!isset($releases[$tag_id])) { 182 | $new_tags[$tag_id] = $tag; 183 | } 184 | } 185 | return $new_tags; 186 | } 187 | 188 | /** 189 | * Get release nodes for this project. 190 | */ 191 | function get_releases() { 192 | if (!isset($this->releases)) { 193 | $this->releases = array(); 194 | $result = db_query("SELECT nid FROM {node} WHERE type = 'fserver_release' AND status = 1"); 195 | while ($row = db_fetch_object($result)) { 196 | $node = node_load($row->nid); 197 | if ($node && isset($node->field_fserver_project[0]['nid']) && $node->field_fserver_project[0]['nid'] == $this->node->nid) { 198 | $this->releases[fserver_generate_version($node, TRUE)] = $node; 199 | } 200 | } 201 | } 202 | return $this->releases; 203 | } 204 | 205 | function get_tag($tag_id) { 206 | if (isset($this->backend)) { 207 | return $this->backend->get_tag($tag_id); 208 | } 209 | } 210 | 211 | /** 212 | * Get tags for this project. 213 | */ 214 | function get_tags() { 215 | if (isset($this->backend)) { 216 | return $this->backend->get_tags(); 217 | } 218 | return array(); 219 | } 220 | 221 | /** 222 | * Create a release node for the given tag. 223 | */ 224 | function create_release($tag_id) { 225 | $tag = $this->get_tag($tag_id); 226 | if ($tag && $file = $this->create_package($tag_id)) { 227 | $node = new stdClass(); 228 | $node->type = 'fserver_release'; 229 | $node->status = 1; 230 | $node->created = !empty($tag['timestamp']) ? $tag['timestamp'] : time(); 231 | $node->uid = $this->node->uid; 232 | $node->title = "{$this->name} {$tag_id}"; 233 | $node->body = !empty($tag['message']) ? $tag['message'] : ''; 234 | 235 | $node->field_fserver_file = array(0 => (array) $file); 236 | $node->field_fserver_project = array(0 => array('nid' => $this->node->nid)); 237 | $node->field_fserver_api = array(0 => array('value' => $tag['core'])); 238 | $node->field_fserver_versionmajor = array(0 => array('value' => $tag['major'])); 239 | $node->field_fserver_versionpatch = array(0 => array('value' => $tag['patch'])); 240 | $node->field_fserver_versionextra = array(0 => array('value' => $tag['extra'])); 241 | 242 | // Handle the release extra info 243 | $extratype = FSERVER_EXTRATYPE_RELEASE; 244 | $extranum = NULL; 245 | if (!empty($tag['extra'])) { 246 | $extratypes = fserver_cck_options('extratype'); 247 | $extratypes = array_flip($extratypes); 248 | $extratype = array_key_exists($tag['extratype'], $extratypes) ? $extratypes[$tag['extratype']] : FSERVER_EXTRATYPE_OTHER; 249 | $extranum = $tag['extranum']; 250 | } 251 | $node->field_fserver_versionextratype = array(0 => array('value' => $extratype)); 252 | $node->field_fserver_versionextranum = array(0 => array('value' => $extranum)); 253 | 254 | // @TODO 255 | $node->field_fserver_recommended = array(0 => array('value' => 1)); 256 | $node->field_fserver_security = array(0 => array('value' => 0)); 257 | node_save($node); 258 | } 259 | return $node; 260 | } 261 | 262 | /** 263 | * Create an archive package for the given tag. 264 | */ 265 | function create_package($tag_id) { 266 | if (isset($this->backend)) { 267 | return $this->backend->create_package($tag_id); 268 | } 269 | return FALSE; 270 | } 271 | 272 | /** 273 | * Write packaging information for a release. 274 | */ 275 | function write_package_info($tag, $exclude_mask = array('.', '..', 'CVS')) { 276 | if (isset($this->backend)) { 277 | $fserver_url = url("fserver", array('purl' => array('disabled' => TRUE), 'absolute' => TRUE)); 278 | 279 | $packaging = array(); 280 | $packaging[] = "; Information added by fserver"; 281 | $packaging[] = "core = \"{$tag['core']}\""; 282 | $packaging[] = "datestamp = \"{$tag['timestamp']}\""; 283 | $packaging[] = "project = \"{$this->name}\""; 284 | $packaging[] = "project status url = \"{$fserver_url}\""; 285 | $packaging[] = "version = \"{$tag['version']}\""; 286 | $packaging = "\n" . implode("\n", $packaging); 287 | 288 | $files = file_scan_directory($this->backend->path, '.info$', $exclude_mask); 289 | foreach ($files as $path => $file) { 290 | // @TODO: Parse the info file or not? 291 | $info_file = file_get_contents($file->filename); 292 | $info_file .= $packaging; 293 | file_put_contents($file->filename, $info_file); 294 | } 295 | } 296 | } 297 | } 298 | 299 | class FserverProject_git { 300 | 301 | /** 302 | * We store the parent FserverProject object here. 303 | */ 304 | var $FserverProject; 305 | 306 | /** 307 | * Constructor. 308 | */ 309 | function __construct(&$FserverProject) { 310 | $this->FserverProject = $FserverProject; 311 | } 312 | 313 | /** 314 | * Destructor. 315 | */ 316 | function __destruct() { 317 | if (isset($this->path)) { 318 | drush_op('drush_shell_exec', "rm -rf {$this->path}"); 319 | } 320 | } 321 | 322 | /** 323 | * Initialize a working copy for this project. 324 | */ 325 | function init_wc() { 326 | if (!isset($this->path)) { 327 | $this->path = file_directory_temp() . '/fserver_git_'. $this->FserverProject->name .'_'. time(); 328 | drush_op('drush_shell_exec', "git clone {$this->FserverProject->repository} {$this->path}"); 329 | } 330 | } 331 | 332 | /** 333 | * Get tags for this project. 334 | */ 335 | function get_tags() { 336 | if (!isset($this->tags)) { 337 | $this->tags = array(); 338 | _drush_shell_exec_output_set(' '); // Clear output cache. 339 | drush_op('drush_shell_exec', "git ls-remote --tags {$this->FserverProject->repository} | awk '{print $2;}'"); 340 | $lines = drush_shell_exec_output(); 341 | while ($line = array_shift($lines)) { 342 | $vc = array_pop(explode('/', $line)); 343 | $parsed = fserver_parse_tag_name($vc); 344 | if (!empty($parsed)) { 345 | $this->tags[$parsed['version']] = $vc; 346 | } 347 | } 348 | } 349 | return $this->tags; 350 | } 351 | 352 | function get_tag($tag_id) { 353 | $tags = $this->get_tags(); 354 | if (isset($tags[$tag_id])) { 355 | $vc = $tags[$tag_id]; 356 | $tag = fserver_parse_tag_name($vc); 357 | $this->init_wc(); 358 | 359 | // Retrieve tag info 360 | _drush_shell_exec_output_set(' '); // Clear output cache. 361 | drush_op('drush_shell_exec', "git --git-dir={$this->path}/.git log -1 --pretty=format:%ct {$vc}"); 362 | $info = drush_shell_exec_output(); 363 | $tag['timestamp'] = $info[0]; 364 | drush_op('drush_shell_exec', "git --git-dir={$this->path}/.git tag -l {$vc} -n 1000"); 365 | $info = drush_shell_exec_output(); 366 | // Remove the tag from the first line of the message: 367 | $info[0] = str_replace($vc, '', $info[0]); 368 | $tag['message'] = implode("\n", $info); 369 | return $tag; 370 | } 371 | } 372 | 373 | /** 374 | * Create an archive package for the given tag. 375 | */ 376 | function create_package($tag_id) { 377 | $this->init_wc(); 378 | $tag = $this->get_tag($tag_id); 379 | if ($tag) { 380 | $base = "{$this->FserverProject->name}-{$tag_id}"; 381 | $file_path = file_directory_path() .'/fserver'; 382 | // Create the directory if it doesn't exist. 383 | if (file_check_directory($file_path, TRUE)) { 384 | $vc = $tag['original']; 385 | drush_op('drush_shell_exec', "git --git-dir={$this->path}/.git checkout {$vc}"); 386 | $this->FserverProject->write_package_info($tag, array('.git')); 387 | drush_op('drush_shell_exec', "tar -Pcf - --exclude='.git' --transform='s,{$this->path},{$this->FserverProject->name},' {$this->path} | gzip > {$file_path}/{$base}.tgz"); 388 | 389 | // @TODO 390 | // We need to properly chown and permission these directories. 391 | // Is it possible for drush to know the web server user? 392 | drush_op('chmod', $file_path, 0775); 393 | drush_op('chgrp', $file_path, fserver_posix_groupname()); 394 | drush_op('chmod', "{$file_path}/{$base}.tgz", 0775); 395 | drush_op('chgrp', "{$file_path}/{$base}.tgz", fserver_posix_groupname()); 396 | 397 | $file = new stdClass(); 398 | $file->uid = $this->node->uid; 399 | $file->filename = "{$base}.tgz"; 400 | $file->filepath = "{$file_path}/{$base}.tgz"; 401 | $file->filemime = file_get_mimetype($file->filename); 402 | $file->filesize = filesize($file->filepath); 403 | $file->status = FILE_STATUS_PERMANENT; 404 | $file->timestamp = time(); 405 | drupal_write_record('files', $file); 406 | 407 | return $file; 408 | } 409 | } 410 | return FALSE; 411 | } 412 | 413 | } 414 | 415 | class FserverProject_svn { 416 | /** 417 | * We store the parent FserverProject object here. 418 | */ 419 | var $FserverProject; 420 | 421 | /** 422 | * Constructor. 423 | */ 424 | function __construct(&$FserverProject) { 425 | $this->FserverProject = $FserverProject; 426 | } 427 | 428 | /** 429 | * Destructor. 430 | */ 431 | function __destruct() { 432 | if (isset($this->path)) { 433 | drush_op('drush_shell_exec', "rm -rf {$this->path}"); 434 | } 435 | } 436 | 437 | /** 438 | * Initialize a working copy for this project. 439 | */ 440 | function init_wc() { 441 | if (!isset($this->path)) { 442 | $this->path = file_directory_temp() . '/fserver_svn_'. $this->FserverProject->name .'_'. time(); 443 | //drush_op('drush_shell_exec', "git clone {$this->FserverProject->repository} {$this->path}"); 444 | } 445 | } 446 | 447 | /** 448 | * Get tags for this project. 449 | */ 450 | function get_tags() { 451 | if (!isset($this->tags)) { 452 | $this->tags = array(); 453 | _drush_shell_exec_output_set(' '); // Clear output cache. 454 | drush_op('drush_shell_exec', "svn ls {$this->FserverProject->repository}/tags | awk '{print $1;}'"); 455 | $lines = drush_shell_exec_output(); 456 | while ($line = array_shift($lines)) { 457 | $vc = array_shift(explode('/', $line)); 458 | $parsed = fserver_parse_tag_name($vc); 459 | if (!empty($parsed)) { 460 | $this->tags[$parsed['version']] = $vc; 461 | } 462 | } 463 | } 464 | return $this->tags; 465 | } 466 | 467 | function get_tag($tag_id) { 468 | $tags = $this->get_tags(); 469 | if (isset($tags[$tag_id])) { 470 | $vc = $tags[$tag_id]; 471 | $tag = fserver_parse_tag_name($vc); 472 | $this->init_wc(); 473 | 474 | // Retrieve tag info 475 | _drush_shell_exec_output_set(' '); // Clear output cache. 476 | drush_op('drush_shell_exec', "svn info --non-interactive --xml {$this->FserverProject->repository}/tags/{$vc}"); 477 | $info = drush_shell_exec_output(); 478 | if (!empty($info)) { 479 | $info = implode("\n", $info); 480 | // $info is now an xml string: 481 | $info_xml = simplexml_load_string($info); 482 | foreach ($info_xml->xpath('//commit/date') as $date_element) { 483 | $date = strtotime((string)$date_element); 484 | } 485 | } 486 | 487 | 488 | $tag['timestamp'] = is_numeric($date) ? $date : time(); 489 | return $tag; 490 | } 491 | } 492 | 493 | /** 494 | * Create an archive package for the given tag. 495 | */ 496 | function create_package($tag_id) { 497 | $this->init_wc(); 498 | $tag = $this->get_tag($tag_id); 499 | if ($tag) { 500 | $base = "{$this->FserverProject->name}-{$tag_id}"; 501 | $file_path = file_directory_path() .'/fserver'; 502 | // Create the directory if it doesn't exist. 503 | if (file_check_directory($file_path, TRUE)) { 504 | $vc = $tag['original']; 505 | if (is_dir($this->path)) { 506 | // I'd quite like to do a switch here, but couldn't get it to work reliably. 507 | drush_op('drush_shell_exec', "rm -rf {$this->path}"); 508 | } 509 | drush_op('drush_shell_exec', "svn checkout --non-interactive {$this->FserverProject->repository}/tags/{$vc} {$this->path}"); 510 | $this->FserverProject->write_package_info($tag, array('.svn')); 511 | drush_op('drush_shell_exec', "tar -Pcf - --exclude='.svn' --transform='s,{$this->path},{$this->FserverProject->name},' {$this->path} | gzip > {$file_path}/{$base}.tgz"); 512 | 513 | // @TODO 514 | // We need to properly chown and permission these directories. 515 | // Is it possible for drush to know the web server user? 516 | drush_op('chmod', $file_path, 0775); 517 | drush_op('chgrp', $file_path, fserver_posix_groupname()); 518 | drush_op('chmod', "{$file_path}/{$base}.tgz", 0775); 519 | drush_op('chgrp', "{$file_path}/{$base}.tgz", fserver_posix_groupname()); 520 | 521 | $file = new stdClass(); 522 | $file->uid = $this->node->uid; 523 | $file->filename = "{$base}.tgz"; 524 | $file->filepath = "{$file_path}/{$base}.tgz"; 525 | $file->filemime = file_get_mimetype($file->filename); 526 | $file->filesize = filesize($file->filepath); 527 | $file->status = FILE_STATUS_PERMANENT; 528 | $file->timestamp = time(); 529 | drupal_write_record('files', $file); 530 | 531 | return $file; 532 | } 533 | } 534 | return FALSE; 535 | } 536 | } 537 | 538 | /** 539 | * Discover the web server group. Taken from provision. 540 | */ 541 | function fserver_posix_groupname() { 542 | $info = posix_getgrgid(posix_getgid()); 543 | $common_groups = array( 544 | 'httpd', 545 | 'www-data', 546 | 'apache', 547 | 'nogroup', 548 | 'nobody', 549 | $info['name']); 550 | foreach ($common_groups as $group) { 551 | $groupname = ''; 552 | if (is_numeric($group)) { 553 | $info = posix_getgrgid($group); 554 | $groupname = $info['name']; 555 | } 556 | else { 557 | $info = posix_getgrnam($group); 558 | $groupname = $info['name']; 559 | } 560 | if ($groupname) { 561 | return $groupname; 562 | break; 563 | } 564 | } 565 | return NULL; 566 | } 567 | 568 | function drush_fserver_distro() { 569 | if (!drush_get_option('version')) { 570 | drush_die('No version supplied, please use --version to specify a version for your release.'); 571 | } 572 | $distros = _fserver_drush_get_distros(); 573 | 574 | // Filter the project list by the argument. 575 | $args = func_get_args(); 576 | $arg = array_shift($args); 577 | $version = drush_get_option('version'); 578 | if (!empty($arg)) { 579 | if (isset($distros[$arg])) { 580 | $distros = array($arg => $distros[$arg]); 581 | } 582 | else { 583 | drush_die('The distribution '. $arg .' could not be found.'); 584 | } 585 | } 586 | 587 | $rows = array(); 588 | foreach ($distros as $distro) { 589 | $release = $distro->create_release($version); 590 | $rows[] = array($distro->node->title, $release->field_fserver_file[0]['filename']); 591 | } 592 | if (!empty($rows)) { 593 | array_unshift($rows, array(dt('Project'), dt('Filename'))); 594 | drush_print_table($rows, TRUE); 595 | } 596 | else { 597 | drush_print(dt('No distributions to update.')); 598 | } 599 | } 600 | 601 | function _fserver_drush_get_distros() { 602 | static $distros; 603 | if (!isset($distros)) { 604 | $projects = array(); 605 | $result = db_query("SELECT nid, title FROM {node} WHERE type = 'fserver_distro' AND status = 1"); 606 | while ($row = db_fetch_object($result)) { 607 | $node = node_load($row->nid); 608 | $distro = new FserverDistro($node, $node->field_fserver_name[0]['value']); 609 | $distros[$distro->name] = $distro; 610 | } 611 | } 612 | return $distros; 613 | } 614 | 615 | /** 616 | * Project class. Contains helpful methods for detecting tags, packaging, etc. 617 | */ 618 | class FserverDistro { 619 | var $node, $name; 620 | 621 | /** 622 | * Constructor. 623 | */ 624 | function __construct($node, $name, $version = NULL) { 625 | $this->node = $node; 626 | $this->name = $name; 627 | //$this->version = $version; 628 | } 629 | 630 | /** 631 | * Destructor. 632 | */ 633 | function __destruct() { 634 | if (isset($this->path)) { 635 | drush_op('drush_shell_exec', "rm -rf {$this->path}"); 636 | } 637 | } 638 | 639 | /** 640 | * Initialize a working copy for this project. 641 | */ 642 | function init_wc() { 643 | if (!isset($this->raw_version)) { 644 | drush_die('Version was not parsed properly. Please supply versions in the drupal-6--1-0-alpha1 format.'); 645 | } 646 | if (!isset($this->path)) { 647 | $this->path = file_directory_temp() . '/fserver_'. $this->name .'_'. time(); 648 | if (file_check_directory($this->path, TRUE)) { 649 | if(!file_save_data($this->node->field_fserver_drushmake[0]['value'], $this->path .'/'. $this->name .'-'. $this->raw_version .'.make', FILE_EXISTS_REPLACE)) { 650 | return FALSE; 651 | } 652 | // @TODO 653 | // We need to properly chown and permission these directories. 654 | // Is it possible for drush to know the web server user? 655 | drush_op('chmod', $this->path, 0775); 656 | drush_op('chgrp', $this->path, fserver_posix_groupname()); 657 | drush_op('chmod', "{$this->path}/{$this->name}-{$this->raw_version}.make", 0775); 658 | drush_op('chgrp', "{$this->path}/{$this->name}-{$this->raw_version}.make", fserver_posix_groupname()); 659 | } 660 | } 661 | return TRUE; 662 | } 663 | 664 | /** 665 | * Get release nodes for this project. 666 | */ 667 | function get_releases() { 668 | if (!isset($this->releases)) { 669 | $this->releases = array(); 670 | $result = db_query("SELECT nid FROM {node} WHERE type = 'fserver_release' AND status = 1"); 671 | while ($row = db_fetch_object($result)) { 672 | $node = node_load($row->nid); 673 | if ($node && isset($node->field_fserver_project[0]['nid']) && $node->field_fserver_project[0]['nid'] == $this->node->nid) { 674 | $this->releases[fserver_generate_version($node, TRUE)] = $node; 675 | } 676 | } 677 | } 678 | return $this->releases; 679 | } 680 | 681 | function parse_version($version) { 682 | if (isset($version)) { 683 | $this->version = array(); 684 | $parsed = fserver_parse_tag_name($version); 685 | if (!empty($parsed)) { 686 | $extra = $parsed['extra'] ? $parsed['extra'] : 0; 687 | $view = views_get_view('fserver_release_lookup'); 688 | $view->set_display('default'); 689 | $args = array(); 690 | $args[] = $this->node->nid; 691 | $args[] = $parsed['core']; 692 | $args[] = $extra; 693 | $view->set_arguments($args); 694 | $preview = $view->preview($form_state['display_id'], $args); 695 | $query = db_prefix_tables($view->build_info['query']); 696 | _db_query_callback($view->build_info['query_args'], TRUE); 697 | $query = preg_replace_callback(DB_QUERY_REGEXP, '_db_query_callback', $query); 698 | // Next line required because views passes 0 as "IS NULL" to the query, and we actually want 0, so it's been hacked in manually 699 | $query .= " AND (node_data_field_fserver_project.field_fserver_versionmajor_value = %d) AND (node_data_field_fserver_api.field_fserver_versionpatch_value = %d)"; 700 | $items = db_query($query, $parsed['major'], $parsed['patch']); 701 | while ($result = db_fetch_object($items)) { 702 | $results[] = $result->nid; 703 | } 704 | if (!$results[0]) { 705 | $this->version = $parsed; 706 | $this->raw_version = $parsed['version']; 707 | } 708 | else { 709 | return FALSE; 710 | } 711 | } 712 | else { 713 | return FALSE; 714 | } 715 | } 716 | return $this->version; 717 | } 718 | 719 | /** 720 | * Create a release node for the given tag. 721 | */ 722 | function create_release($version = NULL) { 723 | $version = $this->parse_version($version); 724 | if ($file = $this->create_package()) { 725 | //if ($version) { 726 | $node = new stdClass(); 727 | $node->type = 'fserver_release'; 728 | $node->status = 1; 729 | $node->created = !empty($tag['timestamp']) ? $tag['timestamp'] : time(); 730 | $node->uid = $this->node->uid; 731 | $node->title = "{$this->name} {$tag_id}"; 732 | $node->body = !empty($tag['message']) ? $tag['message'] : ''; 733 | 734 | $node->field_fserver_file = array(0 => (array) $file); 735 | $node->field_fserver_project = array(0 => array('nid' => $this->node->nid)); 736 | $node->field_fserver_api = array(0 => array('value' => $version['core'])); 737 | $node->field_fserver_versionmajor = array(0 => array('value' => $version['major'])); 738 | $node->field_fserver_versionpatch = array(0 => array('value' => $version['patch'])); 739 | $node->field_fserver_versionextra = array(0 => array('value' => $version['extra'])); 740 | 741 | // Handle the release extra info 742 | $extratype = FSERVER_EXTRATYPE_RELEASE; 743 | $extranum = NULL; 744 | if (!empty($version['extra'])) { 745 | $extratypes = fserver_cck_options('extratype'); 746 | $extratypes = array_flip($extratypes); 747 | $extratype = array_key_exists($tag['extratype'], $extratypes) ? $extratypes[$version['extratype']] : FSERVER_EXTRATYPE_OTHER; 748 | $extranum = $version['extranum']; 749 | } 750 | $node->field_fserver_versionextratype = array(0 => array('value' => $extratype)); 751 | $node->field_fserver_versionextranum = array(0 => array('value' => $extranum)); 752 | 753 | // @TODO 754 | $node->field_fserver_recommended = array(0 => array('value' => 1)); 755 | $node->field_fserver_security = array(0 => array('value' => 0)); 756 | node_save($node); 757 | } 758 | return $node; 759 | } 760 | 761 | /** 762 | * Create an archive package for the given tag. 763 | */ 764 | function create_package() { 765 | if (!$this->init_wc()) { 766 | return FALSE; 767 | } 768 | $base = "{$this->name}-{$this->raw_version}"; 769 | $file_path = file_directory_path() .'/fserver'; 770 | // Create the directory if it doesn't exist. 771 | if (file_check_directory($file_path, TRUE)) { 772 | drush_backend_invoke('make', array("{$this->path}/{$base}.make", "{$file_path}/{$base}", "--tar")); 773 | drush_op('drush_shell_exec', "mv {$file_path}/{$base}.tar.gz {$file_path}/{$base}.tgz"); 774 | 775 | // @TODO 776 | // We need to properly chown and permission these directories. 777 | // Is it possible for drush to know the web server user? 778 | drush_op('chmod', $file_path, 0775); 779 | drush_op('chgrp', $file_path, fserver_posix_groupname()); 780 | drush_op('chmod', "{$file_path}/{$base}.tgz", 0775); 781 | drush_op('chgrp', "{$file_path}/{$base}.tgz", fserver_posix_groupname()); 782 | 783 | $file = new stdClass(); 784 | $file->uid = $this->node->uid; 785 | $file->filename = "{$base}.tgz"; 786 | $file->filepath = "{$file_path}/{$base}.tgz"; 787 | $file->filemime = file_get_mimetype($file->filename); 788 | $file->filesize = filesize($file->filepath); 789 | $file->status = FILE_STATUS_PERMANENT; 790 | $file->timestamp = time(); 791 | drupal_write_record('files', $file); 792 | 793 | return $file; 794 | } 795 | return FALSE; 796 | } 797 | } 798 | -------------------------------------------------------------------------------- /fserver.features.content.inc: -------------------------------------------------------------------------------- 1 | 'field_fserver_drushmake', 12 | 'type_name' => 'fserver_distro', 13 | 'display_settings' => array( 14 | 'label' => array( 15 | 'format' => 'above', 16 | 'exclude' => 0, 17 | ), 18 | 'teaser' => array( 19 | 'format' => 'default', 20 | 'exclude' => 0, 21 | ), 22 | 'full' => array( 23 | 'format' => 'default', 24 | 'exclude' => 0, 25 | ), 26 | '4' => array( 27 | 'format' => 'default', 28 | 'exclude' => 0, 29 | ), 30 | ), 31 | 'widget_active' => '1', 32 | 'type' => 'text', 33 | 'required' => '1', 34 | 'multiple' => '0', 35 | 'module' => 'text', 36 | 'active' => '1', 37 | 'text_processing' => '0', 38 | 'max_length' => '', 39 | 'allowed_values' => '', 40 | 'allowed_values_php' => '', 41 | 'widget' => array( 42 | 'rows' => '5', 43 | 'size' => 60, 44 | 'default_value' => array( 45 | '0' => array( 46 | 'value' => '', 47 | '_error_element' => 'default_value_widget][field_fserver_drushmake][0][value', 48 | ), 49 | ), 50 | 'default_value_php' => NULL, 51 | 'label' => 'Drush Make Script', 52 | 'weight' => '-3', 53 | 'description' => '', 54 | 'type' => 'text_textarea', 55 | 'module' => 'text', 56 | ), 57 | ); 58 | 59 | // Exported field: field_fserver_name 60 | $fields['fserver_distro-field_fserver_name'] = array( 61 | 'field_name' => 'field_fserver_name', 62 | 'type_name' => 'fserver_distro', 63 | 'display_settings' => array( 64 | 'weight' => '-4', 65 | 'parent' => '', 66 | 'label' => array( 67 | 'format' => 'hidden', 68 | ), 69 | 'teaser' => array( 70 | 'format' => 'hidden', 71 | 'exclude' => 0, 72 | ), 73 | 'full' => array( 74 | 'format' => 'hidden', 75 | 'exclude' => 0, 76 | ), 77 | '4' => array( 78 | 'format' => 'default', 79 | 'exclude' => 0, 80 | ), 81 | ), 82 | 'widget_active' => '1', 83 | 'type' => 'text', 84 | 'required' => '1', 85 | 'multiple' => '0', 86 | 'module' => 'text', 87 | 'active' => '1', 88 | 'text_processing' => '0', 89 | 'max_length' => '', 90 | 'allowed_values' => '', 91 | 'allowed_values_php' => '', 92 | 'widget' => array( 93 | 'rows' => 5, 94 | 'size' => '30', 95 | 'default_value' => array( 96 | '0' => array( 97 | 'value' => '', 98 | '_error_element' => 'default_value_widget][field_fserver_name][0][value', 99 | ), 100 | ), 101 | 'default_value_php' => NULL, 102 | 'label' => 'Machine name', 103 | 'weight' => '-4', 104 | 'description' => 'The machine-readable name for your project. This name must contain only lowercase letters, numbers, and underscores. Example: cooking_recipes.', 105 | 'type' => 'text_textfield', 106 | 'module' => 'text', 107 | ), 108 | ); 109 | 110 | // Exported field: field_fserver_method 111 | $fields['fserver_project-field_fserver_method'] = array( 112 | 'field_name' => 'field_fserver_method', 113 | 'type_name' => 'fserver_project', 114 | 'display_settings' => array( 115 | 'weight' => '-2', 116 | 'parent' => '', 117 | 'label' => array( 118 | 'format' => 'hidden', 119 | ), 120 | 'teaser' => array( 121 | 'format' => 'hidden', 122 | 'exclude' => 0, 123 | ), 124 | 'full' => array( 125 | 'format' => 'hidden', 126 | 'exclude' => 0, 127 | ), 128 | '4' => array( 129 | 'format' => 'default', 130 | 'exclude' => 0, 131 | ), 132 | ), 133 | 'widget_active' => '1', 134 | 'type' => 'text', 135 | 'required' => '1', 136 | 'multiple' => '0', 137 | 'module' => 'text', 138 | 'active' => '1', 139 | 'text_processing' => '0', 140 | 'max_length' => '', 141 | 'allowed_values' => '', 142 | 'allowed_values_php' => 'return fserver_cck_options("method");', 143 | 'widget' => array( 144 | 'default_value' => array( 145 | '0' => array( 146 | 'value' => '', 147 | ), 148 | ), 149 | 'default_value_php' => NULL, 150 | 'label' => 'Packaging method', 151 | 'weight' => '1', 152 | 'description' => 'Choose the packaging method to use for this project.', 153 | 'type' => 'optionwidgets_select', 154 | 'module' => 'optionwidgets', 155 | ), 156 | ); 157 | 158 | // Exported field: field_fserver_name 159 | $fields['fserver_project-field_fserver_name'] = array( 160 | 'field_name' => 'field_fserver_name', 161 | 'type_name' => 'fserver_project', 162 | 'display_settings' => array( 163 | 'weight' => '-4', 164 | 'parent' => '', 165 | 'label' => array( 166 | 'format' => 'hidden', 167 | ), 168 | 'teaser' => array( 169 | 'format' => 'hidden', 170 | 'exclude' => 0, 171 | ), 172 | 'full' => array( 173 | 'format' => 'hidden', 174 | 'exclude' => 0, 175 | ), 176 | '4' => array( 177 | 'format' => 'default', 178 | 'exclude' => 0, 179 | ), 180 | ), 181 | 'widget_active' => '1', 182 | 'type' => 'text', 183 | 'required' => '1', 184 | 'multiple' => '0', 185 | 'module' => 'text', 186 | 'active' => '1', 187 | 'text_processing' => '0', 188 | 'max_length' => '', 189 | 'allowed_values' => '', 190 | 'allowed_values_php' => '', 191 | 'widget' => array( 192 | 'rows' => 5, 193 | 'size' => '30', 194 | 'default_value' => array( 195 | '0' => array( 196 | 'value' => '', 197 | '_error_element' => 'default_value_widget][field_fserver_name][0][value', 198 | ), 199 | ), 200 | 'default_value_php' => NULL, 201 | 'label' => 'Machine name', 202 | 'weight' => '-4', 203 | 'description' => 'The machine-readable name for your project. This name must contain only lowercase letters, numbers, and underscores. Example: cooking_recipes.', 204 | 'type' => 'text_textfield', 205 | 'module' => 'text', 206 | ), 207 | ); 208 | 209 | // Exported field: field_fserver_redirect 210 | $fields['fserver_project-field_fserver_redirect'] = array( 211 | 'field_name' => 'field_fserver_redirect', 212 | 'type_name' => 'fserver_project', 213 | 'display_settings' => array( 214 | 'label' => array( 215 | 'format' => 'above', 216 | 'exclude' => 0, 217 | ), 218 | '5' => array( 219 | 'format' => 'default', 220 | 'exclude' => 0, 221 | ), 222 | 'teaser' => array( 223 | 'format' => 'default', 224 | 'exclude' => 0, 225 | ), 226 | 'full' => array( 227 | 'format' => 'default', 228 | 'exclude' => 0, 229 | ), 230 | '4' => array( 231 | 'format' => 'default', 232 | 'exclude' => 0, 233 | ), 234 | '2' => array( 235 | 'format' => 'default', 236 | 'exclude' => 0, 237 | ), 238 | '3' => array( 239 | 'format' => 'default', 240 | 'exclude' => 0, 241 | ), 242 | ), 243 | 'widget_active' => '1', 244 | 'type' => 'text', 245 | 'required' => '0', 246 | 'multiple' => '0', 247 | 'module' => 'text', 248 | 'active' => '1', 249 | 'text_processing' => '0', 250 | 'max_length' => '', 251 | 'allowed_values' => '', 252 | 'allowed_values_php' => '', 253 | 'widget' => array( 254 | 'rows' => 5, 255 | 'size' => '60', 256 | 'default_value' => array( 257 | '0' => array( 258 | 'value' => '', 259 | '_error_element' => 'default_value_widget][field_fserver_redirect][0][value', 260 | ), 261 | ), 262 | 'default_value_php' => NULL, 263 | 'label' => 'Redirect URL (for legacy projects)', 264 | 'weight' => '3', 265 | 'description' => 'Enter a redirect URL to use for this project\'s update XML feed if this project has moved.', 266 | 'type' => 'text_textfield', 267 | 'module' => 'text', 268 | ), 269 | ); 270 | 271 | // Exported field: field_fserver_repository 272 | $fields['fserver_project-field_fserver_repository'] = array( 273 | 'field_name' => 'field_fserver_repository', 274 | 'type_name' => 'fserver_project', 275 | 'display_settings' => array( 276 | 'weight' => '-1', 277 | 'parent' => '', 278 | 'label' => array( 279 | 'format' => 'inline', 280 | ), 281 | 'teaser' => array( 282 | 'format' => 'default', 283 | 'exclude' => 0, 284 | ), 285 | 'full' => array( 286 | 'format' => 'default', 287 | 'exclude' => 0, 288 | ), 289 | '4' => array( 290 | 'format' => 'default', 291 | 'exclude' => 0, 292 | ), 293 | ), 294 | 'widget_active' => '1', 295 | 'type' => 'text', 296 | 'required' => '0', 297 | 'multiple' => '0', 298 | 'module' => 'text', 299 | 'active' => '1', 300 | 'text_processing' => '0', 301 | 'max_length' => '', 302 | 'allowed_values' => '', 303 | 'allowed_values_php' => '', 304 | 'widget' => array( 305 | 'rows' => 5, 306 | 'size' => '60', 307 | 'default_value' => array( 308 | '0' => array( 309 | 'value' => '', 310 | '_error_element' => 'default_value_widget][field_fserver_repository][0][value', 311 | ), 312 | ), 313 | 'default_value_php' => NULL, 314 | 'label' => 'Repository URL', 315 | 'weight' => '2', 316 | 'description' => 'Example: git://github.com/myname/myproject.git', 317 | 'type' => 'text_textfield', 318 | 'module' => 'text', 319 | ), 320 | ); 321 | 322 | // Exported field: field_fserver_type 323 | $fields['fserver_project-field_fserver_type'] = array( 324 | 'field_name' => 'field_fserver_type', 325 | 'type_name' => 'fserver_project', 326 | 'display_settings' => array( 327 | 'weight' => '-3', 328 | 'parent' => '', 329 | 'label' => array( 330 | 'format' => 'hidden', 331 | ), 332 | 'teaser' => array( 333 | 'format' => 'hidden', 334 | 'exclude' => 0, 335 | ), 336 | 'full' => array( 337 | 'format' => 'hidden', 338 | 'exclude' => 0, 339 | ), 340 | '4' => array( 341 | 'format' => 'default', 342 | 'exclude' => 0, 343 | ), 344 | ), 345 | 'widget_active' => '1', 346 | 'type' => 'text', 347 | 'required' => '1', 348 | 'multiple' => '0', 349 | 'module' => 'text', 350 | 'active' => '1', 351 | 'text_processing' => '0', 352 | 'max_length' => '', 353 | 'allowed_values' => '', 354 | 'allowed_values_php' => 'return fserver_cck_options(\'type\');', 355 | 'widget' => array( 356 | 'default_value' => array( 357 | '0' => array( 358 | 'value' => '', 359 | ), 360 | ), 361 | 'default_value_php' => NULL, 362 | 'label' => 'Type', 363 | 'weight' => '-2', 364 | 'description' => '', 365 | 'type' => 'optionwidgets_select', 366 | 'module' => 'optionwidgets', 367 | ), 368 | ); 369 | 370 | // Exported field: field_fserver_api 371 | $fields['fserver_release-field_fserver_api'] = array( 372 | 'field_name' => 'field_fserver_api', 373 | 'type_name' => 'fserver_release', 374 | 'display_settings' => array( 375 | 'weight' => '-10', 376 | 'parent' => '', 377 | 'label' => array( 378 | 'format' => 'hidden', 379 | ), 380 | 'teaser' => array( 381 | 'format' => 'hidden', 382 | 'exclude' => 1, 383 | ), 384 | 'full' => array( 385 | 'format' => 'hidden', 386 | 'exclude' => 1, 387 | ), 388 | '4' => array( 389 | 'format' => 'default', 390 | 'exclude' => 0, 391 | ), 392 | ), 393 | 'widget_active' => '1', 394 | 'type' => 'text', 395 | 'required' => '1', 396 | 'multiple' => '0', 397 | 'module' => 'text', 398 | 'active' => '1', 399 | 'text_processing' => '0', 400 | 'max_length' => '', 401 | 'allowed_values' => '', 402 | 'allowed_values_php' => 'return fserver_cck_options(\'core\');', 403 | 'widget' => array( 404 | 'default_value' => array( 405 | '0' => array( 406 | 'value' => '6.x', 407 | ), 408 | ), 409 | 'default_value_php' => NULL, 410 | 'label' => 'Core compatibility', 411 | 'weight' => '-11', 412 | 'description' => '', 413 | 'type' => 'optionwidgets_select', 414 | 'module' => 'optionwidgets', 415 | ), 416 | ); 417 | 418 | // Exported field: field_fserver_file 419 | $fields['fserver_release-field_fserver_file'] = array( 420 | 'field_name' => 'field_fserver_file', 421 | 'type_name' => 'fserver_release', 422 | 'display_settings' => array( 423 | 'weight' => '-13', 424 | 'parent' => '', 425 | 'label' => array( 426 | 'format' => 'hidden', 427 | ), 428 | 'teaser' => array( 429 | 'format' => 'hidden', 430 | 'exclude' => 1, 431 | ), 432 | 'full' => array( 433 | 'format' => 'hidden', 434 | 'exclude' => 1, 435 | ), 436 | '4' => array( 437 | 'format' => 'default', 438 | 'exclude' => 0, 439 | ), 440 | ), 441 | 'widget_active' => '1', 442 | 'type' => 'filefield', 443 | 'required' => '1', 444 | 'multiple' => '0', 445 | 'module' => 'filefield', 446 | 'active' => '1', 447 | 'list_field' => '0', 448 | 'list_default' => 1, 449 | 'description_field' => '0', 450 | 'widget' => array( 451 | 'file_extensions' => 'tgz tar gz', 452 | 'file_path' => 'fserver', 453 | 'progress_indicator' => 'bar', 454 | 'max_filesize_per_file' => '', 455 | 'max_filesize_per_node' => '', 456 | 'label' => 'Package', 457 | 'weight' => '-13', 458 | 'description' => '', 459 | 'type' => 'filefield_widget', 460 | 'module' => 'filefield', 461 | ), 462 | ); 463 | 464 | // Exported field: field_fserver_project 465 | $fields['fserver_release-field_fserver_project'] = array( 466 | 'field_name' => 'field_fserver_project', 467 | 'type_name' => 'fserver_release', 468 | 'display_settings' => array( 469 | 'weight' => '-11', 470 | 'parent' => '', 471 | 'label' => array( 472 | 'format' => 'hidden', 473 | ), 474 | 'teaser' => array( 475 | 'format' => 'hidden', 476 | 'exclude' => 1, 477 | ), 478 | 'full' => array( 479 | 'format' => 'hidden', 480 | 'exclude' => 1, 481 | ), 482 | '4' => array( 483 | 'format' => 'default', 484 | 'exclude' => 0, 485 | ), 486 | ), 487 | 'widget_active' => '1', 488 | 'type' => 'nodereference', 489 | 'required' => '1', 490 | 'multiple' => '0', 491 | 'module' => 'nodereference', 492 | 'active' => '1', 493 | 'referenceable_types' => array( 494 | 'fserver_distro' => 'fserver_distro', 495 | 'fserver_project' => 'fserver_project', 496 | 'page' => 0, 497 | 'fserver_release' => 0, 498 | 'story' => 0, 499 | ), 500 | 'advanced_view' => '--', 501 | 'advanced_view_args' => '', 502 | 'widget' => array( 503 | 'autocomplete_match' => 'contains', 504 | 'size' => 60, 505 | 'default_value' => array( 506 | '0' => array( 507 | 'nid' => '', 508 | ), 509 | ), 510 | 'default_value_php' => NULL, 511 | 'node_link' => array( 512 | 'teaser' => 0, 513 | 'full' => 0, 514 | 'title' => '', 515 | 'hover_title' => '', 516 | 'destination' => 'node', 517 | ), 518 | 'fallback' => 'select', 519 | 'edit_fallback' => 0, 520 | 'label' => 'Project', 521 | 'weight' => '-12', 522 | 'description' => 'Select your project from the box.', 523 | 'type' => 'nodereference_url', 524 | 'module' => 'nodereference_url', 525 | ), 526 | ); 527 | 528 | // Exported field: field_fserver_recommended 529 | $fields['fserver_release-field_fserver_recommended'] = array( 530 | 'field_name' => 'field_fserver_recommended', 531 | 'type_name' => 'fserver_release', 532 | 'display_settings' => array( 533 | 'weight' => '-6', 534 | 'parent' => '', 535 | 'label' => array( 536 | 'format' => 'hidden', 537 | ), 538 | 'teaser' => array( 539 | 'format' => 'hidden', 540 | 'exclude' => 1, 541 | ), 542 | 'full' => array( 543 | 'format' => 'hidden', 544 | 'exclude' => 1, 545 | ), 546 | '4' => array( 547 | 'format' => 'default', 548 | 'exclude' => 0, 549 | ), 550 | ), 551 | 'widget_active' => '1', 552 | 'type' => 'text', 553 | 'required' => '1', 554 | 'multiple' => '0', 555 | 'module' => 'text', 556 | 'active' => '1', 557 | 'text_processing' => '0', 558 | 'max_length' => '', 559 | 'allowed_values' => '', 560 | 'allowed_values_php' => 'return fserver_cck_options(\'recommended\');', 561 | 'widget' => array( 562 | 'default_value' => array( 563 | '0' => array( 564 | 'value' => 0, 565 | ), 566 | ), 567 | 'default_value_php' => NULL, 568 | 'label' => 'Recommended', 569 | 'weight' => '-5', 570 | 'description' => 'The recommended releases will be displayed on the project page. The latest recommended release per major version will be offered for update status.', 571 | 'type' => 'optionwidgets_onoff', 572 | 'module' => 'optionwidgets', 573 | ), 574 | ); 575 | 576 | // Exported field: field_fserver_security 577 | $fields['fserver_release-field_fserver_security'] = array( 578 | 'field_name' => 'field_fserver_security', 579 | 'type_name' => 'fserver_release', 580 | 'display_settings' => array( 581 | 'weight' => '-5', 582 | 'parent' => '', 583 | 'label' => array( 584 | 'format' => 'hidden', 585 | ), 586 | 'teaser' => array( 587 | 'format' => 'hidden', 588 | 'exclude' => 1, 589 | ), 590 | 'full' => array( 591 | 'format' => 'hidden', 592 | 'exclude' => 1, 593 | ), 594 | '4' => array( 595 | 'format' => 'default', 596 | 'exclude' => 0, 597 | ), 598 | ), 599 | 'widget_active' => '1', 600 | 'type' => 'text', 601 | 'required' => '0', 602 | 'multiple' => '0', 603 | 'module' => 'text', 604 | 'active' => '1', 605 | 'text_processing' => '0', 606 | 'max_length' => '', 607 | 'allowed_values' => '', 608 | 'allowed_values_php' => 'return fserver_cck_options(\'security\');', 609 | 'widget' => array( 610 | 'default_value' => array( 611 | '0' => array( 612 | 'value' => 'Not a security release', 613 | ), 614 | ), 615 | 'default_value_php' => NULL, 616 | 'label' => 'Security release', 617 | 'weight' => '-4', 618 | 'description' => '', 619 | 'type' => 'optionwidgets_onoff', 620 | 'module' => 'optionwidgets', 621 | ), 622 | ); 623 | 624 | // Exported field: field_fserver_versionextra 625 | $fields['fserver_release-field_fserver_versionextra'] = array( 626 | 'field_name' => 'field_fserver_versionextra', 627 | 'type_name' => 'fserver_release', 628 | 'display_settings' => array( 629 | 'weight' => '-7', 630 | 'parent' => '', 631 | 'label' => array( 632 | 'format' => 'hidden', 633 | ), 634 | 'teaser' => array( 635 | 'format' => 'hidden', 636 | 'exclude' => 1, 637 | ), 638 | 'full' => array( 639 | 'format' => 'hidden', 640 | 'exclude' => 1, 641 | ), 642 | '4' => array( 643 | 'format' => 'default', 644 | 'exclude' => 0, 645 | ), 646 | ), 647 | 'widget_active' => '1', 648 | 'type' => 'text', 649 | 'required' => '0', 650 | 'multiple' => '0', 651 | 'module' => 'text', 652 | 'active' => '1', 653 | 'text_processing' => '0', 654 | 'max_length' => '', 655 | 'allowed_values' => '', 656 | 'allowed_values_php' => '', 657 | 'widget' => array( 658 | 'rows' => 5, 659 | 'size' => '20', 660 | 'default_value' => array( 661 | '0' => array( 662 | 'value' => '', 663 | '_error_element' => 'default_value_widget][field_fserver_versionextra][0][value', 664 | ), 665 | ), 666 | 'default_value_php' => NULL, 667 | 'label' => 'Extra version', 668 | 'weight' => '-8', 669 | 'description' => 'This is the version designation and number, i.e. beat10, alpha9, rc2. This should be specified even if the Extra Version Num and Type are specified since those are used specifically to provide more accurate sorting/ordering and this is used for display.', 670 | 'type' => 'text_textfield', 671 | 'module' => 'text', 672 | ), 673 | ); 674 | 675 | // Exported field: field_fserver_versionextranum 676 | $fields['fserver_release-field_fserver_versionextranum'] = array( 677 | 'field_name' => 'field_fserver_versionextranum', 678 | 'type_name' => 'fserver_release', 679 | 'display_settings' => array( 680 | 'label' => array( 681 | 'format' => 'above', 682 | 'exclude' => 0, 683 | ), 684 | 'teaser' => array( 685 | 'format' => 'default', 686 | 'exclude' => 0, 687 | ), 688 | 'full' => array( 689 | 'format' => 'default', 690 | 'exclude' => 0, 691 | ), 692 | '4' => array( 693 | 'format' => 'default', 694 | 'exclude' => 0, 695 | ), 696 | 'token' => array( 697 | 'format' => 'default', 698 | 'exclude' => 0, 699 | ), 700 | ), 701 | 'widget_active' => '1', 702 | 'type' => 'number_integer', 703 | 'required' => '0', 704 | 'multiple' => '0', 705 | 'module' => 'number', 706 | 'active' => '1', 707 | 'prefix' => '', 708 | 'suffix' => '', 709 | 'min' => '', 710 | 'max' => '', 711 | 'allowed_values' => '', 712 | 'allowed_values_php' => 'return fserver_cck_options(\'extranum\');', 713 | 'widget' => array( 714 | 'default_value' => array( 715 | '0' => array( 716 | 'value' => '', 717 | ), 718 | ), 719 | 'default_value_php' => NULL, 720 | 'label' => 'Extra version number', 721 | 'weight' => '-6', 722 | 'description' => 'This is the number of the extra version. For a release that is beta10, this value would be 10.', 723 | 'type' => 'optionwidgets_select', 724 | 'module' => 'optionwidgets', 725 | ), 726 | ); 727 | 728 | // Exported field: field_fserver_versionextratype 729 | $fields['fserver_release-field_fserver_versionextratype'] = array( 730 | 'field_name' => 'field_fserver_versionextratype', 731 | 'type_name' => 'fserver_release', 732 | 'display_settings' => array( 733 | 'label' => array( 734 | 'format' => 'above', 735 | 'exclude' => 0, 736 | ), 737 | 'teaser' => array( 738 | 'format' => 'default', 739 | 'exclude' => 0, 740 | ), 741 | 'full' => array( 742 | 'format' => 'default', 743 | 'exclude' => 0, 744 | ), 745 | '4' => array( 746 | 'format' => 'default', 747 | 'exclude' => 0, 748 | ), 749 | 'token' => array( 750 | 'format' => 'default', 751 | 'exclude' => 0, 752 | ), 753 | ), 754 | 'widget_active' => '1', 755 | 'type' => 'number_integer', 756 | 'required' => '1', 757 | 'multiple' => '0', 758 | 'module' => 'number', 759 | 'active' => '1', 760 | 'prefix' => '', 761 | 'suffix' => '', 762 | 'min' => '', 763 | 'max' => '', 764 | 'allowed_values' => '', 765 | 'allowed_values_php' => 'return fserver_cck_options(\'extratype\');', 766 | 'widget' => array( 767 | 'default_value' => array( 768 | '0' => array( 769 | 'value' => '', 770 | ), 771 | ), 772 | 'default_value_php' => NULL, 773 | 'label' => 'Extra version type', 774 | 'weight' => '-7', 775 | 'description' => '', 776 | 'type' => 'optionwidgets_select', 777 | 'module' => 'optionwidgets', 778 | ), 779 | ); 780 | 781 | // Exported field: field_fserver_versionmajor 782 | $fields['fserver_release-field_fserver_versionmajor'] = array( 783 | 'field_name' => 'field_fserver_versionmajor', 784 | 'type_name' => 'fserver_release', 785 | 'display_settings' => array( 786 | 'weight' => '-9', 787 | 'parent' => '', 788 | 'label' => array( 789 | 'format' => 'hidden', 790 | ), 791 | 'teaser' => array( 792 | 'format' => 'hidden', 793 | 'exclude' => 1, 794 | ), 795 | 'full' => array( 796 | 'format' => 'hidden', 797 | 'exclude' => 1, 798 | ), 799 | '4' => array( 800 | 'format' => 'default', 801 | 'exclude' => 0, 802 | ), 803 | ), 804 | 'widget_active' => '1', 805 | 'type' => 'number_integer', 806 | 'required' => '1', 807 | 'multiple' => '0', 808 | 'module' => 'number', 809 | 'active' => '1', 810 | 'prefix' => '', 811 | 'suffix' => '', 812 | 'min' => '0', 813 | 'max' => '50', 814 | 'allowed_values' => '', 815 | 'allowed_values_php' => 'return fserver_cck_options(\'major\');', 816 | 'widget' => array( 817 | 'default_value' => array( 818 | '0' => array( 819 | 'value' => '', 820 | ), 821 | ), 822 | 'default_value_php' => NULL, 823 | 'label' => 'Major version', 824 | 'weight' => '-10', 825 | 'description' => '', 826 | 'type' => 'optionwidgets_select', 827 | 'module' => 'optionwidgets', 828 | ), 829 | ); 830 | 831 | // Exported field: field_fserver_versionpatch 832 | $fields['fserver_release-field_fserver_versionpatch'] = array( 833 | 'field_name' => 'field_fserver_versionpatch', 834 | 'type_name' => 'fserver_release', 835 | 'display_settings' => array( 836 | 'weight' => '-8', 837 | 'parent' => '', 838 | 'label' => array( 839 | 'format' => 'hidden', 840 | ), 841 | 'teaser' => array( 842 | 'format' => 'hidden', 843 | 'exclude' => 1, 844 | ), 845 | 'full' => array( 846 | 'format' => 'hidden', 847 | 'exclude' => 1, 848 | ), 849 | '4' => array( 850 | 'format' => 'default', 851 | 'exclude' => 0, 852 | ), 853 | ), 854 | 'widget_active' => '1', 855 | 'type' => 'number_integer', 856 | 'required' => '1', 857 | 'multiple' => '0', 858 | 'module' => 'number', 859 | 'active' => '1', 860 | 'prefix' => '', 861 | 'suffix' => '', 862 | 'min' => '0', 863 | 'max' => '50', 864 | 'allowed_values' => '', 865 | 'allowed_values_php' => 'return fserver_cck_options(\'patch\');', 866 | 'widget' => array( 867 | 'default_value' => array( 868 | '0' => array( 869 | 'value' => '', 870 | ), 871 | ), 872 | 'default_value_php' => NULL, 873 | 'label' => 'Patch version', 874 | 'weight' => '-9', 875 | 'description' => '', 876 | 'type' => 'optionwidgets_select', 877 | 'module' => 'optionwidgets', 878 | ), 879 | ); 880 | 881 | // Translatables 882 | // Included for use with string extractors like potx. 883 | t('Core compatibility'); 884 | t('Drush Make Script'); 885 | t('Extra version'); 886 | t('Extra version number'); 887 | t('Extra version type'); 888 | t('Machine name'); 889 | t('Major version'); 890 | t('Package'); 891 | t('Packaging method'); 892 | t('Patch version'); 893 | t('Project'); 894 | t('Recommended'); 895 | t('Redirect URL (for legacy projects)'); 896 | t('Repository URL'); 897 | t('Security release'); 898 | t('Type'); 899 | 900 | return $fields; 901 | } 902 | -------------------------------------------------------------------------------- /fserver.features.inc: -------------------------------------------------------------------------------- 1 | 3); 10 | } 11 | elseif ($module == "strongarm" && $api == "strongarm") { 12 | return array("version" => 1); 13 | } 14 | } 15 | 16 | /** 17 | * Implementation of hook_node_info(). 18 | */ 19 | function fserver_node_info() { 20 | $items = array( 21 | 'fserver_distro' => array( 22 | 'name' => t('Distribution'), 23 | 'module' => 'features', 24 | 'description' => t('A feature distribution page. Provides the drush make commands and releases for download.'), 25 | 'has_title' => '1', 26 | 'title_label' => t('Distribution'), 27 | 'has_body' => '1', 28 | 'body_label' => t('Body'), 29 | 'min_word_count' => '0', 30 | 'help' => '', 31 | ), 32 | 'fserver_project' => array( 33 | 'name' => t('Project'), 34 | 'module' => 'features', 35 | 'description' => t('A feature project page. Provides a summary of project information and releases for download.'), 36 | 'has_title' => '1', 37 | 'title_label' => t('Project'), 38 | 'has_body' => '1', 39 | 'body_label' => t('Description'), 40 | 'min_word_count' => '0', 41 | 'help' => '', 42 | ), 43 | 'fserver_release' => array( 44 | 'name' => t('Release'), 45 | 'module' => 'features', 46 | 'description' => t('A single release package for a feature.'), 47 | 'has_title' => '1', 48 | 'title_label' => t('Release'), 49 | 'has_body' => '1', 50 | 'body_label' => t('Notes'), 51 | 'min_word_count' => '0', 52 | 'help' => '', 53 | ), 54 | ); 55 | return $items; 56 | } 57 | 58 | /** 59 | * Implementation of hook_views_api(). 60 | */ 61 | function fserver_views_api() { 62 | return array( 63 | 'api' => '2', 64 | ); 65 | } 66 | -------------------------------------------------------------------------------- /fserver.features.menu_links.inc: -------------------------------------------------------------------------------- 1 | 'features', 12 | 'link_path' => 'fserver', 13 | 'router_path' => 'fserver', 14 | 'link_title' => 'Projects', 15 | 'options' => array(), 16 | 'module' => 'system', 17 | 'hidden' => '0', 18 | 'external' => '0', 19 | 'has_children' => '0', 20 | 'expanded' => '0', 21 | 'weight' => '0', 22 | ); 23 | // Translatables 24 | // Included for use with string extractors like potx. 25 | t('Projects'); 26 | 27 | 28 | return $menu_links; 29 | } 30 | -------------------------------------------------------------------------------- /fserver.info: -------------------------------------------------------------------------------- 1 | core = "6.x" 2 | dependencies[] = "context" 3 | dependencies[] = "features" 4 | dependencies[] = "filefield" 5 | dependencies[] = "menu" 6 | dependencies[] = "node" 7 | dependencies[] = "nodereference" 8 | dependencies[] = "nodereference_url" 9 | dependencies[] = "number" 10 | dependencies[] = "strongarm" 11 | dependencies[] = "views" 12 | description = "Provides feature projects and releases." 13 | features[content][] = "fserver_distro-field_fserver_drushmake" 14 | features[content][] = "fserver_distro-field_fserver_name" 15 | features[content][] = "fserver_project-field_fserver_method" 16 | features[content][] = "fserver_project-field_fserver_name" 17 | features[content][] = "fserver_project-field_fserver_redirect" 18 | features[content][] = "fserver_project-field_fserver_repository" 19 | features[content][] = "fserver_project-field_fserver_type" 20 | features[content][] = "fserver_release-field_fserver_api" 21 | features[content][] = "fserver_release-field_fserver_file" 22 | features[content][] = "fserver_release-field_fserver_project" 23 | features[content][] = "fserver_release-field_fserver_recommended" 24 | features[content][] = "fserver_release-field_fserver_security" 25 | features[content][] = "fserver_release-field_fserver_versionextra" 26 | features[content][] = "fserver_release-field_fserver_versionextranum" 27 | features[content][] = "fserver_release-field_fserver_versionextratype" 28 | features[content][] = "fserver_release-field_fserver_versionmajor" 29 | features[content][] = "fserver_release-field_fserver_versionpatch" 30 | features[context][] = "fserver-section-project" 31 | features[ctools][] = "context:context:3" 32 | features[ctools][] = "strongarm:strongarm:1" 33 | features[menu_links][] = "features:fserver" 34 | features[node][] = "fserver_distro" 35 | features[node][] = "fserver_project" 36 | features[node][] = "fserver_release" 37 | features[variable][] = "content_extra_weights_fserver_project" 38 | features[variable][] = "content_extra_weights_fserver_release" 39 | features[views][] = "fserver_projects" 40 | features[views][] = "fserver_release_lookup" 41 | features[views][] = "fserver_releases" 42 | features[views][] = "fserver_updates" 43 | features[views_api][] = "api:2" 44 | name = "Feature Server" 45 | package = "Features" 46 | -------------------------------------------------------------------------------- /fserver.install: -------------------------------------------------------------------------------- 1 | [A-Za-z]+)(?P\d+)$/', $extraversion, $matches); 28 | $type = array_key_exists($matches['type'], $types) ? $types[$matches['type']] : 0; 29 | $num = !empty($matches['num']) ? $matches['num'] : 1; 30 | } 31 | 32 | db_query('UPDATE {content_type_fserver_release} 33 | SET field_fserver_versionextratype_value = %d, 34 | field_fserver_versionextranum_value = %d 35 | WHERE vid = %d', array($type, $num, $row['vid'])); 36 | $count++; 37 | } 38 | $ret[] = array( 39 | 'success' => TRUE, 40 | 'query' => "Updated $count releases." 41 | ); 42 | } 43 | else { 44 | $ret['#abort'] = array( 45 | 'success' => FALSE, 46 | 'query' => 'Extra version number and Extra version type have not been created yet.' 47 | ); 48 | } 49 | 50 | return $ret; 51 | } 52 | -------------------------------------------------------------------------------- /fserver.js: -------------------------------------------------------------------------------- 1 | // $Id$ 2 | 3 | /** 4 | * JS behaviors for fserver. 5 | */ 6 | Drupal.behaviors.fserver = function() { 7 | $('#edit-field-fserver-method-value:not(.processed)').each(function() { 8 | $(this).addClass('processed'); 9 | $(this).change(function() { 10 | switch ($(this).val()) { 11 | case '0': 12 | $('#edit-field-fserver-repository-0-value-wrapper').hide(); 13 | break; 14 | default: 15 | $('#edit-field-fserver-repository-0-value-wrapper').show(); 16 | break; 17 | } 18 | }); 19 | $(this).change(); 20 | }); 21 | }; 22 | -------------------------------------------------------------------------------- /fserver.module: -------------------------------------------------------------------------------- 1 | 'Manual'. 17 | $links = array(); 18 | if ($type == 'node' && $object->type == 'fserver_project' && empty($object->field_fserver_method[0]['value'])) { 19 | $item = menu_get_item('node/add/fserver-release'); 20 | if ($item && $item['access']) { 21 | $links['fserver-add-release'] = array( 22 | 'title' => t('Add new @release', array('@release' => strtolower($item['title']))), 23 | 'href' => 'node/add/fserver-release/'.$object->nid, 24 | ); 25 | } 26 | } 27 | return $links; 28 | } 29 | 30 | /** 31 | * Implementation of hook_nodeapi(). 32 | */ 33 | function fserver_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) { 34 | if ($op == 'view' && $node->type == 'fserver_distro' && menu_get_object()->nid === $node->nid) { 35 | //$node->content['field_fserver_drushmake'][0]['value'] = ''. $node->field_fserver_drushmake[0]['value'] .''; 36 | $node->content['field_fserver_drushmake']['field']['items'][0]['#item']['safe'] = '
'. implode('
', explode("\r\n", $node->content['field_fserver_drushmake']['field']['items'][0]['#item']['safe'])) .'
'; 37 | 38 | } 39 | if ($op == 'view' && $node->type == 'fserver_project' && menu_get_object()->nid === $node->nid) { 40 | $url = url("fserver", array('purl' => array('disabled' => TRUE), 'absolute' => TRUE)); 41 | $project = check_plain($node->field_fserver_name[0]['value']); 42 | $node->content['project_info'] = array( 43 | '#type' => 'fieldset', 44 | 'info' => array( 45 | '#access' => node_access('update', $node), 46 | '#title' => t("For @project.info", array('@project' => $project)), 47 | '#type' => 'item', 48 | '#value' => "project status url = {$url}", 49 | ), 50 | 'drush_make' => array( 51 | '#title' => t("For drush make makefiles"), 52 | '#type' => 'item', 53 | '#value' => "projects[{$project}][location] = {$url}", 54 | ), 55 | '#weight' => -10, 56 | ); 57 | } 58 | else if ($op == 'presave' && $node->type == 'fserver_project') { 59 | if (empty($node->field_fserver_method[0]['value'])) { 60 | $node->field_fserver_repository[0]['value'] = ''; 61 | } 62 | } 63 | else if ($op == 'presave' && $node->type == 'fserver_release') { 64 | $node->title = fserver_generate_version($node); 65 | 66 | // If this release is recommended, set all other ones to not recommended. 67 | if ($node->field_fserver_recommended[0]['value'] == 1) { 68 | $view = views_get_view('fserver_releases'); 69 | $view->set_arguments(array($node->field_fserver_project[0]['nid'], $node->field_fserver_api[0]['value'])); 70 | $view->execute('block_1'); 71 | foreach ($view->result as $data) { 72 | if (!isset($node->nid) || $data->nid != $node->nid) { 73 | $release = node_load($data->nid); 74 | $release->field_fserver_recommended[0]['value'] = 0; 75 | node_save($release); 76 | } 77 | } 78 | } 79 | } 80 | else if ($op == 'view' && $node->type == 'fserver_release') { 81 | drupal_add_css(drupal_get_path('module', 'fserver') . '/fserver.css'); 82 | $download_url = url($node->field_fserver_file[0]['filepath'], array('purl' => array('disabled' => TRUE), 'absolute' => TRUE)); 83 | $contents = file_exists($node->field_fserver_file[0]['filepath']) ? file_get_contents($node->field_fserver_file[0]['filepath']) : ''; 84 | $info = array(); 85 | $info[] = t('Download: !url', array('!url' => l($download_url, $download_url, array('absolute' => TRUE)))); 86 | $info[] = t('md5 hash: !md5', array('!md5' => md5($contents))); 87 | $info[] = t('Size: !size', array('!size' => format_size($node->field_fserver_file[0]['filesize']))); 88 | $node->content['fserver_info'] = array( 89 | '#type' => 'fieldset', 90 | 'content' => array( 91 | '#type' => 'markup', 92 | '#value' => theme('item_list', $info, NULL, 'ul', array('id' => 'fserver-release-info')), 93 | ), 94 | '#weight' => -10, 95 | ); 96 | $project = node_load($node->field_fserver_project[0]['nid']); 97 | drupal_set_breadcrumb(array(l(t('Home'), NULL), l($project->title, 'node/' . $project->nid))); 98 | } 99 | } 100 | 101 | /** 102 | * Option field callback for version options. 103 | */ 104 | function fserver_cck_options($type = 'core') { 105 | switch ($type) { 106 | case 'core': 107 | $result = drupal_map_assoc(array('5.x', '6.x', '7.x')); 108 | break; 109 | case 'major': 110 | $major = range(0, 50); 111 | unset($major[0]); 112 | $result = $major; 113 | break; 114 | case 'method': 115 | $result = array( 116 | 0 => t('Manual upload'), 117 | 'git' => t('GIT repository tags'), 118 | 'svn' => t('SVN repository tags folder'), 119 | ); 120 | break; 121 | case 'patch': 122 | $result = range(0, 50); 123 | break; 124 | case 'recommended': 125 | $result = array(t('Not recommended'), t('Recommended')); 126 | break; 127 | case 'security': 128 | $result = array(t('Not a security release'), t('Security release')); 129 | break; 130 | case 'type': 131 | // We don't use t() here as the update XML requires these strings to be uniform. 132 | $result = array( 133 | // 'core' => 'Drupal project', 134 | 'profile' => 'Installation profiles', 135 | 'module' => 'Modules', 136 | 'theme' => 'Themes', 137 | // 'theme engine' => 'Theme engines', 138 | // 'translation' => 'Translations', 139 | ); 140 | break; 141 | case 'extratype': 142 | // We don't use t() here as the update XML requires these strings to be uniform. 143 | $result = array( 144 | FSERVER_EXTRATYPE_RELEASE => '- None -', 145 | FSERVER_EXTRATYPE_RC => 'rc', 146 | FSERVER_EXTRATYPE_BETA => 'beta', 147 | FSERVER_EXTRATYPE_ALPHA => 'alpha', 148 | FSERVER_EXTRATYPE_UNSTABLE => 'unstable', 149 | FSERVER_EXTRATYPE_OTHER => 'other', 150 | ); 151 | break; 152 | case 'extranum': 153 | $extranum = range(0, 50); 154 | unset($extranum[0]); 155 | $result = $extranum; 156 | break; 157 | } 158 | 159 | drupal_alter('fserver_cck_options', $result, $type); 160 | 161 | return $result; 162 | } 163 | 164 | /** 165 | * Parse a package name into values: core, major, patch and extra. 166 | */ 167 | function fserver_parse_package_name($package_filename) { 168 | // example: fserver-6.x-2.0-rc3.tar.gz 169 | if (preg_match('/^(?\w+)-(?\d+\.x)-(?\d+)\.(?\d+)-?(?\w+)?\.(tar\.gz|tgz)$/', $package_filename, $matches)) { 170 | if (!empty($matches['extra']) && preg_match('/^(?P[A-Za-z]+)(?P\d+)?$/', $matches['extra'], $extra_matches)) { 171 | $matches = array_merge($matches, array_intersect_key($extra_matches, array('extratype' => '', 'extranum' => ''))); 172 | } 173 | return $matches; 174 | }; 175 | return array(); 176 | } 177 | 178 | /** 179 | * Parse a tag name into values: core, major, patch and extra, extra type and extra num. 180 | * 181 | * Supports CVS style drupal tags (drupal-6--1-0-alpha1) as well as git style tags (7.x-1.0-alpha1). 182 | */ 183 | function fserver_parse_tag_name($tag) { 184 | 185 | $regex = (stripos($tag, 'drupal-') === 0) 186 | ? '/^(?P\w+)-(?P\d+)--(?P\d+)-(?P\d+)-?(?P\w+)?$/' 187 | : '/^(?P\d+)\.x-(?P\d+)\.(?P\d+)-?(?P\w+)?$/'; 188 | 189 | if (preg_match($regex, $tag, $matches)) { 190 | $parsed = array_intersect_key($matches, array('core' => '', 'major' => '', 'patch' => '', 'extra' => '')); 191 | if (!empty($parsed)) { 192 | $parsed['original'] = $tag; 193 | $parsed['core'] = "{$parsed['core']}.x"; 194 | $parsed['version'] = "{$parsed['core']}-{$parsed['major']}.{$parsed['patch']}" . (!empty($parsed['extra']) ? "-{$parsed['extra']}" : ''); 195 | if (!empty($parsed['extra']) && preg_match('/^(?P[A-Za-z]+)(?P\d+)?$/', $parsed['extra'], $extra_matches)) { 196 | $parsed = array_merge($parsed, array_intersect_key($extra_matches, array('extratype' => '', 'extranum' => ''))); 197 | } 198 | return $parsed; 199 | } 200 | } 201 | 202 | return array(); 203 | } 204 | 205 | /** 206 | * Implementation of hook_form_alter() for fserver_project_node_form. 207 | */ 208 | function fserver_form_fserver_project_node_form_alter(&$form, $form_state) { 209 | drupal_add_js(drupal_get_path('module', 'fserver') . '/fserver.js'); 210 | $form['#validate'][] = 'fserver_project_node_form_validate'; 211 | } 212 | 213 | /** 214 | * Validate handler for fserver_project_node_form. 215 | */ 216 | function fserver_project_node_form_validate($form, &$form_state) { 217 | // Ensure repository URL is set if using a non-manual method. 218 | if (!empty($form_state['values']['field_fserver_method'][0]['value']) && empty($form_state['values']['field_fserver_repository'][0]['value'])) { 219 | form_set_error($form_state['values']['field_fserver_repository'][0]['_error_element'], t('Please provide a valid repository URL for this project.')); 220 | } 221 | } 222 | 223 | /** 224 | * Implementation of hook_form_alter() for fserver_release_node_form. 225 | */ 226 | function fserver_form_fserver_release_node_form_alter(&$form, $form_state) { 227 | drupal_add_css(drupal_get_path('module', 'fserver') . '/fserver.css'); 228 | $form['title'] = array( 229 | '#type' => 'value', 230 | '#value' => 'VOID', 231 | ); 232 | $form['#submit'][] = 'fserver_release_node_form_submit'; 233 | } 234 | 235 | /** 236 | * Submit handler for fserver_release_node_form. 237 | */ 238 | function fserver_release_node_form_submit($form, &$form_state) { 239 | // Only do something, if the user clicked the preview button. 240 | if (isset($form_state['clicked_button']['#submit']) && in_array('node_form_build_preview', $form_state['clicked_button']['#submit'])) { 241 | $node = node_submit($form_state['values']); 242 | $node->title = fserver_generate_version($node); 243 | $form_state['values'] = (array) $node; 244 | } 245 | } 246 | 247 | /** 248 | * Generate a standard version string from a node object. 249 | * @TODO: Merge this or make use of it in fserver_handler_field_release_tag::render(). 250 | */ 251 | function fserver_generate_version($node, $raw = FALSE) { 252 | $project = node_load($node->field_fserver_project[0]['nid']); 253 | $core = $node->field_fserver_api[0]['value']; 254 | $major = $node->field_fserver_versionmajor[0]['value']; 255 | $patch = $node->field_fserver_versionpatch[0]['value']; 256 | $extra = $node->field_fserver_versionextra[0]['value']; 257 | $version = "{$core}-{$major}.{$patch}" . (!empty($extra) ? "-{$extra}" : ''); 258 | return $raw ? $version : "{$project->title} $version"; 259 | } 260 | -------------------------------------------------------------------------------- /fserver.strongarm.inc: -------------------------------------------------------------------------------- 1 | disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ 10 | $strongarm->api_version = 1; 11 | $strongarm->name = 'content_extra_weights_fserver_project'; 12 | $strongarm->value = array( 13 | 'title' => '-5', 14 | 'body_field' => '8', 15 | 'revision_information' => '10', 16 | 'menu' => '0', 17 | 'book' => '9', 18 | 'attachments' => '13', 19 | ); 20 | 21 | $export['content_extra_weights_fserver_project'] = $strongarm; 22 | $strongarm = new stdClass; 23 | $strongarm->disabled = FALSE; /* Edit this to true to make a default strongarm disabled initially */ 24 | $strongarm->api_version = 1; 25 | $strongarm->name = 'content_extra_weights_fserver_release'; 26 | $strongarm->value = array( 27 | 'title' => '-3', 28 | 'body_field' => '-1', 29 | 'revision_information' => '1', 30 | 'author' => '0', 31 | 'options' => '2', 32 | 'menu' => '-2', 33 | 'path' => '3', 34 | ); 35 | 36 | $export['content_extra_weights_fserver_release'] = $strongarm; 37 | return $export; 38 | } 39 | -------------------------------------------------------------------------------- /fserver.views.inc: -------------------------------------------------------------------------------- 1 | 'views', 9 | 'style' => array( 10 | 'updatexml' => array( 11 | 'title' => t('Update XML'), 12 | 'help' => t('Generates a project XML feed compatible with the update module.'), 13 | 'handler' => 'fserver_plugin_style_updatexml', 14 | 'theme' => 'fserver_updatexml', 15 | 'theme path' => drupal_get_path('module', 'fserver') .'/views', 16 | 'path' => drupal_get_path('module', 'fserver') .'/views', 17 | 'uses row plugin' => FALSE, 18 | 'uses fields' => TRUE, 19 | 'uses options' => TRUE, 20 | 'type' => 'feed', 21 | ), 22 | ), 23 | ); 24 | } 25 | 26 | /** 27 | * Implementation of hook_views_plugins(). 28 | */ 29 | function fserver_views_data() { 30 | $data = array(); 31 | 32 | // MD5 hash 33 | $data['files']['mdhash'] = array( 34 | 'real field' => 'filepath', 35 | 'title' => t('MD5 hash'), 36 | 'help' => t('Provides an MD5 hash of the file.'), 37 | 'field' => array( 38 | 'handler' => 'fserver_handler_field_mdhash', 39 | ), 40 | ); 41 | 42 | // Release tag (Content group) 43 | $data['views']['release_tag'] = array( 44 | 'group' => t('Content'), 45 | 'title' => t('Release tag'), 46 | 'help' => t('Formatted release tag [Core].x-[Major].[Patch][-Extra]'), 47 | 'field' => array( 48 | 'handler' => 'fserver_handler_field_release_tag', 49 | 'click sortable' => TRUE, 50 | 'title' => t('Release'), 51 | ), 52 | 'sort' => array( 53 | 'handler' => 'fserver_handler_sort_release_tag', 54 | ), 55 | ); 56 | 57 | return $data; 58 | } 59 | 60 | /** 61 | * Implementation of hook_views_handlers(). 62 | */ 63 | function fserver_views_handlers() { 64 | return array( 65 | 'info' => array( 66 | 'path' => drupal_get_path('module', 'fserver') .'/views', 67 | ), 68 | 'handlers' => array( 69 | 'fserver_handler_field_mdhash' => array( 70 | 'parent' => 'views_handler_field', 71 | ), 72 | 'fserver_handler_field_release_tag' => array( 73 | 'parent' => 'views_handler_field', 74 | ), 75 | 'fserver_handler_sort_release_tag' => array( 76 | 'parent' => 'views_handler_sort', 77 | ), 78 | ), 79 | ); 80 | } 81 | -------------------------------------------------------------------------------- /fserver.views_default.inc: -------------------------------------------------------------------------------- 1 | name = 'fserver_projects'; 12 | $view->description = 'Feature Server > Projects'; 13 | $view->tag = 'fserver'; 14 | $view->view_php = ''; 15 | $view->base_table = 'node'; 16 | $view->is_cacheable = FALSE; 17 | $view->api_version = 2; 18 | $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ 19 | $handler = $view->new_display('default', 'Defaults', 'default'); 20 | $handler->override_option('fields', array( 21 | 'title' => array( 22 | 'label' => '', 23 | 'alter' => array( 24 | 'alter_text' => 0, 25 | 'text' => '', 26 | 'make_link' => 0, 27 | 'path' => '', 28 | 'link_class' => '', 29 | 'alt' => '', 30 | 'prefix' => '', 31 | 'suffix' => '', 32 | 'help' => '', 33 | 'trim' => 0, 34 | 'max_length' => '', 35 | 'word_boundary' => 1, 36 | 'ellipsis' => 1, 37 | 'strip_tags' => 0, 38 | 'html' => 0, 39 | ), 40 | 'link_to_node' => 1, 41 | 'exclude' => 0, 42 | 'id' => 'title', 43 | 'table' => 'node', 44 | 'field' => 'title', 45 | 'relationship' => 'none', 46 | ), 47 | 'teaser' => array( 48 | 'label' => '', 49 | 'alter' => array( 50 | 'alter_text' => 0, 51 | 'text' => '', 52 | 'make_link' => 0, 53 | 'path' => '', 54 | 'link_class' => '', 55 | 'alt' => '', 56 | 'prefix' => '', 57 | 'suffix' => '', 58 | 'help' => '', 59 | 'trim' => 1, 60 | 'max_length' => '100', 61 | 'word_boundary' => 1, 62 | 'ellipsis' => 1, 63 | 'strip_tags' => 1, 64 | 'html' => 0, 65 | ), 66 | 'exclude' => 0, 67 | 'id' => 'teaser', 68 | 'table' => 'node_revisions', 69 | 'field' => 'teaser', 70 | 'relationship' => 'none', 71 | ), 72 | )); 73 | $handler->override_option('sorts', array( 74 | 'title' => array( 75 | 'order' => 'ASC', 76 | 'id' => 'title', 77 | 'table' => 'node', 78 | 'field' => 'title', 79 | 'relationship' => 'none', 80 | ), 81 | )); 82 | $handler->override_option('filters', array( 83 | 'status' => array( 84 | 'operator' => '=', 85 | 'value' => '1', 86 | 'group' => '0', 87 | 'exposed' => FALSE, 88 | 'expose' => array( 89 | 'operator' => FALSE, 90 | 'label' => '', 91 | ), 92 | 'id' => 'status', 93 | 'table' => 'node', 94 | 'field' => 'status', 95 | 'relationship' => 'none', 96 | ), 97 | 'type' => array( 98 | 'operator' => 'in', 99 | 'value' => array( 100 | 'fserver_distro' => 'fserver_distro', 101 | 'fserver_project' => 'fserver_project', 102 | ), 103 | 'group' => '0', 104 | 'exposed' => FALSE, 105 | 'expose' => array( 106 | 'operator' => FALSE, 107 | 'label' => '', 108 | ), 109 | 'id' => 'type', 110 | 'table' => 'node', 111 | 'field' => 'type', 112 | 'relationship' => 'none', 113 | ), 114 | )); 115 | $handler->override_option('access', array( 116 | 'type' => 'none', 117 | )); 118 | $handler->override_option('cache', array( 119 | 'type' => 'none', 120 | )); 121 | $handler->override_option('title', 'Projects and distributions'); 122 | $handler->override_option('empty', 'There are currently no projects or distributions available.'); 123 | $handler->override_option('items_per_page', 20); 124 | $handler->override_option('use_pager', '1'); 125 | $handler->override_option('style_plugin', 'grid'); 126 | $handler->override_option('style_options', array( 127 | 'grouping' => '', 128 | 'columns' => '2', 129 | 'alignment' => 'vertical', 130 | )); 131 | $handler = $view->new_display('page', 'Page', 'page_1'); 132 | $handler->override_option('path', 'fserver'); 133 | $handler->override_option('menu', array( 134 | 'type' => 'normal', 135 | 'title' => 'Projects', 136 | 'description' => '', 137 | 'weight' => '0', 138 | 'name' => 'features', 139 | )); 140 | $handler->override_option('tab_options', array( 141 | 'type' => 'none', 142 | 'title' => '', 143 | 'description' => '', 144 | 'weight' => 0, 145 | 'name' => 'navigation', 146 | )); 147 | 148 | $views[$view->name] = $view; 149 | 150 | // Exported view: fserver_release_lookup 151 | $view = new view; 152 | $view->name = 'fserver_release_lookup'; 153 | $view->description = ''; 154 | $view->tag = 'fserver'; 155 | $view->view_php = ''; 156 | $view->base_table = 'node'; 157 | $view->is_cacheable = FALSE; 158 | $view->api_version = 2; 159 | $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ 160 | $handler = $view->new_display('default', 'Defaults', 'default'); 161 | $handler->override_option('fields', array( 162 | 'nid' => array( 163 | 'label' => '', 164 | 'alter' => array( 165 | 'alter_text' => 0, 166 | 'text' => '', 167 | 'make_link' => 0, 168 | 'path' => '', 169 | 'link_class' => '', 170 | 'alt' => '', 171 | 'prefix' => '', 172 | 'suffix' => '', 173 | 'target' => '', 174 | 'help' => '', 175 | 'trim' => 0, 176 | 'max_length' => '', 177 | 'word_boundary' => 1, 178 | 'ellipsis' => 1, 179 | 'strip_tags' => 0, 180 | 'html' => 0, 181 | ), 182 | 'empty' => '', 183 | 'hide_empty' => 0, 184 | 'empty_zero' => 0, 185 | 'link_to_node' => 0, 186 | 'exclude' => 0, 187 | 'id' => 'nid', 188 | 'table' => 'node', 189 | 'field' => 'nid', 190 | 'relationship' => 'none', 191 | ), 192 | )); 193 | $handler->override_option('arguments', array( 194 | 'field_fserver_project_nid' => array( 195 | 'default_action' => 'not found', 196 | 'style_plugin' => 'default_summary', 197 | 'style_options' => array(), 198 | 'wildcard' => 'all', 199 | 'wildcard_substitution' => 'All', 200 | 'title' => '', 201 | 'breadcrumb' => '', 202 | 'default_argument_type' => 'fixed', 203 | 'default_argument' => '', 204 | 'validate_type' => 'none', 205 | 'validate_fail' => 'not found', 206 | 'break_phrase' => 0, 207 | 'not' => 0, 208 | 'id' => 'field_fserver_project_nid', 209 | 'table' => 'node_data_field_fserver_project', 210 | 'field' => 'field_fserver_project_nid', 211 | 'validate_user_argument_type' => 'uid', 212 | 'validate_user_roles' => array( 213 | '2' => 0, 214 | ), 215 | 'relationship' => 'none', 216 | 'default_options_div_prefix' => '', 217 | 'default_argument_user' => 0, 218 | 'default_argument_fixed' => '', 219 | 'default_argument_php' => '', 220 | 'validate_argument_node_type' => array( 221 | 'feed' => 0, 222 | 'feed_item' => 0, 223 | 'fserver_project' => 0, 224 | 'fserver_release' => 0, 225 | 'fserver_distro' => 0, 226 | 'page' => 0, 227 | 'story' => 0, 228 | ), 229 | 'validate_argument_node_access' => 0, 230 | 'validate_argument_nid_type' => 'nid', 231 | 'validate_argument_vocabulary' => array(), 232 | 'validate_argument_type' => 'tid', 233 | 'validate_argument_transform' => 0, 234 | 'validate_user_restrict_roles' => 0, 235 | 'validate_argument_php' => '', 236 | ), 237 | 'field_fserver_api_value' => array( 238 | 'default_action' => 'ignore', 239 | 'style_plugin' => 'default_summary', 240 | 'style_options' => array(), 241 | 'wildcard' => 'all', 242 | 'wildcard_substitution' => 'All', 243 | 'title' => '', 244 | 'breadcrumb' => '', 245 | 'default_argument_type' => 'fixed', 246 | 'default_argument' => '', 247 | 'validate_type' => 'none', 248 | 'validate_fail' => 'not found', 249 | 'add_table' => 0, 250 | 'require_value' => 0, 251 | 'reduce_duplicates' => 0, 252 | 'id' => 'field_fserver_api_value', 253 | 'table' => 'node_data_field_fserver_api', 254 | 'field' => 'field_fserver_api_value', 255 | 'validate_user_argument_type' => 'uid', 256 | 'validate_user_roles' => array( 257 | '2' => 0, 258 | ), 259 | 'relationship' => 'none', 260 | 'default_options_div_prefix' => '', 261 | 'default_argument_user' => 0, 262 | 'default_argument_fixed' => '', 263 | 'default_argument_php' => '', 264 | 'validate_argument_node_type' => array( 265 | 'fserver_project' => 0, 266 | 'fserver_release' => 0, 267 | 'fserver_distro' => 0, 268 | 'page' => 0, 269 | 'story' => 0, 270 | ), 271 | 'validate_argument_node_access' => 0, 272 | 'validate_argument_nid_type' => 'nid', 273 | 'validate_argument_vocabulary' => array(), 274 | 'validate_argument_type' => 'tid', 275 | 'validate_argument_transform' => 0, 276 | 'validate_user_restrict_roles' => 0, 277 | 'validate_argument_php' => '', 278 | ), 279 | 'field_fserver_versionextra_value' => array( 280 | 'default_action' => 'ignore', 281 | 'style_plugin' => 'default_summary', 282 | 'style_options' => array(), 283 | 'wildcard' => 'all', 284 | 'wildcard_substitution' => 'All', 285 | 'title' => '', 286 | 'breadcrumb' => '', 287 | 'default_argument_type' => 'fixed', 288 | 'default_argument' => '', 289 | 'validate_type' => 'none', 290 | 'validate_fail' => 'not found', 291 | 'glossary' => 0, 292 | 'limit' => '0', 293 | 'case' => 'none', 294 | 'path_case' => 'none', 295 | 'transform_dash' => 0, 296 | 'id' => 'field_fserver_versionextra_value', 297 | 'table' => 'node_data_field_fserver_versionextra', 298 | 'field' => 'field_fserver_versionextra_value', 299 | 'validate_user_argument_type' => 'uid', 300 | 'validate_user_roles' => array( 301 | '2' => 0, 302 | ), 303 | 'relationship' => 'none', 304 | 'default_options_div_prefix' => '', 305 | 'default_argument_user' => 0, 306 | 'default_argument_fixed' => '', 307 | 'default_argument_php' => '', 308 | 'validate_argument_node_type' => array( 309 | 'fserver_project' => 0, 310 | 'fserver_release' => 0, 311 | 'fserver_distro' => 0, 312 | 'page' => 0, 313 | 'story' => 0, 314 | ), 315 | 'validate_argument_node_access' => 0, 316 | 'validate_argument_nid_type' => 'nid', 317 | 'validate_argument_vocabulary' => array(), 318 | 'validate_argument_type' => 'tid', 319 | 'validate_argument_transform' => 0, 320 | 'validate_user_restrict_roles' => 0, 321 | 'validate_argument_php' => '', 322 | ), 323 | )); 324 | $handler->override_option('filters', array( 325 | 'status' => array( 326 | 'operator' => '=', 327 | 'value' => '1', 328 | 'group' => '0', 329 | 'exposed' => FALSE, 330 | 'expose' => array( 331 | 'operator' => FALSE, 332 | 'label' => '', 333 | ), 334 | 'id' => 'status', 335 | 'table' => 'node', 336 | 'field' => 'status', 337 | 'relationship' => 'none', 338 | ), 339 | 'type' => array( 340 | 'operator' => 'in', 341 | 'value' => array( 342 | 'fserver_release' => 'fserver_release', 343 | ), 344 | 'group' => '0', 345 | 'exposed' => FALSE, 346 | 'expose' => array( 347 | 'operator' => FALSE, 348 | 'label' => '', 349 | ), 350 | 'id' => 'type', 351 | 'table' => 'node', 352 | 'field' => 'type', 353 | 'relationship' => 'none', 354 | ), 355 | )); 356 | $handler->override_option('access', array( 357 | 'type' => 'none', 358 | )); 359 | $handler->override_option('cache', array( 360 | 'type' => 'none', 361 | )); 362 | $handler->override_option('items_per_page', 0); 363 | 364 | $views[$view->name] = $view; 365 | 366 | // Exported view: fserver_releases 367 | $view = new view; 368 | $view->name = 'fserver_releases'; 369 | $view->description = 'Feature Server > Releases'; 370 | $view->tag = 'fserver'; 371 | $view->view_php = ''; 372 | $view->base_table = 'node'; 373 | $view->is_cacheable = FALSE; 374 | $view->api_version = 2; 375 | $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ 376 | $handler = $view->new_display('default', 'Defaults', 'default'); 377 | $handler->override_option('relationships', array( 378 | 'field_fserver_file_fid' => array( 379 | 'label' => 'Package', 380 | 'required' => 1, 381 | 'delta' => -1, 382 | 'id' => 'field_fserver_file_fid', 383 | 'table' => 'node_data_field_fserver_file', 384 | 'field' => 'field_fserver_file_fid', 385 | 'relationship' => 'none', 386 | ), 387 | )); 388 | $handler->override_option('fields', array( 389 | 'nid' => array( 390 | 'label' => 'Nid', 391 | 'alter' => array( 392 | 'alter_text' => 0, 393 | 'text' => '', 394 | 'make_link' => 0, 395 | 'path' => '', 396 | 'link_class' => '', 397 | 'alt' => '', 398 | 'prefix' => '', 399 | 'suffix' => '', 400 | 'help' => '', 401 | 'trim' => 0, 402 | 'max_length' => '', 403 | 'word_boundary' => 1, 404 | 'ellipsis' => 1, 405 | 'strip_tags' => 0, 406 | 'html' => 0, 407 | ), 408 | 'link_to_node' => 0, 409 | 'exclude' => 1, 410 | 'id' => 'nid', 411 | 'table' => 'node', 412 | 'field' => 'nid', 413 | 'override' => array( 414 | 'button' => 'Override', 415 | ), 416 | 'relationship' => 'none', 417 | ), 418 | 'release_tag' => array( 419 | 'label' => 'Release', 420 | 'alter' => array( 421 | 'alter_text' => 0, 422 | 'text' => '', 423 | 'make_link' => 1, 424 | 'path' => 'node/[nid]', 425 | 'link_class' => '', 426 | 'alt' => '', 427 | 'prefix' => '', 428 | 'suffix' => '', 429 | 'help' => '', 430 | 'trim' => 0, 431 | 'max_length' => '', 432 | 'word_boundary' => 1, 433 | 'ellipsis' => 1, 434 | 'strip_tags' => 0, 435 | 'html' => 0, 436 | ), 437 | 'exclude' => 0, 438 | 'id' => 'release_tag', 439 | 'table' => 'views', 440 | 'field' => 'release_tag', 441 | 'override' => array( 442 | 'button' => 'Override', 443 | ), 444 | 'relationship' => 'none', 445 | ), 446 | 'filesize' => array( 447 | 'label' => '', 448 | 'alter' => array( 449 | 'alter_text' => 0, 450 | 'text' => '', 451 | 'make_link' => 0, 452 | 'path' => '', 453 | 'link_class' => '', 454 | 'alt' => '', 455 | 'prefix' => '', 456 | 'suffix' => '', 457 | 'help' => '', 458 | 'trim' => 0, 459 | 'max_length' => '', 460 | 'word_boundary' => 1, 461 | 'ellipsis' => 1, 462 | 'strip_tags' => 0, 463 | 'html' => 0, 464 | ), 465 | 'file_size_display' => 'formatted', 466 | 'exclude' => 1, 467 | 'id' => 'filesize', 468 | 'table' => 'files', 469 | 'field' => 'filesize', 470 | 'relationship' => 'field_fserver_file_fid', 471 | ), 472 | 'field_fserver_file_fid' => array( 473 | 'label' => 'Package', 474 | 'alter' => array( 475 | 'alter_text' => 1, 476 | 'text' => 'Download ([filesize])', 477 | 'make_link' => 0, 478 | 'path' => '', 479 | 'link_class' => '', 480 | 'alt' => '', 481 | 'prefix' => '', 482 | 'suffix' => '', 483 | 'help' => '', 484 | 'trim' => 0, 485 | 'max_length' => '', 486 | 'word_boundary' => 1, 487 | 'ellipsis' => 1, 488 | 'strip_tags' => 0, 489 | 'html' => 0, 490 | ), 491 | 'link_to_node' => 0, 492 | 'label_type' => 'widget', 493 | 'format' => 'url_plain', 494 | 'multiple' => array( 495 | 'group' => TRUE, 496 | 'multiple_number' => '', 497 | 'multiple_from' => '', 498 | 'multiple_reversed' => FALSE, 499 | ), 500 | 'exclude' => 0, 501 | 'id' => 'field_fserver_file_fid', 502 | 'table' => 'node_data_field_fserver_file', 503 | 'field' => 'field_fserver_file_fid', 504 | 'relationship' => 'none', 505 | 'override' => array( 506 | 'button' => 'Override', 507 | ), 508 | ), 509 | 'view_node' => array( 510 | 'label' => '', 511 | 'alter' => array( 512 | 'alter_text' => 0, 513 | 'text' => '', 514 | 'make_link' => 0, 515 | 'path' => '', 516 | 'link_class' => '', 517 | 'alt' => '', 518 | 'prefix' => '', 519 | 'suffix' => '', 520 | 'help' => '', 521 | 'trim' => 0, 522 | 'max_length' => '', 523 | 'word_boundary' => 1, 524 | 'ellipsis' => 1, 525 | 'strip_tags' => 0, 526 | 'html' => 0, 527 | ), 528 | 'text' => 'Release notes', 529 | 'exclude' => 0, 530 | 'id' => 'view_node', 531 | 'table' => 'node', 532 | 'field' => 'view_node', 533 | 'relationship' => 'none', 534 | 'override' => array( 535 | 'button' => 'Override', 536 | ), 537 | ), 538 | 'created' => array( 539 | 'label' => 'Date', 540 | 'alter' => array( 541 | 'alter_text' => 0, 542 | 'text' => '', 543 | 'make_link' => 0, 544 | 'path' => '', 545 | 'link_class' => '', 546 | 'alt' => '', 547 | 'prefix' => '', 548 | 'suffix' => '', 549 | 'help' => '', 550 | 'trim' => 0, 551 | 'max_length' => '', 552 | 'word_boundary' => 1, 553 | 'ellipsis' => 1, 554 | 'strip_tags' => 0, 555 | 'html' => 0, 556 | ), 557 | 'date_format' => 'custom', 558 | 'custom_date_format' => 'M j Y', 559 | 'exclude' => 0, 560 | 'id' => 'created', 561 | 'table' => 'node', 562 | 'field' => 'created', 563 | 'relationship' => 'none', 564 | ), 565 | 'field_fserver_api_value' => array( 566 | 'label' => 'Core compatibility', 567 | 'alter' => array( 568 | 'alter_text' => 0, 569 | 'text' => '', 570 | 'make_link' => 0, 571 | 'path' => '', 572 | 'link_class' => '', 573 | 'alt' => '', 574 | 'prefix' => '', 575 | 'suffix' => '', 576 | 'help' => '', 577 | 'trim' => 0, 578 | 'max_length' => '', 579 | 'word_boundary' => 1, 580 | 'ellipsis' => 1, 581 | 'strip_tags' => 0, 582 | 'html' => 0, 583 | ), 584 | 'link_to_node' => 0, 585 | 'label_type' => 'widget', 586 | 'format' => 'default', 587 | 'multiple' => array( 588 | 'group' => TRUE, 589 | 'multiple_number' => '', 590 | 'multiple_from' => '', 591 | 'multiple_reversed' => FALSE, 592 | ), 593 | 'exclude' => 1, 594 | 'id' => 'field_fserver_api_value', 595 | 'table' => 'node_data_field_fserver_api', 596 | 'field' => 'field_fserver_api_value', 597 | 'relationship' => 'none', 598 | ), 599 | )); 600 | $handler->override_option('sorts', array( 601 | 'release_tag' => array( 602 | 'order' => 'DESC', 603 | 'id' => 'release_tag', 604 | 'table' => 'views', 605 | 'field' => 'release_tag', 606 | 'relationship' => 'none', 607 | 'override' => array( 608 | 'button' => 'Override', 609 | ), 610 | ), 611 | )); 612 | $handler->override_option('arguments', array( 613 | 'field_fserver_project_nid' => array( 614 | 'default_action' => 'default', 615 | 'style_plugin' => 'default_summary', 616 | 'style_options' => array(), 617 | 'wildcard' => 'all', 618 | 'wildcard_substitution' => 'All', 619 | 'title' => '', 620 | 'breadcrumb' => '', 621 | 'default_argument_type' => 'node', 622 | 'default_argument' => '', 623 | 'validate_type' => 'none', 624 | 'validate_fail' => 'not found', 625 | 'break_phrase' => 0, 626 | 'not' => 0, 627 | 'id' => 'field_fserver_project_nid', 628 | 'table' => 'node_data_field_fserver_project', 629 | 'field' => 'field_fserver_project_nid', 630 | 'validate_user_argument_type' => 'uid', 631 | 'validate_user_roles' => array( 632 | '2' => 0, 633 | ), 634 | 'relationship' => 'none', 635 | 'default_options_div_prefix' => '', 636 | 'default_argument_user' => 0, 637 | 'default_argument_fixed' => '', 638 | 'default_argument_php' => '', 639 | 'validate_argument_node_type' => array( 640 | 'fserver_project' => 0, 641 | 'fserver_release' => 0, 642 | 'page' => 0, 643 | 'story' => 0, 644 | ), 645 | 'validate_argument_node_access' => 0, 646 | 'validate_argument_nid_type' => 'nid', 647 | 'validate_argument_vocabulary' => array(), 648 | 'validate_argument_type' => 'tid', 649 | 'validate_argument_transform' => 0, 650 | 'validate_user_restrict_roles' => 0, 651 | 'validate_argument_php' => '', 652 | 'override' => array( 653 | 'button' => 'Override', 654 | ), 655 | ), 656 | 'field_fserver_api_value' => array( 657 | 'default_action' => 'ignore', 658 | 'style_plugin' => 'default_summary', 659 | 'style_options' => array(), 660 | 'wildcard' => 'all', 661 | 'wildcard_substitution' => 'All', 662 | 'title' => '', 663 | 'breadcrumb' => '', 664 | 'default_argument_type' => 'fixed', 665 | 'default_argument' => '', 666 | 'validate_type' => 'none', 667 | 'validate_fail' => 'not found', 668 | 'add_table' => 0, 669 | 'require_value' => 0, 670 | 'reduce_duplicates' => 0, 671 | 'id' => 'field_fserver_api_value', 672 | 'table' => 'node_data_field_fserver_api', 673 | 'field' => 'field_fserver_api_value', 674 | 'validate_user_argument_type' => 'uid', 675 | 'validate_user_roles' => array( 676 | '2' => 0, 677 | ), 678 | 'override' => array( 679 | 'button' => 'Override', 680 | ), 681 | 'relationship' => 'none', 682 | 'default_options_div_prefix' => '', 683 | 'default_argument_user' => 0, 684 | 'default_argument_fixed' => '', 685 | 'default_argument_php' => '', 686 | 'validate_argument_node_type' => array( 687 | 'fserver_project' => 0, 688 | 'fserver_release' => 0, 689 | 'page' => 0, 690 | 'story' => 0, 691 | ), 692 | 'validate_argument_node_access' => 0, 693 | 'validate_argument_nid_type' => 'nid', 694 | 'validate_argument_vocabulary' => array(), 695 | 'validate_argument_type' => 'tid', 696 | 'validate_argument_transform' => 0, 697 | 'validate_user_restrict_roles' => 0, 698 | 'validate_argument_php' => '', 699 | ), 700 | )); 701 | $handler->override_option('filters', array( 702 | 'status' => array( 703 | 'operator' => '=', 704 | 'value' => '1', 705 | 'group' => '0', 706 | 'exposed' => FALSE, 707 | 'expose' => array( 708 | 'operator' => FALSE, 709 | 'label' => '', 710 | ), 711 | 'id' => 'status', 712 | 'table' => 'node', 713 | 'field' => 'status', 714 | 'relationship' => 'none', 715 | ), 716 | 'type' => array( 717 | 'operator' => 'in', 718 | 'value' => array( 719 | 'fserver_release' => 'fserver_release', 720 | ), 721 | 'group' => '0', 722 | 'exposed' => FALSE, 723 | 'expose' => array( 724 | 'operator' => FALSE, 725 | 'label' => '', 726 | ), 727 | 'id' => 'type', 728 | 'table' => 'node', 729 | 'field' => 'type', 730 | 'relationship' => 'none', 731 | ), 732 | )); 733 | $handler->override_option('access', array( 734 | 'type' => 'none', 735 | )); 736 | $handler->override_option('cache', array( 737 | 'type' => 'none', 738 | )); 739 | $handler->override_option('items_per_page', 25); 740 | $handler->override_option('use_pager', '1'); 741 | $handler->override_option('style_plugin', 'table'); 742 | $handler->override_option('style_options', array( 743 | 'grouping' => '', 744 | 'override' => 1, 745 | 'sticky' => 0, 746 | 'order' => 'asc', 747 | 'columns' => array( 748 | 'title' => 'title', 749 | 'filesize' => 'field_fserver_file_fid', 750 | 'field_fserver_file_fid' => 'field_fserver_file_fid', 751 | 'view_node' => 'view_node', 752 | 'created' => 'created', 753 | 'field_fserver_api_value' => 'field_fserver_api_value', 754 | ), 755 | 'info' => array( 756 | 'title' => array( 757 | 'sortable' => 0, 758 | 'separator' => '', 759 | ), 760 | 'filesize' => array( 761 | 'sortable' => 0, 762 | 'separator' => '', 763 | ), 764 | 'field_fserver_file_fid' => array( 765 | 'separator' => '', 766 | ), 767 | 'view_node' => array( 768 | 'separator' => '', 769 | ), 770 | 'created' => array( 771 | 'sortable' => 0, 772 | 'separator' => '', 773 | ), 774 | 'field_fserver_api_value' => array( 775 | 'sortable' => 0, 776 | 'separator' => '', 777 | ), 778 | ), 779 | 'default' => '-1', 780 | )); 781 | $handler = $view->new_display('block', 'Recommended releases', 'block_1'); 782 | $handler->override_option('filters', array( 783 | 'status' => array( 784 | 'operator' => '=', 785 | 'value' => '1', 786 | 'group' => '0', 787 | 'exposed' => FALSE, 788 | 'expose' => array( 789 | 'operator' => FALSE, 790 | 'label' => '', 791 | ), 792 | 'id' => 'status', 793 | 'table' => 'node', 794 | 'field' => 'status', 795 | 'relationship' => 'none', 796 | ), 797 | 'type' => array( 798 | 'operator' => 'in', 799 | 'value' => array( 800 | 'fserver_release' => 'fserver_release', 801 | ), 802 | 'group' => '0', 803 | 'exposed' => FALSE, 804 | 'expose' => array( 805 | 'operator' => FALSE, 806 | 'label' => '', 807 | ), 808 | 'id' => 'type', 809 | 'table' => 'node', 810 | 'field' => 'type', 811 | 'relationship' => 'none', 812 | ), 813 | 'field_fserver_recommended_value_many_to_one' => array( 814 | 'operator' => 'or', 815 | 'value' => array( 816 | '1' => '1', 817 | ), 818 | 'group' => '0', 819 | 'exposed' => FALSE, 820 | 'expose' => array( 821 | 'operator' => FALSE, 822 | 'label' => '', 823 | ), 824 | 'id' => 'field_fserver_recommended_value_many_to_one', 825 | 'table' => 'node_data_field_fserver_recommended', 826 | 'field' => 'field_fserver_recommended_value_many_to_one', 827 | 'override' => array( 828 | 'button' => 'Use default', 829 | ), 830 | 'relationship' => 'none', 831 | 'reduce_duplicates' => 0, 832 | ), 833 | )); 834 | $handler->override_option('title', 'Releases'); 835 | $handler->override_option('items_per_page', 0); 836 | $handler->override_option('use_pager', '0'); 837 | $handler->override_option('block_description', ''); 838 | $handler->override_option('block_caching', -1); 839 | $handler = $view->new_display('page', 'All releases', 'page_1'); 840 | $handler->override_option('arguments', array( 841 | 'field_fserver_project_nid' => array( 842 | 'default_action' => 'default', 843 | 'style_plugin' => 'default_summary', 844 | 'style_options' => array(), 845 | 'wildcard' => 'all', 846 | 'wildcard_substitution' => 'All', 847 | 'title' => '%1', 848 | 'breadcrumb' => '', 849 | 'default_argument_type' => 'node', 850 | 'default_argument' => '', 851 | 'validate_type' => 'node', 852 | 'validate_fail' => 'not found', 853 | 'break_phrase' => 0, 854 | 'not' => 0, 855 | 'id' => 'field_fserver_project_nid', 856 | 'table' => 'node_data_field_fserver_project', 857 | 'field' => 'field_fserver_project_nid', 858 | 'validate_user_argument_type' => 'uid', 859 | 'validate_user_roles' => array( 860 | '2' => 0, 861 | ), 862 | 'relationship' => 'none', 863 | 'default_options_div_prefix' => '', 864 | 'default_argument_user' => 0, 865 | 'default_argument_fixed' => '', 866 | 'default_argument_php' => '', 867 | 'validate_argument_node_type' => array( 868 | 'fserver_distro' => 'fserver_distro', 869 | 'fserver_project' => 'fserver_project', 870 | 'fserver_release' => 0, 871 | 'page' => 0, 872 | 'story' => 0, 873 | ), 874 | 'validate_argument_node_access' => 0, 875 | 'validate_argument_nid_type' => 'nid', 876 | 'validate_argument_vocabulary' => array(), 877 | 'validate_argument_type' => 'tid', 878 | 'validate_argument_transform' => 0, 879 | 'validate_user_restrict_roles' => 0, 880 | 'validate_argument_php' => '', 881 | 'override' => array( 882 | 'button' => 'Use default', 883 | ), 884 | ), 885 | )); 886 | $handler->override_option('path', 'node/%/releases'); 887 | $handler->override_option('menu', array( 888 | 'type' => 'tab', 889 | 'title' => 'All releases', 890 | 'description' => '', 891 | 'weight' => '0', 892 | 'name' => 'navigation', 893 | )); 894 | $handler->override_option('tab_options', array( 895 | 'type' => 'none', 896 | 'title' => '', 897 | 'description' => '', 898 | 'weight' => 0, 899 | 'name' => 'navigation', 900 | )); 901 | 902 | $views[$view->name] = $view; 903 | 904 | // Exported view: fserver_updates 905 | $view = new view; 906 | $view->name = 'fserver_updates'; 907 | $view->description = 'Feature Server > Update feed'; 908 | $view->tag = 'fserver'; 909 | $view->view_php = ''; 910 | $view->base_table = 'node'; 911 | $view->is_cacheable = FALSE; 912 | $view->api_version = 2; 913 | $view->disabled = FALSE; /* Edit this to true to make a default view disabled initially */ 914 | $handler = $view->new_display('default', 'Defaults', 'default'); 915 | $handler->override_option('relationships', array( 916 | 'field_fserver_project_nid' => array( 917 | 'label' => 'Project', 918 | 'required' => 1, 919 | 'delta' => -1, 920 | 'id' => 'field_fserver_project_nid', 921 | 'table' => 'node_data_field_fserver_project', 922 | 'field' => 'field_fserver_project_nid', 923 | 'relationship' => 'none', 924 | ), 925 | 'field_fserver_file_fid' => array( 926 | 'label' => 'Package', 927 | 'required' => 1, 928 | 'delta' => -1, 929 | 'id' => 'field_fserver_file_fid', 930 | 'table' => 'node_data_field_fserver_file', 931 | 'field' => 'field_fserver_file_fid', 932 | 'relationship' => 'none', 933 | ), 934 | )); 935 | $handler->override_option('fields', array( 936 | 'field_fserver_api_value' => array( 937 | 'label' => 'API version', 938 | 'alter' => array( 939 | 'alter_text' => 0, 940 | 'text' => '', 941 | 'make_link' => 0, 942 | 'path' => '', 943 | 'link_class' => '', 944 | 'alt' => '', 945 | 'prefix' => '', 946 | 'suffix' => '', 947 | 'help' => '', 948 | 'trim' => 0, 949 | 'max_length' => '', 950 | 'word_boundary' => 1, 951 | 'ellipsis' => 1, 952 | 'strip_tags' => 0, 953 | 'html' => 0, 954 | ), 955 | 'link_to_node' => 0, 956 | 'label_type' => 'custom', 957 | 'format' => 'default', 958 | 'multiple' => array( 959 | 'group' => TRUE, 960 | 'multiple_number' => '', 961 | 'multiple_from' => '', 962 | 'multiple_reversed' => FALSE, 963 | ), 964 | 'exclude' => 0, 965 | 'id' => 'field_fserver_api_value', 966 | 'table' => 'node_data_field_fserver_api', 967 | 'field' => 'field_fserver_api_value', 968 | 'relationship' => 'none', 969 | ), 970 | 'field_fserver_versionextra_value' => array( 971 | 'label' => 'Extra version', 972 | 'alter' => array( 973 | 'alter_text' => 0, 974 | 'text' => '', 975 | 'make_link' => 0, 976 | 'path' => '', 977 | 'link_class' => '', 978 | 'alt' => '', 979 | 'prefix' => '', 980 | 'suffix' => '', 981 | 'help' => '', 982 | 'trim' => 0, 983 | 'max_length' => '', 984 | 'word_boundary' => 1, 985 | 'ellipsis' => 1, 986 | 'strip_tags' => 0, 987 | 'html' => 0, 988 | ), 989 | 'link_to_node' => 0, 990 | 'label_type' => 'widget', 991 | 'format' => 'default', 992 | 'multiple' => array( 993 | 'group' => TRUE, 994 | 'multiple_number' => '', 995 | 'multiple_from' => '', 996 | 'multiple_reversed' => FALSE, 997 | ), 998 | 'exclude' => 0, 999 | 'id' => 'field_fserver_versionextra_value', 1000 | 'table' => 'node_data_field_fserver_versionextra', 1001 | 'field' => 'field_fserver_versionextra_value', 1002 | 'relationship' => 'none', 1003 | ), 1004 | 'field_fserver_versionmajor_value' => array( 1005 | 'label' => 'Major version', 1006 | 'alter' => array( 1007 | 'alter_text' => 0, 1008 | 'text' => '', 1009 | 'make_link' => 0, 1010 | 'path' => '', 1011 | 'link_class' => '', 1012 | 'alt' => '', 1013 | 'prefix' => '', 1014 | 'suffix' => '', 1015 | 'help' => '', 1016 | 'trim' => 0, 1017 | 'max_length' => '', 1018 | 'word_boundary' => 1, 1019 | 'ellipsis' => 1, 1020 | 'strip_tags' => 0, 1021 | 'html' => 0, 1022 | ), 1023 | 'link_to_node' => 0, 1024 | 'label_type' => 'widget', 1025 | 'format' => 'default', 1026 | 'multiple' => array( 1027 | 'group' => TRUE, 1028 | 'multiple_number' => '', 1029 | 'multiple_from' => '', 1030 | 'multiple_reversed' => FALSE, 1031 | ), 1032 | 'exclude' => 0, 1033 | 'id' => 'field_fserver_versionmajor_value', 1034 | 'table' => 'node_data_field_fserver_versionmajor', 1035 | 'field' => 'field_fserver_versionmajor_value', 1036 | 'relationship' => 'none', 1037 | ), 1038 | 'field_fserver_versionpatch_value' => array( 1039 | 'label' => 'Patch version', 1040 | 'alter' => array( 1041 | 'alter_text' => 0, 1042 | 'text' => '', 1043 | 'make_link' => 0, 1044 | 'path' => '', 1045 | 'link_class' => '', 1046 | 'alt' => '', 1047 | 'prefix' => '', 1048 | 'suffix' => '', 1049 | 'help' => '', 1050 | 'trim' => 0, 1051 | 'max_length' => '', 1052 | 'word_boundary' => 1, 1053 | 'ellipsis' => 1, 1054 | 'strip_tags' => 0, 1055 | 'html' => 0, 1056 | ), 1057 | 'link_to_node' => 0, 1058 | 'label_type' => 'widget', 1059 | 'format' => 'default', 1060 | 'multiple' => array( 1061 | 'group' => TRUE, 1062 | 'multiple_number' => '', 1063 | 'multiple_from' => '', 1064 | 'multiple_reversed' => FALSE, 1065 | ), 1066 | 'exclude' => 0, 1067 | 'id' => 'field_fserver_versionpatch_value', 1068 | 'table' => 'node_data_field_fserver_versionpatch', 1069 | 'field' => 'field_fserver_versionpatch_value', 1070 | 'relationship' => 'none', 1071 | ), 1072 | 'created' => array( 1073 | 'label' => 'Post date', 1074 | 'alter' => array( 1075 | 'alter_text' => 0, 1076 | 'text' => '', 1077 | 'make_link' => 0, 1078 | 'path' => '', 1079 | 'link_class' => '', 1080 | 'alt' => '', 1081 | 'prefix' => '', 1082 | 'suffix' => '', 1083 | 'help' => '', 1084 | 'trim' => 0, 1085 | 'max_length' => '', 1086 | 'word_boundary' => 1, 1087 | 'ellipsis' => 1, 1088 | 'strip_tags' => 0, 1089 | 'html' => 0, 1090 | ), 1091 | 'date_format' => 'custom', 1092 | 'custom_date_format' => 'U', 1093 | 'exclude' => 0, 1094 | 'id' => 'created', 1095 | 'table' => 'node', 1096 | 'field' => 'created', 1097 | 'relationship' => 'none', 1098 | ), 1099 | 'title' => array( 1100 | 'label' => 'Project title', 1101 | 'alter' => array( 1102 | 'alter_text' => 0, 1103 | 'text' => '', 1104 | 'make_link' => 0, 1105 | 'path' => '', 1106 | 'link_class' => '', 1107 | 'alt' => '', 1108 | 'prefix' => '', 1109 | 'suffix' => '', 1110 | 'help' => '', 1111 | 'trim' => 0, 1112 | 'max_length' => '', 1113 | 'word_boundary' => 1, 1114 | 'ellipsis' => 1, 1115 | 'strip_tags' => 0, 1116 | 'html' => 0, 1117 | ), 1118 | 'link_to_node' => 0, 1119 | 'exclude' => 0, 1120 | 'id' => 'title', 1121 | 'table' => 'node', 1122 | 'field' => 'title', 1123 | 'relationship' => 'field_fserver_project_nid', 1124 | ), 1125 | 'field_fserver_name_value' => array( 1126 | 'label' => 'Project name', 1127 | 'alter' => array( 1128 | 'alter_text' => 0, 1129 | 'text' => '', 1130 | 'make_link' => 0, 1131 | 'path' => '', 1132 | 'link_class' => '', 1133 | 'alt' => '', 1134 | 'prefix' => '', 1135 | 'suffix' => '', 1136 | 'help' => '', 1137 | 'trim' => 0, 1138 | 'max_length' => '', 1139 | 'word_boundary' => 1, 1140 | 'ellipsis' => 1, 1141 | 'strip_tags' => 0, 1142 | 'html' => 0, 1143 | ), 1144 | 'link_to_node' => 0, 1145 | 'label_type' => 'widget', 1146 | 'format' => 'default', 1147 | 'multiple' => array( 1148 | 'group' => TRUE, 1149 | 'multiple_number' => '', 1150 | 'multiple_from' => '', 1151 | 'multiple_reversed' => FALSE, 1152 | ), 1153 | 'exclude' => 0, 1154 | 'id' => 'field_fserver_name_value', 1155 | 'table' => 'node_data_field_fserver_name', 1156 | 'field' => 'field_fserver_name_value', 1157 | 'relationship' => 'field_fserver_project_nid', 1158 | ), 1159 | 'nid' => array( 1160 | 'label' => 'Project URL', 1161 | 'alter' => array( 1162 | 'alter_text' => 1, 1163 | 'text' => 'node/[nid]', 1164 | 'make_link' => 0, 1165 | 'path' => '', 1166 | 'link_class' => '', 1167 | 'alt' => '', 1168 | 'prefix' => '', 1169 | 'suffix' => '', 1170 | 'help' => '', 1171 | 'trim' => 0, 1172 | 'max_length' => '', 1173 | 'word_boundary' => 1, 1174 | 'ellipsis' => 1, 1175 | 'strip_tags' => 0, 1176 | 'html' => 0, 1177 | ), 1178 | 'link_to_node' => 0, 1179 | 'exclude' => 0, 1180 | 'id' => 'nid', 1181 | 'table' => 'node', 1182 | 'field' => 'nid', 1183 | 'relationship' => 'field_fserver_project_nid', 1184 | ), 1185 | 'filepath' => array( 1186 | 'label' => 'File path', 1187 | 'alter' => array( 1188 | 'alter_text' => 0, 1189 | 'text' => '', 1190 | 'make_link' => 0, 1191 | 'path' => '', 1192 | 'link_class' => '', 1193 | 'alt' => '', 1194 | 'prefix' => '', 1195 | 'suffix' => '', 1196 | 'help' => '', 1197 | 'trim' => 0, 1198 | 'max_length' => '', 1199 | 'word_boundary' => 1, 1200 | 'ellipsis' => 1, 1201 | 'strip_tags' => 0, 1202 | 'html' => 0, 1203 | ), 1204 | 'link_to_file' => 0, 1205 | 'exclude' => 0, 1206 | 'id' => 'filepath', 1207 | 'table' => 'files', 1208 | 'field' => 'filepath', 1209 | 'relationship' => 'field_fserver_file_fid', 1210 | ), 1211 | 'filesize' => array( 1212 | 'label' => 'Filesize', 1213 | 'alter' => array( 1214 | 'alter_text' => 0, 1215 | 'text' => '', 1216 | 'make_link' => 0, 1217 | 'path' => '', 1218 | 'link_class' => '', 1219 | 'alt' => '', 1220 | 'prefix' => '', 1221 | 'suffix' => '', 1222 | 'help' => '', 1223 | 'trim' => 0, 1224 | 'max_length' => '', 1225 | 'word_boundary' => 1, 1226 | 'ellipsis' => 1, 1227 | 'strip_tags' => 0, 1228 | 'html' => 0, 1229 | ), 1230 | 'file_size_display' => 'bytes', 1231 | 'exclude' => 0, 1232 | 'id' => 'filesize', 1233 | 'table' => 'files', 1234 | 'field' => 'filesize', 1235 | 'relationship' => 'field_fserver_file_fid', 1236 | ), 1237 | 'nid_1' => array( 1238 | 'label' => 'Release URL', 1239 | 'alter' => array( 1240 | 'alter_text' => 1, 1241 | 'text' => 'node/[nid_1]', 1242 | 'make_link' => 0, 1243 | 'path' => '', 1244 | 'link_class' => '', 1245 | 'alt' => '', 1246 | 'prefix' => '', 1247 | 'suffix' => '', 1248 | 'help' => '', 1249 | 'trim' => 0, 1250 | 'max_length' => '', 1251 | 'word_boundary' => 1, 1252 | 'ellipsis' => 1, 1253 | 'strip_tags' => 0, 1254 | 'html' => 0, 1255 | ), 1256 | 'link_to_node' => 0, 1257 | 'exclude' => 0, 1258 | 'id' => 'nid_1', 1259 | 'table' => 'node', 1260 | 'field' => 'nid', 1261 | 'relationship' => 'none', 1262 | ), 1263 | 'mdhash' => array( 1264 | 'label' => 'MD5 hash', 1265 | 'alter' => array( 1266 | 'alter_text' => FALSE, 1267 | 'text' => '', 1268 | 'make_link' => FALSE, 1269 | 'path' => '', 1270 | 'alt' => '', 1271 | 'link_class' => '', 1272 | 'prefix' => '', 1273 | 'suffix' => '', 1274 | 'trim' => FALSE, 1275 | 'max_length' => '', 1276 | 'word_boundary' => TRUE, 1277 | 'ellipsis' => TRUE, 1278 | 'strip_tags' => FALSE, 1279 | 'html' => FALSE, 1280 | ), 1281 | 'exclude' => 0, 1282 | 'id' => 'mdhash', 1283 | 'table' => 'files', 1284 | 'field' => 'mdhash', 1285 | 'relationship' => 'field_fserver_file_fid', 1286 | ), 1287 | 'field_fserver_security_value' => array( 1288 | 'label' => 'Security release', 1289 | 'alter' => array( 1290 | 'alter_text' => 0, 1291 | 'text' => '', 1292 | 'make_link' => 0, 1293 | 'path' => '', 1294 | 'link_class' => '', 1295 | 'alt' => '', 1296 | 'prefix' => '', 1297 | 'suffix' => '', 1298 | 'help' => '', 1299 | 'trim' => 0, 1300 | 'max_length' => '', 1301 | 'word_boundary' => 1, 1302 | 'ellipsis' => 1, 1303 | 'strip_tags' => 0, 1304 | 'html' => 0, 1305 | ), 1306 | 'link_to_node' => 0, 1307 | 'label_type' => 'widget', 1308 | 'format' => 'default', 1309 | 'multiple' => array( 1310 | 'group' => TRUE, 1311 | 'multiple_number' => '', 1312 | 'multiple_from' => '', 1313 | 'multiple_reversed' => FALSE, 1314 | ), 1315 | 'exclude' => 0, 1316 | 'id' => 'field_fserver_security_value', 1317 | 'table' => 'node_data_field_fserver_security', 1318 | 'field' => 'field_fserver_security_value', 1319 | 'relationship' => 'none', 1320 | ), 1321 | 'field_fserver_recommended_value' => array( 1322 | 'label' => 'Recommended', 1323 | 'alter' => array( 1324 | 'alter_text' => 0, 1325 | 'text' => '', 1326 | 'make_link' => 0, 1327 | 'path' => '', 1328 | 'link_class' => '', 1329 | 'alt' => '', 1330 | 'prefix' => '', 1331 | 'suffix' => '', 1332 | 'help' => '', 1333 | 'trim' => 0, 1334 | 'max_length' => '', 1335 | 'word_boundary' => 1, 1336 | 'ellipsis' => 1, 1337 | 'strip_tags' => 0, 1338 | 'html' => 0, 1339 | ), 1340 | 'link_to_node' => 0, 1341 | 'label_type' => 'widget', 1342 | 'format' => 'default', 1343 | 'multiple' => array( 1344 | 'group' => TRUE, 1345 | 'multiple_number' => '', 1346 | 'multiple_from' => '', 1347 | 'multiple_reversed' => FALSE, 1348 | ), 1349 | 'exclude' => 0, 1350 | 'id' => 'field_fserver_recommended_value', 1351 | 'table' => 'node_data_field_fserver_recommended', 1352 | 'field' => 'field_fserver_recommended_value', 1353 | 'relationship' => 'none', 1354 | ), 1355 | 'field_fserver_type_value' => array( 1356 | 'label' => 'Type', 1357 | 'alter' => array( 1358 | 'alter_text' => 0, 1359 | 'text' => '', 1360 | 'make_link' => 0, 1361 | 'path' => '', 1362 | 'link_class' => '', 1363 | 'alt' => '', 1364 | 'prefix' => '', 1365 | 'suffix' => '', 1366 | 'help' => '', 1367 | 'trim' => 0, 1368 | 'max_length' => '', 1369 | 'word_boundary' => 1, 1370 | 'ellipsis' => 1, 1371 | 'strip_tags' => 0, 1372 | 'html' => 0, 1373 | ), 1374 | 'link_to_node' => 0, 1375 | 'label_type' => 'widget', 1376 | 'format' => 'plain', 1377 | 'multiple' => array( 1378 | 'group' => TRUE, 1379 | 'multiple_number' => '', 1380 | 'multiple_from' => '', 1381 | 'multiple_reversed' => FALSE, 1382 | ), 1383 | 'exclude' => 0, 1384 | 'id' => 'field_fserver_type_value', 1385 | 'table' => 'node_data_field_fserver_type', 1386 | 'field' => 'field_fserver_type_value', 1387 | 'relationship' => 'field_fserver_project_nid', 1388 | ), 1389 | 'field_fserver_redirect_value' => array( 1390 | 'label' => 'Type', 1391 | 'alter' => array( 1392 | 'alter_text' => 0, 1393 | 'text' => '', 1394 | 'make_link' => 0, 1395 | 'path' => '', 1396 | 'link_class' => '', 1397 | 'alt' => '', 1398 | 'prefix' => '', 1399 | 'suffix' => '', 1400 | 'help' => '', 1401 | 'trim' => 0, 1402 | 'max_length' => '', 1403 | 'word_boundary' => 1, 1404 | 'ellipsis' => 1, 1405 | 'strip_tags' => 0, 1406 | 'html' => 0, 1407 | ), 1408 | 'link_to_node' => 0, 1409 | 'label_type' => 'widget', 1410 | 'format' => 'plain', 1411 | 'multiple' => array( 1412 | 'group' => TRUE, 1413 | 'multiple_number' => '', 1414 | 'multiple_from' => '', 1415 | 'multiple_reversed' => FALSE, 1416 | ), 1417 | 'exclude' => 0, 1418 | 'id' => 'field_fserver_redirect_value', 1419 | 'table' => 'node_data_field_fserver_redirect', 1420 | 'field' => 'field_fserver_redirect_value', 1421 | 'relationship' => 'field_fserver_project_nid', 1422 | ), 1423 | 'field_fserver_method_value' => array( 1424 | 'label' => 'Packaging method', 1425 | 'alter' => array( 1426 | 'alter_text' => 0, 1427 | 'text' => '', 1428 | 'make_link' => 0, 1429 | 'path' => '', 1430 | 'link_class' => '', 1431 | 'alt' => '', 1432 | 'prefix' => '', 1433 | 'suffix' => '', 1434 | 'target' => '', 1435 | 'help' => '', 1436 | 'trim' => 0, 1437 | 'max_length' => '', 1438 | 'word_boundary' => 1, 1439 | 'ellipsis' => 1, 1440 | 'html' => 0, 1441 | 'strip_tags' => 0, 1442 | ), 1443 | 'empty' => '', 1444 | 'hide_empty' => 0, 1445 | 'empty_zero' => 0, 1446 | 'link_to_node' => 0, 1447 | 'label_type' => 'widget', 1448 | 'format' => 'default', 1449 | 'multiple' => array( 1450 | 'group' => TRUE, 1451 | 'multiple_number' => '', 1452 | 'multiple_from' => '', 1453 | 'multiple_reversed' => FALSE, 1454 | ), 1455 | 'exclude' => 0, 1456 | 'id' => 'field_fserver_method_value', 1457 | 'table' => 'node_data_field_fserver_method', 1458 | 'field' => 'field_fserver_method_value', 1459 | 'relationship' => 'field_fserver_project_nid', 1460 | ), 1461 | 'field_fserver_repository_value' => array( 1462 | 'label' => 'Repository URL', 1463 | 'alter' => array( 1464 | 'alter_text' => 0, 1465 | 'text' => '', 1466 | 'make_link' => 0, 1467 | 'path' => '', 1468 | 'link_class' => '', 1469 | 'alt' => '', 1470 | 'prefix' => '', 1471 | 'suffix' => '', 1472 | 'target' => '', 1473 | 'help' => '', 1474 | 'trim' => 0, 1475 | 'max_length' => '', 1476 | 'word_boundary' => 1, 1477 | 'ellipsis' => 1, 1478 | 'html' => 0, 1479 | 'strip_tags' => 0, 1480 | ), 1481 | 'empty' => '', 1482 | 'hide_empty' => 0, 1483 | 'empty_zero' => 0, 1484 | 'link_to_node' => 0, 1485 | 'label_type' => 'widget', 1486 | 'format' => 'default', 1487 | 'multiple' => array( 1488 | 'group' => TRUE, 1489 | 'multiple_number' => '', 1490 | 'multiple_from' => '', 1491 | 'multiple_reversed' => FALSE, 1492 | ), 1493 | 'exclude' => 0, 1494 | 'id' => 'field_fserver_repository_value', 1495 | 'table' => 'node_data_field_fserver_repository', 1496 | 'field' => 'field_fserver_repository_value', 1497 | 'relationship' => 'field_fserver_project_nid', 1498 | ), 1499 | )); 1500 | $handler->override_option('sorts', array( 1501 | 'release_tag' => array( 1502 | 'order' => 'DESC', 1503 | 'id' => 'release_tag', 1504 | 'table' => 'views', 1505 | 'field' => 'release_tag', 1506 | 'relationship' => 'none', 1507 | ), 1508 | 'status' => array( 1509 | 'order' => 'DESC', 1510 | 'id' => 'status', 1511 | 'table' => 'node', 1512 | 'field' => 'status', 1513 | 'override' => array( 1514 | 'button' => 'Override', 1515 | ), 1516 | 'relationship' => 'none', 1517 | ), 1518 | )); 1519 | $handler->override_option('arguments', array( 1520 | 'field_fserver_name_value' => array( 1521 | 'default_action' => 'not found', 1522 | 'style_plugin' => 'default_summary', 1523 | 'style_options' => array(), 1524 | 'wildcard' => 'all', 1525 | 'wildcard_substitution' => 'All', 1526 | 'title' => '', 1527 | 'breadcrumb' => '', 1528 | 'default_argument_type' => 'fixed', 1529 | 'default_argument' => '', 1530 | 'validate_type' => 'none', 1531 | 'validate_fail' => 'not found', 1532 | 'glossary' => 0, 1533 | 'limit' => '0', 1534 | 'case' => 'none', 1535 | 'path_case' => 'none', 1536 | 'transform_dash' => 0, 1537 | 'id' => 'field_fserver_name_value', 1538 | 'table' => 'node_data_field_fserver_name', 1539 | 'field' => 'field_fserver_name_value', 1540 | 'validate_user_argument_type' => 'uid', 1541 | 'validate_user_roles' => array( 1542 | '2' => 0, 1543 | ), 1544 | 'relationship' => 'field_fserver_project_nid', 1545 | 'default_options_div_prefix' => '', 1546 | 'default_argument_user' => 0, 1547 | 'default_argument_fixed' => '', 1548 | 'default_argument_php' => '', 1549 | 'validate_argument_node_type' => array( 1550 | 'fserver_project' => 0, 1551 | 'fserver_release' => 0, 1552 | 'image' => 0, 1553 | ), 1554 | 'validate_argument_node_access' => 0, 1555 | 'validate_argument_nid_type' => 'nid', 1556 | 'validate_argument_vocabulary' => array(), 1557 | 'validate_argument_type' => 'tid', 1558 | 'validate_argument_transform' => 0, 1559 | 'validate_user_restrict_roles' => 0, 1560 | 'validate_argument_php' => '', 1561 | ), 1562 | 'field_fserver_api_value' => array( 1563 | 'default_action' => 'not found', 1564 | 'style_plugin' => 'default_summary', 1565 | 'style_options' => array(), 1566 | 'wildcard' => 'all', 1567 | 'wildcard_substitution' => 'All', 1568 | 'title' => '', 1569 | 'breadcrumb' => '', 1570 | 'default_argument_type' => 'fixed', 1571 | 'default_argument' => '', 1572 | 'validate_type' => 'none', 1573 | 'validate_fail' => 'not found', 1574 | 'add_table' => 0, 1575 | 'require_value' => 0, 1576 | 'reduce_duplicates' => 0, 1577 | 'id' => 'field_fserver_api_value', 1578 | 'table' => 'node_data_field_fserver_api', 1579 | 'field' => 'field_fserver_api_value', 1580 | 'validate_user_argument_type' => 'uid', 1581 | 'validate_user_roles' => array( 1582 | '2' => 0, 1583 | ), 1584 | 'relationship' => 'none', 1585 | 'default_options_div_prefix' => '', 1586 | 'default_argument_user' => 0, 1587 | 'default_argument_fixed' => '', 1588 | 'default_argument_php' => '', 1589 | 'validate_argument_node_type' => array( 1590 | 'fserver_project' => 0, 1591 | 'fserver_release' => 0, 1592 | 'image' => 0, 1593 | ), 1594 | 'validate_argument_node_access' => 0, 1595 | 'validate_argument_nid_type' => 'nid', 1596 | 'validate_argument_vocabulary' => array(), 1597 | 'validate_argument_type' => 'tid', 1598 | 'validate_argument_transform' => 0, 1599 | 'validate_user_restrict_roles' => 0, 1600 | 'validate_argument_php' => '', 1601 | ), 1602 | )); 1603 | $handler->override_option('filters', array( 1604 | 'status' => array( 1605 | 'operator' => '=', 1606 | 'value' => '1', 1607 | 'group' => '0', 1608 | 'exposed' => FALSE, 1609 | 'expose' => array( 1610 | 'operator' => FALSE, 1611 | 'label' => '', 1612 | ), 1613 | 'id' => 'status', 1614 | 'table' => 'node', 1615 | 'field' => 'status', 1616 | 'relationship' => 'none', 1617 | ), 1618 | 'type' => array( 1619 | 'operator' => 'in', 1620 | 'value' => array( 1621 | 'fserver_release' => 'fserver_release', 1622 | ), 1623 | 'group' => '0', 1624 | 'exposed' => FALSE, 1625 | 'expose' => array( 1626 | 'operator' => FALSE, 1627 | 'label' => '', 1628 | ), 1629 | 'id' => 'type', 1630 | 'table' => 'node', 1631 | 'field' => 'type', 1632 | 'relationship' => 'none', 1633 | ), 1634 | )); 1635 | $handler->override_option('access', array( 1636 | 'type' => 'none', 1637 | )); 1638 | $handler->override_option('cache', array( 1639 | 'type' => 'none', 1640 | )); 1641 | $handler->override_option('items_per_page', 0); 1642 | $handler->override_option('style_options', array( 1643 | 'grouping' => '', 1644 | )); 1645 | $handler = $view->new_display('feed', 'Update XML feed', 'feed_1'); 1646 | $handler->override_option('style_plugin', 'updatexml'); 1647 | $handler->override_option('style_options', array( 1648 | 'mission_description' => FALSE, 1649 | 'description' => '', 1650 | 'project' => array( 1651 | 'title' => 'title', 1652 | 'short_name' => 'field_fserver_name_value', 1653 | 'api_version' => 'field_fserver_api_value', 1654 | 'link' => 'nid', 1655 | 'type' => 'field_fserver_type_value', 1656 | 'redirect' => 'field_fserver_redirect_value', 1657 | 'sourcecode_type' => 'field_fserver_method_value', 1658 | 'sourcecode_uri' => 'field_fserver_repository_value', 1659 | ), 1660 | 'release' => array( 1661 | 'version_major' => 'field_fserver_versionmajor_value', 1662 | 'version_patch' => 'field_fserver_versionpatch_value', 1663 | 'version_extra' => 'field_fserver_versionextra_value', 1664 | 'release_link' => 'nid_1', 1665 | 'download_link' => 'filepath', 1666 | 'date' => 'created', 1667 | 'mdhash' => 'mdhash', 1668 | 'filesize' => 'filesize', 1669 | 'security' => 'field_fserver_security_value', 1670 | 'recommended' => 'field_fserver_recommended_value', 1671 | ), 1672 | )); 1673 | $handler->override_option('row_plugin', ''); 1674 | $handler->override_option('path', 'fserver/%/%'); 1675 | $handler->override_option('menu', array( 1676 | 'type' => 'none', 1677 | 'title' => '', 1678 | 'description' => '', 1679 | 'weight' => 0, 1680 | 'name' => 'navigation', 1681 | )); 1682 | $handler->override_option('tab_options', array( 1683 | 'type' => 'none', 1684 | 'title' => '', 1685 | 'description' => '', 1686 | 'weight' => 0, 1687 | 'name' => 'navigation', 1688 | )); 1689 | $handler->override_option('displays', array()); 1690 | $handler->override_option('sitename_title', FALSE); 1691 | 1692 | $views[$view->name] = $view; 1693 | 1694 | return $views; 1695 | } 1696 | -------------------------------------------------------------------------------- /tests/fserver.test: -------------------------------------------------------------------------------- 1 | t('Feature Server tests'), 13 | 'description' => t('Run tests for the Feature Server.') , 14 | 'group' => t('Feature Server'), 15 | ); 16 | } 17 | 18 | /** 19 | * Run test of tag parsing. 20 | */ 21 | public function testTagParsing() { 22 | module_load_include('module', 'fserver'); 23 | 24 | // Test Drupal CVS style tags 25 | $tag = 'DRUPAL-6--1-0-random66'; 26 | $params = array('@tag' => $tag); 27 | $parsed = fserver_parse_tag_name($tag); 28 | $this->pass(print_r($parsed, TRUE)); 29 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 30 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 31 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 32 | $this->assertEqual('random66', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 33 | $this->assertEqual('random', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 34 | $this->assertEqual(66, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 35 | $this->assertEqual('6.x-1.0-random66', $parsed['version'], t('Version is correct for @tag', $params)); 36 | 37 | $tag = 'DRUPAL-6--1-0-unstable'; 38 | $params = array('@tag' => $tag); 39 | $parsed = fserver_parse_tag_name($tag); 40 | $this->pass(print_r($parsed, TRUE)); 41 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 42 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 43 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 44 | $this->assertEqual('unstable', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 45 | $this->assertEqual('unstable', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 46 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @tag', $params)); 47 | $this->assertEqual('6.x-1.0-unstable', $parsed['version'], t('Version is correct for @tag', $params)); 48 | 49 | $tag = 'DRUPAL-7--4-3-alpha4'; 50 | $params = array('@tag' => $tag); 51 | $parsed = fserver_parse_tag_name($tag); 52 | $this->pass(print_r($parsed, TRUE)); 53 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 54 | $this->assertEqual('4', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 55 | $this->assertEqual('3', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 56 | $this->assertEqual('alpha4', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 57 | $this->assertEqual('alpha', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 58 | $this->assertEqual(4, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 59 | $this->assertEqual('7.x-4.3-alpha4', $parsed['version'], t('Version is correct for @tag', $params)); 60 | 61 | $tag = 'DRUPAL-7--2-0-beta18'; 62 | $params = array('@tag' => $tag); 63 | $parsed = fserver_parse_tag_name($tag); 64 | $this->pass(print_r($parsed, TRUE)); 65 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 66 | $this->assertEqual('2', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 67 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 68 | $this->assertEqual('beta18', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 69 | $this->assertEqual('beta', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 70 | $this->assertEqual(18, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 71 | $this->assertEqual('7.x-2.0-beta18', $parsed['version'], t('Version is correct for @tag', $params)); 72 | 73 | $tag = 'drupal-8--30-230-rc1111'; 74 | $params = array('@tag' => $tag); 75 | $parsed = fserver_parse_tag_name($tag); 76 | $this->pass(print_r($parsed, TRUE)); 77 | $this->assertEqual('8.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 78 | $this->assertEqual('30', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 79 | $this->assertEqual('230', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 80 | $this->assertEqual('rc1111', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 81 | $this->assertEqual('rc', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 82 | $this->assertEqual(1111, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 83 | $this->assertEqual('8.x-30.230-rc1111', $parsed['version'], t('Version is correct for @tag', $params)); 84 | 85 | $tag = 'DRUPAL-6--1-0'; 86 | $params = array('@tag' => $tag); 87 | $parsed = fserver_parse_tag_name($tag); 88 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 89 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 90 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 91 | $this->assertTrue(empty($parsed['extra']), t('Version extra is empty for @tag', $params)); 92 | $this->assertFalse(isset($parsed['extratype']), t('Version extra type is NULL for @tag', $params)); 93 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @tag', $params)); 94 | $this->assertEqual('6.x-1.0', $parsed['version'], t('Version is correct for @tag', $params)); 95 | 96 | // Test Drupal git style tags 97 | $tag = '6.x-1.0-random66'; 98 | $params = array('@tag' => $tag); 99 | $parsed = fserver_parse_tag_name($tag); 100 | $this->pass(print_r($parsed, TRUE)); 101 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 102 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 103 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 104 | $this->assertEqual('random66', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 105 | $this->assertEqual('random', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 106 | $this->assertEqual(66, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 107 | $this->assertEqual('6.x-1.0-random66', $parsed['version'], t('Version is correct for @tag', $params)); 108 | 109 | $tag = '6.x-1.0-unstable'; 110 | $params = array('@tag' => $tag); 111 | $parsed = fserver_parse_tag_name($tag); 112 | $this->pass(print_r($parsed, TRUE)); 113 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 114 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 115 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 116 | $this->assertEqual('unstable', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 117 | $this->assertEqual('unstable', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 118 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @tag', $params)); 119 | $this->assertEqual('6.x-1.0-unstable', $parsed['version'], t('Version is correct for @tag', $params)); 120 | 121 | $tag = '7.x-4.3-alpha4'; 122 | $params = array('@tag' => $tag); 123 | $parsed = fserver_parse_tag_name($tag); 124 | $this->pass(print_r($parsed, TRUE)); 125 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 126 | $this->assertEqual('4', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 127 | $this->assertEqual('3', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 128 | $this->assertEqual('alpha4', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 129 | $this->assertEqual('alpha', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 130 | $this->assertEqual(4, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 131 | $this->assertEqual('7.x-4.3-alpha4', $parsed['version'], t('Version is correct for @tag', $params)); 132 | 133 | $tag = '7.x-2.0-beta18'; 134 | $params = array('@tag' => $tag); 135 | $parsed = fserver_parse_tag_name($tag); 136 | $this->pass(print_r($parsed, TRUE)); 137 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 138 | $this->assertEqual('2', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 139 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 140 | $this->assertEqual('beta18', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 141 | $this->assertEqual('beta', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 142 | $this->assertEqual(18, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 143 | $this->assertEqual('7.x-2.0-beta18', $parsed['version'], t('Version is correct for @tag', $params)); 144 | 145 | $tag = '8.x-30.230-rc1111'; 146 | $params = array('@tag' => $tag); 147 | $parsed = fserver_parse_tag_name($tag); 148 | $this->pass(print_r($parsed, TRUE)); 149 | $this->assertEqual('8.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 150 | $this->assertEqual('30', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 151 | $this->assertEqual('230', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 152 | $this->assertEqual('rc1111', $parsed['extra'], t('Version extra parsed correctly for @tag', $params)); 153 | $this->assertEqual('rc', $parsed['extratype'], t('Version extra type set correctly for @tag', $params)); 154 | $this->assertEqual(1111, $parsed['extranum'], t('Version extra num set correctly for @tag', $params)); 155 | $this->assertEqual('8.x-30.230-rc1111', $parsed['version'], t('Version is correct for @tag', $params)); 156 | 157 | $tag = '6.x-1.0'; 158 | $params = array('@tag' => $tag); 159 | $parsed = fserver_parse_tag_name($tag); 160 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @tag', $params)); 161 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @tag', $params)); 162 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @tag', $params)); 163 | $this->assertTrue(empty($parsed['extra']), t('Version extra is empty for @tag', $params)); 164 | $this->assertFalse(isset($parsed['extratype']), t('Version extra type is NULL for @tag', $params)); 165 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @tag', $params)); 166 | $this->assertEqual('6.x-1.0', $parsed['version'], t('Version is correct for @tag', $params)); 167 | 168 | $tag = $this->randomString(25); 169 | $params = array('@tag' => $tag); 170 | $parsed = fserver_parse_tag_name($tag); 171 | $this->assertTrue(empty($parsed), t('Bad tag @tag was not parsed', $params)); 172 | } 173 | 174 | /** 175 | * Run test of tag parsing. 176 | */ 177 | public function testPackageParsing() { 178 | module_load_include('module', 'fserver'); 179 | 180 | // Test Drupal CVS style tags 181 | $package = 'fserver-6.x-1.0-random66.tar.gz'; 182 | $params = array('@package' => $package); 183 | $parsed = fserver_parse_package_name($package); 184 | $this->pass(print_r($parsed, TRUE)); 185 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 186 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @package', $params)); 187 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 188 | $this->assertEqual('random66', $parsed['extra'], t('Version extra parsed correctly for @package', $params)); 189 | $this->assertEqual('random', $parsed['extratype'], t('Version extra type set correctly for @package', $params)); 190 | $this->assertEqual(66, $parsed['extranum'], t('Version extra num set correctly for @package', $params)); 191 | 192 | $package = 'fserver-6.x-1.0-unstable.tgz'; 193 | $params = array('@package' => $package); 194 | $parsed = fserver_parse_package_name($package); 195 | $this->pass(print_r($parsed, TRUE)); 196 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 197 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @package', $params)); 198 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 199 | $this->assertEqual('unstable', $parsed['extra'], t('Version extra parsed correctly for @package', $params)); 200 | $this->assertEqual('unstable', $parsed['extratype'], t('Version extra type set correctly for @package', $params)); 201 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @package', $params)); 202 | 203 | $package = 'fserver-7.x-4.3-alpha4.tar.gz'; 204 | $params = array('@package' => $package); 205 | $parsed = fserver_parse_package_name($package); 206 | $this->pass(print_r($parsed, TRUE)); 207 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 208 | $this->assertEqual('4', $parsed['major'], t('Major version parsed correctly for @package', $params)); 209 | $this->assertEqual('3', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 210 | $this->assertEqual('alpha4', $parsed['extra'], t('Version extra parsed correctly for @package', $params)); 211 | $this->assertEqual('alpha', $parsed['extratype'], t('Version extra type set correctly for @package', $params)); 212 | $this->assertEqual(4, $parsed['extranum'], t('Version extra num set correctly for @package', $params)); 213 | 214 | $package = 'fserver-7.x-2.0-beta18.tgz'; 215 | $params = array('@package' => $package); 216 | $parsed = fserver_parse_package_name($package); 217 | $this->pass(print_r($parsed, TRUE)); 218 | $this->assertEqual('7.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 219 | $this->assertEqual('2', $parsed['major'], t('Major version parsed correctly for @package', $params)); 220 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 221 | $this->assertEqual('beta18', $parsed['extra'], t('Version extra parsed correctly for @package', $params)); 222 | $this->assertEqual('beta', $parsed['extratype'], t('Version extra type set correctly for @package', $params)); 223 | $this->assertEqual(18, $parsed['extranum'], t('Version extra num set correctly for @package', $params)); 224 | 225 | $package = 'drupal-8.x-30.230-rc1111.tar.gz'; 226 | $params = array('@package' => $package); 227 | $parsed = fserver_parse_package_name($package); 228 | $this->pass(print_r($parsed, TRUE)); 229 | $this->assertEqual('8.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 230 | $this->assertEqual('30', $parsed['major'], t('Major version parsed correctly for @package', $params)); 231 | $this->assertEqual('230', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 232 | $this->assertEqual('rc1111', $parsed['extra'], t('Version extra parsed correctly for @package', $params)); 233 | $this->assertEqual('rc', $parsed['extratype'], t('Version extra type set correctly for @package', $params)); 234 | $this->assertEqual(1111, $parsed['extranum'], t('Version extra num set correctly for @package', $params)); 235 | 236 | $package = 'fserver-6.x-1.0.tar.gz'; 237 | $params = array('@package' => $package); 238 | $parsed = fserver_parse_package_name($package); 239 | $this->assertEqual('6.x', $parsed['core'], t('Core version parsed correctly for @package', $params)); 240 | $this->assertEqual('1', $parsed['major'], t('Major version parsed correctly for @package', $params)); 241 | $this->assertEqual('0', $parsed['patch'], t('Patch version parsed correctly for @package', $params)); 242 | $this->assertTrue(empty($parsed['extra']), t('Version extra is empty for @package', $params)); 243 | $this->assertFalse(isset($parsed['extratype']), t('Version extra type is NULL for @package', $params)); 244 | $this->assertFalse(isset($parsed['extranum']), t('Version extra num is NULL for @package', $params)); 245 | 246 | $package = 'fserver-6.x-1.0.zip'; 247 | $params = array('@package' => $package); 248 | $parsed = fserver_parse_package_name($package); 249 | $this->assertTrue(empty($parsed), t('Zip was not parsed for @package', $params)); 250 | } 251 | } -------------------------------------------------------------------------------- /views/fserver-updatexml.tpl.php: -------------------------------------------------------------------------------- 1 | " ?> 2 | 3 | 4 | 5 | <?php print $project['title'] ?> 6 | 7 | 8 | 9 | 10 | 11 | 1 12 | 13 | 14 | 15 | Projects 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | published 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | Release type 40 | Security update 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | -------------------------------------------------------------------------------- /views/fserver_handler_field_mdhash.inc: -------------------------------------------------------------------------------- 1 | {$this->field_alias}; 8 | if (file_exists($filepath)) { 9 | $contents = file_get_contents($filepath); 10 | return md5($contents); 11 | } 12 | } 13 | } 14 | -------------------------------------------------------------------------------- /views/fserver_handler_field_release_tag.inc: -------------------------------------------------------------------------------- 1 | add_additional_fields(); 11 | } 12 | 13 | function construct() { 14 | parent::construct(); 15 | $fields = array( 16 | 0 => array('alias'=> 'core', 'field_name' => 'field_fserver_api'), 17 | 1 => array('alias'=> 'major', 'field_name' => 'field_fserver_versionmajor'), 18 | 2 => array('alias'=> 'patch', 'field_name' => 'field_fserver_versionpatch'), 19 | 3 => array('alias'=> 'extra', 'field_name' => 'field_fserver_versionextra'), 20 | ); 21 | 22 | foreach ($fields as $field) { 23 | $alias = $field['alias']; 24 | $table = content_views_tablename($field); 25 | $column = $field['field_name'] .'_value'; 26 | 27 | $this->additional_fields[$alias] = array('table' => $table, 'field' => $column); 28 | } 29 | } 30 | 31 | function render($values) { 32 | $core = check_plain($values->{$this->aliases['core']}); 33 | $major = check_plain($values->{$this->aliases['major']}); 34 | $patch = check_plain($values->{$this->aliases['patch']}); 35 | $extra = check_plain($values->{$this->aliases['extra']}); 36 | 37 | $release = "$core-$major.$patch" . (!empty($extra) ? "-$extra" : ''); 38 | return $release; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /views/fserver_handler_sort_release_tag.inc: -------------------------------------------------------------------------------- 1 | query->ensure_table($table, $this->relationship); 14 | 15 | // Order by: 16 | // 1. API version (e.g. 6.x before 5.x). 17 | // 2. no_extra pseudo-field (e.g. 2.0 before 2.0-beta1). 18 | // 3. versionmajor (2.x before 1.x). 19 | // 4. versionpatch (2.1 before 2.0). 20 | // 5. versionextra stuff (2.1-beta1 before 2.1-alpha1). 21 | 22 | // 1. API. 23 | $this->query->add_orderby($table_alias, 'field_fserver_api_value', $this->options['order']); 24 | 25 | // 2. 26 | $this->query->add_field(NULL, "IF ({$table}.field_fserver_versionextra_value IS NULL, 1, 0)", "{$table}_no_extra"); 27 | $this->query->add_orderby(NULL, NULL, $this->options['order'], "{$table}_no_extra"); 28 | 29 | // 3-5. 30 | $fields = array( 31 | array('field_name' => 'field_fserver_versionmajor'), 32 | array('field_name' => 'field_fserver_versionpatch'), 33 | array('field_name' => 'field_fserver_versionextratype'), 34 | array('field_name' => 'field_fserver_versionextranum'), 35 | ); 36 | foreach ($fields as $field) { 37 | $column = $field['field_name'] .'_value'; 38 | $this->query->add_orderby($table_alias, $column, $this->options['order']); 39 | } 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /views/fserver_plugin_style_updatexml.inc: -------------------------------------------------------------------------------- 1 | project_elements() as $element) { 26 | $project_defaults[$element] = ''; 27 | } 28 | $options['project'] = array('default' => $project_defaults); 29 | 30 | $release_defaults = array(); 31 | foreach ($this->release_elements() as $element) { 32 | $release_defaults[$element] = ''; 33 | } 34 | $options['release'] = array('default' => $release_defaults); 35 | 36 | return $options; 37 | } 38 | 39 | /** 40 | * Render the given style. 41 | */ 42 | function options_form(&$form, &$form_state) { 43 | // Build list of valid fields 44 | $options = array(); 45 | $handlers = $this->display->handler->get_handlers('field'); 46 | foreach ($handlers as $field => $handler) { 47 | if (empty($handler->options['exclude'])) { 48 | $options[$field] = $handler->label(); 49 | } 50 | } 51 | 52 | $form['project'] = array( 53 | '#tree' => TRUE, 54 | '#type' => 'fieldset', 55 | '#title' => t('Project fields'), 56 | ); 57 | foreach ($this->project_elements() as $element) { 58 | $form['project'][$element] = array( 59 | '#title' => $element, 60 | '#type' => 'select', 61 | '#options' => $options, 62 | '#default_value' => $this->options['project'][$element], 63 | ); 64 | } 65 | 66 | $form['release'] = array( 67 | '#tree' => TRUE, 68 | '#type' => 'fieldset', 69 | '#title' => t('Release fields'), 70 | ); 71 | foreach ($this->release_elements() as $element) { 72 | $form['release'][$element] = array( 73 | '#title' => $element, 74 | '#type' => 'select', 75 | '#options' => $options, 76 | '#default_value' => $this->options['release'][$element], 77 | ); 78 | } 79 | } 80 | 81 | /** 82 | * Theme preprocessor. 83 | */ 84 | function preprocess(&$vars) { 85 | $fields = $vars['view']->field; 86 | 87 | // Build project XML values 88 | $project = array(); 89 | foreach ($vars['options']['project'] as $element => $field) { 90 | $alias = $fields[$field]->field_alias; 91 | foreach ($vars['rows'] as $row) { 92 | if (isset($row->{$alias})) { 93 | $project[$element] = $fields[$field]->theme($row); 94 | continue; 95 | } 96 | } 97 | } 98 | // @TODO: need to correct the api version in project tag, if we have multiple api versions 99 | // we need the key "all" instead of 5.x / 6.x / 7.x /... 100 | 101 | // If this is a legacy project and has a redirect URL use it immediately. 102 | if (!empty($project['redirect'])) { 103 | $redirect = $project['redirect']; 104 | $redirect .= !empty($vars['view']->args) ? '/'. implode('/', $vars['view']->args) : ''; 105 | drupal_goto($redirect); 106 | } 107 | 108 | // Additional formatting for some values 109 | if (isset($project['link'])) { 110 | $project['link'] = url($project['link'], array('absolute' => TRUE)); 111 | } 112 | 113 | // Build release XML values 114 | $releases = array(); 115 | $project['recommended_major'] = ''; 116 | $project['supported_majors'] = array(); 117 | 118 | // Helper array for detecting multiple API Versions... (not the best way?) 119 | $multiple_api_versions = array(); 120 | 121 | foreach ($vars['rows'] as $num => $row) { 122 | foreach ($vars['options']['release'] as $element => $field) { 123 | $alias = $fields[$field]->field_alias; 124 | if (isset($row->{$alias})) { 125 | switch ($element) { 126 | // Don't mess with certain fields, period. 127 | case 'recommended': 128 | case 'security': 129 | case 'version_major': 130 | case 'version_patch': 131 | case 'version_extra': 132 | $releases[$num][$element] = check_plain($row->{$alias}); 133 | break; 134 | default: 135 | $releases[$num][$element] = $fields[$field]->theme($row); 136 | break; 137 | } 138 | } 139 | } 140 | 141 | // manual mapping from project api field to release api field 142 | $project_api_version_mapping = $fields[$vars['options']['project']['api_version']]->field_alias; 143 | if(isset($row->{$project_api_version_mapping})) { 144 | $releases[$num]['api_version'] = $fields[$vars['options']['project']['api_version']]->theme($row); 145 | // add current version to helper array... 146 | $multiple_api_versions[$releases[$num]['api_version']] = $releases[$num]['api_version']; 147 | } 148 | 149 | if ($releases[$num]['recommended']) { 150 | // Use the first major version for the project major. 151 | // The list is sorted by "major desc", this way the latest branch will be 152 | // recommended and all other branches (which have a recommended release) 153 | // will be tagged as supported. 154 | if (empty($project['recommended_major'])) { 155 | $project['recommended_major'] = $releases[$num]['version_major']; 156 | } 157 | $project['supported_majors'][$releases[$num]['version_major']] = $releases[$num]['version_major']; 158 | } 159 | 160 | // Version 161 | $releases[$num]['version'] = "{$releases[$num]['api_version']}-{$releases[$num]['version_major']}.{$releases[$num]['version_patch']}"; 162 | if (!empty($releases[$num]['version_extra'])) { 163 | $releases[$num]['version'] .= "-{$releases[$num]['version_extra']}"; 164 | } 165 | 166 | // Name 167 | $releases[$num]['name'] = "{$project['short_name']} {$releases[$num]['version']}"; 168 | 169 | // Release link 170 | $releases[$num]['release_link'] = url($releases[$num]['release_link'], array('absolute' => TRUE)); 171 | 172 | // Download link 173 | $releases[$num]['download_link'] = file_create_url($releases[$num]['download_link']); 174 | } 175 | 176 | sort($project['supported_majors']); 177 | $project['supported_majors'] = implode(",", $project['supported_majors']); 178 | 179 | // overwrite projects api version if we have multiple versions to "all" 180 | if (count($multiple_api_versions) > 1) { 181 | $project['api_version'] = 'all'; 182 | } 183 | 184 | // Finalize 185 | $vars['project'] = $project; 186 | $vars['releases'] = $releases; 187 | drupal_set_header('Content-Type: application/xml; charset=utf-8'); 188 | } 189 | } 190 | -------------------------------------------------------------------------------- /views/theme.inc: -------------------------------------------------------------------------------- 1 | style_plugin->preprocess($vars); 8 | } 9 | --------------------------------------------------------------------------------