- See http://blog.riff.org/2009_05_24_gadgets_module_now_available_for_drupal_6
233 lines
5.9 KiB
Text
233 lines
5.9 KiB
Text
<?php
|
|
/**
|
|
* This module demonstrates a way to create Google Gadgets from within Drupal.
|
|
*
|
|
* It is expected that users will actually evolve it to a generalized gadget
|
|
* creation class, from which actual gadgets will be derived without having to
|
|
* create a module for each gadget.
|
|
*
|
|
* It requires PHP5 and the DOM extension.
|
|
*
|
|
* Licensed under the CeCILL 2.0.
|
|
* Also licenced under the General Public License 2.0 and later, for compatibility
|
|
* with Drupal itself.
|
|
*
|
|
* @copyright 2007-2009 Frederic G. MARAND fgm@riff.org
|
|
* @license http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
|
|
*/
|
|
|
|
/*
|
|
* Base class for gadget creation
|
|
*/
|
|
class GoogleGadget
|
|
{
|
|
/**
|
|
* Content type attribute
|
|
*
|
|
* @var string
|
|
*/
|
|
public $contentType;
|
|
|
|
/**
|
|
* Raw content. Data should be in the format described by $this->contentType
|
|
* @var string
|
|
*/
|
|
public $content = '';
|
|
|
|
/**
|
|
* Hold elements (#-prefixed) and attributes below ModulePrefs
|
|
*
|
|
* @var array
|
|
*/
|
|
public $modulePrefs;
|
|
|
|
/**
|
|
* Hold attributes for UserPref elements
|
|
*
|
|
* @var array
|
|
*/
|
|
public $userPrefs;
|
|
|
|
/**
|
|
* Constructor builds an empty HTML element by default
|
|
*
|
|
* @param mixed $body
|
|
*/
|
|
public function __construct($body = '', $type = 'html')
|
|
{
|
|
$this->contentType = $type;
|
|
$this->content = $body;
|
|
$this->modulePrefs = array();
|
|
$this->userPrefs = array();
|
|
}
|
|
|
|
/**
|
|
* Shortcut to set up module preferences
|
|
*
|
|
* @param string $section
|
|
* @param string $name
|
|
* @param string $value
|
|
* @return void
|
|
*/
|
|
public function setModulePref($section, $name, $value)
|
|
{
|
|
$this->modulePrefs["#$section"][$name] = $value;
|
|
}
|
|
|
|
/**
|
|
* Add user-defined preferences
|
|
*
|
|
* $attributes is an associative array of optional name/value attribute pairs
|
|
*
|
|
* @param string $name
|
|
* @param string $displayName
|
|
* @param array $attributes
|
|
*/
|
|
public function addUserPref($name, $displayName, $attributes = array())
|
|
{
|
|
$this->userPrefs[$name] = $attributes;
|
|
$this->userPrefs[$name]['name'] = $name;
|
|
$this->userPrefs[$name]['display_name'] = $displayName;
|
|
}
|
|
|
|
/**
|
|
* Return the rendered module and die() to avoid drupal theming on XML content
|
|
*
|
|
* @return void
|
|
*/
|
|
public function render()
|
|
{
|
|
/**
|
|
* We don't use drupal_set_header because we're not letting drupal do the
|
|
* rendering
|
|
*/
|
|
header('Content-type: text/xml; charset=utf-8');
|
|
|
|
$doc = new DOMDocument();
|
|
$module = $doc->createElement('Module');
|
|
$module = $doc->appendChild($module);
|
|
|
|
/**
|
|
* module preferences
|
|
*/
|
|
if (count($this->modulePrefs) > 0)
|
|
{
|
|
$prefsNode = $doc->createElement('ModulePrefs');
|
|
$prefsNode = $module->appendChild($prefsNode);
|
|
$sections = array();
|
|
|
|
foreach ($this->modulePrefs as $prefName => $prefValue)
|
|
{
|
|
if ($prefName[0] == '#')
|
|
{
|
|
$prefName = substr($prefName, 1);
|
|
if (!in_array($prefName, $sections)) // must create it
|
|
{
|
|
${$prefName} = $doc->createElement($prefName);
|
|
${$prefName} = $prefsNode->appendChild(${$prefName});
|
|
$sections[] = $prefName;
|
|
}
|
|
foreach ($prefValue as $attrName => $attrValue)
|
|
{
|
|
${$prefName}->setAttribute($attrName, $attrValue);
|
|
}
|
|
}
|
|
else
|
|
{
|
|
$prefsNode->setAttribute($prefName, $prefValue);
|
|
}
|
|
}
|
|
} // module preferences
|
|
|
|
/**
|
|
* user preferences
|
|
*/
|
|
if (count($this->userPrefs > 0))
|
|
{
|
|
foreach ($this->userPrefs as $prefArray)
|
|
{
|
|
$prefNode = $doc->createElement('UserPref');
|
|
$prefNode = $module->appendChild($prefNode);
|
|
foreach ($prefArray as $prefName => $prefValue)
|
|
{
|
|
$prefNode->setAttribute($prefName, $prefValue);
|
|
}
|
|
}
|
|
}
|
|
|
|
/**
|
|
* module contents
|
|
*/
|
|
$content = $doc->createElement('Content');
|
|
$content = $module->appendChild($content);
|
|
$content->setAttribute('type', $this->contentType);
|
|
$data = $doc->createCDATASection($this->content);
|
|
$data = $content->appendChild($data);
|
|
|
|
/**
|
|
* clean up
|
|
*/
|
|
echo $doc->saveXML();
|
|
die();
|
|
}
|
|
} // end of class
|
|
|
|
/**
|
|
* Implement hook_menu
|
|
*
|
|
* @param boolean $may_cache
|
|
* @return array
|
|
*/
|
|
function gadgets_menu()
|
|
{
|
|
$items = array();
|
|
$items['gadgets/api'] = array(
|
|
'title' => 'Google Gadget sample',
|
|
'description' => 'Display a Drupal API search box',
|
|
'access arguments' => array('access content'),
|
|
'page callback' => 'gadgets_main',
|
|
);
|
|
|
|
return $items;
|
|
}
|
|
|
|
/**
|
|
* Main entry point for gadget creation
|
|
*
|
|
* @return void
|
|
*/
|
|
function gadgets_main()
|
|
{
|
|
$g = new GoogleGadget(
|
|
<<<EOT
|
|
<div style="padding: 0 0.5em; margin: 0">
|
|
<script type="text/javascript">
|
|
function drupalapisearch(q)
|
|
{
|
|
destination = "http://api.drupal.org/api/__UP_apiversion__/function/" + q;
|
|
top.location.href = destination;
|
|
}
|
|
</script>
|
|
<form name="drupalapiform" onsubmit="drupalapisearch(drupalapiform.q.value)">
|
|
<input type="text" maxlength="128" name="q" size="40" value="" />
|
|
<input type="submit" value="Lookup Drupal function" />
|
|
</form>
|
|
<script>_IG_AdjustIFrameHeight();</script>
|
|
</div>
|
|
EOT
|
|
);
|
|
|
|
$g->contentType = 'html'; // default value, just added here to show it exists
|
|
$g->modulePrefs['title'] = 'Drupal API reference';
|
|
$g->modulePrefs['author'] = 'Frederic G. MARAND';
|
|
$g->modulePrefs['description'] = 'A simple module to demonstrate how to build google gadgets within Drupal';
|
|
$g->modulePrefs['author_email'] = 'http://blog.riff.org/contact';
|
|
$g->modulePrefs['author_link'] = 'http://blog.riff.org/';
|
|
$g->setModulePref('Require', 'feature', 'dynamic-height');
|
|
$g->addUserPref('apiversion', 'Drupal API version', array
|
|
(
|
|
'default_value' => '6'
|
|
));
|
|
$g->render(); // includes die() to avoid drupal themeing
|
|
}
|
|
|