/**
  * Since there's no UUID for the directory page, just override index
  */
 function index()
 {
     // only html
     if ($this->view != 'html') {
         show_error('Only HTML view available', 415);
     }
     // users directory (flat)
     $args = array('limit' => 15, 'sort' => 'org_display_name asc,user_last_name asc,user_first_name asc', 'status' => 'AP', 'type' => 'A');
     $users = $this->api->query('user', $args);
     $params = array('status' => 'AP', 'type' => 'A');
     // organizations directory (tree)
     $args = array('limit' => 0, 'sort' => 'org_display_name asc');
     $orgs = $this->api->query('orgtree', $args);
     // 5 newest users
     $new_users = $this->api->query('user', array('limit' => 5, 'sort' => 'user_cre_dtim desc'));
     // 5 newest orgs
     $new_orgs = $this->api->query('organization', array('limit' => 5, 'sort' => 'org_cre_dtim desc'));
     // super-secret PIN-manager only view!
     $o = Doctrine::getTable('Organization')->find(Organization::$GLOBALPIN_ORG_ID);
     $pinmanage = $o->user_may_manage($this->airuser->get_user());
     // inline data
     $inline = array('URL' => air2_uri_for('/directory'), 'PINMNG' => $pinmanage, 'USERDIR' => $users, 'UPARAMS' => $params, 'ORGDIR' => $orgs, 'USERNEW' => $new_users, 'ORGNEW' => $new_orgs);
     // show page
     $title = 'Directory - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Directory', $inline);
     $this->response($data);
 }
 /**
  *
  * Load inline HTML for the "index" page
  *
  * @param array $index_rs
  */
 protected function index_html($index_rs)
 {
     $inline = array('URL' => air2_uri_for($index_rs['path']), 'BASE' => $index_rs);
     // show page
     $title = 'Search Emails - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'EmailSearch', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param string $uuid
  * @param array  $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'SRCDATA' => $this->api->query("bin/{$uuid}/srcsub", array('limit' => 15, 'sort' => 'src_last_name asc')), 'EXPORTS' => $this->api->query("bin/{$uuid}/export", array('limit' => 5, 'sort' => 'se_cre_dtim desc')));
     // show page
     $title = $base_rs['radix']['bin_name'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Bin', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param type $uuid
  * @param type $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'SRCDATA' => $this->api->query("outcome/{$uuid}/source", array('limit' => 8)), 'PRJDATA' => $this->api->query("outcome/{$uuid}/project", array('limit' => 5)), 'INQDATA' => $this->api->query("outcome/{$uuid}/inquiry", array('limit' => 5)));
     // show page
     $title = $base_rs['radix']['out_headline'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Outcome', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param type $uuid
  * @param type $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     $search_query = array('q' => "prj_uuid={$uuid}");
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'SUBMSRCH' => air2_uri_for('search/responses', $search_query), 'INQSRCH' => air2_uri_for('search/queries', $search_query), 'SRCSRCH' => air2_uri_for('search/sources', $search_query), 'SUBMDATA' => $this->api->query("project/{$uuid}/submission", array('limit' => 4)), 'INQDATA' => $this->api->query("project/{$uuid}/inquiry", array('limit' => 5)), 'ORGDATA' => $this->api->query("project/{$uuid}/organization", array('limit' => 4)), 'OUTDATA' => $this->api->query("project/{$uuid}/outcome", array('limit' => 3)), 'STATSDATA' => $this->_stats_data($uuid), 'ANNOTDATA' => $this->api->query("project/{$uuid}/annotation", array('limit' => 3)), 'ACTIVDATA' => $this->api->query("project/{$uuid}/activity", array('limit' => 5)), 'TAGDATA' => $this->api->query("project/{$uuid}/tag", array('limit' => 0)));
     // show page
     $title = $base_rs['radix']['prj_display_name'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Project', $inline);
     $this->response($data);
 }
 /**
  * Since there's no UUID for the source emails page, just override index
  */
 function index()
 {
     // inline data
     $inline = array('URL' => air2_uri_for('srcemail'), 'DATA' => $this->api->query('srcemail', array('limit' => 30, 'sort' => 'sem_upd_dtim desc', 'status' => SrcEmail::$STATUS_BOUNCED)), 'STATS' => null, 'PARMS' => array('status' => SrcEmail::$STATUS_BOUNCED));
     // show page
     $title = 'Bounced Emails - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'SrcEmail', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param type $uuid
  * @param type $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     $name = $base_rs['radix']['org_name'];
     $search_query = array('q' => "org_name={$name}");
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'INQSRCH' => air2_uri_for('search/queries', $search_query), 'SRCSRCH' => air2_uri_for('search/active-sources', $search_query), 'CHILDDATA' => $this->api->query("organization/{$uuid}/child", array('limit' => 6, 'sort' => 'org_name asc')), 'PRJDATA' => $this->api->query("organization/{$uuid}/project", array('limit' => 10, 'sort' => 'prj_display_name asc')), 'SRCDATA' => $this->api->query("organization/{$uuid}/source", array('limit' => 5, 'sort' => 'so_cre_dtim desc')), 'USRDATA' => $this->api->query("organization/{$uuid}/user", array('limit' => 8, 'sort' => 'user_status asc, user_first_name asc')), 'INQDATA' => $this->api->query("organization/{$uuid}/inquiry", array('limit' => 5, 'sort' => 'inq_cre_dtim desc')), 'SYSIDDATA' => $this->api->query("organization/{$uuid}/sysid", array('limit' => 5, 'sort' => 'osid_type desc')), 'ACTVDATA' => $this->api->query("organization/{$uuid}/activity", array('limit' => 8)), 'OUTDATA' => $this->api->query("organization/{$uuid}/outcome", array('limit' => 4)), 'NETDATA' => $this->api->query("organization/{$uuid}/network", array('limit' => 6)));
     // show page
     $title = $base_rs['radix']['org_display_name'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Organization', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param string $uuid
  * @param array  $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     // load radix from CSV-api, if this is a CSV file
     $csv_rs = false;
     if ($base_rs['radix']['tank_type'] == Tank::$TYPE_CSV) {
         $csv_rs = $this->api->fetch("csv/{$uuid}");
         $base_rs['radix'] = $csv_rs['radix'];
     }
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'TSRCDATA' => $this->api->query("tank/{$uuid}/source", array('limit' => 25, 'sort' => 'status_sort asc', 'src_username asc')), 'ORGDATA' => $this->api->query("tank/{$uuid}/organization", array('limit' => 0, 'sort' => 'org_display_name asc')), 'ACTDATA' => $this->api->query("tank/{$uuid}/activity", array('limit' => 0, 'sort' => 'tact_dtim desc')), 'CSVDATA' => $csv_rs);
     // show page
     $title = $base_rs['radix']['tank_name'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Import', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param type    $uuid
  * @param type    $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     $inq = AIR2_Record::find('Inquiry', $uuid);
     // redmine #7794 adminstrative queries disallowed for non-system users
     if (!$this->user->is_system()) {
         if ($inq && $inq->inq_type == Inquiry::$TYPE_MANUAL_ENTRY) {
             $this->airoutput->write_error(403, 'Query for internal use only', 'This query is for internal use only');
             return;
         }
     }
     $search_query = array('q' => "inq_uuid={$uuid}");
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'QUESDATA' => $this->api->query("inquiry/{$uuid}/question", array('limit' => 0, 'sort' => 'ques_dis_seq asc')), 'QUESTPLS' => AIR2_QueryBuilder::get_defs(), 'QUESURL' => air2_uri_for("inquiry/{$uuid}/question"), 'ORGDATA' => $this->api->query("inquiry/{$uuid}/organization", array('sort' => 'org_display_name asc')), 'PROJDATA' => $this->api->query("inquiry/{$uuid}/project", array('sort' => 'prj_display_name asc')), 'OUTDATA' => $this->api->query("inquiry/{$uuid}/outcome", array('limit' => 10)), 'ANNOTDATA' => $this->api->query("inquiry/{$uuid}/annotation", array('limit' => 3, 'sort' => 'inqan_cre_dtim desc')), 'TAGDATA' => $this->api->query("inquiry/{$uuid}/tag", array('limit' => 0)), 'STATSDATA' => $this->_stats_data($inq), 'SUBMDATA' => $this->api->query("inquiry/{$uuid}/submission", array('limit' => 5)), 'SUBMSRCH' => air2_uri_for("reader/query/{$uuid}"), 'ACTIVDATA' => $this->api->query("inquiry/{$uuid}/activity", array('limit' => 5)), 'AUTHORDATA' => $this->api->query("inquiry/{$uuid}/author", array('limit' => 5)), 'WATCHERDATA' => $this->api->query("inquiry/{$uuid}/watcher", array('limit' => 5)));
     // show page
     $title = $base_rs['radix']['inq_ext_title'] . ' - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Inquiry', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param string  $uuid
  * @param array   $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     // use local url unless this AIR instance is on PINSSO
     $pwdurl = air2_uri_for('password');
     $is_sys = $base_rs['radix']['user_type'] == User::$TYPE_SYSTEM;
     if (!$is_sys && AIR2_PIN_SSO_TRUST) {
         $pwdurl = 'https://www.publicinsightnetwork.org/authn/password';
     }
     // inline user data
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'ORGDATA' => $this->api->query("user/{$uuid}/organization", array('limit' => 5, 'sort' => 'uo_home_flag desc')), 'ACTDATA' => $this->api->query("user/{$uuid}/activity", array('limit' => 12)), 'NETDATA' => $this->api->query("user/{$uuid}/network", array('limit' => 6)), 'SIGDATA' => $this->api->query("user/{$uuid}/signature", array('limit' => 5)), 'PWDURL' => $pwdurl);
     // show page
     $uname = $base_rs['radix']['user_username'];
     $first = $base_rs['radix']['user_first_name'];
     $last = $base_rs['radix']['user_last_name'];
     $name = $first && $last ? "{$first} {$last}" : $uname;
     $title = "{$name} - " . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'User', $inline);
     $this->response($data);
 }
 /**
  * Since there's no UUID for the translations page, just override index
  */
 function index()
 {
     // valid facts for translations (fv_type_multiple)
     $facts = $this->api->query('fact', array('type' => Fact::$FV_TYPE_MULTIPLE));
     $simplified_facts = array();
     foreach ($facts['radix'] as $fact) {
         $simplified_facts[] = array($fact['fact_identifier'], $fact['fact_name']);
     }
     // potential authz
     $fake = new TranslationMap();
     $user = $this->airuser->get_user();
     $authz = array('may_read' => $fake->user_may_read($user), 'may_write' => $fake->user_may_write($user), 'may_manage' => $fake->user_may_manage($user));
     // inline data
     $inline = array('URL' => air2_uri_for('translation'), 'DATA' => $this->api->query('translation', array('type' => 'gender', 'limit' => 18, 'sort' => 'xm_xlate_from asc')), 'PARMS' => array('type' => 'gender'), 'FACTDATA' => $facts, 'FACTS' => $simplified_facts, 'AUTHZ' => $authz);
     // show page
     $title = 'Manage Translations - ' . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Translation', $inline);
     $this->response($data);
 }
 /**
  * Load inline HTML
  *
  * @param type $uuid
  * @param type $base_rs
  */
 protected function show_html($uuid, $base_rs)
 {
     // Record visit by the current user against the current source. See UserVisit model.
     $source = AIR2_Record::find('Source', $uuid);
     $source->visit(array('ip' => $this->input->ip_address(), 'user' => $this->user));
     /**
      * Prep and display page.
      */
     $search_query = array('q' => "src_uuid={$uuid}");
     $inline = array('UUID' => $base_rs['uuid'], 'URL' => air2_uri_for($base_rs['path']), 'BASE' => $base_rs, 'SUBMSRCH' => air2_uri_for('search/responses', $search_query), 'ORGDATA' => $this->api->query("source/{$uuid}/organization", array('limit' => 5, 'sort' => 'so_home_flag desc,so_status asc,org_display_name asc')), 'SUBMDATA' => $this->api->query("source/{$uuid}/submission", array('limit' => 8, 'sort' => 'srs_date desc,srs_cre_dtim desc')), 'FACTDATA' => $this->api->query("source/{$uuid}/fact", array('limit' => 7, 'sort' => 'fact_id asc')), 'ACTVDATA' => $this->api->query("source/{$uuid}/activity", array('limit' => 5, 'sort' => 'sact_dtim desc')), 'INTDATA' => $this->api->query("source/{$uuid}/interest", array('limit' => 5)), 'EXPDATA' => $this->api->query("source/{$uuid}/experience", array('limit' => 5)), 'ANNOTDATA' => $this->api->query("source/{$uuid}/annotation", array('limit' => 4, 'sort' => 'srcan_upd_dtim desc')), 'TAGDATA' => $this->api->query("source/{$uuid}/tag", array('limit' => 0)), 'OUTDATA' => $this->api->query("source/{$uuid}/outcome", array('limit' => 4)), 'PREFDATA' => $this->api->query("source/{$uuid}/preference", array('limit' => 4)), 'STATSDATA' => $this->_stats_data($uuid), 'FLDDATA' => $this->api->query("fact", array('limit' => 0)), 'PREFSDATA' => $this->api->query("preference", array('pt_identifier' => 'preferred_language', 'limit' => 0)));
     // show page
     $uname = $base_rs['radix']['src_username'];
     $first = $base_rs['radix']['src_first_name'];
     $last = $base_rs['radix']['src_last_name'];
     $name = $first && $last ? "{$first} {$last}" : $uname;
     $title = "{$name} - " . AIR2_SYSTEM_DISP_NAME;
     $data = $this->airhtml->get_inline($title, 'Source', $inline);
     $this->response($data);
 }
예제 #13
0
 /**
  * Static calculator of image paths.  By default, these are absolute
  * filesystem paths.
  *
  * @param char    $ref_type
  * @param string  $img_uuid
  * @param unknown $as_uri   (optional)
  * @param string  $dtim
  * @return array  $paths
  */
 public static function get_images($ref_type, $img_uuid, $as_uri = false, $dtim = null)
 {
     $dir = self::get_directory($ref_type, $img_uuid, $as_uri);
     $ext = self::$CONFIG[$ref_type]['convert_to'];
     $name = self::$CONFIG[$ref_type]['filename'];
     $images = array('original' => "{$dir}{$name}.{$ext}");
     if ($as_uri) {
         $images['original'] = air2_uri_for($images['original']);
         if ($dtim) {
             $images['original'] .= '?' . strtotime($dtim);
         }
     }
     foreach (self::$CONFIG[$ref_type]['sizes'] as $size => $dim) {
         $images[$size] = "{$dir}{$name}_{$size}.{$ext}";
         if ($as_uri) {
             $images[$size] = air2_uri_for($images[$size]);
             if ($dtim) {
                 $images[$size] .= '?' . strtotime($dtim);
             }
         }
     }
     return $images;
 }
 /**
  * Route an HTTP request through the AIR2 API, and map the response into
  * HTTP-land.
  */
 public function route_api()
 {
     $segments = func_get_args();
     $path = implode('/', $segments);
     $rs;
     // determine request type
     if ($this->method == 'GET') {
         unset($this->input_all['_dc']);
         //unset cache-busting
         $rs = $this->api->query_or_fetch($path, $this->input_all);
     } elseif ($this->method == 'POST') {
         $rs = $this->api->create($path, $this->input_radix);
     } elseif ($this->method == 'PUT') {
         $rs = $this->api->update($path, $this->input_radix);
     } elseif ($this->method == 'DELETE') {
         $rs = $this->api->delete($path);
     } else {
         throw new Exception("Unknown request method '{$method}'");
     }
     // map api-code to http status
     $status;
     $code = $rs['code'];
     if (array_key_exists($code, self::$API_TO_STATUS)) {
         $status = self::$API_TO_STATUS[$code];
     } elseif ($code >= AIRAPI::OKAY) {
         $status = 200;
     } else {
         throw new Exception("Unknown API code '{$code}'");
     }
     // redirect a successful proxy resource
     $metatype = isset($rs['meta']['type']) ? $rs['meta']['type'] : null;
     if ($status == 200 && $metatype == 'imageproxy') {
         $url = $rs['radix']['url'];
         $def = null;
         if ($rs['radix']['default']) {
             $def = air2_uri_for('css/img/' . $rs['radix']['default']);
         }
         air2_proxy_image($url, $def);
         exit;
     }
     if ($status == 200 && $metatype == 'fileproxy') {
         $path = $rs['radix']['path'];
         $name = $rs['radix']['name'];
         $size = $rs['radix']['size'];
         $type = $rs['radix']['type'];
         header("Content-Type: {$type}");
         header("Content-length: {$size}");
         header("Content-Disposition: attachment; filename=\"{$name}\"");
         readfile($path);
         exit;
     }
     // special handling for search resource
     if (isset($rs['api']) && $rs['api']['route'] == 'search') {
         $this->handle_search_resource($rs);
         exit;
     }
     // reject html requests (but show the right code)
     if ($this->view == 'html') {
         if ($code >= Rframe::OKAY) {
             show_error('Invalid request type', 415);
         } else {
             $msg = isset($rs['message']) ? $rs['message'] : 'Unknown error';
             show_error($msg, $status);
         }
     }
     // respond
     $this->response($rs, $status);
 }
 *
 *************************************************************************/
/*
|--------------------------------------------------------------------------
| Unsupported browser page
|--------------------------------------------------------------------------
*/
?>
<!DOCTYPE html
	PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
	 "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" lang="en-US" xml:lang="en-US">
 <head>
  <title>AIR2 | Unsupported Browser</title>
  <link rel="stylesheet" type="text/css" href="<?php 
echo air2_uri_for('');
?>
/css/login.css" />
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
 </head>
 <body>
  <div align="center">
   <h2>AIR2 | Unsupported Browser</h2>
   <table border="0" cellpadding="5" style="width:370px">
    <tr>
     <td>If you're seeing this, <b>don't panic</b>. You've just tried to do something that your web browser just wasn't up to.</td>
    </tr>
    <tr>
     <td>How do we break this to you? You need to use another browser.</td>
    </tr>
    <tr>
 /**
  * RSS Feed for PIN statistics
  */
 public function stats()
 {
     if ($this->method != 'GET') {
         header('Allow: GET');
         show_error("Error: Unsupported request method: {$this->method}", 405);
     }
     if ($this->view != 'rss' && $this->view != 'json') {
         show_error("Only rss and json views available", 415);
     }
     // CHECK FOR CACHE (stored as json-encoded data array)
     $data = Cache::instance()->get('stats_rss_all');
     if ($data) {
         $data = json_decode($data, true);
     } else {
         // count sources
         $conn = AIR2_DBManager::get_connection();
         $q = "select count(*) from source where (src_status in ('A','E','T'))";
         $num_sources = $conn->fetchOne($q, array(), 0);
         $q = "select count(*) from user where (user_type != 'S' and user_status in ('A','P'))";
         $num_users = $conn->fetchOne($q, array(), 0);
         // attempt to non-prospective orgs in one query... just check 4 levels down
         $nonprospect = "select org_id from organization where org_parent_id is null and org_name != 'prospect'";
         $lvl0 = "org_id in ({$nonprospect})";
         $lvl1 = "org_parent_id in ({$nonprospect})";
         $lvl2 = "org_parent_id in (select org_id from organization where {$lvl1})";
         $lvl3 = "org_parent_id in (select org_id from organization where {$lvl2})";
         $where = "{$lvl0} or {$lvl1} or {$lvl2} or {$lvl3}";
         $q = "select count(*) from organization where (org_status='A' or org_status='P') and ({$where})";
         $num_orgs = $conn->fetchOne($q, array(), 0);
         // assemble data
         $link = air2_uri_for('rss/stats', $this->input_all);
         $data = array('title' => 'PIN Statistics', 'link' => $link, 'description' => 'Statistics concerning the Public Insight Network', 'language' => 'en-us', 'lastBuildDate' => $this->_rss_datetime(), 'generator' => 'AIR2', 'item' => array(array('title' => 'PIN Organization Count', 'link' => $link, 'description' => $num_orgs, 'guid' => 'pin_org_count'), array('title' => 'Active Sources Count', 'link' => $link, 'description' => $num_sources, 'guid' => 'active_src_count'), array('title' => 'Active Users Count', 'link' => $link, 'description' => $num_users, 'guid' => 'active_user_count')));
         // cache the data
         Cache::instance()->save(json_encode($data), 'stats_rss_all');
     }
     // output data
     $this->airoutput->write($data);
 }
 /**
  * Send a notification email that a new PINfluence has been created
  *
  * @param Outcome $outcome
  */
 private function _send_notification_email($outcome)
 {
     $subj = "New PINfluence Filed in AIR";
     $link = air2_uri_for("outcome/{$outcome->out_uuid}");
     $body = "It's here!  A brand new PINfluence!\n\n";
     $body .= "Filed by: {$this->user->user_username}\n";
     $body .= "Permalink: {$link}\n\n";
     // Build based on entered fields
     $fields = array('Story Headline' => 'out_headline', 'How the PIN influenced this story' => 'out_teaser', 'Content Link' => 'out_url', 'Publish/Air/Event Date' => 'out_dtim', 'Show in feeds' => 'out_status', 'Content Type' => 'out_type', 'Program/Event/Website' => 'out_show', 'Additional Information' => 'out_internal_teaser');
     $statuses = array('A' => 'Yes', 'N' => 'No');
     $types = array('S' => 'Story', 'R' => 'Series', 'E' => 'Event', 'O' => 'Other');
     foreach ($fields as $name => $fld) {
         if ($val = $outcome->{$fld}) {
             if ($fld == 'out_status') {
                 $val = $statuses[$val];
             }
             if ($fld == 'out_type') {
                 $val = $types[$val];
             }
             $body .= "{$name}: {$val}\n";
         }
     }
     $body .= "\n";
     // add more complex fields
     if ($outcome->Organization) {
         $body .= "Organization: {$outcome->Organization->org_display_name}\n";
     }
     foreach ($outcome->PrjOutcome as $pout) {
         $body .= "Project: {$pout->Project->prj_display_name}\n";
     }
     if ($outcome->SrcOutcome->count() > 0) {
         $srcs = array();
         foreach ($outcome->SrcOutcome as $sout) {
             $srcs[] = $sout->Source->src_username;
         }
         $body .= "Sources: " . implode(", ", $srcs) . "\n";
     }
     foreach ($outcome->InqOutcome as $iout) {
         $body .= "Query: {$iout->Inquiry->inq_ext_title}\n";
     }
     if ($outcome->out_survey && ($surv = json_decode($outcome->out_survey, true))) {
         $checked = array();
         foreach ($surv as $key => $val) {
             if ($val) {
                 $checked[] = $key;
             }
         }
         if (count($checked)) {
             $body .= "Survey: " . implode(" - ", $checked) . "\n";
         }
     }
     // send the mail!
     mail(AIR2_EMAIL_ALERTS, $subj, $body);
 }
 /**
  * uri_for() will return the full URI for a part of the application.
  * Example:
  *   $this->uri_for('foo/bar', array('color'=>'red'));
  *   //  https://myhost/foo/bar?color=red
  *
  * @param string  $path
  * @param array   $query (optional)
  * @return unknown
  */
 public function uri_for($path, $query = array())
 {
     return air2_uri_for($path, $query);
 }
 /**
  * Generate a mailto link to request access to a submission.
  *
  * @param  string $email
  * @param  string $srs_uuid
  * @return string $link
  */
 private function _mailto_markup($email, $srs_uuid)
 {
     $url = air2_uri_for("/submission/{$srs_uuid}");
     $subj = rawurlencode("Access request for submission {$srs_uuid}");
     $body = rawurlencode("Submission URL: {$url}");
     $href = "href=\"mailto:{$email}?subject={$subj}&body={$body}\"";
     return "<a class=\"email\" {$href}>{$email}</a>";
 }
 /**
  * Get an array of css includes
  *
  * @return array $css
  */
 public function css_includes()
 {
     // only need compressed file, if it exists
     if (file_exists(AIR2_DOCROOT . '/css/air2-compressed.css')) {
         return array(air2_uri_for('css/air2-compressed.css'));
     }
     // recursively scan css directory
     $css = air2_dirscan(AIR2_DOCROOT . '/css/', '/.css$/');
     $rmv = array('docbook.css', 'login.css', 'ie.css', 'print.css', 'ext-theme-air2.css', 'query.css', 'pinform.css', 'third_party.css');
     air2_array_remove($rmv, $css);
     // change to absolute paths
     foreach ($css as &$file) {
         $mtime = filemtime(AIR2_DOCROOT . '/css/' . $file);
         $file = air2_uri_for("css/{$file}", array('_' => $mtime));
     }
     return $css;
 }