PageRenderTime 43ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 0ms

/library/Adapto/Module.php

http://github.com/egeniq/adapto
PHP | 362 lines | 138 code | 42 blank | 182 comment | 17 complexity | 0264d2dba9a512d2534f1ed74f7dd148 MD5 | raw file
  1. <?php
  2. /**
  3. * This file is part of the Adapto Toolkit.
  4. * Detailed copyright and licensing information can be found
  5. * in the doc/COPYRIGHT and doc/LICENSE files which should be
  6. * included in the distribution.
  7. *
  8. * @package adapto
  9. * @subpackage modules
  10. *
  11. * @copyright (c)2000-2004 Ibuildings.nl BV
  12. * @license http://www.achievo.org/atk/licensing ATK Open Source License
  13. *
  14. */
  15. /**
  16. * The Adapto_Module abstract base class.
  17. *
  18. * All modules in an ATK application should derive from this class, and
  19. * override the methods of this abstract class as they see fit.
  20. *
  21. * @author petercv
  22. * @package adapto
  23. * @subpackage modules
  24. * @abstract
  25. */
  26. class Adapto_Module
  27. {
  28. /**
  29. * We keep track if the entity currently being instantiated is an
  30. * overloader or not.
  31. *
  32. * @var boolean
  33. */
  34. static $s_isOverloader = false;
  35. public $m_name; // defaulted to public
  36. /**
  37. * Constructor. The module needs to register it's entitys
  38. * overhere, create its menuitems etc.
  39. * @param String $name The name of the module.
  40. */
  41. public function __construct($name = "")
  42. {
  43. $this->m_name = $name;
  44. }
  45. /**
  46. * Register entitys with their supported actions. Can be used
  47. * for security etc.
  48. */
  49. function getEntitys()
  50. {
  51. }
  52. /**
  53. * Returns an array with filenames of attributes that need to be included
  54. * in order to let this module work properly.
  55. * @return array with attribute filenames
  56. */
  57. function getAttributes()
  58. {
  59. }
  60. /**
  61. * This method returns an array with menu items that need to be available
  62. * in the main ATK menu. This function returns the array created with
  63. * the menuitem() method, and does not have to be extended!
  64. * @return array with menu items for this module
  65. */
  66. function getMenuItems()
  67. {
  68. }
  69. /**
  70. * Create a new menu item, optionally configuring access control. This
  71. * function can also be used to create separators, submenus and submenu items.
  72. *
  73. * @param String $name The menuitem name. The name that is displayed in the
  74. * userinterface can be influenced by putting
  75. * "menu_something" in the language files, where 'something'
  76. * is equal to the $name parameter.
  77. * If "-" is specified as name, the item is a separator.
  78. * In this case, the $url parameter should be empty.
  79. * @param String $url The url to load in the main application area when the
  80. * menuitem is clicked. If set to "", the menu is treated
  81. * as a submenu (or a separator if $name equals "-").
  82. * The dispatch_url() method is a useful function to
  83. * pass as this parameter.
  84. * @param String $parent The parent menu. If omitted or set to "main", the
  85. * item is added to the main menu.
  86. * @param mixed $enable This parameter supports the following options:
  87. * 1: menuitem is always enabled
  88. * 0: menuitem is always disabled
  89. * (this is useful when you want to use a function
  90. * call to determine when a menuitem should be
  91. * enabled. If the function returns 1 or 0, it can
  92. * directly be passed to this method in the $enable
  93. * parameter.
  94. * array: when an array is passed, it should have the
  95. * following format:
  96. * array("entity","action","entity","action",...)
  97. * When an array is passed, the menu checks user
  98. * privileges. If the user has any of the
  99. * entity/action privileges, the menuitem is
  100. * enabled. Otherwise, it's disabled.
  101. * @param int $order The order in which the menuitem appears. If omitted,
  102. * the items appear in the order in which they are added
  103. * to the menu, with steps of 100. So, if you have a menu
  104. * with default ordering and you want to place a new
  105. * menuitem at the third position, pass 250 for $order.
  106. */
  107. function menuitem($name = "", $url = "", $parent = "main", $enable = 1, $order = 0)
  108. {
  109. /* call basic menuitem */
  110. if (empty($parent))
  111. $parent = 'main';
  112. menuitem($name, $url, $parent, $enable, $order, $this->m_name);
  113. }
  114. /**
  115. * This method can be used to return an array similar to the menu array
  116. * but with links to (a) preference(s) page(s) for this module. The items
  117. * that will be returned have to be added with the preferencelink() method.
  118. * @return array with preference links for this module
  119. */
  120. function getPreferenceLinks()
  121. {
  122. }
  123. /**
  124. * This method is similar to the getPreferenceLinks() method but instead
  125. * will return links to (an) admin page(s) for this module. The array which
  126. * will be returned have to be created with the adminlink() method.
  127. * @return array with admin links for this module
  128. */
  129. function getAdminLinks()
  130. {
  131. }
  132. /**
  133. * Returns the entity overloader if it exists. Else it
  134. * will just return the module/entity name of the given entity.
  135. * @param string $entity module/entity string
  136. * @return string (overloader) module/entity string
  137. */
  138. function entityOverloader($entity)
  139. {
  140. global $g_overloaders;
  141. /* overloader check */
  142. if (!empty($g_overloaders[$entity])) {
  143. Adapto_Util_Debugger::debug("Using overloader '" . $g_overloaders[$entity] . "' for class '" . $entity . "'");
  144. self::$s_isOverloader = true;
  145. $entity = newEntity($g_overloaders[$entity], FALSE);
  146. self::$s_isOverloader = false;
  147. return $entity;
  148. }
  149. /* no overloader */
  150. else {
  151. return null;
  152. }
  153. }
  154. /**
  155. * Returns the entity file for the given entity.
  156. *
  157. * @see entityFile()
  158. * @param string $entity the entity type
  159. * @return string entity filename
  160. */
  161. function getEntityFile($entity)
  162. {
  163. return entityFile($entity);
  164. }
  165. /**
  166. * Returns the fixture path for the given fixture.
  167. *
  168. * @param string $fixture <module.fixture> string
  169. * @return string path to fixture without extension
  170. */
  171. function getFixturePath($fixture)
  172. {
  173. $module = getEntityModule($fixture);
  174. $fixture = getEntityType($fixture);
  175. $path = moduleDir($module) . 'testcases/fixtures/' . $fixture;
  176. return $path;
  177. }
  178. /**
  179. * Construct a new entity. A module can override this method for it's own entitys.
  180. * @param atkEntity $entity the entity type
  181. * @return new entity object
  182. */
  183. function &newEntity($entity)
  184. {
  185. global $config_atkroot;
  186. /* include the base file */
  187. $corporate_base = Adapto_Config::getGlobal("corporate_entity_base");
  188. if ($corporate_base != "") {
  189. }
  190. /* check for file */
  191. $file = $this->getEntityFile($entity);
  192. if (!file_exists($file)) {
  193. $res = atkClassLoader::invokeFromString(Adapto_Config::getGlobal("missing_class_handler"), array(array("entity" => $entity, "module" => $this->m_name)));
  194. if ($res !== false) {
  195. return $res;
  196. } else {
  197. throw new Adapto_Exception("Cannot create entity, because a required file ($file) does not exist!", "critical");
  198. return NULL;
  199. }
  200. }
  201. /* include file */
  202. include_once($file);
  203. /* module */
  204. $module = getEntityModule($entity);
  205. // set the current module scope, this will be retrieved in atkEntity
  206. // to set it's $this->m_module instance variable in an early stage
  207. if (!self::$s_isOverloader) {
  208. Adapto_Module::setModuleScope($module);
  209. }
  210. /* now that we have included the entity source file, we check
  211. * for overloaders (because overloaders might need the included file!)
  212. */
  213. $overloader = &$this->entityOverloader($entity);
  214. if ($overloader != NULL) {
  215. $overloader->m_module = $module;
  216. if (!self::$s_isOverloader) {
  217. Adapto_Module::resetModuleScope();
  218. }
  219. return $overloader;
  220. }
  221. /* initialize entity and return */
  222. $type = getEntityType($entity);
  223. $entity = new $type();
  224. $entity->m_module = $module;
  225. if (!self::$s_isOverloader) {
  226. Adapto_Module::resetModuleScope();
  227. }
  228. return $entity;
  229. }
  230. /**
  231. * Set current module scope.
  232. *
  233. * @param string $module current module
  234. * @static
  235. */
  236. function setModuleScope($module)
  237. {
  238. global $g_atkModuleScope;
  239. $g_atkModuleScope = $module;
  240. }
  241. /**
  242. * Returns the current module scope.
  243. *
  244. * @return string current module
  245. * @static
  246. */
  247. function getModuleScope()
  248. {
  249. global $g_atkModuleScope;
  250. return $g_atkModuleScope;
  251. }
  252. /**
  253. * Resets the current module scope.
  254. *
  255. * @static
  256. */
  257. function resetModuleScope()
  258. {
  259. Adapto_Module::setModuleScope(null);
  260. }
  261. /**
  262. * Checks if a certain entity exists for this module.
  263. * @param string $entity the entity type
  264. * @return entity exists?
  265. */
  266. function entityExists($entity)
  267. {
  268. // check for file
  269. $file = $this->getEntityFile($entity);
  270. return file_exists($file);
  271. }
  272. /**
  273. * Get the modifier functions for this entity
  274. *
  275. * @param atkEntity $entity
  276. * @return array Array with modifier function names
  277. */
  278. function getModifierFunctions(&$entity)
  279. {
  280. return array($entity->m_type . "_modifier", str_replace(".", "_", $entity->atkentitytype()) . "_modifier");
  281. }
  282. /**
  283. * Modifies the given entity
  284. *
  285. * @param atkEntity $entity Entity to be modified
  286. */
  287. function modifier(&$entity)
  288. {
  289. // Determine the modifier name and existance for modifiers that modify any entity having the this entity's type in any module
  290. $specificmodifiers = $this->getModifierFunctions($entity);
  291. // Set the number of applied modifiers to zero
  292. $appliedmodifiers = 0;
  293. // Loop through the possible modifiers and apply them if found
  294. foreach ($specificmodifiers as $modifiername) {
  295. // If the modifiers is found
  296. if (method_exists($this, $modifiername)) {
  297. // Add a debug line so we know, the modifier is applied
  298. Adapto_Util_Debugger::debug(sprintf("Applying modifier %s from module %s to entity %s", $modifiername, $this->m_name, $entity->m_type));
  299. // Apply the modifier
  300. $entity->m_modifier = $this->m_name;
  301. $this->$modifiername($entity);
  302. $entity->m_modifier = "";
  303. // Increase the number of applied modifiers
  304. $appliedmodifiers++;
  305. }
  306. }
  307. // If none of the modifiers was found, add a warning to the debug log
  308. if ($appliedmodifiers == 0)
  309. Adapto_Util_Debugger::debug(
  310. sprintf("Failed to apply modifier function %s from module %s to entity %s; modifier function not found", implode(" or ", $specificmodifiers),
  311. $this->m_name, $entity->m_type), DEBUG_WARNING);
  312. }
  313. static public function pathForModule($moduleName)
  314. {
  315. // Todo, read this from ZF somewhere.
  316. return APPLICATION_PATH."/modules/".$moduleName;
  317. }
  318. }