Na Web, feeds são resumos do conteúdo que podem ser lidos por máquina, em geral organizados em ordem cronológica reversa. A maioria dos feeds tem sido usada tradicionalmente para organizar o conteúdo de um blog nos populares formatos baseados em RSS ou Atom XML. Depois de publicado por um site, o conteúdo pode ser lido por meio de agregadores fáceis e simples ou transformado e interpretado por produtos de software em rede.
Feeds organizados são consumidos dessa forma desde 1999. Atualmente, os usuários da Web também têm consumido conteúdo de forma mais social, por meio de sites como Facebook, MySpace e Twitter.
Esses sites operam ao permitir que as pessoas marquem outros usuários como “amigos” e agreguem as atividades dos amigos por meio de painéis unificados. Em vez de assinar um único fluxo de conteúdo, os usuários desses sites assinam o conteúdo indivíduos, esperando ver tudo o que elas criam, carregam e compartilham.
Um fluxo de atividade (também chamado às vezes de lifestream) é a coleção de todas as atividades que uma pessoa executa em determinado site. Os usuários da Web confiam cada vez mais em fluxos de atividades para consumo de informações, faz sentido ser capaz de organizar e assinar os dados de fluxos de atividade. Já que o RSS e o Atom não suportam metadados sociais, é necessário um novo formato para organizar a atividade social.
Este artigo apresenta as funcionalidades e o potencial do Activity Streams, um padrão em desenvolvimento que estende o Atom para expressar objetos sociais. Embora seja um padrão novo, o Activity Streams está se tornando rapidamente o método real para organização de atividade entre aplicativos da Web.
Por exemplo, MySpace, Facebook e TypePad agora produzem feeds XML em Activity Streams. Mas essa tecnologia não serve apenas para o ambiente Web do consumidor. À medida que intranets corporativas e softwares internos se tornam mais sociais, sólidas razões comerciais apoiam a implementação do Activity Streams como recurso.
Origem do Activity Streams
O Activity Streams surgiu do DiSo Project: um esforço de software livre para criar uma Web social descentralizada usando plug-ins desenvolvidos para a plataforma de blogs WordPress como ponto de partida. No modelo DiSo, o perfil de cada usuário é um blog WordPress separado que pode ser hospedado em qualquer infraestrutura conectada à Internet. As ações sociais ocorrem então pela Internet entre esses sites WordPress.
Um formato de organização é uma parte importante dessa abordagem. Ao contrário de um site como o Facebook, que abriga centenas de milhões de membros sob um único teto digital, o DiSo supõe que há apenas um usuário por site WordPress. Portanto, o único modo de dar uma olhada no que seus amigos estão fazendo é assinar seus feeds, analisá-los nas estruturas de dados internas e visualizá-los em uma interface agregada.
XML é a tecnologia perfeita para implementar essa abordagem porque funciona entre plataformas, é fácil de publicar e analisar e não precisa de um especialista em tecnologia. O DiSo Project foi um passo à frente e criou o padrão Activity Streams como extensão do formato de feed Atom.O Atom foi concebido como alternativa ao RSS que pode ser:
- 100% neutro no que se refere ao fornecedor
- Implementado por qualquer um
- Livremente extensível por qualquer um
- Especificado de forma limpa e completa
A neutralidade de fornecedor, extensibilidade e especificações limpas são essenciais para um padrão que resista ao futuro. Para o padrão Activity Streams ser uma base viável para a Web social descentralizada, também deve seguir esses princípios. Graças à extensibilidade do Atom, o Activity Streams pode aproveitar a lógica de aplicativo e os analisadores existentes. Se você já dispuser de código para lidar com o Atom (ou usa uma das muitas bibliotecas existentes), será necessário desenvolver apenas algum código extra.
Em março de 2009, o MySpace se tornou o primeiro grande provedor de mídia social a publicar feeds no formato Activity Streams. Desde então, muitos outros fizeram o mesmo, incluindo Facebook, Hulu, TypePad e Opera. Mas o escopo do Activity Streams não se limita a sites como o Facebook. Intranets, por exemplo, podem ser muito melhoradas pelo conhecimento da atividade social dentro da empresa ou entre empresas.
O formato Activity Streams também cria possibilidades para agregar múltiplos fluxos para acompanhar as interações de uma empresa e quantificar o progresso em direção a objetivos entre sites comerciais de mídia social, além de apresentar muitas oportunidades para novos tipos de aplicativos de software.
Anatomia do fluxo de atividade
O Activity Streams estende o Atom com alguns novos elementos de esquema baseados no espaço para nome XML http://activitystrea.ms/spec/1.0/.
Um feed Atom consiste em um único elemento principal feed, que inclui alguns metadados iniciais (por exemplo, o título do feed, autores, sua URL e a URL do conteúdo geral a que se refere).
Dentro desse elemento principal está qualquer número de elementos entry, que definem itens de conteúdo dentro do feed. A listagem 1 apresenta uma amostra de feed Atom com um único elemento entry, derivado do meu próprio Web site:
Listagem 1. Amostra de feed Atom do Web site do autor
<?xml version="1.0" encoding="UTF-8"?><br /><feed<br /> xmlns="http://www.w3.org/2005/Atom"<br /> xmlns:thr="http://purl.org/syndication/thread/1.0"<br /> xmlns:activity="http://activitystrea.ms/spec/1.0/"<br /> xml:lang="en"<br /> xml:base="http://benwerd.com/wp-atom.php"<br /> ><br /> <title type="text">Ben Werdmuller von Elgg</title><br /> <subtitle type="text"></subtitle><br /><br /> <updated>2010-05-01T13:13:04Z</updated><br /><br /> <link rel="alternate" type="text/html" href="http://benwerd.com" /><br /> <id>http://benwerd.com/feed/atom/</id><br /> <link rel="self" type="application/atom+xml" href="http://benwerd.com<br />/feed/atom/" /><br /><br /> <entry><br /> <id>http://benwerd.com/2010/05/sample-article-title/#actionID</id><br /> <title type="text">Ben posted a blog entry.</title><br /> <published>2010-05-01T13:06:22Z</published><br /> <author><br /> <name>Ben Werdmuller von Elgg</name><br /> <uri>http://benwerd.com/</uri><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/person<br /> </activity:object-type><br /> </author><br /> <activity:verb><br /> http://activitystrea.ms/schema/1.0/post<br /> </activity:verb><br /> <activity:object><br /> <title type="html"><![CDATA[Sample article title]]><br /></title><br /> <link rel="alternate" type="text/html"<br /> href="http://benwerd.com/2010/05/sample-article-title/" /><br /> <id>http://benwerd.com/2010/05/sample-article-title/</id><br /> <published>2010-05-01T13:06:22Z</published><br /> <content type="html" ><br /> ...<br /> </content><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/article<br /> </activity:object-type><br /> </activity><br /> </entry><br /></feed>O Activity Streams estende o modelo do Atom inserindo dados sobre objetos sociais dentro de cada elemento entry. As possibilidades existentes para elementos-filho do elemento
entry
não são afetadas. Por exemplo, é possível incluir um título e uma
descrição que possa ser lida por humanos sobre a ação dentro dos
elementos-filho title e content, ou incluir metadados sociais dentro de um elemento padrão content formatado no Atom.
Um elemento entry do Activity Streams sempre contém três elementos principais que indicam:
- O agente: a pessoa que executa a ação (exemplo: John Doe)
- O verbo: o tipo de ação sendo executada (exemplo: added)
- O objeto: o item sobre o qual se age (exemplo: Ben’s photo)
Em algumas circunstâncias, um elemento
entry também pode conter o destino, um objeto contêiner no qual a ação foi executada ou colocada (por exemplo:
John’s photo gallery na ação
John Doe added Ben’s photo to John’s photo gallery).
Os seguintes elementos são usados dentro do elemento entry para definir verbos, objetos, agentes e destinos:
- O elemento Activity:verb contém um URI Atom que define o verbo que está sendo usado.
- O elemento Activity:object contém vários elementos activity:object-type (descritos no próximo parágrafo), além de outros elementos necessários para descrever o objeto da ação.
- Os agentes são definidos pelo elemento atom:author existente, como mostrado na listagem 1.
- O elemento Activity:target é similar ao elemento activity:object, mas especificamente define o destino onde ele existe.
Dentro dos elementos activity:object, activity:target e atom:author há um ou mais elementos Activity:object-type que contêm um URI Atom que define o objeto-pai.
Cada tipo de verbo e objeto tem um URI Atom que define as propriedades que pode conter. Por exemplo, a listagem 2 mostra alguns URIs Atom da especificação base do Activity Streams que definem uma pessoa, verbo a compartilhar e post de blog:
Listagem 2. URIs base do Activity Streams para pessoas, compartilhamento e posts de blog
http://activitystrea.ms/schema/1.0/person<br />http://activitystrea.ms/schema/1.0/share<br />http://activitystrea.ms/schema/1.0/articleEsses URIs correspondem a entradas que podem ser lidas por humanos na especificação do Activity Streams.
Na listagem 3, converti o elemento entry do exemplo de feed Atom na listagem 1 em uma representação em Activity Streams de Ben Werdmuller postando uma entrada de blog:
Listagem 3. Versão social da listagem 1 em formato de Activity Streams
<?xml version="1.0" encoding="UTF-8"?><br /><feed<br /> xmlns="http://www.w3.org/2005/Atom"<br /> xmlns:thr="http://purl.org/syndication/thread/1.0"<br /> xmlns:activity="http://activitystrea.ms/spec/1.0/"<br /> xml:lang="en"<br /> xml:base="http://benwerd.com/wp-atom.php"<br /> ><br /> <title type="text">Ben Werdmuller von Elgg</title><br /> <subtitle type="text"></subtitle><br /><br /> <updated>2010-05-01T13:13:04Z</updated><br /><br /> <link rel="alternate" type="text/html" href="http://benwerd.com" /><br /> <id>http://benwerd.com/feed/atom/</id><br /> <link rel="self" type="application/atom+xml" href="http://benwerd.com<br />/feed/atom/" /><br /><br /> <entry><br /> <id>http://benwerd.com/2010/05/sample-article-title/#actionID</id><br /> <title type="text">Ben posted a blog entry.</title><br /> <published>2010-05-01T13:06:22Z</published><br /> <author><br /> <name>Ben Werdmuller von Elgg</name><br /> <uri>http://benwerd.com/</uri><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/person<br /> </activity:object-type><br /> </author><br /> <activity:verb><br /> http://activitystrea.ms/schema/1.0/post<br /> </activity:verb><br /> <activity:object><br /> <title type="html"><![CDATA[Sample article title]]><br /></title><br /> <link rel="alternate" type="text/html"<br /> href="http://benwerd.com/2010/05/sample-article-title/" /><br /> <id>http://benwerd.com/2010/05/sample-article-title/</id><br /> <published>2010-05-01T13:06:22Z</published><br /> <content type="html" ><br /> ...<br /> </content><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/article<br /> </activity:object-type><br /> </activity><br /> </entry><br /></feed>Observe que:
- A declaração de espaço de nomes xmlns:activity=http://activitystrea.ms/spec/1.0/ foi adicionada acima do feed para definir o vocabulário do Activity Streams.
- O ID do elemento Atom entry geral e seu elemento activity:object contido não podem ser idênticos.
- Os detalhes sobre o post do blog – aqueles no elemento entry padrão na listagem 1 – agora se encontram no elemento activity:object, juntamente com o elemento activity:object-type necessário.
- Os elementos padrão atom:title e atom:content foram retidos para uso com analisadores que não suportam feeds de Activity Streams.
Embora essa ação tenha apenas um único objeto, é válida para incorporar múltiplos objetos em uma entrada de Activity Streams – por exemplo, para modificar a listagem 3 a fim de representar a ação Ben posted two blog entries. O blog como um todo pode ser adicionado como elemento activity:target para representar a ação semanticamente um pouco diferente Ben added two entries to his blog.
Usei deliberadamente tipos de conteúdo básicos no exemplo de feed na listagem 3. Contudo, a especificação do Activity Streams permite a especialização de verbos e objetos.
Por exemplo, um aplicativo de gerenciamento de projeto colaborativo pode indicar quando os usuários concluem as tarefas. O software pode definir um verbo especializado para conclusão e um objeto especializado para tarefa, cada um com seu URI Atom personalizado. Contudo, muitas ferramentas compatíveis com Activity Streams talvez não saibam o que esses termos querem dizer, o que pode causar problemas durante a agregação.
Para reduzir a probabilidade de isso ocorrer, as entradas dos feeds do Activity Streams podem incluir mais de um verbo que descreva a mesma atividade. Nesses casos, é uma boa ideia incluir o inteiro conjunto de ancestrais de determinado verbo ou objeto. Complete pode ser simplesmente uma especialização do verbo base update, e Task pode ser uma especialização do objeto base note. A entrada resultante do Activity Streams pode ser semelhante à listagem 4:
Listagem 4. Uma hipotética tarefa concluída em um feed de Activity Streams
<entry><br /> <id>http://samplecompany.com/tasks/activity/23432/3242345/</id><br /> <title type="text">Roger Taylor completed a task.</title><br /> <published>2010-05-01T13:06:22Z</published><br /> <author><br /> <name>Roger Taylor</name><br /> <uri>http://samplecompany.com/people/Roger+Taylor/</uri><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/person<br /> </activity:object-type><br /> </author><br /> <activity:verb><br /> http://samplecompany.com/activity/schema/1.0/complete<br /> </activity:verb><br /> <activity:verb><br /> http://activitystrea.ms/schema/1.0/update<br /> </activity:verb><br /> <activity:object><br /> <title type="html"><![CDATA[Sample task]]></title><br /> <link rel="alternate" type="text/html" href="http://samplecompany.com<br />/tasks/23432/" /><br /> <id>http://samplecompany.com/tasks/23432/</id><br /> <published>2010-05-01T13:06:22Z</published><br /> <content type="html" ><br /> ...<br /> </content><br /> <activity:object-type><br /> http://samplecompany.com/activity/schema/1.0/task<br /> </activity:object-type><br /> <activity:object-type><br /> http://activitystrea.ms/schema/1.0/note<br /> </activity:object-type><br /> </activity><br /></entry>Observações:
- Cada URI de tipo de objeto obtém seu próprio elemento activity:object-type.
- Cada URI de verbo obtém seu próprio elemento activity:verb.
- Os tipos de objeto e verbo especializados devem ter seus próprios URIs especializados.
No momento em que escrevo este artigo, a documentação wiki do Activity Streams alista 21 tipos de verbos e 25 de objetos, com 11 tipos de verbos base e 19 de objetos base definidos no documento de especificação formal. Um analisador de Activity Streams deve reconhecer cada um desses verbos e objetos base, e lidar com eles de forma apropriada.
Criando um codificador de Activity Streams
A simplicidade do padrão Activity Streams torna fácil criar um codificador. Aqui, criaremos um objeto codificador PHP básico que representa um feed Activity Streams ao convertê-lo para uma cadeia de caractere (por exemplo, usando a instrução PHP echo com ele).
Primeiro, crie a classe de stub, ActivityStreamEncoder, e defina seu método construtor para usar um ID, título e descrição para a entrada. Defina também um array particular, $entries, para conter suas entradas do Activity Streams. A listagem 5 mostra a classe e o construtor:
Listagem 5. Classe ActivityStreamEncoder base com o construtor
class ActivityStreamsEncoder {<br /><br /> private $id = "";<br /> private $title = "";<br /> private $link = "";<br /> private $entries = array();<br /><br /> function __construct($id, $title = '', $description = '') {<br /> $this->id = $id;<br /> $this->title = $title;<br /> $this->description = $description;<br /> } <br />}A seguir, adicione algumas classes base para entradas, objetos e autores. Visto que os verbos simplesmente consistem em URIs, sempre faça a referência a eles como cadeias de caracteres. As entradas e os objetos definirão sua data publicada como data atual (usando a função PHP time()) por padrão. A listagem 6 mostra a classe base das entradas:
Listagem 6. Classe base ActivityStreamEntry
class ActivityStreamsEntry {<br /><br /> public $id = "";<br /> public $title = "";<br /> public $author;<br /> public $objects = array();<br /> public $verbs = array();<br /> public $published;<br /><br /> function __construct() {<br /> $this->published = time();<br /> }<br /><br /> function addObject(ActivityStreamsObject $object) {<br /> $this->objects[] = $object;<br /> }<br /> function addVerb(string $verb) {<br /> $this->verbs[] = $verb;<br /> }<br /> function setAuthor(ActivityStreamsAuthor $author) {<br /> $this->author = $author;<br /> }<br /><br />}A classe ActivityStreamsEntry também inclui métodos auxiliares simples para adicionar um autor, objetos e verbos à entrada, assegurando um tipo de variável adequado para esses valores.
Visto que os elementos filho de um elemento activity:object são variáveis, pode-se obter e definir dinamicamente as propriedades de ActivityStreamsObject – sua classe de objeto – usando os métodos getProperty() e setProperty() personalizados, respectivamente. Isso é definido na listagem 7, que mostra ActivityStreamsObject e a classe do autor, que é classe-filha de ActivityStreamsObject.
Listagem 7. Classes de codificador de objeto e autor do Activity Streams
class ActivityStreamsObject {<br /> public $properties = array();<br /><br /> function getProperty($property_name) {<br /> if (isset($this->properties[$property_name])) <br />return $this->properties[$property_name];<br /> }<br /> function setProperty($property_name, $property_value) {<br /> $this->properties[$property_name] = $property_value;<br /> }<br /> function __construct() {<br /> $this->published = time();<br /> }<br /><br /> function addObjectType($object_type) {<br /> if (!isset($this->properties['object-type'])) $this->properties<br /> ['object-type'] = array();<br /> $this->properties['object-type'][] = (string) $object_type;<br /> }<br /><br /> function __toString() {<br /> $string = '';<br /> $string .= "\n<activity:object>";<br /> foreach($this->properties as $property => $value) {<br /> if (!is_array($value)) $value = array($value);<br /> switch($property) {<br /> case 'title':<br /> $attr = 'type="html"';<br /> break;<br /> case 'link':<br /> $attr = 'rel="alternate" type="text/html" <br />href="'.$value[0].'"';<br /> $value = array(''); <br /> break;<br /> default: $attr = '';<br /> break;<br /> }<br /> if (sizeof($value))<br /> foreach($value as $val) {<br /> if (empty($val))<br /> $string .= "\n\t<{$property} {$attr} />";<br /> else if ($property == 'content' || $property == 'title')<br /> $string .= "\n\t<{$property}<br /> {$attr}><![CDATA[{$val}]]></{$property}>";<br /> else<br /> $string .= "\n\t<{$property} {$attr}><br />{$val}</{$property}>";<br /> }<br /> }<br /> $string .= "\n</activity:object>";<br /><br /> return $string;<br /> }<br /><br />}<br /><br />class ActivityStreamsAuthor extends ActivityStreamsObject {<br /> function __construct() {<br /> $this->addObjectType("http://activitystrea.ms/schema/1.0/person");<br /> }<br /> function __toString() {<br /> $string = parent::__toString();<br /> $string = str_replace('activity:object>','author>',$string);<br /> return $string;<br /> }<br />}Aqui suas classes representam uma versão estruturada dos elementos activity:object e atom:author, respectivamente. Ao tentar convertê-las para cadeia de caractere (por exemplo, ecoando-as no navegador), XML estruturado é retornado automaticamente. Assegurando que a classe PHP equivalente de cada elemento do Activity Streams é responsável por sua própria representação XML, é possível criar um conjunto limpo de objetos manipuladores do Activity Streams.
Na listagem 8, adicione uma classe similar para representar o elemento entry em geral:
Listagem 8. Classe PHP que representa um elemento entry do Activity Streams
class ActivityStreamsEntry {<br /><br /> public $id = "";<br /> public $title = "";<br /> public $author;<br /> public $objects = array();<br /> public $verbs = array();<br /> public $published;<br /><br /> function __construct() {<br /> $this->published = time();<br /> }<br /><br /> function addObject(ActivityStreamsObject $object) {<br /> $this->objects[] = $object;<br /> }<br /> function addVerb($verb) {<br /> $this->verbs[] = $verb;<br /> }<br /> function setAuthor(ActivityStreamsAuthor $author) {<br /> $this->author = $author;<br /> }<br /><br /> function __toString() {<br /><br /> $string = '';<br /> $string .= "\n<entry>";<br /> $published = date('c',$this->published);<br /> $string .= <<< END<br /> <id>{$this->id}</id><br /> <title type="text"><![CDATA[{$this->title}]]></title><br /><br /> <published>{$published}</published><br />END;<br /> if ($this->author instanceof ActivityStreamsAuthor) $string .= <br />$this->author;<br /> if (sizeof($this->verbs)) foreach($this->verbs as $verb)<br /> $string .= "\n<activity:verb>{$verb}</activity:verb>";<br /> if (sizeof($this->objects)) foreach($this->objects as $object)<br /> if ($object instanceof ActivityStreamsObject) $string .= $object;<br /> $string .= "\n</entry>";<br /> return $string; <br /> }<br />}Na listagem 8, o código também inclui os métodos addVerb(), addObject() e setAuthor() para manipular os elementos activity:verb, activity:object e atom:author do Activity Streams dentro do elemento entry.
Por fim, é possível modificar sua classe ActivityStreamsEncoder geral para conter um método addEntry() correspondente (adicionar seus objetos ActivityStreamsEntry a partir da listagem 8 do fluxo) e um método mágico __toString() para ecoar o feed do Activity Streams inteiro.
O método __toString() inclui o cabeçalho XML e as declarações de espaço de nomes necessários para o uso correto do vocabulário do Activity Streams. A listagem 9 mostra os métodos addEntry() e __toString():
Listagem 9. Métodos addEntry() e __toString() para a classe ActivityStreamsEncoder na listagem 5
function addEntry(ActivityStreamsEntry $entry) {<br /> $this->entries[] = $entry;<br /> }<br /><br /> function __toString() {<br /> // Display header<br /> $string = '';<br /> $updated_time = date('c',time());<br /> $string .= <<<END<br /><?xml version="1.0" encoding="UTF-8"?><br /><feed<br />xmlns="http://www.w3.org/2005/Atom"<br />xmlns:thr="http://purl.org/syndication/thread/1.0"<br />xmlns:activity="http://activitystrea.ms/spec/1.0/"<br />xml:lang="en"<br />><br /><br /><title type="text">{$this->title}</title><br /><updated>{$updated_time}</updated><br /><br /><link rel="alternate" type="text/html" href="{$this->link}" /><br /><id>{$this->id}</id><br /><link rel="self" type="application/atom+xml" href="{$this->id}" /><br /><br />END;<br /> if (sizeof($this->entries))<br /> foreach($this->entries as $entry)<br /> if ($entry instanceof ActivityStreamsEntry) $string .= (string) $entry;<br /><br /> $string .= <<<END<br /></feed><br />END;<br /> return $string;<br /> }Agora, para reunir um feed estruturado do Activity Streams, conecte uma série desses objetos e os ecoe para o navegador, como na listagem 10:
Listagem 10. Renderizando o feed do Activity Streams a partir da listagem 4 usando o código PHP das listagens 5 a 9
// Create a new Activity Stream<br />$stream = new ActivityStreamsEncoder('http://samplecompany.com/tasks/activity/', <br /> 'Task activities at Sample Company');<br /><br />// Define the action's object<br />$object = new ActivityStreamsObject();<br />$object->setProperty('id','http://samplecompany.com/tasks/23432/');<br />$object->setProperty('title','Sample task.');<br />$object->setProperty('content','...');<br />$object->addObjectType('http://samplecompany.com/activity/schema/1.0/task');<br />$object->addObjectType('http://activitystrea.ms/schema/1.0/note');<br />$object->setProperty('link','http://samplecompany.com/tasks/23432/');<br /><br />// Define the action's author<br />$author = new ActivityStreamsAuthor();<br />$author->setProperty('name','Roger Taylor');<br />$author->setProperty('uri','http://samplecompany.com/people/Roger+Taylor/');<br /><br />// Define the overall entry, adding the object, verbs and author<br />$entry = new ActivityStreamsEntry();<br />$entry->addVerb("http://samplecompany.com/activity/schema/1.0/complete");<br />$entry->addVerb("http://activitystrea.ms/schema/1.0/update");<br />$entry->title = "Roger Taylor completed a task.";<br />$entry->id = 'http://samplecompany.com/tasks/activity/23432/3242345/';<br />$entry->addObject($object);<br />$entry->setAuthor($author);<br /><br />// Add the entry to the stream<br />$stream->addEntry($entry);<br /><br />// Echo the stream<br />header('Content type: text/xml');<br />echo $stream;O código na listagem 10 mantém uma versão estruturada do Activity Streams, que pode ser consultada usando o método PHP padrão, orientado a objetos, e chamadas de propriedade.
Depois que echo é chamado para exibir o feed, cada método mágico __toString() interno do objeto é chamado, renderizando-o como XML. Um cabeçalho Content type: text/xml é enviado primeiro para anunciar para o navegador que você exibirá um arquivo XML.
Analisando um feed do Activity Streams
O PHP torna extremamente simples analisar qualquer tipo de feed XML. Basta carregar a estrutura com as funções integradas do SimpleXML:
- Simplexml_load_file($filename) carrega XML estruturado a partir de um arquivo.
- Simplexml_load_string($filename) carrega XML estruturado a partir de uma cadeia de caractere.
Várias modificações das suas classes ActivityStreams são óbvias. Uma
delas é para unificar cada classe-filha em uma única classe
ActivityStreamsElement de usos múltiplos, que herda a classe PHP
incorporada SimpleXMLElement. Basta chamar o SimpleXML para processar
um feed de XML de volta nesses objetos manipuladores:
$activityStream = simplexml_load_string($xmlFeed, "ActivityStreamsElement");Mas manusear um fluxo como série estruturada de SimpleXMLElements, que é o valor-padrão retornado pelas funções de análise do SimpleXML, é tão fácil quanto fazer um loop pelos elementos de um array, como mostrado na listagem 11. Cuidado, porém, para fazer referência aos espaços de nomes Atom e ActivityStreams.
Listagem 11. Loop pelos elementos em um feed Atom do SimpleXML
$activityStream = simplexml_load_string($stream);<br />$activityStream = $activityStream->children('http://www.w3.org/2005/Atom');<br />if (is_array(!$activityStream->entry) && sizeof($activityStream->entry)) {<br /> foreach($activityStream->entry as $entry) {<br /> // Handle entry<br /> }<br />}É possível desenvolver funções recursivas para manusear entradas, objetos dentro delas, autores, e assim por diante. Os feeds do Activity Streams, como seus pais, os feeds Atom, são arquivos XML simples que podem ser analisados rapidamente e usados para muitas finalidades.
Conclusão
O formato Activity Streams está emergindo como a resposta de aplicativos sociais da Web ao RSS: simples e fácil de desenvolver, mas poderoso em uma grande variedade de contextos. Em configurações corporativas, existem inúmeras possibilidades para estender o Activity Streams a fim de fornecer maior segurança e funcionalidade mais elaborada.
Além de criar tipos de objetos e verbos especializados para manusear as atividades de negócios, é possível assinar fluxos usando uma tecnologia como OAuth para criar visualizações personalizadas, baseadas em permissões, das atividades da empresa. E a extensão Atom Media proposta permite que itens de mídia, como fotos, vídeos e arquivos de áudio, e apresentações de negócios sejam integrados a um feed de Activity Streams.
Faça o download do ActiveStreamsEncoder através do dW Brasil e conheça melhor os recursos do código completo.
*
artigo publicado originalmente em IBM developerWorks, por Ben Werdmuller
Ben Werdmuller é estrategista e desenvolvedor da Web especializado em plataformas de software livre. Ele foi cofundador e líder técnico da Elgg, uma estrutura de rede social de software livre. Ben escreve regularmente no seu blog em http://benwerd.com/.







