applicationcontext.class.inc.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303
  1. <?php
  2. // Copyright (C) 2010 Combodo SARL
  3. //
  4. // This program is free software; you can redistribute it and/or modify
  5. // it under the terms of the GNU General Public License as published by
  6. // the Free Software Foundation; version 3 of the License.
  7. //
  8. // This program is distributed in the hope that it will be useful,
  9. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  10. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  11. // GNU General Public License for more details.
  12. //
  13. // You should have received a copy of the GNU General Public License
  14. // along with this program; if not, write to the Free Software
  15. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
  16. /**
  17. * Class ApplicationContext
  18. *
  19. * @author Erwan Taloc <erwan.taloc@combodo.com>
  20. * @author Romain Quetiez <romain.quetiez@combodo.com>
  21. * @author Denis Flaven <denis.flaven@combodo.com>
  22. * @license http://www.opensource.org/licenses/gpl-3.0.html LGPL
  23. */
  24. require_once(APPROOT."/application/utils.inc.php");
  25. /**
  26. * Interface for directing end-users to the relevant application
  27. */
  28. interface iDBObjectURLMaker
  29. {
  30. public static function MakeObjectURL($sClass, $iId);
  31. }
  32. /**
  33. * Direct end-users to the standard iTop application: UI.php
  34. */
  35. class iTopStandardURLMaker implements iDBObjectURLMaker
  36. {
  37. public static function MakeObjectURL($sClass, $iId)
  38. {
  39. $sPage = DBObject::ComputeStandardUIPage($sClass);
  40. $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
  41. $sUrl = "{$sAbsoluteUrl}pages/$sPage?operation=details&class=$sClass&id=$iId";
  42. return $sUrl;
  43. }
  44. }
  45. /**
  46. * Direct end-users to the standard Portal application
  47. */
  48. class PortalURLMaker implements iDBObjectURLMaker
  49. {
  50. public static function MakeObjectURL($sClass, $iId)
  51. {
  52. $sAbsoluteUrl = utils::GetAbsoluteUrlAppRoot();
  53. $sUrl = "{$sAbsoluteUrl}portal/index.php?operation=details&class=$sClass&id=$iId";
  54. return $sUrl;
  55. }
  56. }
  57. /**
  58. * Helper class to store and manipulate the parameters that make the application's context
  59. *
  60. * Usage:
  61. * 1) Build the application's context by constructing the object
  62. * (the object will read some of the page's parameters)
  63. *
  64. * 2) Add these parameters to hyperlinks or to forms using the helper, functions
  65. * GetForLink(), GetForForm() or GetAsHash()
  66. */
  67. class ApplicationContext
  68. {
  69. protected $aNames;
  70. protected $aValues;
  71. protected static $aDefaultValues; // Cache shared among all instances
  72. public function __construct()
  73. {
  74. $this->aNames = array(
  75. 'org_id', 'menu'
  76. );
  77. $this->ReadContext();
  78. }
  79. /**
  80. * Read the context directly in the PHP parameters (either POST or GET)
  81. * return nothing
  82. */
  83. protected function ReadContext()
  84. {
  85. if (!isset(self::$aDefaultValues))
  86. {
  87. self::$aDefaultValues = array();
  88. $aContext = utils::ReadParam('c', array());
  89. foreach($this->aNames as $sName)
  90. {
  91. $sValue = isset($aContext[$sName]) ? $aContext[$sName] : '';
  92. // TO DO: check if some of the context parameters are mandatory (or have default values)
  93. if (!empty($sValue))
  94. {
  95. self::$aDefaultValues[$sName] = $sValue;
  96. }
  97. // Hmm, there must be a better (more generic) way to handle the case below:
  98. // When there is only one possible (allowed) organization, the context must be
  99. // fixed to this org
  100. if ($sName == 'org_id')
  101. {
  102. if (MetaModel::IsValidClass('Organization'))
  103. {
  104. $oSearchFilter = new DBObjectSearch('Organization');
  105. $oSet = new CMDBObjectSet($oSearchFilter);
  106. $iCount = $oSet->Count();
  107. if ($iCount == 1)
  108. {
  109. // Only one possible value for org_id, set it in the context
  110. $oOrg = $oSet->Fetch();
  111. self::$aDefaultValues[$sName] = $oOrg->GetKey();
  112. }
  113. }
  114. }
  115. }
  116. }
  117. $this->aValues = self::$aDefaultValues;
  118. }
  119. /**
  120. * Returns the current value for the given parameter
  121. * @param string $sParamName Name of the parameter to read
  122. * @return mixed The value for this parameter
  123. */
  124. public function GetCurrentValue($sParamName, $defaultValue = '')
  125. {
  126. if (isset($this->aValues[$sParamName]))
  127. {
  128. return $this->aValues[$sParamName];
  129. }
  130. return $defaultValue;
  131. }
  132. /**
  133. * Returns the context as string with the format name1=value1&name2=value2....
  134. * return string The context as a string to be appended to an href property
  135. */
  136. public function GetForLink()
  137. {
  138. $aParams = array();
  139. foreach($this->aValues as $sName => $sValue)
  140. {
  141. $aParams[] = "c[$sName]".'='.urlencode($sValue);
  142. }
  143. return implode("&", $aParams);
  144. }
  145. /**
  146. * Returns the context as sequence of input tags to be inserted inside a <form> tag
  147. * return string The context as a sequence of <input type="hidden" /> tags
  148. */
  149. public function GetForForm()
  150. {
  151. $sContext = "";
  152. foreach($this->aValues as $sName => $sValue)
  153. {
  154. $sContext .= "<input type=\"hidden\" name=\"c[$sName]\" value=\"".htmlentities($sValue, ENT_QUOTES, 'UTF-8')."\" />\n";
  155. }
  156. return $sContext;
  157. }
  158. /**
  159. * Returns the context as a hash array 'parameter_name' => value
  160. * return array The context information
  161. */
  162. public function GetAsHash()
  163. {
  164. $aReturn = array();
  165. foreach($this->aValues as $sName => $sValue)
  166. {
  167. $aReturn["c[$sName]"] = $sValue;
  168. }
  169. return $aReturn;
  170. }
  171. /**
  172. * Returns an array of the context parameters NAMEs
  173. * @return array The list of context parameters
  174. */
  175. public function GetNames()
  176. {
  177. return $this->aNames;
  178. }
  179. /**
  180. * Removes the specified parameter from the context, for example when the same parameter
  181. * is already a search parameter
  182. * @param string $sParamName Name of the parameter to remove
  183. * @return none
  184. */
  185. public function Reset($sParamName)
  186. {
  187. if (isset($this->aValues[$sParamName]))
  188. {
  189. unset($this->aValues[$sParamName]);
  190. }
  191. }
  192. /**
  193. * Initializes the given object with the default values provided by the context
  194. */
  195. public function InitObjectFromContext(DBObject &$oObj)
  196. {
  197. $sClass = get_class($oObj);
  198. foreach($this->GetNames() as $key)
  199. {
  200. $aCallSpec = array($sClass, 'MapContextParam');
  201. if (is_callable($aCallSpec))
  202. {
  203. $sAttCode = call_user_func($aCallSpec, $key); // Returns null when there is no mapping for this parameter
  204. }
  205. if (MetaModel::IsValidAttCode($sClass, $sAttCode))
  206. {
  207. $oAttDef = MetaModel::GetAttributeDef($sClass, $sAttCode);
  208. if ($oAttDef->IsWritable())
  209. {
  210. $value = $this->GetCurrentValue($key, null);
  211. if (!is_null($value))
  212. {
  213. $oObj->Set($sAttCode, $value);
  214. }
  215. }
  216. }
  217. }
  218. }
  219. static $m_sUrlMakerClass = null;
  220. /**
  221. * Set the current application url provider
  222. * @param sClass string Class implementing iDBObjectURLMaker
  223. * @return void
  224. */
  225. public static function SetUrlMakerClass($sClass = 'iTopStandardURLMaker')
  226. {
  227. $sPrevious = self::GetUrlMakerClass();
  228. self::$m_sUrlMakerClass = $sClass;
  229. $_SESSION['UrlMakerClass'] = $sClass;
  230. return $sPrevious;
  231. }
  232. /**
  233. * Get the current application url provider
  234. * @return string the name of the class
  235. */
  236. public static function GetUrlMakerClass()
  237. {
  238. if (is_null(self::$m_sUrlMakerClass))
  239. {
  240. if (isset($_SESSION['UrlMakerClass']))
  241. {
  242. self::$m_sUrlMakerClass = $_SESSION['UrlMakerClass'];
  243. }
  244. else
  245. {
  246. self::$m_sUrlMakerClass = 'iTopStandardURLMaker';
  247. }
  248. }
  249. return self::$m_sUrlMakerClass;
  250. }
  251. /**
  252. * Get the current application url provider
  253. * @return string the name of the class
  254. */
  255. public static function MakeObjectUrl($sObjClass, $sObjKey, $sUrlMakerClass = null, $bWithNavigationContext = true)
  256. {
  257. $oAppContext = new ApplicationContext();
  258. if (is_null($sUrlMakerClass))
  259. {
  260. $sUrlMakerClass = self::GetUrlMakerClass();
  261. }
  262. $sUrl = call_user_func(array($sUrlMakerClass, 'MakeObjectUrl'), $sObjClass, $sObjKey);
  263. if (strlen($sUrl) > 0)
  264. {
  265. if ($bWithNavigationContext)
  266. {
  267. return $sUrl."&".$oAppContext->GetForLink();
  268. }
  269. else
  270. {
  271. return $sUrl;
  272. }
  273. }
  274. else
  275. {
  276. return '';
  277. }
  278. }
  279. }
  280. ?>