Source for file Theme.class.php

Documentation is available at Theme.class.php

  1. <?php
  2.  
  3. require_once(HARMONI."GUIManager/Theme.interface.php");
  4. require_once(HARMONI."GUIManager/Component.class.php");
  5. require_once(HARMONI."GUIManager/Container.class.php");
  6. require_once(HARMONI."GUIManager/StyleCollection.class.php");
  7.  
  8. /**
  9. * A generic <code>Theme</code> implementation. It should be sufficient just to
  10. * extend it to create new fully fledged Themes.
  11. * <br /><br />
  12. * A <code>Theme</code> is a combination of two things: first, it stores a variety
  13. * of reusable <code>StyleCollections</code> and second, it offers a mechanism for
  14. * printing an HTML web page.
  15. * <br /><br />
  16. * Each <code>Theme</code> has a set of style collections that correspond to
  17. * each component type.
  18. * <br /><br />
  19. * Each <code>Theme</code> has a single component (could be container) that will
  20. * be printed when <code>printPage()</code> is called.
  21. *
  22. * @package harmoni.gui
  23. *
  24. * @copyright Copyright &copy; 2005, Middlebury College
  25. * @license http://www.gnu.org/copyleft/gpl.html GNU General Public License (GPL)
  26. *
  27. * @version $Id: Theme.class.php,v 1.27 2007/09/04 20:25:21 adamfranco Exp $
  28. */
  29. class Theme extends ThemeInterface {
  30.  
  31. /**
  32. * @var $id; the id of the theme
  33. * @access private
  34. * @since 5/1/06
  35. */
  36. var $_id;
  37.  
  38. /**
  39. * The display name of this Theme.
  40. * @var string _displayName
  41. * @access private
  42. */
  43. var $_displayName;
  44. /**
  45. * The description of this Theme.
  46. * @var string _description
  47. * @access private
  48. */
  49. var $_description;
  50.  
  51. /**
  52. * The component of this Theme.
  53. * @var object _component
  54. * @access private
  55. */
  56. var $_component;
  57.  
  58. /**
  59. * The page title.
  60. * @var string _pageTitle
  61. * @access private
  62. */
  63. var $_pageTitle;
  64. /**
  65. * @var string $_headJavascript The javascript functions to put between &lt;script&gt; tags
  66. * in the &lt;head&gt; section.
  67. * @access private
  68. ***/
  69. var $_headJavascript = "";
  70. /**
  71. * An array storing style collections for the different
  72. * component types. The first dimension is the component type. The second
  73. * dimension is the index. The third dimension is the selector of the style
  74. * collection.
  75. * @var array _componentStyles
  76. * @access private
  77. */
  78. var $_componentStyles;
  79. /**
  80. * An array storing global style collections. It is one-dimensional. The key
  81. * is the selector of the style collection. The element is the style collection
  82. * itself.
  83. * @var array _globalStyles
  84. * @access private
  85. */
  86. var $_globalStyles;
  87. /**
  88. * This array combines <code>_componentStyles</code> and <code>_globalStyles</code>
  89. * into one. The purpose is to avoid duplication of style collection and to
  90. * provide an easy way to implement the <code>getCSS()</code> method.
  91. * @var array _styles
  92. * @access private
  93. */
  94. var $_styles;
  95. /**
  96. * This array will store the pre-HTML strings for the different component
  97. * types. The first dimension is the component type. The second
  98. * dimension is the index.
  99. * @var array _componentPreHTML
  100. * @access private
  101. */
  102. var $_componentPreHTML;
  103. /**
  104. * This array will store the post-HTML strings for the different component
  105. * types. The first dimension is the component type. The second
  106. * dimension is the index.
  107. * @var array _componentPostHTML
  108. * @access private
  109. */
  110. var $_componentPostHTML;
  111. /**
  112. * This array stores all registered mutable <code>StyleProperties</code>.
  113. * @var array _registeredSPs
  114. * @access private
  115. */
  116. var $_registeredSPs;
  117. /**
  118. * This array stores the names of the methods that will be run after
  119. * importing of registered <code>StyleProperties</code>.
  120. * @var array _postImportMethods
  121. * @access private
  122. */
  123. var $_postImportMethods;
  124.  
  125. /**
  126. * The constructor.
  127. * @access public
  128. * @param string $displayName
  129. * @param string $description
  130. ***/
  131. function Theme($displayName, $description) {
  132. // ** parameter validation
  133. $rule = OptionalRule::getRule(StringValidatorRule::getRule());
  134. ArgumentValidator::validate($displayName, $rule, true);
  135. ArgumentValidator::validate($description, $rule, true);
  136. // ** end of parameter validation
  137.  
  138. $this->_component = null;
  139. $this->_pageTitle = "";
  140. $this->_componentStyles = array();
  141. $this->_globalStyles = array();
  142. $this->_styles = array();
  143. $this->_registeredSPs = array();
  144. $this->_postImportMethods = array();
  145. $this->_displayName = $displayName;
  146. $this->_description = $description;
  147. }
  148. /**
  149. * Sets the id
  150. *
  151. * @param string $id
  152. * @return void
  153. * @access public
  154. * @since 4/26/06
  155. */
  156. function setId ($id) {
  157. // $idManager = Services::getService("Id");
  158. // $this->_id =$idManager->getId($id);
  159. if (!is_object($id))
  160. throwError(new Error("GUIMANAGER", "STRING ID PASSED"));
  161. $this->_id =$id;
  162. }
  163. /**
  164. * Answers the id
  165. *
  166. * @return object HarmoniId
  167. * @access public
  168. * @since 4/26/06
  169. */
  170. function getId () {
  171. if (isset($this->_id)){
  172. return $this->_id;
  173. }else{
  174. $null = null;
  175. return $null;
  176. }
  177. }
  178.  
  179. /**
  180. * Returns the display name of this Theme.
  181. * @access public
  182. * @return string The display name of this Theme.
  183. ***/
  184. function getDisplayName() {
  185. return $this->_displayName;
  186. }
  187.  
  188. /**
  189. * Sets the display name of this Theme.
  190. * @access public
  191. * @param string displayName The new display name of this Theme.
  192. ***/
  193. function setDisplayName($displayName) {
  194. // ** parameter validation
  195. ArgumentValidator::validate($displayName, StringValidatorRule::getRule(), true);
  196. // ** end of parameter validation
  197.  
  198. $this->_displayName = $displayName;
  199. }
  200.  
  201. /**
  202. * Returns the description of this Theme.
  203. * @access public
  204. * @return string The description of this Theme.
  205. ***/
  206. function getDescription() {
  207. return $this->_description;
  208. }
  209.  
  210. /**
  211. * Sets the description of this Theme.
  212. * @access public
  213. * @param string description The new description of this Theme.
  214. ***/
  215. function setDescription($description) {
  216. // ** parameter validation
  217. ArgumentValidator::validate($description, StringValidatorRule::getRule(), true);
  218. // ** end of parameter validation
  219.  
  220. $this->_description = $description;
  221. }
  222.  
  223. /**
  224. * Sets the template
  225. *
  226. * @param string $template
  227. * @return void
  228. * @access public
  229. * @since 4/26/06
  230. */
  231. function setTemplate ($template) {
  232. $this->_template = $template;
  233. }
  234. /**
  235. * Answers the template
  236. *
  237. * @return string
  238. * @access public
  239. * @since 4/26/06
  240. */
  241. function getTemplate () {
  242. if (isset($this->_template))
  243. return $this->_template;
  244. }
  245.  
  246. /**
  247. * Sets the level of customization for the theme
  248. *
  249. * @param string $custom_lev
  250. * @return void
  251. * @access public
  252. * @since 4/26/06
  253. */
  254. function setCustom ($custom_lev) {
  255. $this->_custom_lev = $custom_lev;
  256. }
  257. /**
  258. * Answers the customization level for the theme
  259. *
  260. * @return string
  261. * @access public
  262. * @since 4/26/06
  263. */
  264. function getCustom () {
  265. if (isset($this->_custom_lev))
  266. return $this->_custom_lev;
  267. }
  268. /**
  269. * Answers the _styles array
  270. *
  271. * @return ref array
  272. * @access public
  273. * @since 4/26/06
  274. */
  275. function getStyleCollections () {
  276. return $this->_styles;
  277. }
  278. /**
  279. * Returns the StyleCollection with the given selector
  280. *
  281. * @param string $selector the selector of the StyleCollection
  282. * @access public
  283. * @return ref object StyleCollection
  284. ***/
  285. function getStyleCollection($selector) {
  286. if(array_key_exists($selector,$this->_styles)){
  287. return $this->_styles[$selector];
  288. }else{
  289. $null=null;
  290. return $null;
  291. }
  292. }
  293.  
  294. /**
  295. * Answers the class for constructing Style Collections for this theme
  296. *
  297. * @return string
  298. * @access public
  299. * @since 5/30/06
  300. */
  301. function getCollectionClass () {
  302. reset($this->_styles);
  303. if (current($this->_styles)) {
  304. $key = key($this->_styles);
  305. while (!ereg("^.", $key)) {
  306. next($this->_styles);
  307. $key = key($this->_styles);
  308. }
  309. return get_class($this->_styles[$key]);
  310. }
  311. else return 'stylecollection';
  312. }
  313.  
  314. /**
  315. * removes the style collection from the theme, and the DB is called for
  316. *
  317. * @param boolean $removeFromDatabase whether to remove the data from the database
  318. * @param ref object StyleCollection $style the style
  319. * @return void
  320. * @access public
  321. * @since 5/16/06
  322. */
  323. function removeStyleCollection ($style, $removeFromDatabase=false) {
  324. $guiManager = Services::getService("GUI");
  325. $dbHandler = Services::getService('DBHandler');
  326. $guiManager->deletePropertiesForCollection($style);
  327.  
  328. if(is_object($style->_id)){
  329. $id =$style->getId();
  330. $idValue = $id->getIdString();
  331. $query = new DeleteQuery();
  332. $query->setTable($guiManager->_dbName.".tm_style_collection");
  333. $query->addWhere("FK_theme_id = $idValue");
  334. $result =$dbHandler->query($query, $guiManager->_dbIndex);
  335. }
  336. unset($this->_styles[$style->getSelector()]);
  337. }
  338. /**
  339. * Attaches to the Theme a style collection that will have a global effect
  340. * on the page look and feel. For example, this could be a style collection
  341. * affecting the <code>body</code> HTML element.
  342. * @access public
  343. * @param ref object styleCollection The style collection to attach.
  344. ***/
  345. function addGlobalStyle($styleCollection) {
  346. // ** parameter validation
  347. $rule = ExtendsValidatorRule::getRule("StyleCollectionInterface");
  348. ArgumentValidator::validate($styleCollection, $rule, true);
  349. // ** end of parameter validation
  350. // check that this styleCollection hasn't been added already
  351. if (!isset($this->_globalStyles[$styleCollection->getSelector()]))
  352. $this->_globalStyles[$styleCollection->getSelector()] =$styleCollection;
  353. if (!isset($this->_styles[$styleCollection->getSelector()]))
  354. $this->_styles[$styleCollection->getSelector()] =$styleCollection;
  355. }
  356.  
  357. /**
  358. * Answers the Style Collection that has global effects.
  359. *
  360. * @access public
  361. * @return ref array global styles array
  362. ***/
  363. function getGlobalStyles() {
  364. if (isset($this->_globalStyles))
  365. return $this->_globalStyles;
  366. $array = array();
  367. return $array;
  368. }
  369.  
  370. /**
  371. * This method returns all style collections for the given component type and
  372. * the given numeric index.
  373. * <br /><br />
  374. * Each <code>Theme</code> has a set of style collections that correspond to
  375. * a combination of a component type and a numeric index. For example, the user
  376. * can define two style collections for components of type BLOCK and index 1 and
  377. * a totally different set of three style collections for componets of type
  378. * MENU and index 2.
  379. * <br /><br />
  380. * The index has no semantic meaning: you can think of the index as 'level' of the
  381. * component. Alternatively, the index could serve as means of distinguishing
  382. * between components with the same type.
  383. * For example, a BLOCK component with index 2 will normally have a
  384. * different set of style collections than a BLOCK component with index 1.
  385. * <br /><br />
  386. * Another way of interpreting the index is drawing a parallel to the HTML headings
  387. * &lt;h1&gt;, &lt;h2&gt;, &lt;h3&gt;, ..., where the lower the index,
  388. * the more "prominent" the look of the component.
  389. * <br /><br />
  390. * The style collections would be normally set by the
  391. * <code>setStyleForComponentType()</code> method in the Theme constructor.
  392. * @access public
  393. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  394. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  395. * @param integer index The index that will determine which style collections
  396. * to return. If the given index is greater than the maximum registered index
  397. * for the given component type, then the highest index availible will be used.
  398. * @return ref array An array of Style Collections.
  399. ***/
  400. function getStylesForComponentType($type, $index = null) {
  401. // ** parameter validation
  402. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  403. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  404. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  405. ArgumentValidator::validate($type, $rule, true);
  406. // ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  407. // ** end of parameter validation
  408.  
  409. // Frst of all, see if there are any registered styles for this
  410. // component type at all.
  411. // if there are and no index has been requested then return all of them
  412. $blank = array();
  413. if (!isset($this->_componentStyles[$type]))
  414. return $blank;
  415. else if (is_null($index))
  416. return $this->_componentStyles[$type];
  417. // Now, we know there is at least one style collection for this
  418. // component type. See, if there are any for the given index.
  419. if (isset($this->_componentStyles[$type][$index]))
  420. return $this->_componentStyles[$type][$index];
  421.  
  422. // If not, then see if there are any style collections for smaller indices.
  423. // To do so, sort the indices in a reversed order and find the first
  424. // index that is smaller than the given one.
  425. $keys = array_keys($this->_componentStyles[$type]);
  426. rsort($keys, SORT_NUMERIC);
  427. for ($i = 0; $i < count($keys); $i++)
  428. if ($keys[$i] < $index)
  429. return $this->_componentStyles[$type][$keys[$i]];
  430.  
  431. // nothing has been found
  432. $array = array();
  433. return $array;
  434. }
  435.  
  436. /**
  437. * Registers the specified style collection with the given component type.
  438. * @access public
  439. * @param ref object styleCollection The style collection to add.
  440. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  441. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  442. * @param integer index The index with which to register the style collection.
  443. * For a description of the role of indices, see the documentation of
  444. * <code>getStylesForComponentType()</code>.
  445. ***/
  446. function addStyleForComponentType($styleCollection, $type, $index) {
  447. // ** parameter validation
  448. $rule = ExtendsValidatorRule::getRule("StyleCollectionInterface");
  449. ArgumentValidator::validate($styleCollection, $rule, true);
  450. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  451. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  452. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  453. ArgumentValidator::validate($type, $rule, true);
  454. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  455. // ** end of parameter validation
  456. // make sure we can apply it
  457. if (!$styleCollection->canBeApplied()) {
  458. $err = "This style collection cannot be applied to components.";
  459. throwError(new Error($err, "GUIManager", false));
  460. return;
  461. }
  462. // check that this styleCollection hasn't been added already
  463. if (!isset($this->_componentStyles[$type][$index][$styleCollection->getSelector()]))
  464. $this->_componentStyles[$type][$index][$styleCollection->getSelector()] =$styleCollection;
  465. if (!isset($this->_styles[$styleCollection->getSelector()])){
  466. $this->_styles[$styleCollection->getSelector()] =$styleCollection;
  467. }
  468. }
  469.  
  470. /**
  471. * Sets the HTML string that needs to be printed before an attempt is made
  472. * to render components of the given type and index. Note: use of the PreHTML
  473. * and PostHTML get/set methods is discouraged - use styles instead: see
  474. * <code>addStyleForComponentType()</code> and <code>getStylesForComponentType()</code>.
  475. * @access public
  476. * @param string html The HTML code to use.
  477. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  478. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  479. * @param integer index The index with which to register the HTML string.
  480. * For a description of the role of indices, see the documentation of
  481. * <code>getStylesForComponentType()</code>.
  482. ***/
  483. function setPreHTMLForComponentType($html, $type, $index) {
  484. // ** parameter validation
  485. ArgumentValidator::validate($html, StringValidatorRule::getRule(), true);
  486. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  487. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  488. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  489. ArgumentValidator::validate($type, $rule, true);
  490. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  491. // ** end of parameter validation
  492. $this->_componentPreHTML[$type][$index] = $html;
  493. }
  494.  
  495. /**
  496. * Returns the HTML string that needs to be printed before an attempt is made
  497. * to render components of the given type and index. Note: use of the PreHTML
  498. * and PostHTML get/set methods is discouraged - use styles instead: see
  499. * <code>addStyleForComponentType()</code> and <code>getStylesForComponentType()</code>.
  500. * @access public
  501. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  502. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  503. * @param integer index The index that will determine which HTML string to return
  504. * If the given index is greater than the maximal registered index
  505. * for the given component type, then the highest index availible will be used.
  506. * @return string The HTML string.
  507. ***/
  508. function getPreHTMLForComponentType($type, $index) {
  509. // ** parameter validation
  510. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  511. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  512. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  513. ArgumentValidator::validate($type, $rule, true);
  514. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  515. // ** end of parameter validation
  516.  
  517. // Frst of all, see if there are any registered HTML strings for this
  518. // component type at all.
  519. if (!isset($this->_componentPreHTML[$type]))
  520. return "";
  521.  
  522. // Now, we know there is at least one HTML string for this
  523. // component type. See, if there are any for the given index.
  524. if (isset($this->_componentPreHTML[$type][$index]))
  525. return $this->_componentPreHTML[$type][$index];
  526.  
  527. // If not, then see if there are any HTML strings for smaller indices.
  528. // To do so, sort the indices in a reversed order and find the first
  529. // index that is smaller than the given one.
  530. $keys = array_keys($this->_componentPreHTML[$type]);
  531. rsort($keys, SORT_NUMERIC);
  532. for ($i = 0; $i < count($keys); $i++)
  533. if ($keys[$i] < $index)
  534. return $this->_componentPreHTML[$type][$keys[$i]];
  535.  
  536. // nothing has been found
  537. return "";
  538. }
  539. /**
  540. * Sets the HTML string that needs to be printed after successful rendering
  541. * of components of the given type and index. Note: use of the PreHTML
  542. * and PostHTML get/set methods is discouraged - use styles instead: see
  543. * <code>addStyleForComponentType()</code> and <code>getStylesForComponentType()</code>.
  544. * @access public
  545. * @param string html The HTML code to use.
  546. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  547. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  548. * @param integer index The index with which to register the HTML string.
  549. * For a description of the role of indices, see the documentation of
  550. * <code>getStylesForComponentType()</code>.
  551. ***/
  552. function setPostHTMLForComponentType($html, $type, $index) {
  553. // ** parameter validation
  554. ArgumentValidator::validate($html, StringValidatorRule::getRule(), true);
  555. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  556. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  557. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  558. ArgumentValidator::validate($type, $rule, true);
  559. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  560. // ** end of parameter validation
  561. $this->_componentPostHTML[$type][$index] = $html;
  562. }
  563. /**
  564. * Returns the HTML string that needs to be printed after successful rendering
  565. * of components of the given type and index. Note: use of the PreHTML
  566. * and PostHTML get/set methods is discouraged - use styles instead: see
  567. * <code>addStyleForComponentType()</code> and <code>getStylesForComponentType()</code>.
  568. * @access public
  569. * @param integer type The type of the component. One of BLANK, HEADING, HEADER, FOOTER,
  570. * BLOCK, MENU, MENU_ITEM_LINK_UNSELECTED, MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER.
  571. * @param integer index The index that will determine which HTML string to return
  572. * If the given index is greater than the maximal registered index
  573. * for the given component type, then the highest index availible will be used.
  574. * @return string The HTML string.
  575. ***/
  576. function getPostHTMLForComponentType($type, $index) {
  577. // ** parameter validation
  578. $rule = ChoiceValidatorRule::getRule(BLANK, HEADING, HEADER, FOOTER, BLOCK, MENU,
  579. SUB_MENU, MENU_ITEM_LINK_UNSELECTED,
  580. MENU_ITEM_LINK_SELECTED, MENU_ITEM_HEADING, OTHER);
  581. ArgumentValidator::validate($type, $rule, true);
  582. ArgumentValidator::validate($index, IntegerValidatorRule::getRule(), true);
  583. // ** end of parameter validation
  584.  
  585. // Frst of all, see if there are any registered HTML strings for this
  586. // component type at all.
  587. if (!isset($this->_componentPostHTML[$type]))
  588. return "";
  589.  
  590. // Now, we know there is at least one HTML string for this
  591. // component type. See, if there are any for the given index.
  592. if (isset($this->_componentPostHTML[$type][$index]))
  593. return $this->_componentPostHTML[$type][$index];
  594.  
  595. // If not, then see if there are any HTML strings for smaller indices.
  596. // To do so, sort the indices in a reversed order and find the first
  597. // index that is smaller than the given one.
  598. $keys = array_keys($this->_componentPostHTML[$type]);
  599. rsort($keys, SORT_NUMERIC);
  600. for ($i = 0; $i < count($keys); $i++)
  601. if ($keys[$i] < $index)
  602. return $this->_componentPostHTML[$type][$keys[$i]];
  603.  
  604. // nothing has been found
  605. return "";
  606. }
  607. /**
  608. * Returns the component of this <code>Theme</code>.
  609. * @access public
  610. * @return ref object The component of this <code>Theme</code>.
  611. ***/
  612. function getComponent() {
  613. return $this->_component;
  614. }
  615. /**
  616. * Sets the component of this <code>Theme</code>.
  617. * @access public
  618. * @param ref object A component.
  619. ***/
  620. function setComponent($component) {
  621. // ** parameter validation
  622. $rule = ExtendsValidatorRule::getRule("ComponentInterface");
  623. ArgumentValidator::validate($component, $rule, true);
  624. // ** end of parameter validation
  625.  
  626. $this->_component =$component;
  627. }
  628.  
  629. /**
  630. * Returns all CSS code: The CSS code for the Theme, the various component types,
  631. * the theme component and all sub-components (if any). Theme styles should come
  632. * first, followed by individual component's styles to allow the latter to take
  633. * precedence.
  634. * @access public
  635. * @param string tabs This is a string (normally a bunch of tabs) that will be
  636. * prepended to each text line. This argument is optional but its usage is highly
  637. * recommended in order to produce a nicely formatted HTML output.
  638. * @return string CSS code.
  639. ***/
  640. function getCSS($tabs = "") {
  641. $css = "";
  642. // Get any style collections explicitly registered with this Theme
  643. $styleCollections = $this->_styles;
  644.  
  645. // If the Theme does has an assigned component then get all the style
  646. // collection of the component and any subcomponents it might have.
  647. if (isset($this->_component)) {
  648. $this->_getAllStyles($this->_component, $styleCollections);
  649. }
  650. // Now convert the array of style collections to a string with CSS code.
  651. foreach (array_keys($styleCollections) as $key) {
  652. if (is_string($styleCollections[$key]))
  653. $css .= $styleCollections[$key];
  654. else{//printpre($styleCollections[$key]);
  655. $css .= $styleCollections[$key]->getCSS($tabs);}
  656. $css .= "\n";
  657. }
  658. return $css;
  659. }
  660. /**
  661. * A private function that returns all style collections for the given component and
  662. * any subcomponents it might have.
  663. * @access public
  664. * @param ref object component The component to start at.
  665. * @param array result This array will be recursively filled with
  666. * all the style collections.
  667. * @return string The CSS code.
  668. ***/
  669. function _getAllStyles($component, $result) {
  670. // get all style collections for current component and add them to $result
  671. $styleCollections =$component->getStyles();
  672. foreach (array_keys($styleCollections) as $key)
  673. // if not already in, then add it
  674. if (!isset($result[$key]))
  675. $result[$key] =$styleCollections[$key];
  676.  
  677. // now, see if $component is a container, if yes then recurse to children,
  678. // else return (base case)
  679. if (!is_a($component, "Container"))
  680. return; // base case
  681. else {
  682. // Get the styles for its layout
  683. $layout =$component->getLayout();
  684. $result[] = $layout->getCSS();
  685. // Get the styles for its children
  686. $subcomponents =$component->getComponents();
  687. foreach (array_keys($subcomponents) as $key)
  688. $this->_getAllStyles($subcomponents[$key], $result);
  689. }
  690. }
  691. /**
  692. * Prints the HTML page.
  693. * @access public
  694. ***/
  695. function printPage() {
  696. if (isset($this->_component))
  697. $this->_component->render($this, "\t\t");
  698. }
  699.  
  700. /**
  701. * Adds the given StyleProperty to the internally maintained list of mutable
  702. * (updateable) style properties and assigns it an id. This method and
  703. * the <code>getRegisteredSP</code> method enable the user to quickly change
  704. * the values of key Theme settings. For example,
  705. * let us assume that Bob has created his own theme and he has added a global
  706. * style collection for the main content block. Bob would like to allow the
  707. * user to change the width property of that collection. In order to do so,
  708. * Bob needs to call <code>registerSP()</code> and pass the WidthSP
  709. * object accordingly. This WidthSP object must be the same object that had
  710. * been added to the aforementioned global style collection. The user now can
  711. * call <code>getRegisteredSP</code> with the id that was returned by
  712. * <code>registerSP</code> and access/modify the <code>WidthSP</code> object.
  713. * @access public
  714. * @param ref object sp The StyleProperty object that will be registered as
  715. * mutable within this Theme.
  716. * @param optional string postImportMethod This is the name of the method that will
  717. * be called after this SP is imported (an optional argument). This can be useful in case other
  718. * properties depend on the content of this property, but the user does not
  719. * to export all of them.
  720. * @return integer An integer id assigned to the given style property. The id
  721. * only meaningful within the context of this Theme (i.e. this is not a system wide unique id).
  722. ***/
  723. function registerSP($sp, $postImportMethod=NULL) {
  724. // ** parameter validation
  725. $rule = ExtendsValidatorRule::getRule("StylePropertyInterface");
  726. ArgumentValidator::validate($sp, $rule, true);
  727. $rule = OptionalRule::getRule(StringValidatorRule::getRule());
  728. ArgumentValidator::validate($postImportMethod, $rule, true);
  729. // ** end of parameter validation
  730. $this->_registeredSPs[] =$sp;
  731. $id = count($this->_registeredSPs) - 1;
  732. if (isset($postImportMethod)){
  733. $this->_postImportMethods[$id] = $postImportMethod;
  734. }
  735. return $id;
  736. }
  737. /**
  738. * Returns a <code> </code>previously registered by <code>registerSP()</code>
  739. * for the given id.
  740. * @access public
  741. * @param integer id The id identifying which StyleProperty to return; as returned
  742. * by <code>registerSP()</code>.
  743. * @return ref object A <code>StylePorperty</code> object.
  744. ***/
  745. function getRegisteredSP($id) {
  746. // ** parameter validation
  747. $rule = IntegerRangeValidatorRule::getRule(0, count($this->_registeredSPs) - 1);
  748. ArgumentValidator::validate($sp, $rule, true);
  749. // ** end of parameter validation
  750. return $this->_registeredSPs[$id];
  751. }
  752.  
  753. /**
  754. * This methods exports the content of a registered style property object. The
  755. * output is implementation specific. The only requirement is that if the output
  756. * of this method is passed as an input to <code>importRegisteredSP()</code>,
  757. * then the contents of the <code>StyleProperty</code> should not change.
  758. * @access public
  759. * @param integer id The id of the <code>StyleProperty</code> as returned
  760. * by <code>registerSP()</code>.
  761. * @return mixed The contens of the <code>StyleProperty</code>. The output
  762. * representation is implementation specific.
  763. ***/
  764. function exportRegisteredSP($id) {
  765. // get the StylePorperty
  766. $sp =$this->getRegisteredSP($id);
  767. // now get its StyleComponents
  768. $scs = $sp->getSCs();
  769. //print "Here it comes!!!!!!";
  770. //print_r($scs);
  771. // this is the export data - simply an array storing the values
  772. // of each style component
  773. $exportData = array();
  774. foreach (array_keys($scs) as $i => $key)
  775. $exportData[$key] = $scs[$key]->getValue();
  776. return $exportData;
  777. }
  778. /**
  779. * This method is like <code>exportRegisteredSP</code> but exports all
  780. * registered stlye properties at the same time. The output is an array
  781. * whose elements are the inividual export data as returned by <code>exportRegisteredSP</code>.
  782. * @access public
  783. * @return array An array containing the export data for each registered
  784. * <code>StylePorperty</code>. The indexes of the array are the ids of the
  785. * style properties.
  786. ***/
  787. function exportAllRegisteredSPs() {
  788. // the export data array
  789. $exportData = array();
  790. // export each registered style property and put in the array
  791. foreach (array_keys($this->_registeredSPs) as $i => $key)
  792. $exportData[$key] = $this->exportRegisteredSP($key);
  793. return $exportData;
  794. }
  795.  
  796.  
  797. /**
  798. * Imports the contents of a registered mutable <code>StyleProperty</code>.
  799. * The input to this method should be an output obtained from calling
  800. * <code>exportRegisteredSP</code> on the same <code>StyleProperty</code>.
  801. * @access public
  802. * @param integer id The id of the <code>StyleProperty</code> as returned
  803. * by <code>registerSP()</code>.
  804. * @param mixed importData The contens of the <code>StyleProperty</code> as exported by
  805. * <code>exportRegisteredSP()</code>.
  806. * @return ref object The updated <code>StyleProperty</code> object.
  807. ***/
  808. function importRegisteredSP($id, $importData) {
  809. // ** parameter validation
  810. $rule = ArrayValidatorRule::getRule();
  811. ArgumentValidator::validate($importData, $rule, true);
  812. // ** end of parameter validation
  813. // first, get the style property and its style components
  814. $sp =$this->getRegisteredSP($id);
  815. $scs =$sp->getSCs();
  816. // if the number of style components is different from the number
  817. // of elements in the importData array, then it's no good!
  818. if (count($importData) != count($scs)) {
  819. $err = "Invalid import data or invalid style property id!";
  820. throwError(new Error($err, "GUIManager", true));
  821. return;
  822. }
  823. // now set the value of each style component
  824. foreach (array_keys($importData) as $i => $key)
  825. $scs[$key]->setValue($importData[$key]);
  826. // now see if there is a post import method set for this style property
  827. // if yes, run it
  828. if (isset($this->_postImportMethods[$id]))
  829. $this->{$this->_postImportMethods[$id]}();
  830. return $sp;
  831. }
  832. /**
  833. * Returns all registered mutable style properties in an array whose indexes are the
  834. * ids of the style properties (as returned by <code>registerSP()</code>).
  835. * @access public
  836. * @return ref array An array containing all registered mutable
  837. * <code>StyleProperty</code> objects.
  838. ***/
  839. function getAllRegisteredSPs() {
  840. return $this->_registeredSPs;
  841. }
  842. }
  843. ?>

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