/** at the least, authors are considered a match under the following conditions: 1) exact case-insensitive match of first/last name 2) case-insensitive match of first letter of first name */ public static function bestMatch($qb, $params) { $processed = static::processForStorage($params, $qb->db); $qb->filter(array("name_last" => array($qb->db->ilike, $processed["name_last"]))); $fname = preg_replace("/[^a-zA-Z0-9\\-]/", "", $processed["name_first"]); //remove non-alphanumeric $obj = null; try { //first, try for an exact match on first name $exact_match = clone $qb; if (!empty($processed["name_first"])) { $exact_match->filter(array("name_first" => array($qb->db->ilike, $fname))); } $obj = new static($exact_match); $obj->clean($qb->db); $obj->merge($processed); $obj->update($qb->db); } catch (Exception $e) { if ($e->getCode() == 1) { //the record doesn't exist, try first letters or insert $changes = array(); $filter = clone $qb; if (strlen($fname) == 1) { //if the incoming author name is only the first letter, match by the first letter $filter->filter(array("SUBSTR(name_first,1,1)" => array($qb->db->ilike, $fname))); } else { //try to match based on first letter substring $first_letter = substr($fname, 0, 1); if ($first_letter != "\\") { //don't try to use any wacky first names... $filter->filter(array("SUBSTR(name_first,1,1)" => array($qb->db->ilike, $first_letter))); } else { //create a new record $filter->fail(); } } $obj = static::upsert($filter, $changes, $processed); // if we only had the first letter, and we have more available, update it if (strlen($obj["name_first"]) == 1 && strlen($processed["name_first"]) > 1) { $obj["name_first"] = $processed["name_first"]; //save for this instance static::updateRows($qb->db->filter(array("id" => $obj["id"])), array("name_first" => $processed["name_first"])); } } else { throw $e; } } return $obj; }
/** * Factory helper * * @param array $data * @return array */ public static function cleanData($data, $allowed) { $cls = new static(); $cls->setData($data, $allowed); return $cls->clean(); }