Index: review/coder/pifr_coder.server.inc
===================================================================
RCS file: review/coder/pifr_coder.server.inc
diff -N review/coder/pifr_coder.server.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ review/coder/pifr_coder.server.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,37 @@
+<?php
+// $Id: pifr_simpletest.server.inc,v 1.7 2009/12/04 20:29:08 boombatower Exp $
+
+/**
+ * @file
+ * Provide Coder server review implementation.
+ *
+ * @author Jimmy Berry ("boombatower", http://drupal.org/user/214218)
+ */
+
+module_load_include('server.inc', 'pifr_drupal');
+
+/**
+ * Coder server review implementation.
+ */
+class pifr_server_review_pifr_coder extends pifr_server_review_pifr_drupal {
+
+  /**
+   * Modify step information.
+   */
+  public function __construct() {
+    $this->steps['review'] = array(
+      'confirmation' => FALSE,
+    );
+    $this->steps['fail'] = array(
+      'title' => 'detect coder flags',
+      'description' => 'Ensure that your code follows the Drupal standard and passes a coder & tough love review.',
+      'confirmation' => 'pifr_coder',
+    );
+    $this->steps['pass'] = array(
+      'title' => 'coder review passed',
+      'confirmation' => 'no-patch',
+    );
+
+    parent::__construct();
+  }
+}
Index: review/coder/pifr_coder.client.inc
===================================================================
RCS file: review/coder/pifr_coder.client.inc
diff -N review/coder/pifr_coder.client.inc
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ review/coder/pifr_coder.client.inc	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,112 @@
+<?php
+// $Id: pifr_simpletest.client.inc,v 1.12 2009/12/04 22:28:54 boombatower Exp $
+
+/**
+ * @file
+ * Provide Coder client review implementation.
+ *
+ * @author Jimmy Berry ("boombatower", http://drupal.org/user/214218)
+ */
+
+module_load_include('client.inc', 'pifr_drupal');
+
+/**
+ * SimpleTest PIFR review implementation.
+ */
+class pifr_client_review_pifr_coder extends pifr_client_review_pifr_drupal {
+
+  protected $results = array();
+
+  /**
+   * Perform coder review.
+   */
+  protected function review() {
+    // Get the review information for the selected reviews.
+    $selected_reviews = array('comment', 'sql', 'i18n', 'style', 'security', 'coder_tough_love');
+    $reviews = _coder_reviews();
+    foreach ($reviews as $key => $review) {
+      if (!in_array($key, $selected_reviews)) {
+        unset($reviews[$key]);
+      }
+    }
+
+    // Prepare the base arguments array.
+    $php_extensions = array('php', 'inc', 'install', 'module', 'test');
+    $args = array(
+      '#reviews' => $reviews,
+      '#severity' => SEVERITY_MINOR,
+      '#filename' => '',
+      '#patch' => '',
+      '#php_extensions' => $php_extensions,
+      '#include_extensions' => _coder_get_reviews_extensions($php_extensions, $reviews),
+    );
+
+    // Cycle through all relevant files and perform review.
+    $files = parent::syntax_files();
+    foreach ($files as $file) {
+      // Ensure that the file exists and is not a reference to a file that was
+      // removed in a patch, or the like.
+      if (!file_exists($file)) {
+        $not_found++;
+        continue;
+      }
+
+      $args['#filename'] = $file;
+      $this->results[$file] = do_coder_reviews($args);
+    }
+  }
+
+  /**
+   * Add the Coder results.
+   */
+  public function get_result() {
+    $result = parent::get_result();
+
+    // If result code is one greater then number of operations then all the
+    // operations passed, so the test results need to be added.
+    $fail_code = count($this->operations) + 1;
+    if ($result['code'] == $fail_code) {
+      $result['details'] = array(
+        '@pass' => 0,
+        '@fail' => 0,
+        '@exception' => 0,
+      );
+      $result['data'] = array();
+
+      // Cycle through results for each file.
+      foreach ($results as $file => $result) {
+        $result['data'][$file] = array(
+          'test_name' => $file,
+          'pass' => 0,
+          'fail' => 0,
+          'exception' => 0,
+          'assertions' => array(),
+        );
+
+        foreach ($result as $assertion) {
+          // Fill in details with summary of assertion counts.
+          $result['details']['@' . $assertion['status']]++;
+
+          // Add up summary totals for test class.
+          $result['data'][$file][$assertion['status']]++;
+
+          // Store non-pass assertion until reaching maximum number.
+          if ($non_pass < PIFR_CLIENT_MAX_ASSERTIONS) {
+            // Make file only include name, instead of absolute reference.
+            $assertion['file'] = basename($file);
+
+            // Add assertion to set of non-pass assertions for the class.
+            $result['data'][$file]['assertions'][] = $assertion;
+          }
+        }
+      }
+
+      // Remove file name keys.
+      $result['data'] = array_values($result['data']);
+
+      // Assign the code bassed on the test results.
+      $result['code'] = ($result['details']['@fail'] + $result['details']['@exception'] ? $fail_code : $fail_code + 1);
+    }
+    return $result;
+  }
+}
Index: review/coder/pifr_coder.info
===================================================================
RCS file: review/coder/pifr_coder.info
diff -N review/coder/pifr_coder.info
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ review/coder/pifr_coder.info	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,12 @@
+; $Id$
+name = PIFR Coder
+description = Provide PIFR review implementation for Coder.
+package = Project Issue File Review Plugins
+core = 6.x
+php = 5
+files[] = pifr_coder.client.inc
+files[] = pifr_coder.module
+files[] = pifr_coder.server.inc
+; dependencies[] = coder
+; dependencies[] = coder_tough_love
+dependencies[] = pifr_assertion
Index: review/coder/pifr_coder.module
===================================================================
RCS file: review/coder/pifr_coder.module
diff -N review/coder/pifr_coder.module
--- /dev/null	1 Jan 1970 00:00:00 -0000
+++ review/coder/pifr_coder.module	1 Jan 1970 00:00:00 -0000
@@ -0,0 +1,62 @@
+<?php
+// $Id$
+
+/**
+ * @file
+ * Provide PIFR review implementation for Coder.
+ *
+ * @author Jimmy Berry ("boombatower", http://drupal.org/user/214218)
+ */
+
+/**
+ * Implementation of hook_pifr_info().
+ */
+function pifr_coder_pifr_info() {
+  return array(
+    'pifr_coder' => t('Coder'),
+  );
+}
+
+/**
+ * Implementation of hook_theme_registry_alter().
+ */
+function pifr_coder_theme_registry_alter(&$theme_registry) {
+  $theme_registry['coder_warning'] = array(
+    'file' => 'pifr_coder.module',
+    'path' => drupal_get_path('module', 'pifr_coder'),
+    'function' => 'theme_pifr_coder_warning',
+  );
+}
+
+/**
+ * Create assertion information array.
+ *
+ * @see theme_coder_warning()
+ */
+function theme_pifr_coder_warning($warning, $severity_name, $lineno = 0, $line = '') {
+  static $map = array(
+    'critical' => 'pass',
+    'normal' => 'fail',
+    'minor' => 'exception',
+  );
+
+  $assertion = array(
+    'status' => $map[$severity_name],
+    'message' => $warning,
+    'message_group' => 'Other',
+    'function' => 'N/A',
+    'line' => $lineno,
+  );
+
+  if (is_array($warning)) {
+    $assertion['message'] = $warning['#warning'];
+    if (isset($warning['#link'])) {
+      $assertion['message'] .= ' (' . l(t('Drupal Docs'), $warning['#link']) . ')';
+    }
+  }
+  if ($line) {
+    $warning .= ' <pre>' . check_plain($line) . '</pre>';
+  }
+
+  return $assertion;
+}
