gadgets.module 5.9 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233
  1. <?php
  2. /**
  3. * This module demonstrates a way to create Google Gadgets from within Drupal.
  4. *
  5. * It is expected that users will actually evolve it to a generalized gadget
  6. * creation class, from which actual gadgets will be derived without having to
  7. * create a module for each gadget.
  8. *
  9. * It requires PHP5 and the DOM extension.
  10. *
  11. * Licensed under the CeCILL 2.0.
  12. * Also licenced under the General Public License 2.0 and later, for compatibility
  13. * with Drupal itself.
  14. *
  15. * @copyright 2007-2009 Frederic G. MARAND fgm@riff.org
  16. * @license http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
  17. */
  18. /*
  19. * Base class for gadget creation
  20. */
  21. class GoogleGadget
  22. {
  23. /**
  24. * Content type attribute
  25. *
  26. * @var string
  27. */
  28. public $contentType;
  29. /**
  30. * Raw content. Data should be in the format described by $this->contentType
  31. * @var string
  32. */
  33. public $content = '';
  34. /**
  35. * Hold elements (#-prefixed) and attributes below ModulePrefs
  36. *
  37. * @var array
  38. */
  39. public $modulePrefs;
  40. /**
  41. * Hold attributes for UserPref elements
  42. *
  43. * @var array
  44. */
  45. public $userPrefs;
  46. /**
  47. * Constructor builds an empty HTML element by default
  48. *
  49. * @param mixed $body
  50. */
  51. public function __construct($body = '', $type = 'html')
  52. {
  53. $this->contentType = $type;
  54. $this->content = $body;
  55. $this->modulePrefs = array();
  56. $this->userPrefs = array();
  57. }
  58. /**
  59. * Shortcut to set up module preferences
  60. *
  61. * @param string $section
  62. * @param string $name
  63. * @param string $value
  64. * @return void
  65. */
  66. public function setModulePref($section, $name, $value)
  67. {
  68. $this->modulePrefs["#$section"][$name] = $value;
  69. }
  70. /**
  71. * Add user-defined preferences
  72. *
  73. * $attributes is an associative array of optional name/value attribute pairs
  74. *
  75. * @param string $name
  76. * @param string $displayName
  77. * @param array $attributes
  78. */
  79. public function addUserPref($name, $displayName, $attributes = array())
  80. {
  81. $this->userPrefs[$name] = $attributes;
  82. $this->userPrefs[$name]['name'] = $name;
  83. $this->userPrefs[$name]['display_name'] = $displayName;
  84. }
  85. /**
  86. * Return the rendered module and die() to avoid drupal theming on XML content
  87. *
  88. * @return void
  89. */
  90. public function render()
  91. {
  92. /**
  93. * We don't use drupal_set_header because we're not letting drupal do the
  94. * rendering
  95. */
  96. header('Content-type: text/xml; charset=utf-8');
  97. $doc = new DOMDocument();
  98. $module = $doc->createElement('Module');
  99. $module = $doc->appendChild($module);
  100. /**
  101. * module preferences
  102. */
  103. if (count($this->modulePrefs) > 0)
  104. {
  105. $prefsNode = $doc->createElement('ModulePrefs');
  106. $prefsNode = $module->appendChild($prefsNode);
  107. $sections = array();
  108. foreach ($this->modulePrefs as $prefName => $prefValue)
  109. {
  110. if ($prefName[0] == '#')
  111. {
  112. $prefName = substr($prefName, 1);
  113. if (!in_array($prefName, $sections)) // must create it
  114. {
  115. ${$prefName} = $doc->createElement($prefName);
  116. ${$prefName} = $prefsNode->appendChild(${$prefName});
  117. $sections[] = $prefName;
  118. }
  119. foreach ($prefValue as $attrName => $attrValue)
  120. {
  121. ${$prefName}->setAttribute($attrName, $attrValue);
  122. }
  123. }
  124. else
  125. {
  126. $prefsNode->setAttribute($prefName, $prefValue);
  127. }
  128. }
  129. } // module preferences
  130. /**
  131. * user preferences
  132. */
  133. if (count($this->userPrefs > 0))
  134. {
  135. foreach ($this->userPrefs as $prefArray)
  136. {
  137. $prefNode = $doc->createElement('UserPref');
  138. $prefNode = $module->appendChild($prefNode);
  139. foreach ($prefArray as $prefName => $prefValue)
  140. {
  141. $prefNode->setAttribute($prefName, $prefValue);
  142. }
  143. }
  144. }
  145. /**
  146. * module contents
  147. */
  148. $content = $doc->createElement('Content');
  149. $content = $module->appendChild($content);
  150. $content->setAttribute('type', $this->contentType);
  151. $data = $doc->createCDATASection($this->content);
  152. $data = $content->appendChild($data);
  153. /**
  154. * clean up
  155. */
  156. echo $doc->saveXML();
  157. die();
  158. }
  159. } // end of class
  160. /**
  161. * Implement hook_menu
  162. *
  163. * @param boolean $may_cache
  164. * @return array
  165. */
  166. function gadgets_menu()
  167. {
  168. $items = array();
  169. $items['gadgets/api'] = array(
  170. 'title' => 'Google Gadget sample',
  171. 'description' => 'Display a Drupal API search box',
  172. 'access arguments' => array('access content'),
  173. 'page callback' => 'gadgets_main',
  174. );
  175. return $items;
  176. }
  177. /**
  178. * Main entry point for gadget creation
  179. *
  180. * @return void
  181. */
  182. function gadgets_main()
  183. {
  184. $g = new GoogleGadget(
  185. <<<EOT
  186. <div style="padding: 0 0.5em; margin: 0">
  187. <script type="text/javascript">
  188. function drupalapisearch(q)
  189. {
  190. destination = "http://api.drupal.org/api/__UP_apiversion__/function/" + q;
  191. top.location.href = destination;
  192. }
  193. </script>
  194. <form name="drupalapiform" onsubmit="drupalapisearch(drupalapiform.q.value)">
  195. <input type="text" maxlength="128" name="q" size="40" value="" />
  196. <input type="submit" value="Lookup Drupal function" />
  197. </form>
  198. <script>_IG_AdjustIFrameHeight();</script>
  199. </div>
  200. EOT
  201. );
  202. $g->contentType = 'html'; // default value, just added here to show it exists
  203. $g->modulePrefs['title'] = 'Drupal API reference';
  204. $g->modulePrefs['author'] = 'Frederic G. MARAND';
  205. $g->modulePrefs['description'] = 'A simple module to demonstrate how to build google gadgets within Drupal';
  206. $g->modulePrefs['author_email'] = 'http://blog.riff.org/contact';
  207. $g->modulePrefs['author_link'] = 'http://blog.riff.org/';
  208. $g->setModulePref('Require', 'feature', 'dynamic-height');
  209. $g->addUserPref('apiversion', 'Drupal API version', array
  210. (
  211. 'default_value' => '6'
  212. ));
  213. $g->render(); // includes die() to avoid drupal themeing
  214. }