<?php
// $Id: xrds_simple.module,v 1.1.2.4 2010/08/20 03:19:52 walkah Exp $

function xrds_simple_menu() {
  $items = array();
  
  $items['xrds'] = array(
    'page callback' => 'xrds_simple_page',
    'access callback' => TRUE,
    'type' => MENU_CALLBACK,
  );
  
  $items['user/%user/xrds'] = array(
    'page callback' => 'xrds_simple_page',
    'page arguments' => array(1),
    'access callback' => TRUE,
    'type' => MENU_CALLBACK    
  );
  
  return $items;
}

function xrds_simple_init() {
  if (arg(0) == 'user' && is_numeric(arg(1))) {
    $path = 'user/'. arg(1) .'/xrds';
  }
  else {
    $path = 'xrds';
  }

  // Prevent any language modifications to the url by generating and using a
  // fake language object.
  $language = new stdClass();
  $language->language = '';
  $language->prefix = '';

  $url = url($path, array('absolute' => TRUE, 'language' => $language));
  drupal_set_header('X-XRDS-Location: '. $url);
  drupal_set_header('X-Yadis-Location: '. $url);
  drupal_set_html_head('<meta http-equiv="X-XRDS-Location" content="' . $url . '" />');
  drupal_set_html_head('<meta http-equiv="X-Yadis-Location" content="' . $url . '" />');
}

function xrds_simple_page($account = NULL) {
  $output = xrds_simple_document($account);
  if ($output) {
    drupal_set_header('Content-type: application/xrds+xml');
    print $output;
  }
}

/**
 * Generates an XRDS document
 *
 * @param object $account A user account object to generate the XRDS for.
 */
function xrds_simple_document($account = NULL) {
  $xrds = module_invoke_all('xrds', $account);
  
  if (empty($xrds)) {
    return FALSE;
  }
  
  $output = '<?xml version="1.0" encoding="UTF-8" ?>' . "\n";
  $output .= '<XRDS xmlns="xri://$xrds">' . "\n";
  
  foreach ($xrds as $xrd) {
    $output .= '  <XRD xmlns="xri://$xrd*($v*2.0)" version="2.0" xmlns:simple="http://xrds-simple.net/core/1.0"';
    $output .= drupal_attributes($xrd['namespaces']);
    $output .= ">\n";
    
    if (is_array($xrd['type'])) { 
      foreach($xrd['type'] as $type) {
        $output .= '    <Type>' . check_plain($type) . '</Type>'."\n";
      }
    }
    
    if (is_array($xrd['expires'])) { 
      foreach($xrd['expires'] as $expires) {
        $output .= '    <Expires>' . check_plain($expires) . '</Expires>'."\n";
      }
    }
    
    foreach($xrd['services'] as $service) {
      $output .= '    <Service priority="'.floor($service['priority']).'">'."\n";
      foreach($service['data'] as $element => $values) {
        foreach($values as $value) {
          if (!is_array($value)) {
            $data = $value;
            $value = array();
            $value['data'] = $data;
            $value['attributes'] = array();
          }
          
          $output .= '      <'. check_plain($element);
          $output .= drupal_attributes($value['attributes']);
          $output .= '>';          
          $output .= check_plain($value['data']) . '</'. check_plain($element) . ">\n";
        }
      }
      $output .= '    </Service>'."\n";
    }
    $output .= '  </XRD>'."\n";
    
  }
  $output .= '</XRDS>';
  
  return $output;
}

/**
 * You need this to prevent some OpenID providers (e.g. Yahoo) from issuing
 * warnings that your site is unreliable, when people log into your site
 * using an OpenID identity from those providers. It would probably be part
 * of the core OpenID module, if XRDS Simple was in core.
 */
function openid_xrds($account = NULL) {
  module_load_include('inc', 'openid');

  $xrds['openid_xrds'] = array(
    'services' => array(
      array('priority' => 0,
        'data' => array(
          'Type' => array(OPENID_NS_2_0 . '/return_to'),
          'URI' => array(url('openid/authenticate', array('absolute' => true))),
        ),
      ),
    ),
  );

  return $xrds;
}
