/** * process one entity * * This function may process either the global message, or any embedded entity. * * According to RFC 2046, the processing depends on content type. * * The five discrete top-level media types are: * * [*] text -- textual information. The subtype "plain" in * particular indicates plain text containing no * formatting commands or directives of any sort. Plain * text is intended to be displayed "as-is". * YACS attemps to create a page out of provided text. * * [*] image -- image data. "Image" requires a display device * (such as a graphical display, a graphics printer, or a * FAX machine) to view the information. * YACS stores the image entity in the file system, and * creates an article to reference it. * * [*] audio -- audio data. "Audio" requires an audio output * device (such as a speaker or a telephone) to "display" * the contents. * YACS stores the audio entity in the file system, and * creates an article to reference it. * * [*] video -- video data. "Video" requires the capability * to display moving images, typically including * specialized hardware and software. * YACS stores the video entity in the file system, and * creates an article to reference it. * * [*] application -- some other kind of data, typically * either uninterpreted binary data or information to be * processed by an application. * YACS stores the entity in the file system, and * creates an article to reference it. * * [*] multipart -- data consisting of multiple entities of * independent data types. * YACS separate entities, attempts to locate an article, * and attach all other entities to it. * * [*] message -- an encapsulated message. A body of media * type "message" is itself all or a portion of some kind * of message object. * YACS processes only sub types 'message/rfc822' and 'message/delivery-status', as plain text. * * @link http://www.faqs.org/rfcs/rfc2046.html MIME Media Types * * @param string the entity to be processed * @param array poster attributes * @param string the main anchor to use * @param string reference of the object to be extended, if any * @return string reference to the created object, or NULL * * @see files/files.php * @see images/images.php */ public static function process_entity($entity, $user, $anchor, $target = NULL) { global $context; // sanity check if (!trim($entity)) { return NULL; } // split headers and body if (!($position = strpos($entity, "\n\n"))) { Logger::remember('agents/messages.php: Can not split header and body', $entity); return NULL; } // parse and decode all headers $entity_headers = Messages::parse_headers(substr($entity, 0, $position)); if (!$entity_headers) { $entity_headers[] = array('name' => 'Content-Type', 'value' => 'text/plain; charset=us-ascii'); } // determine content encoding $content_transfer_encoding = '7bit'; foreach ($entity_headers as $header) { if (preg_match('/Content-Transfer-Encoding/i', $header['name'])) { $content_transfer_encoding = $header['value']; break; } } // decode the entity $content = Messages::decode(substr($entity, $position + 2), $content_transfer_encoding); // determine content type $content_type = 'text/plain'; foreach ($entity_headers as $header) { if (preg_match('/Content-Type/i', $header['name'])) { $content_type = $header['value']; break; } } // nothing has been created yet $reference = NULL; // text type -- create a page or a comment out of it if (preg_match('/^text\\//i', $content_type)) { // transcode content, if necessary if (preg_match('/-(8859|1252)/', $content_type)) { $content = utf8::from_iso8859($content); } $reference = Messages::submit_page($entity_headers, $content, $user, $anchor, $target); // image type -- save as an image file and create a page to reference it } elseif (preg_match('/^image\\//i', $content_type)) { $reference = Messages::submit_image($entity_headers, $content, $user, $anchor, $target); // audio, video or application types -- create a page and attache the file to it } elseif (preg_match('/^(audio|video|application)\\//i', $content_type)) { $reference = Messages::submit_file($entity_headers, $content, $user, $anchor, $target); // multipart -- split entities and process each of them } elseif (preg_match('/^multipart\\//i', $content_type)) { // look for the boundary if (!preg_match('/boundary="*([a-zA-Z0-9\'\\(\\)\\+_,-\\.\\/:=\\?]+)"*\\s*/i', $content_type, $matches)) { Logger::remember('agents/messages.php: No multipart boundary in ' . $content_type, $content_type); return NULL; } // split entities $entities = explode('--' . $matches[1], $content); if (@count($entities) < 3) { Logger::remember('agents/messages.php: Empty multipart message', $content); return NULL; } // if multipart/alternative, select only one entity if (preg_match('/^multipart\\/alternative/i', $content_type)) { // ignore preamble and epilogue parts; start from the end for ($index = count($entities) - 1; $index > 1; $index--) { // stop when we actually create some content if ($reference = Messages::process_entity($entities[count($entities) - 2], $user, $anchor, $target)) { break; } } // we have a mix of entities to save } else { // skip preamble and epilogue for ($index = 1; $index < count($entities) - 1; $index++) { // process one entity $reference = Messages::process_entity($entities[$index], $user, $anchor, $target); // post everything at the same place if (!$anchor) { $anchor = $reference; } // combine all elements at one single place if (!$target) { $target = $reference; } } } // message/delivery-status -- create a page or a comment out of it } elseif (preg_match('/^message\\/delivery-status/i', $content_type)) { $reference = Messages::submit_page($entity_headers, nl2br($content), $user, $anchor, $target); // message/rfc822 -- process it as the main entity } elseif (preg_match('/^message\\/rfc822/i', $content_type)) { $reference = Messages::process_entity($entity_headers, $content, $user, $anchor, $target); // unknown type } else { Logger::remember('agents/messages.php: Do not know how to process type ' . $content_type); return NULL; } // job done return $reference; }
function parse_cdata($parser, $text) { // transcode non-UTF-8 data if ($this->encoding != 'UTF-8') { $text = utf8::from_iso8859($text); } // skip entry, feed, entries first time we see them if ($this->elements_stack[0] == $this->current_field or !$this->current_field) { return; } // we are describing a feed if ($this->elements_stack[0] == 'feed') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->feed[$this->current_name_space][$this->current_field])) { $this->feed[$this->current_name_space][$this->current_field] .= $text; } else { $this->feed[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->feed[$this->current_field])) { $this->feed[$this->current_field] .= $text; } else { $this->feed[$this->current_field] = $text; } } // we are describing one information entry } elseif ($this->elements_stack[0] == 'entry') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->current_entry[$this->current_name_space][$this->current_field])) { $this->current_entry[$this->current_name_space][$this->current_field] .= $text; } else { $this->current_entry[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->current_entry[$this->current_field])) { $this->current_entry[$this->current_field] .= $text; } else { $this->current_entry[$this->current_field] = $text; } } // echo '.'.$this->current_entry[$this->current_field].BR; // we are describing a textinput } elseif ($this->elements_stack[0] == 'textinput') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->textinput[$this->current_name_space][$this->current_field])) { $this->textinput[$this->current_name_space][$this->current_field] .= $text; } else { $this->textinput[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->textinput[$this->current_field])) { $this->textinput[$this->current_field] .= $text; } else { $this->textinput[$this->current_field] = $text; } } // we are describing an image } elseif ($this->elements_stack[0] == 'image') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->image[$this->current_name_space][$this->current_field])) { $this->image[$this->current_name_space][$this->current_field] .= $text; } else { $this->image[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->image[$this->current_field])) { $this->image[$this->current_field] .= $text; } else { $this->image[$this->current_field] = $text; } } } }
function parse_cdata($parser, $text) { // transcode non-UTF-8 data if ($this->encoding != 'UTF-8') { $text = utf8::from_iso8859($text); } // skip item, channel, items first time we see them if ($this->elements_stack[0] == $this->current_field or !$this->current_field) { return; } // we are describing a channel if ($this->elements_stack[0] == 'channel') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->channel[$this->current_name_space][$this->current_field])) { $this->channel[$this->current_name_space][$this->current_field] .= $text; } else { $this->channel[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->channel[$this->current_field])) { $this->channel[$this->current_field] .= $text; } else { $this->channel[$this->current_field] = $text; } } // we are describing one information item } elseif ($this->elements_stack[0] == 'item') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->current_item[$this->current_name_space][$this->current_field])) { $this->current_item[$this->current_name_space][$this->current_field] .= $text; } else { $this->current_item[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->current_item[$this->current_field])) { $this->current_item[$this->current_field] .= $text; } else { $this->current_item[$this->current_field] = $text; } } // we are describing a textinput } elseif ($this->elements_stack[0] == 'textinput') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->textinput[$this->current_name_space][$this->current_field])) { $this->textinput[$this->current_name_space][$this->current_field] .= $text; } else { $this->textinput[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->textinput[$this->current_field])) { $this->textinput[$this->current_field] .= $text; } else { $this->textinput[$this->current_field] = $text; } } // we are describing an image } elseif ($this->elements_stack[0] == 'image') { if (isset($this->current_name_space) && $this->current_name_space) { if (isset($this->image[$this->current_name_space][$this->current_field])) { $this->image[$this->current_name_space][$this->current_field] .= $text; } else { $this->image[$this->current_name_space][$this->current_field] = $text; } } else { if (isset($this->image[$this->current_field])) { $this->image[$this->current_field] .= $text; } else { $this->image[$this->current_field] = $text; } } } }