/** * Converts an ATOM encoded Salmon post to a SalmonEntry. * @param string $atom_string The raw POST to the Salmon endpoint. * @return SalmonEntry An object representing the information in the POST. */ public static function from_atom($atom_string) { $xml_parser = xml_parser_create(''); $xml_values = array(); $xml_tags = array(); if (!$xml_parser) { return false; } xml_parser_set_option($xml_parser, XML_OPTION_TARGET_ENCODING, 'UTF-8'); xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, 0); xml_parser_set_option($xml_parser, XML_OPTION_SKIP_WHITE, 1); xml_parse_into_struct($xml_parser, trim($atom_string), $xml_values); xml_parser_free($xml_parser); $entry = new SalmonEntry(); $breadcrumbs = array(); for ($i = 0; $atom = $xml_values[$i]; $i++) { // Only process one entry. This could be generalized to a feed later. if (strtolower($atom['tag']) == 'entry' && strtolower($atom['type']) == 'close') { break; } // Keep a "breadcrumb" list of the tag hierarchy we're currently in. $breadcrumbs[$atom['level']] = $atom['tag']; // Parse individual attributes one at a time. switch (strtolower($atom['tag'])) { case 'id': $entry->id = $atom['value']; break; case 'name': if (SalmonEntry::parent_is($atom, 'author', $breadcrumbs)) { $entry->author_name = $atom['value']; } break; case 'uri': if (SalmonEntry::parent_is($atom, 'author', $breadcrumbs)) { $entry->author_uri = $atom['value']; } break; case 'thr:in-reply-to': $entry->thr_in_reply_to = $atom['value']; break; case 'content': $entry->content = $atom['value']; break; case 'title': $entry->title = $atom['value']; break; case 'updated': $entry->updated = $atom['value']; break; case 'sal:signature': $entry->salmon_signature = $atom['value']; break; } } $entry->webfinger = WebFingerAccount::from_acct_string($entry->author_uri); return $entry; }