Source for file Component.class.php

Documentation is available at Component.class.php

  1. <?php
  2.  
  3. require_once(HARMONI."GUIManager/Component.interface.php");
  4. require_once(HARMONI."GUIManager/StyleCollection.interface.php");
  5.  
  6. /**
  7. * This is a generic implementation of the Component interface that allows the user
  8. * to output an arbitrary string (content).
  9. * <br /><br />
  10. * <code>Components</code> are the basic units that can be displayed on
  11. * the screen. The main method <code>render()</code> which renders the component
  12. * on the screen.
  13. *
  14. * @package harmoni.gui
  15. *
  16. * @copyright Copyright &copy; 2005, Middlebury College
  17. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  18. *
  19. * @version $Id: Component.class.php,v 1.21 2007/09/04 20:25:21 adamfranco Exp $
  20. */
  21. class Component extends ComponentInterface {
  22.  
  23. /**
  24. * The content of this component.
  25. * @var string _content
  26. * @access private
  27. */
  28. var $_content;
  29. /**
  30. * This is an array of the style collections that have been applied to this
  31. * component.
  32. * @var array _styleCollections
  33. * @access private
  34. */
  35. var $_styleCollections;
  36. /**
  37. * The type of this <code>Component</code>.
  38. * @var integer _type
  39. * @access private
  40. */
  41. var $_type;
  42. /**
  43. * The index of this component. The index has no semantic meaning:
  44. * you can think of the index as 'level' of the component. Alternatively,
  45. * the index could serve as means of distinguishing between components with
  46. * the same type. Most often one would use the index in conjunction with
  47. * the <code>getStylesForComponentType()</code> and
  48. * <code>addStyleForComponentType()</code> methods.
  49. * @var integer _index
  50. * @access private
  51. */
  52. var $_index;
  53. /**
  54. * @var string $_preHTML; HTML text to surround the component. Useful for
  55. * properly nexting form tags.
  56. * @access private
  57. * @since 7/15/05
  58. */
  59. var $_preHTML;
  60. /**
  61. * @var string $_postHTML; HTML text to surround the component. Useful for
  62. * properly nexting form tags.
  63. * @access private
  64. * @since 7/15/05
  65. */
  66. var $_postHTML;
  67. /**
  68. * @var string $_id; The id of this component. (Optional
  69. * @access private
  70. * @since 1/30/06
  71. */
  72. var $_id = null;
  73. /**
  74. * The constructor.
  75. * @access public
  76. * @param string content This is an arbitrary string that will be printed,
  77. * whenever the user calls the <code>render()</code> method. If <code>null</code>,
  78. * then the component will have no content.
  79. * @param integer type The type of this component. One of BLANK, HEADING, HEADER, FOOTER,
  80. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  81. * @param integer index The index of this component. The index has no semantic meaning:
  82. * you can think of the index as 'level' of the component. Alternatively,
  83. * the index could serve as means of distinguishing between components with
  84. * the same type. Most often one would use the index in conjunction with
  85. * the <code>getStylesForComponentType()</code> and
  86. * <code>addStyleForComponentType()</code> methods.
  87. * @param optional object StyleCollections styles,... Zero, one, or more StyleCollection
  88. * objects that will be added to the newly created Component. Warning, this will
  89. * result in copying the objects instead of referencing them as using
  90. * <code>addStyle()</code> would do.
  91. ***/
  92. function Component($content, $type, $index) {
  93. // ** parameter validation
  94. $rule = OptionalRule::getRule(StringValidatorRule::getRule());
  95. ArgumentValidator::validate($content, $rule, true);
  96. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  97. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  98. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  99. ArgumentValidator::validate($type, $rule, true);
  100. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  101. // ** end of parameter validation
  102.  
  103. $this->_content = $content;
  104. $this->_styleCollections = array();
  105. $this->_type = $type;
  106. $this->_index = $index;
  107.  
  108. // if there are style collections to add
  109. if (func_num_args() > 3)
  110. for ($i = 3; $i < func_num_args(); $i++)
  111. $this->addStyle(func_get_arg($i));
  112. }
  113. /**
  114. * Adds a new <code>StyleCollection</code> to this component. The component
  115. * can have 0 or more style collections attached; each of the latter will
  116. * affect the appearance of the component. The uniqueness of the collections
  117. * is enforce by their selector (i.e., you can't have two collections
  118. * with the same selector). If a style collection has been registered with
  119. * the Theme for this Component's type and level, then the new style collection
  120. * will take precedence.
  121. * @access public
  122. * @param ref object styleCollection The <code>StyleCollection</code> to add
  123. * to this component.
  124. * @return ref object The style collection that was just added.
  125. ***/
  126. function addStyle($styleCollection) {
  127. // ** parameter validation
  128. $rule = ExtendsValidatorRule::getRule("StyleCollectionInterface");
  129. ArgumentValidator::validate($styleCollection, $rule, true);
  130. // ** end of parameter validation
  131.  
  132. // make sure we can apply it
  133. if (!$styleCollection->canBeApplied()) {
  134. $err = "This style collection cannot be applied to components.";
  135. throwError(new Error($err, "GUIManager", false));
  136. return;
  137. }
  138. if (isset($this->_styleCollections[$styleCollection->getSelector()])) {
  139. $err = "Cannot add two StyleCollections with the same selector!";
  140. throwError(new Error($err, "GUIManager", true));
  141. }
  142. $this->_styleCollections[$styleCollection->getSelector()] =$styleCollection;
  143. return $styleCollection;
  144. }
  145. /**
  146. * Returns the style collection with the specified selector.
  147. * @access public
  148. * @param string selector The selector.
  149. * @return ref object The style collection.
  150. ***/
  151. function getStyle($selector) {
  152. if (isset($this->_styleCollections[$selector]))
  153. return $this->_styleCollections[$selector];
  154. else
  155. return null;
  156. }
  157. /**
  158. * Remove the given StyleCollection from this Component.
  159. * @access public
  160. * @param string selector The selector of the style collection to remove.
  161. * @return ref object The style collection that was removed. <code>NULL</code>
  162. * if it could not be found.
  163. ***/
  164. function removeStyle($selector) {
  165. $result =$this->_styleCollections[$selector];
  166. unset($this->_styleCollections[$selector]);
  167. return $result;
  168. }
  169.  
  170. /**
  171. * Returns all style collections for this component.
  172. * @access public
  173. * @return array An array of style collections; the key corresponds to the
  174. * selector of each collection.
  175. ***/
  176. function getStyles() {
  177. return $this->_styleCollections;
  178. }
  179. /**
  180. * Returns the index of this component. The index has no semantic meaning:
  181. * you can think of the index as 'level' of the component. Alternatively,
  182. * the index could serve as means of distinguishing between components with
  183. * the same type. Most often one would use the index in conjunction with
  184. * the <code>getStylesForComponentType()</code> and <code>addStyleForComponentType()</code>
  185. * Theme methods.
  186. * @access public
  187. * @return integer The index of the component.
  188. ***/
  189. function getIndex() {
  190. return $this->_index;
  191. }
  192.  
  193. /**
  194. * Returns any pre HTML code that needs to be printed. This method should be called
  195. * at the beginnig of <code>render()</code>.
  196. * @access public
  197. * @param ref object theme The Theme object to use in producing the result
  198. * of this method.
  199. * @param string tabs This is a string (normally a bunch of tabs) that will be
  200. * prepended to each text line. This argument is optional but its usage is highly
  201. * recommended in order to produce a nicely formatted HTML output.
  202. * @return string The HTML string.
  203. ***/
  204. function getPreHTML($theme, $tabs = "") {
  205. // Sometimes we need to incrementally build our form pre-html, so
  206. // provide access to it without the theme.
  207. if ($theme === null) {
  208. return $this->_preHTML;
  209. }
  210. ob_start();
  211. // print any surrounding form-tags, etc.
  212. print $tabs.$this->_preHTML."\n";
  213. // print any HTML code for this component type that is part of the given theme
  214. print $theme->getPreHTMLForComponentType($this->_type, $this->_index);
  215. $styleCollections = array_merge($this->_styleCollections,
  216. $theme->getStylesForComponentType($this->_type, $this->_index));
  217. if (count($styleCollections) != 0) {
  218. // get the class selectors of all style collections
  219. $classSelectors = "";
  220. $styleCollectionPreHTML = "";
  221. foreach (array_keys($styleCollections) as $key) {
  222. $classSelectors .= $styleCollections[$key]->getClassSelector()." ";
  223. $styleCollectionPreHTML =
  224. $styleCollectionPreHTML
  225. .$styleCollections[$key]->getPreHTML($tabs."\t");
  226. }
  227.  
  228. print $tabs."<div class=\"$classSelectors\"";
  229. if ($this->getId())
  230. print " id=\"".$this->getId()."\"";
  231. print ">\n";
  232. print $styleCollectionPreHTML;
  233. } else if ($this->getId()) {
  234. print $tabs."<div id=\"".$this->getId()."\">\n";
  235. }
  236. $preHTML = ob_get_contents();
  237. ob_end_clean();
  238. return $preHTML;
  239. }
  240. /**
  241. * Set pre HTML code that needs to surround this compontent. This is used to
  242. * properly nest form-tags around tables/divs to generate valid XHTML.
  243. *
  244. * @param string $html
  245. * @return void
  246. * @access public
  247. * @since 7/15/05
  248. */
  249. function setPreHTML ( $html ) {
  250. $this->_preHTML = $html;
  251. }
  252. /**
  253. * Returns any post HTML code that needs to be printed. This method should be called
  254. * at the end of <code>render()</code>.
  255. * @access public
  256. * @param ref object theme The Theme object to use in producing the result
  257. * of this method.
  258. * @param string tabs This is a string (normally a bunch of tabs) that will be
  259. * prepended to each text line. This argument is optional but its usage is highly
  260. * recommended in order to produce a nicely formatted HTML output.
  261. * @return string The HTML string.
  262. ***/
  263. function getPostHTML($theme, $tabs = "") {
  264. // Sometimes we need to incrementally build our form pre-html, so
  265. // provide access to it without the theme.
  266. if ($theme === null) {
  267. return $this->_postHTML;
  268. }
  269. ob_start();
  270. $styleCollections = array_merge($this->_styleCollections,
  271. $theme->getStylesForComponentType($this->_type, $this->_index));
  272.  
  273. if (count($styleCollections) != 0) {
  274. $styleCollectionPostHTML = "";
  275. foreach (array_keys($styleCollections) as $key) {
  276. $styleCollectionPostHTML =
  277. $styleCollections[$key]->getPostHTML($tabs."\t")
  278. .$styleCollectionPostHTML;
  279. }
  280.  
  281. print $styleCollectionPostHTML;
  282. print $tabs."</div>\n";
  283. } else if ($this->getId()) {
  284. print $tabs."</div>\n";
  285. }
  286. // print any HTML code for this component type that is part of the given theme
  287. print $theme->getPostHTMLForComponentType($this->_type, $this->_index);
  288. // print any surrounding form-tags, etc.
  289. print $tabs.$this->_postHTML;
  290. $postHTML = ob_get_contents();
  291. ob_end_clean();
  292. return $postHTML;
  293. }
  294. /**
  295. * Set post HTML code that needs to surround this compontent. This is used to
  296. * properly nest form-tags around tables/divs to generate valid XHTML.
  297. *
  298. * @param string $html
  299. * @return void
  300. * @access public
  301. * @since 7/15/05
  302. */
  303. function setPostHTML ( $html ) {
  304. $this->_postHTML = $html;
  305. }
  306.  
  307. /**
  308. * Renders the component on the screen.
  309. * @param ref object theme The Theme object to use in producing the result
  310. * of this method.
  311. * @param string tabs This is a string (normally a bunch of tabs) that will be
  312. * prepended to each text line. This argument is optional but its usage is highly
  313. * recommended in order to produce a nicely formatted HTML output.
  314. * @access public
  315. ***/
  316. function render($theme, $tabs = "") {
  317. echo $this->getPreHTML($theme, $tabs);
  318. if (isset($this->_content))
  319. echo $tabs.$this->_content;
  320. echo $this->getPostHTML($theme, $tabs);
  321. }
  322. /**
  323. * Returns the type of this component.
  324. * @access public
  325. * @return integer The type of this component.
  326. ***/
  327. function getType() {
  328. return $this->_type;
  329. }
  330. /**
  331. * Set the (HTML) id of this component
  332. *
  333. * @param string $id
  334. * @return void
  335. * @access public
  336. * @since 1/30/06
  337. */
  338. function setId ($id) {
  339. $this->_id = $id;
  340. }
  341. /**
  342. * Answer the Id of this component
  343. *
  344. * @return string or null if not set
  345. * @access public
  346. * @since 1/30/06
  347. */
  348. function getId () {
  349. return $this->_id;
  350. }
  351.  
  352. }
  353.  
  354. ?>

Documentation generated on Wed, 19 Sep 2007 10:22:06 -0400 by phpDocumentor 1.3.0RC3