/**
  * Create
  *
  * @param array   $data
  * @return unknown
  */
 protected function air_create($data)
 {
     if (!isset($data['prj_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "prj_uuid required");
     }
     $prj = AIR2_Record::find('Project', $data['prj_uuid']);
     if (!$prj) {
         $u = $data['prj_uuid'];
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid prj_uuid '{$u}'");
     }
     $pinq = new ProjectInquiry();
     $pinq->pinq_inq_id = $this->parent_rec->inq_id;
     $pinq->Project = $prj;
     $pinq->mapValue('prj_uuid', $pinq->Project->prj_uuid);
     // adding a Project to a Query requires write authz on the Query, not the Project.
     if (!$pinq->user_may_write($this->user)) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid Query authz");
     }
     // log activity
     $activity = new InquiryActivity();
     $activity->ia_inq_id = $this->parent_rec->inq_id;
     $activity->ia_actm_id = 49;
     $activity->ia_dtim = air2_date();
     $activity->ia_desc = sprintf('project %s added by {USER}', $prj->prj_name);
     $this->parent_rec->InquiryActivity[] = $activity;
     return $pinq;
 }
 /**
  * Create
  *
  * @param array $data
  * @return Doctrine_Record $rec
  */
 protected function air_create($data)
 {
     $p = new Project();
     // org_uuid required
     if (!isset($data['org_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Project Organization uuid required!');
     }
     $org = AIR2_Record::find('Organization', $data['org_uuid']);
     if (!$org) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid Organization specified!');
     }
     $p->ProjectOrg[0]->porg_contact_user_id = $this->user->user_id;
     $p->ProjectOrg[0]->Organization = $org;
     // immediately add inquiry to project
     if (isset($data['inq_uuid'])) {
         $inq = AIR2_Record::find('Inquiry', $data['inq_uuid']);
         if (!$inq) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid Inquiry specified!');
         }
         if (!$inq->user_may_write($this->user)) {
             throw new Rframe_Exception(Rframe::BAD_AUTHZ, 'Invalid Inquiry authz!');
         }
         $p->ProjectInquiry[0]->Inquiry = $inq;
     }
     return $p;
 }
 /**
  * Create
  *
  * @param array   $data
  * @return unknown
  */
 protected function air_create($data)
 {
     if (!isset($data['org_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "org_uuid required");
     }
     $org = AIR2_Record::find('Organization', $data['org_uuid']);
     if (!$org) {
         $u = $data['org_uuid'];
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid org_uuid '{$u}'");
     }
     if (!$this->parent_rec->user_may_write($this->user)) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "You do not appear to have access to modify this Inquiry (Invalid Inquiry authz)");
     }
     $iorg = new InqOrg();
     $iorg->iorg_inq_id = $this->parent_rec->inq_id;
     $iorg->Organization = $org;
     $iorg->mapValue('org_uuid', $iorg->Organization->org_uuid);
     // log activity
     $activity = new InquiryActivity();
     $activity->ia_inq_id = $this->parent_rec->inq_id;
     $activity->ia_actm_id = 49;
     $activity->ia_dtim = air2_date();
     $activity->ia_desc = sprintf('org %s added by {USER}', $org->org_name);
     $this->parent_rec->InquiryActivity[] = $activity;
     return $iorg;
 }
 /**
  * Load data for html printing
  *
  * @param type $uuid
  * @param type $base_rs
  */
 protected function show_print_html($uuid, $base_rs)
 {
     $bin = AIR2_Record::find('Bin', $uuid);
     $base_rs['sources'] = array();
     // authorized sources
     $authz_sources = array();
     $q = Doctrine_Query::create()->from('BinSource bs');
     $q->leftJoin('bs.Source s');
     $q->where('bs.bsrc_bin_id = ?', $bin->bin_id);
     $q->select('bs.bsrc_src_id, s.src_uuid');
     BinSource::query_may_read($q, $this->user, 'bs');
     $bsrcs = $q->fetchArray();
     foreach ($bsrcs as $bsrc) {
         $authz_sources[$bsrc['Source']['src_uuid']] = true;
     }
     // only keep fetching if there is stuff to get
     $authz_responses = array();
     if (count($authz_sources) > 0) {
         $q = Doctrine_Query::create()->from('BinSrcResponseSet bs');
         $q->leftJoin('bs.SrcResponseSet s');
         $q->where('bs.bsrs_bin_id = ?', $bin->bin_id);
         $q->select('bs.bsrs_srs_id, s.srs_uuid');
         BinSrcResponseSet::query_may_read($q, $this->user, 'bs');
         $bsrss = $q->fetchArray();
         foreach ($bsrss as $bsrs) {
             $authz_responses[$bsrs['SrcResponseSet']['srs_uuid']] = true;
         }
         // let perl do the heavy lifting
         $binsources = CallPerl::exec('AIR2::Bin->flatten', $bin->bin_id);
         foreach ($binsources as $src) {
             $src_uuid = $src['src_uuid'];
             if (isset($authz_sources[$src_uuid])) {
                 // apply authz to responses
                 if (is_array($src['response_sets'])) {
                     foreach ($src['response_sets'] as $idx => $srs) {
                         $srs_uuid = $srs['srs_uuid'];
                         if (!isset($authz_responses[$srs_uuid])) {
                             unset($src['response_sets'][$idx]);
                         }
                     }
                     $src['response_sets'] = array_values($src['response_sets']);
                 }
                 // add as value
                 $authz_sources[$src_uuid] = $src;
             }
         }
     }
     // reorganize for the print view
     $raw = array('bin' => $base_rs['radix'], 'sources' => array_values($authz_sources));
     $this->airoutput->view = 'print/bin';
     $this->response($raw);
 }
 /**
  * RESTful Create
  *
  * @param  array     $data
  * @return BinSource $rec
  */
 protected function air_create($data)
 {
     $this->require_data($data, array('src_uuid'));
     $src = AIR2_Record::find('Source', $data['src_uuid']);
     if (!$src) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid Source specified!');
     }
     $b = new BinSource();
     $b->Bin = $this->parent_rec;
     $b->Source = $src;
     $b->mapValue('src_uuid', $src->src_uuid);
     return $b;
 }
 /**
  * Create
  *
  * @param array $data
  * @return Doctrine_Record $rec
  */
 protected function air_create($data)
 {
     $o = new Organization();
     // org parent (optional)
     if (isset($data['org_parent_uuid'])) {
         $parent = AIR2_Record::find('Organization', $data['org_parent_uuid']);
         if (!$parent) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid parent Org specified!');
         }
         $o->parent = $parent;
     }
     return $o;
 }
 protected function air_create($data)
 {
     if (!isset($data['org_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Must specify org_uuid');
     }
     $org = AIR2_Record::find('Organization', $data['org_uuid']);
     if (!$org) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid org_uuid');
     }
     $so = new SrcOrg();
     $so->Source = $this->parent_rec;
     $so->Organization = $org;
     return $so;
 }
 /**
  * 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 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);
 }
 /**
  * Create
  *
  * @param array   $data
  * @return unknown
  */
 protected function air_create($data)
 {
     if (!isset($data['User'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "User");
     }
     $user = null;
     if ($data['User']) {
         $user = AIR2_Record::find('User', $data['User']['user_uuid']);
         if (!$user) {
             $u = $data['User']['user_uuid'];
             throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid user_uuid '{$u}'");
         }
     }
     $iauth = new InquiryAuthor();
     $iauth->iu_inq_id = $this->parent_rec->inq_id;
     $iauth->iu_user_id = $user->user_id;
     // log activity
     $activity = new InquiryActivity();
     $activity->ia_inq_id = $this->parent_rec->inq_id;
     $activity->ia_actm_id = 49;
     $activity->ia_dtim = air2_date();
     $activity->ia_desc = sprintf('author %s added by {USER}', $user->user_username);
     $this->parent_rec->InquiryActivity[] = $activity;
     return $iauth;
 }
 /**
  * Create
  *
  * @param array $data
  * @return Doctrine_Record $rec
  */
 protected function air_create($data)
 {
     $this->require_data($data, array('src_uuid'));
     // validate
     $s = AIR2_Record::find('Source', $data['src_uuid']);
     if (!$s) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid src_uuid');
     }
     foreach ($this->parent_rec->SrcOutcome as $sout) {
         if ($sout->sout_src_id == $s->src_id) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Outcome already includes Source');
         }
     }
     // create!
     $rec = new SrcOutcome();
     $rec->sout_out_id = $this->parent_rec->out_id;
     $rec->sout_src_id = $s->src_id;
     $rec->mapValue('src_uuid', $s->src_uuid);
     return $rec;
 }
 /**
  * Process bulk add/remove/etc operations
  *
  * @param Outcome $rec
  * @param string  $bulk_op
  * @param array   $data
  */
 protected function run_bulk($rec, $bulk_op, $data)
 {
     // rethrow any exceptions as 'data' exceptions
     try {
         if ($bulk_op == 'sources') {
             $bin = AIR2_Record::find('Bin', $data['bin_uuid']);
             if (!$bin) {
                 throw new Rframe_Exception(Rframe::BAD_DATA, 'Unable to get the Bin specified.');
                 return;
             }
             $this->bulk_rs = AIR2Outcome::add_sources_from_bin($rec, $bin, $data['sout_type']);
         }
     } catch (Rframe_Exception $e) {
         throw $e;
         //re-throw as-is
     } catch (Exception $e) {
         throw new Rframe_Exception(Rframe::BAD_DATA, $e->getMessage());
     }
 }
 /**
  * Create
  *
  * @param array   $data
  * @return Doctrine_Record $rec
  */
 protected function air_create($data)
 {
     if (isset($data['source_query_uuid'])) {
         return $this->duplicate_query($data['source_query_uuid']);
     }
     $i = new Inquiry();
     $i->inq_type = Inquiry::$TYPE_QUERYBUILDER;
     // default, editable via UI for Global Managers
     $i->inq_status = Inquiry::$STATUS_DRAFT;
     $this->require_data($data, array('inq_ext_title', 'inq_rss_intro', 'loc_key', 'org_uuid', 'prj_uuid'));
     // default to url-ified title
     if (!isset($data['inq_title'])) {
         $i->inq_title = ' ';
     }
     if ($data['loc_key']) {
         $tbl = Doctrine::getTable('Locale');
         $col = 'loc_key';
         $locale = $tbl->findOneBy($col, $data['loc_key']);
         if ($locale) {
             $i->inq_loc_id = $locale->loc_id;
         }
     }
     if ($data['org_uuid']) {
         $org = AIR2_Record::find('Organization', $data['org_uuid']);
         if ($org) {
             $iorg = new InqOrg();
             $iorg->iorg_org_id = $org->org_id;
             $i->InqOrg[] = $iorg;
         }
     }
     if ($data['prj_uuid']) {
         $prj = AIR2_Record::find('Project', $data['prj_uuid']);
         if ($prj) {
             $pinq = new ProjectInquiry();
             $pinq->pinq_prj_id = $prj->prj_id;
             $i->ProjectInquiry[] = $pinq;
         }
     }
     return $i;
 }
 /**
  * Create a new, UNSAVED Tag from either a string tm_name or a tm_id.  Will
  * return false if an invalid tm_id is given.
  *
  * @param string  $flavor
  * @param int     $xid
  * @param mixed   $input
  * @param boolean $use_id
  * @return Tag $rec
  */
 public static function create_tag($flavor, $xid, $input, $use_id = false)
 {
     $tag = new $flavor();
     $tag->tag_xid = $xid;
     if ($use_id) {
         $tm = AIR2_Record::find('TagMaster', $input);
         if (!$tm) {
             return false;
         }
         //bad tm_id
         $tag->TagMaster = $tm;
     } else {
         $tm = Doctrine::getTable('TagMaster')->findOneBy('tm_name', $input);
         if (!$tm) {
             $tm = new TagMaster();
             $tm->tm_type = TagMaster::$TYPE_JOURNALISTIC;
             $tm->tm_name = $input;
         }
         $tag->TagMaster = $tm;
     }
     // check for existing tag on this record
     if ($tag->TagMaster->tm_id) {
         $q = Doctrine_Query::create()->from($flavor);
         $q->andWhere('tag_tm_id = ?', $tag->TagMaster->tm_id);
         $q->andWhere('tag_xid = ?', $xid);
         $dup = $q->fetchOne();
         if ($dup) {
             return $dup;
         }
     }
     return $tag;
 }
 /**
  * Create
  *
  * @param array $data
  * @return UserOrg $rec
  */
 protected function air_create($data)
 {
     $uo = new UserOrg();
     $uo->uo_org_id = $this->parent_rec->org_id;
     // valid user
     if (!isset($data['user_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Must specify user_uuid');
     }
     $user = AIR2_Record::find('User', $data['user_uuid']);
     if (!$user) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid user_uuid');
     }
     $uo->User = $user;
     // unique user_uuid for org
     $q = Doctrine_Query::create()->from('UserOrg uo');
     $q->andWhere('uo_user_id = ?', $user->user_id);
     $q->andWhere('uo_org_id = ?', $this->parent_rec->org_id);
     if ($q->count() > 0) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'User already belongs to Organization');
     }
     // check for space in this Org
     if ($this->parent_rec->is_full()) {
         $n = $this->parent_rec->org_display_name;
         throw new Rframe_Exception(Rframe::BAD_DATA, "Max users for '{$n}' reached");
     }
     return $uo;
 }
 /**
  * Process activity/event input
  *
  * @param Tank  $rec
  * @param array $data
  */
 protected function process_activity($rec, $data)
 {
     $flds = array('prj_uuid', 'evdesc', 'evdtim', 'evtype', 'evdir');
     if (count(array_intersect_key(array_flip($flds), $data)) == 0) {
         return;
     }
     // if DNE, all must be present!
     if ($rec->TankActivity->count() == 0) {
         $this->require_data($data, $flds);
         $rec->TankActivity[0]->tact_type = TankActivity::$TYPE_SOURCE;
         $rec->TankActivity[0]->tact_desc = '{USER} imported source {SRC} in csv ' . $rec->tank_name;
         $rec->TankActivity[0]->tact_xid = $rec->tank_id;
         $rec->TankActivity[0]->tact_ref_type = SrcActivity::$REF_TYPE_TANK;
     }
     // validate event input
     if (isset($data['evtype']) || isset($data['evdir'])) {
         $t = $data['evtype'];
         $d = $data['evdir'];
         if (!$t || !$d) {
             throw new Rframe_Exception(Rframe::BAD_DATA, "Must pass both evtype and evdir");
         }
         if (!in_array($t, array('E', 'P', 'T', 'I', 'O'))) {
             throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid parameter evtype '{$t}'");
         }
         if (!in_array($d, array('I', 'O'))) {
             throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid parameter evdir '{$d}'");
         }
         $rec->TankActivity[0]->tact_actm_id = TankActivity::$ACTM_MAP[$t . $d];
     }
     if (isset($data['evdtim'])) {
         $dt = $data['evdtim'];
         if (!strtotime($dt)) {
             throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid parameter evdtim '{$dt}'");
         }
         $rec->TankActivity[0]->tact_dtim = $dt;
     }
     if (isset($data['evdesc'])) {
         $desc = $data['evdesc'];
         if (strlen($desc) < 1) {
             throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid parameter evdesc '{$desc}'");
         }
         $rec->TankActivity[0]->tact_notes = $desc;
     }
     if (isset($data['prj_uuid'])) {
         $prj = AIR2_Record::find('Project', $data['prj_uuid']);
         if (!$prj) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid prj_uuid');
         }
         $rec->TankActivity[0]->tact_prj_id = $prj->prj_id;
     }
 }
 /**
  * Redirect to perl!
  *
  * @param  array $args
  * @return array $resp
  */
 public function rec_query($args)
 {
     $uid = $this->user->user_id;
     // get options
     $opts = array();
     if (isset($args['sources']) && $args['sources']) {
         $opts['sources'] = 1;
     }
     if (isset($args['org_uuid'])) {
         $org = AIR2_Record::find('Organization', $args['org_uuid']);
         if (!$org) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid org_uuid');
         }
         $opts['org_id'] = $org->org_id;
     }
     if (isset($args['prj_uuid'])) {
         $prj = AIR2_Record::find('Project', $args['prj_uuid']);
         if (!$prj) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid prj_uuid');
         }
         $opts['prj_id'] = $prj->prj_id;
     }
     if (isset($args['inq_uuid'])) {
         $inq = AIR2_Record::find('Inquiry', $args['inq_uuid']);
         if (!$inq) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid inq_uuid');
         }
         $opts['inq_id'] = $inq->inq_id;
     }
     if (isset($args['start_date'])) {
         if (strtotime($args['start_date']) === false) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid start_date');
         }
         $opts['start_date'] = $args['start_date'];
     }
     if (isset($args['end_date'])) {
         if (strtotime($args['end_date']) === false) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid end_date');
         }
         $opts['end_date'] = $args['end_date'];
     }
     # return just the count
     if (isset($args['count']) && $args['count']) {
         $opts['count'] = 1;
         $this->cached_total = CallPerl::exec('AIR2::OutcomeWriter->get_obj', $uid, $opts);
         return array();
     }
     // download results, or email
     $data = array();
     if (isset($args['email']) && $args['email']) {
         $opts['format'] = 'email';
         // build command
         $cmd = "PERL AIR2_ROOT/bin/outcome-export.pl --user_id={$uid}";
         foreach ($opts as $key => $val) {
             if ($key == 'sources') {
                 $cmd .= " --{$key}";
             } else {
                 $cmd .= " --{$key}={$val}";
             }
         }
         $job = new JobQueue();
         $job->jq_job = $cmd;
         $this->air_save($job);
         // success, but we want a non-200, so throw up!
         $msg = 'CSV export scheduled for background processing';
         throw new Rframe_Exception(Rframe::BGND_CREATE, $msg);
     } else {
         if (count($opts) == 0) {
             $opts = null;
         }
         //avoid hash vs array confusion
         $r = CallPerl::exec('AIR2::OutcomeWriter->get_obj', $uid, $opts);
         $this->fields = $r[0];
         $this->reset_fields();
         // unflatten ... yeah, I know this is inefficient
         // but it's backwards compatible
         for ($i = 1; $i < count($r); $i++) {
             $data[$i - 1] = array();
             foreach ($this->fields as $colnum => $name) {
                 $data[$i - 1][$name] = $r[$i][$colnum];
             }
         }
     }
     return $data;
 }
 /**
  * Update a new question from an existing question
  *
  * @param Question $q
  * @param string   $ques_uuid
  */
 public static function copy_question(Question $q, $ques_uuid)
 {
     $from = AIR2_Record::find('Question', $ques_uuid);
     if (!$from) {
         throw new Exception("Invalid ques_uuid({$ques_uuid})");
     }
     $from_array = $from->toArray();
     $reset_keys = array('ques_id', 'ques_uuid', 'ques_inq_id', 'ques_upd_user', 'ques_upd_dtim', 'ques_cre_user', 'ques_cre_dtim');
     foreach ($reset_keys as $reset_key) {
         $from_array[$reset_key] = NULL;
         unset($from_array[$reset_key]);
     }
     $q->fromArray($from_array);
 }
 /**
  * Create
  *
  * @param array $data
  * @return UserOrg $rec
  */
 protected function air_create($data)
 {
     $uo = new UserOrg();
     $uo->uo_user_id = $this->parent_rec->user_id;
     // valid org
     if (!isset($data['org_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Must specify org_uuid');
     }
     $org = AIR2_Record::find('Organization', $data['org_uuid']);
     if (!$org) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid org_uuid');
     }
     if ($org->is_full()) {
         $n = $org->org_display_name;
         throw new Rframe_Exception(Rframe::BAD_DATA, "Max users for '{$n}' reached");
     }
     $uo->Organization = $org;
     // unique org_uuid for user
     $q = Doctrine_Query::create()->from('UserOrg uo');
     $q->andWhere('uo_user_id = ?', $this->parent_rec->user_id);
     $q->andWhere('uo_org_id = ?', $org->org_id);
     if ($q->count() > 0) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'User already belongs to org_uuid');
     }
     return $uo;
 }
 /**
  * Update
  *
  * @param SrcPreference $rec
  * @param array $data
  */
 protected function air_update($rec, $data)
 {
     if (!isset($data['ptv_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "ptv_uuid required");
     }
     $ptv_uuid = $data['ptv_uuid'];
     $preference = AIR2_Record::find('PreferenceTypeValue', $ptv_uuid);
     if (!$preference) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid ptv_id '{$ptv_uuid}'");
     }
     $rec->sp_ptv_id = $preference->ptv_id;
 }
 /**
  * Create
  *
  * @param array $data
  * @return SrcFact
  */
 protected function air_create($data)
 {
     if (!isset($data['fact_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "fact_uuid required");
     }
     $fact = AIR2_Record::find('Fact', $data['fact_uuid']);
     if (!$fact) {
         $u = $data['fact_uuid'];
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid fact_uuid '{$u}'");
     }
     $sf = new SrcFact();
     $sf->Source = $this->parent_rec;
     $sf->Fact = $fact;
     $sf->mapValue('fact_uuid', $fact->fact_uuid);
     return $sf;
 }
 /**
  * Convenience method for adding a SrcOrg record to a new Source.
  *
  * @param Source  $source
  * @param string  $org_uuid
  * @return SrcOrg $src_org
  */
 public static function for_new_source($source, $org_uuid)
 {
     $org = AIR2_Record::find('Organization', $org_uuid);
     if (!$org) {
         throw new Exception("No such Organization for uuid {$org_uuid}");
     }
     $so = new SrcOrg();
     $so->so_home_flag = true;
     $so->so_org_id = $org->org_id;
     $so->so_effective_date = air2_date();
     return $so;
 }
 /**
  * Create
  *
  * @param array $data
  * @return Source
  */
 protected function air_create($data)
 {
     if (!isset($data['sem_email'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "sem_email required");
     }
     if (!isset($data['org_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "org_uuid required");
     }
     $org = AIR2_Record::find('Organization', $data['org_uuid']);
     if (!$org) {
         $u = $data['org_uuid'];
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid org_uuid '{$u}'");
     }
     $s = new Source();
     $s->src_username = $data['sem_email'];
     $s->SrcEmail[0]->sem_email = $data['sem_email'];
     $s->SrcEmail[0]->sem_primary_flag = true;
     $s->SrcOrg[0]->so_home_flag = true;
     $s->SrcOrg[0]->so_org_id = $org->org_id;
     // force opt-in to APMG
     if ($org->org_id != Organization::$APMPIN_ORG_ID) {
         $s->SrcOrg[1]->so_org_id = Organization::$APMPIN_ORG_ID;
         $s->SrcOrg[1]->so_cre_user = 1;
         $s->SrcOrg[1]->so_upd_user = 1;
     }
     return $s;
 }
 /**
  * Get stats data for an organization
  *
  * @param string $org_uuid
  */
 public function get_org_stats($org_uuid)
 {
     if ($this->view != 'json') {
         $this->show_415();
     }
     $org = AIR2_Record::find('Organization', $org_uuid);
     if (!$org) {
         show_404();
     }
     // we do our own "view" here since we are just proxying for search server.
     $search_proxy = new Search_Proxy(array('url' => AIR2_SEARCH_URI . '/report/org', 'cookie_name' => AIR2_AUTH_TKT_NAME, 'params' => array('org_name' => $org->org_name)));
     $response = $search_proxy->response();
     // set headers
     if ($response['response']['http_code'] != 200) {
         header('X-AIR2: server error', false, $response['response']['http_code']);
     }
     if ($this->input->get_post('gzip')) {
         header("Content-Encoding: gzip");
     }
     if (preg_match('/application\\/json/', $this->input->server('HTTP_ACCEPT'))) {
         header("Content-Type: application/json; charset=utf-8");
     } else {
         header("Content-Type: text/javascript; charset=utf-8");
     }
     // respond
     echo $response['json'];
 }
 /**
  * Create
  *
  * @param array $data
  */
 protected function air_create($data)
 {
     if (!isset($data['inq_uuid'])) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "inq_uuid required");
     }
     $inq = AIR2_Record::find('Inquiry', $data['inq_uuid']);
     if (!$inq) {
         $u = $data['inq_uuid'];
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid inq_uuid '{$u}'");
     }
     if (!$inq->user_may_write($this->user)) {
         throw new Rframe_Exception(Rframe::BAD_DATA, "Invalid Inquiry authz");
     }
     $pinq = new ProjectInquiry();
     $pinq->pinq_prj_id = $this->parent_rec->prj_id;
     $pinq->Inquiry = $inq;
     $pinq->mapValue('inq_uuid', $pinq->Inquiry->inq_uuid);
     return $pinq;
 }
 /**
  * Update
  *
  * @param ProjectOrg $rec
  * @param array      $data
  */
 protected function air_update($rec, $data)
 {
     if (isset($data['user_uuid'])) {
         $u = AIR2_Record::find('User', $data['user_uuid']);
         if (!$u) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid user_uuid');
         }
         // user in org, and has W/M role
         $org_and_parents = Organization::get_org_parents($rec->porg_org_id);
         $org_and_parents[] = $rec->porg_org_id;
         $in_org = false;
         foreach ($u->UserOrg as $uo) {
             $r = $uo->AdminRole->ar_code;
             if (in_array($uo->uo_org_id, $org_and_parents)) {
                 if ($r == 'W' || $r == 'M') {
                     $in_org = true;
                     break;
                 }
             }
         }
         if (!$in_org) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'ContactUser not Writer/Manager for organization');
         }
         // set
         $rec->porg_contact_user_id = $u->user_id;
     }
 }
 /**
  * Show a special error for AUTHZ, explaining which users may be contacted
  * to gain access to a submission.
  *
  * @param int $code
  * @param string $msg
  * @param array $rs
  */
 protected function show_html_error($code, $msg, $rs)
 {
     if ($code == AIRAPI::BAD_AUTHZ) {
         $srs = AIR2_Record::find('SrcResponseSet', $rs['uuid']);
         if (!$srs) {
             show_error('Unable to find SrcResponseSet!!!', 500);
         }
         // find inq-org assignments
         $srs_org_ids = array();
         foreach ($srs->Inquiry->InqOrg as $inqorg) {
             $srs_org_ids[$inqorg->iorg_org_id] = true;
         }
         // find all possible contact-users
         $q = Doctrine_Query::create()->from('ProjectOrg po');
         $q->leftJoin('po.ContactUser cu');
         $q->leftJoin('cu.UserEmailAddress e with e.uem_primary_flag = true');
         $q->leftJoin('po.Project p');
         $q->leftJoin('p.ProjectInquiry pi');
         $q->leftJoin('pi.Inquiry i');
         $q->addWhere("i.inq_id = ?", $srs->srs_inq_id);
         $porgs = $q->fetchArray();
         // determine the contact (no system users)
         $contacts = array();
         foreach ($porgs as $porg) {
             if (isset($srs_org_ids[$porg['porg_org_id']])) {
                 if ($porg['ContactUser']['user_type'] == User::$TYPE_AIR_USER) {
                     $contacts[] = $porg['ContactUser'];
                 }
             }
         }
         if (!count($contacts) && count($porgs)) {
             foreach ($porgs as $porg) {
                 if ($porg['ContactUser']['user_type'] == User::$TYPE_AIR_USER) {
                     $contacts[] = $porg['ContactUser'];
                     //not found - add 1st
                 }
             }
         }
         // translate to markup
         foreach ($contacts as $idx => $user) {
             $f = $user['user_first_name'];
             $l = $user['user_last_name'];
             $u = $user['user_username'];
             $s = '<a href="' . air2_uri_for('/user/' . $user['user_uuid']) . '">';
             $s .= $f && $l ? "{$f} {$l}" : "{$u}";
             $s .= '</a>';
             // optional mailto
             if (isset($user['UserEmailAddress'][0]['uem_address'])) {
                 $uem = $user['UserEmailAddress'][0]['uem_address'];
                 $s .= ' at ' . $this->_mailto_markup($uem, $rs['uuid']);
             }
             $contacts[$idx] = $s;
         }
         if (!count($contacts)) {
             $default = AIR2_SUPPORT_EMAIL;
             $contacts[0] = $this->_mailto_markup($default, $rs['uuid']);
         }
         // text
         $contacts = implode(' or ', $contacts);
         $title = "You do not have access to this response";
         $msg = "You're seeing this message because this source shared this " . "particular response with a PIN newsroom that isn't your newsroom. " . "If you want access to this response, feel free to contact " . "{$contacts} and ask to have it emailed to you.";
         $msg .= "<br/><br/>";
         $msg .= "Remember: This is a shared network of sources, but responses " . "to queries are considered the work product of the newsroom(s) that " . "asked the questions. If you do request access to the submission, be " . "aware of that. And if you do get access and choose to contact the source " . "who responded, be clear about how you learned about their response.";
         $this->airoutput->write_error(403, $title, $msg);
     } else {
         return parent::show_html_error($code, $msg, $rs);
     }
 }
 /**
  * Create
  *
  * @param array $data
  * @return Doctrine_Record $rec
  */
 protected function air_create($data)
 {
     $this->require_data($data, array('prj_uuid'));
     // validate
     $p = AIR2_Record::find('Project', $data['prj_uuid']);
     if (!$p) {
         throw new Rframe_Exception(Rframe::BAD_DATA, 'Invalid prj_uuid');
     }
     foreach ($this->parent_rec->PrjOutcome as $pout) {
         if ($pout->pout_prj_id == $p->prj_id) {
             throw new Rframe_Exception(Rframe::BAD_DATA, 'Outcome already includes Project');
         }
     }
     // create!
     $rec = new PrjOutcome();
     $rec->pout_out_id = $this->parent_rec->out_id;
     $rec->pout_prj_id = $p->prj_id;
     $rec->mapValue('prj_uuid', $p->prj_uuid);
     return $rec;
 }
 /**
  * Gets (or creates, if DNE) the manual-input inquiry associated with this
  * particular project.  This is used to manually enter source responses for
  * things like emails and phone calls.
  *
  * @return Inquiry
  */
 public function get_manual_entry_inquiry()
 {
     $me_uuid = air2_str_to_uuid('me-' . $this->prj_name);
     $inq = AIR2_Record::find('Inquiry', $me_uuid);
     if (!$inq) {
         $inq = Inquiry::make_manual_entry();
         $inq->inq_uuid = $me_uuid;
         $inq->add_projects(array($this));
         $orgs = array();
         foreach ($this->ProjectOrg as $porg) {
             $orgs[] = $porg->Organization;
         }
         $inq->add_orgs($orgs);
         $inq->save();
     }
     return $inq;
 }
 /**
  * Initialize input data, showing errors when necessary.
  *
  * @param string  $type
  * @param string  $prime
  * @param string  $merge
  */
 protected function initialize($type, $prime, $merge)
 {
     // check for valid merge type
     if (!isset($this->valid_types[$type])) {
         $this->show_404();
     }
     $this->my_type = $type;
     $this->my_model = $this->valid_types[$type];
     // existence of prime and merge
     $this->prime = AIR2_Record::find($this->my_model, $prime);
     if (!$this->prime) {
         show_error("Invalid prime {$type}", 404);
     }
     $this->merge = AIR2_Record::find($this->my_model, $merge);
     if (!$this->merge) {
         show_error("Invalid merge {$type}", 404);
     }
     // check authz, ignoring src_has_acct (will check later)
     $usr = $this->airuser->get_user();
     if (!$this->prime->user_may_write($usr, false)) {
         show_error("No WRITE authz on prime {$type}", 403);
     }
     if (!$this->merge->user_may_write($usr, false)) {
         show_error("No WRITE authz on merge {$type}", 403);
     }
     // DELETE authz not needed - #2300
     //if (!$this->merge->user_may_delete($usr)) {
     //    $this->error_response("No DELETE authz on merge $type", 403);
     //}
     // check POST/GET params for merge options
     $input_ops = $this->input->get_post(self::$OPS_PARAM);
     if (is_string($input_ops)) {
         $json = json_decode($input_ops, true);
         if ($json) {
             $input_ops = $json;
         }
     }
     $this->ops = $input_ops;
 }