/** * Tag an object using raw connections. Returns true if the tag was added, * or false if the tag already existed. * * @param int $xid * @param string $type * @param string $tag * @return boolean */ public static function make_tag($xid, $type, $tag) { // sanity! if (!is_numeric($xid) || $xid < 1) { throw new Exception("Bad tag XID({$xid})"); } if (!in_array($type, array('I', 'P', 'S', 'R'))) { throw new Exception("Bad tag TYPE({$type})"); } if (!is_string($tag) || strlen($tag) < 1) { throw new Exception("Bad tag '{$tag}'"); } // fetch/create tag master $tm_id = TagMaster::get_tm_id($tag); // params $usrid = defined('AIR2_REMOTE_USER_ID') ? AIR2_REMOTE_USER_ID : 1; $dtim = air2_date(); $cols = array('tag_tm_id', 'tag_xid', 'tag_ref_type', 'tag_cre_user', 'tag_upd_user', 'tag_cre_dtim', 'tag_upd_dtim'); $vals = array($tm_id, $xid, $type, $usrid, $usrid, $dtim, $dtim); // insert ignore $conn = AIR2_DBManager::get_master_connection(); $colstr = implode(',', $cols); $params = air2_sql_param_string($cols); $n = $conn->exec("insert ignore into tag ({$colstr}) values ({$params})", $vals); // if tag existed, update userstamp $tag_was_new = true; if ($n == 0) { $tag_was_new = false; $set = "tag_upd_user={$usrid}, tag_upd_dtim='{$dtim}'"; $where = "tag_tm_id={$tm_id} and tag_xid={$xid} and tag_ref_type='{$type}'"; $conn->exec("update tag set {$set} where {$where}"); } return $tag_was_new; }
/** * Static function to find the tm_id for a string tag. If the tag doesn't * exist, it will be created. * * A doctrine exception will be thrown if the tag string is invalid * * @param string $tagstr * @return int */ public static function get_tm_id($tagstr) { if (!$tagstr || !is_string($tagstr) || !strlen($tagstr)) { throw new Exception('Invalid non-string tag'); } // check cache $lower = strtolower($tagstr); if (isset(self::$TM_ID_CACHE[$lower])) { return self::$TM_ID_CACHE[$lower]; } // lookup or create $tm = Doctrine::getTable('TagMaster')->findOneBy('tm_name', $tagstr); if (!$tm) { $tm = new TagMaster(); $tm->tm_name = $tagstr; $tm->tm_type = TagMaster::$TYPE_JOURNALISTIC; $tm->save(); // could throw exception } // cache and return self::$TM_ID_CACHE[$lower] = $tm->tm_id; return $tm->tm_id; }
/** * Tag sources in a bin (must have read-authz on the actual source) * * @param User $u * @param Bin $bin * @param array $params * @return array $counts */ public function tag_sources($u, $bin, $params) { $stats = self::init_stats($stats = array('total', 'insert', 'duplicate', 'invalid')); // validate params if (is_string($params) && strlen($params) > 0) { $tm_id = TagMaster::get_tm_id($params); } else { if (is_array($params) || is_int($params)) { $tm_id = isset($params['tm_id']) ? $params['tm_id'] : $params; $tm = AIR2_Record::find('TagMaster', $tm_id); if (!$tm) { throw new Exception("Invalid tm_id({$tm_id})"); } } else { throw new Exception('Invalid params for bulk tagging'); } } // calculate total $conn = AIR2_DBManager::get_master_connection(); $q = "select count(*) from bin_source where bsrc_bin_id = ?"; $stats['total'] = $conn->fetchOne($q, array($bin->bin_id), 0); // duplicates $read_org_ids = $u->get_authz_str(ACTION_ORG_SRC_READ, 'soc_org_id'); $cache = "select soc_src_id from src_org_cache where {$read_org_ids}"; $where = "where bsrc_bin_id=? and bsrc_src_id in ({$cache})"; $src_ids = "select bsrc_src_id from bin_source {$where}"; $tags = "tag_tm_id={$tm_id} and tag_ref_type='S' and tag_xid in ({$src_ids})"; $q = "select count(*) from tag where {$tags}"; $stats['duplicate'] = $conn->fetchOne($q, array($bin->bin_id), 0); // fast-sql insert $select = "select bsrc_src_id,'S',{$tm_id},?,?,?,? from bin_source {$where}"; $flds = 'tag_xid,tag_ref_type,tag_tm_id,tag_cre_user,tag_upd_user,tag_cre_dtim,tag_upd_dtim'; $ins = "insert ignore into tag ({$flds}) {$select}"; $params = array($u->user_id, $u->user_id, air2_date(), air2_date(), $bin->bin_id); $stats['insert'] = $conn->exec($ins, $params); // invalid == no authz on source $stats['invalid'] = $stats['total'] - $stats['insert'] - $stats['duplicate']; return $stats; }