PageRenderTime 51ms CodeModel.GetById 22ms RepoModel.GetById 0ms app.codeStats 0ms

/components/com_fabrik/models/pluginmanager.php

https://github.com/danimara/fabrik
PHP | 438 lines | 297 code | 51 blank | 90 comment | 48 complexity | 42e34a3a6065c1900b8104d992eaf84e MD5 | raw file
Possible License(s): GPL-2.0, BSD-3-Clause
  1. <?php
  2. /**
  3. * @package Joomla
  4. * @subpackage Fabrik
  5. * @copyright Copyright (C) 2005 Rob Clayburn. All rights reserved.
  6. * @license http://www.gnu.org/copyleft/gpl.html GNU/GPL, see LICENSE.php
  7. */
  8. // Check to ensure this file is included in Joomla!
  9. defined('_JEXEC') or die();
  10. jimport('joomla.application.component.model');
  11. jimport('joomla.filesystem.file');
  12. class FabrikFEModelPluginmanager extends JModel{
  13. /** @var array plugins */
  14. var $_plugIns = array();
  15. var $_loading = null;
  16. var $_group = null;
  17. var $_runPlugins = 0;
  18. var $_paths = array();
  19. /** @var array element lists */
  20. var $_elementLists = array();
  21. /** @var array containing out put from run plugins */
  22. var $_data = array();
  23. /**
  24. * constructor
  25. */
  26. function __construct()
  27. {
  28. parent::__construct();
  29. }
  30. /**
  31. * get a html drop down list of the elment types with this objs element type selected as default
  32. * @param string default selected option
  33. * @param string html name for drop down
  34. * @param string extra info for drop down
  35. * @return string html element type list
  36. */
  37. function getElementTypeDd($default, $name='plugin', $extra='class="inputbox elementtype" size="1"', $defaultlabel='')
  38. {
  39. $hash = $default.$name.$extra.$defaultlabel;
  40. if (!array_key_exists($hash, $this->_elementLists)) {
  41. if ($defaultlabel == '') {
  42. $defaultlabel = JText::_('COM_FABRIK_PLEASE_SELECT');
  43. }
  44. $a = array(JHTML::_('select.option', '', $defaultlabel));
  45. $elementstypes = $this->_getList();
  46. $elementstypes = array_merge($a, $elementstypes);
  47. $this->_elementLists[$hash] = JHTML::_('select.genericlist', $elementstypes, $name, $extra , 'value', 'text', $default);
  48. }
  49. return $this->_elementLists[$hash];
  50. }
  51. function canUse()
  52. {
  53. return true;
  54. }
  55. /**
  56. * get an unordered list of plugins
  57. * @param string plugin group
  58. * @param string ul id
  59. */
  60. function getList($group, $id)
  61. {
  62. $str = "<ul id='$id'>";
  63. $elementstypes = $this->_getList();
  64. foreach ($elementstypes as $plugin) {
  65. $str .= "<li>" . $plugin->text . "</li>";
  66. }
  67. $str .= "</ul>";
  68. return $str;
  69. }
  70. /**
  71. * get a list of plugin ids/names for usin in a drop down list
  72. * if no group set defaults to element list
  73. * @return array plugin list
  74. */
  75. function _getList()
  76. {
  77. $db = FabrikWorker::getDbo();
  78. if (is_null($this->_group)) {
  79. $this->_group = 'element';
  80. }
  81. $query = $db->getQuery(true);
  82. $folder = $db->Quote('fabrik_'.$this->_group);
  83. //$query->select('name AS value, element AS text')->from('#__extensions')->where('folder ='.$folder);
  84. $query->select('element AS value, name AS text')->from('#__extensions')->where('folder ='.$folder);
  85. $db->setQuery($query);
  86. $elementstypes = $db->loadObjectList();
  87. return $elementstypes;
  88. }
  89. /**
  90. * get a certain group of plugins
  91. * @param string plugin group to load
  92. * @return array plugins
  93. */
  94. function &getPlugInGroup($group)
  95. {
  96. if (array_key_exists($group, $this->_plugIns))
  97. {
  98. return $this->_plugIns[$group];
  99. } else {
  100. return $this->loadPlugInGroup($group);
  101. }
  102. }
  103. /**
  104. * add to the document head all element js files
  105. * used in calendar to ensure all element js files are loaded from unserialized form
  106. */
  107. function loadJS()
  108. {
  109. //JHtml::_('script', 'https://raw.github.com/headjs/headjs/v0.96/dist/head.load.min.js');
  110. JHtml::_('script', 'media/com_fabrik/js/head/head.min.js');
  111. $plugins = JFolder::folders(JPATH_SITE . '/plugins/fabrik_element', '.', false, false);
  112. $files = array();
  113. foreach ($plugins as $plugin) {
  114. $files[] = JPATH_SITE . '/plugins/fabrik_element/'.$plugin.'/'.$plugin.'.js';
  115. }
  116. foreach ($files as $f) {
  117. $f = str_replace("\\", "/", str_replace(JPATH_SITE, '', $f));
  118. $file = basename($f);
  119. $folder = dirname($f);
  120. $folder = FabrikString::ltrimword($folder, '/') .'/';
  121. FabrikHelperHTML::script($folder.$file, true);
  122. }
  123. }
  124. /**
  125. *@param string plugin type - element/form/table/validationrule supported
  126. *loads ABSTRACT version of a plugin group
  127. */
  128. function &loadPlugInGroup($group)
  129. {
  130. $folder = 'fabrik_'.$group;
  131. $this->_plugIns[$group] = array();
  132. $plugins = JPluginHelper::getPlugin($folder);
  133. foreach($plugins as $plugin) {
  134. $this->_plugIns[$group][$plugin->name] = $plugin;
  135. }
  136. return $this->_plugIns[$group];
  137. }
  138. /**
  139. * @param string plugin name e.g. fabrikfield
  140. * @param string plugin type element/ form or table
  141. */
  142. function getPlugIn($className = '', $group)
  143. {
  144. if ($className != '' && (array_key_exists($group, $this->_plugIns) && array_key_exists($className, $this->_plugIns[$group]))) {
  145. return $this->_plugIns[$group][$className];
  146. } else {
  147. // $$$ rob 04/06/2011 hmm this was never caching the plugin so we were always loading it
  148. //return $this->loadPlugIn($className, $group);
  149. $this->_plugIns[$group][$className] = $this->loadPlugIn($className, $group);
  150. return $this->_plugIns[$group][$className];
  151. }
  152. }
  153. /**
  154. * @param string plugin name e.g. fabrikfield
  155. * @param string plugin type element/ form or table
  156. * @return mixed false if not loaded - otherwise plugin object
  157. */
  158. protected function loadPlugIn($className = '', $group)
  159. {
  160. if ($group == 'table'){
  161. $group = 'list';
  162. }
  163. $ok = JPluginHelper::importPlugin('fabrik_'.strtolower($group));
  164. $dispatcher = JDispatcher::getInstance();
  165. if ($className != '') {
  166. if (JFile::exists(JPATH_PLUGINS.DS.'fabrik_'.strtolower($group).DS.$className.DS.$className.'.php')) {
  167. require_once(JPATH_PLUGINS.DS.'fabrik_'.strtolower($group).DS.$className.DS.$className.'.php');
  168. } else {
  169. if (JFile::exists((JPATH_PLUGINS.DS.'fabrik_'.strtolower($group).DS.$className.DS.'models'.DS.$className.'.php'))) {
  170. require_once(JPATH_PLUGINS.DS.'fabrik_'.strtolower($group).DS.$className.DS.'models'.DS.$className.'.php');
  171. } else {
  172. return false;
  173. }
  174. }
  175. }
  176. $class = 'plgFabrik_'.JString::ucfirst($group).JString::ucfirst($className);
  177. $conf = array();
  178. $conf['name'] = strtolower($className);
  179. $conf['type'] = strtolower('fabrik_'.$group);
  180. $plugIn = new $class($dispatcher, $conf);
  181. //needed for viz
  182. $client = JApplicationHelper::getClientInfo(0);
  183. $lang = JFactory::getLanguage();
  184. $folder = 'fabrik_'.strtolower($group);
  185. $lang->load('plg_'.$folder.'_'.$className, $client->path.'/plugins/'.$folder.'/'.$className, null, false, false)
  186. || $lang->load('plg_'.$folder.'_'.$className, $client->path.'/plugins/'.$folder.'/'.$className, $lang->getDefault(), false, false);
  187. return $plugIn;
  188. }
  189. /**
  190. * load all the forms element plugins
  191. *
  192. * @param object form model
  193. * @return array of group objects with plugin objects loaded in group->elements
  194. */
  195. function getFormPlugins(&$form)
  196. {
  197. global $_PROFILER;
  198. if (!isset($this->formplugins)) {
  199. $this->formplugins = array();
  200. }
  201. $sig = $form->get('id');
  202. JDEBUG ? $_PROFILER->mark('pluginmanager:getFormPlugins:start - '.$sig) : null;
  203. if (!array_key_exists($sig, $this->formplugins)) {
  204. $this->formplugins[$sig] = array();
  205. $lang = JFactory::getLanguage();
  206. $folder = 'fabrik_element';
  207. $client = JApplicationHelper::getClientInfo(0);
  208. $groupIds = $form->getGroupIds();
  209. if (empty($groupIds)) { //new form
  210. return array();
  211. }
  212. $db = FabrikWorker::getDbo(true);
  213. $query = $db->getQuery(true);
  214. $query->select('*, e.name AS name, e.id AS id, e.published AS published, e.label AS label, e.plugin, e.params AS params, e.access AS access');
  215. $query->from('#__{package}_elements AS e');
  216. $query->join('INNER', '#__extensions AS p ON p.element = e.plugin');
  217. $query->where('group_id IN (' . implode(',', $groupIds) . ')');
  218. $query->where('p.folder = "fabrik_element"');
  219. $query->where('e.published != -2'); // ignore trashed elements
  220. $query->order("group_id, e.ordering");
  221. $db->setQuery($query);
  222. $elements = (array)$db->loadObjectList();
  223. if ($db->getErrorNum()) {
  224. JError::raiseError(500, $db->getErrorMsg());
  225. }
  226. //dont assign the elements into Joomla's main dispatcher as this causes out of memory errors in J1.6rc1
  227. //$dispatcher =& JDispatcher::getInstance();
  228. $dispatcher = new JDispatcher();
  229. $groupModels = $form->getGroups();
  230. $group = 'element';
  231. foreach ($elements as $element) {
  232. JDEBUG ? $_PROFILER->mark('pluginmanager:getFormPlugins:'.$element->id . ''.$element->plugin) : null;
  233. require_once(JPATH_PLUGINS.DS.'fabrik_element'.DS.$element->plugin.DS.$element->plugin.'.php');
  234. $class = 'plgFabrik_Element'.$element->plugin;
  235. $pluginModel = new $class($dispatcher, array());
  236. if (!is_object($pluginModel)) {
  237. continue;
  238. }
  239. $pluginModel->_xmlPath = COM_FABRIK_FRONTEND.DS.'plugins'.DS.$group.DS.$element->plugin.DS.$element->plugin.'.xml';
  240. $pluginModel->setId($element->id);
  241. $groupModel =& $groupModels[$element->group_id];
  242. $lang->load('plg_'.$folder.'_'.$element->plugin, $client->path.'/plugins/'.$folder.'/'.$element->plugin, null, false, false)
  243. || $lang->load('plg_'.$folder.'_'.$element->plugin, $client->path.'/plugins/'.$folder.'/'.$element->plugin, $lang->getDefault(), false, false);
  244. $pluginModel->setContext($groupModel, $form, $form->_table);
  245. $pluginModel->bindToElement($element);
  246. $groupModel->elements[$pluginModel->_id] = $pluginModel;
  247. }
  248. foreach ($groupModels as $groupid => $g) {
  249. $this->formplugins[$sig][$groupid] = $g;
  250. }
  251. }
  252. return $this->formplugins[$sig];
  253. }
  254. function getElementPlugin($id)
  255. {
  256. $el = FabTable::getInstance('Element', 'FabrikTable');
  257. $el->load($id);
  258. $o = $this->loadPlugIn($el->plugin, 'Element');
  259. $o->setId($id);
  260. $o->getElement();
  261. return $o;
  262. }
  263. /**
  264. * @param string name of plugin group to load
  265. * @param array list of default element lists
  266. * @param array list of default and plugin element lists
  267. */
  268. function loadLists($group, $lists, &$elementModel)
  269. {
  270. if (empty($this->_plugIns)) {
  271. $this->loadPlugInGroup($group);
  272. }
  273. foreach ($this->_plugIns[$group] as $plugIn) {
  274. if (method_exists($plugIn->object, 'getAdminLists')) {
  275. $lists = $plugIn->object->getAdminLists($lists, $elementModel, $plugIn->params);
  276. }
  277. }
  278. return $lists;
  279. }
  280. /**
  281. * run form & element plugins - yeah!
  282. * @param string method to check and call - corresponds to stage of form processing
  283. * @param object model calling the plugin form/table
  284. * @param string plugin type to call form/table
  285. * @return array of bools: false if error found and processed, otherwise true
  286. */
  287. function runPlugins($method, &$oRequest, $type = 'form')
  288. {
  289. if ($type == 'form') {
  290. // $$$ rob allow for table plugins to hook into form plugin calls - methods are mapped as:
  291. //form method = 'onLoad' => table method => 'onFormLoad'
  292. $tmethod = 'onForm'.FabrikString::ltrimword($method, 'on');
  293. $this->runPlugins($tmethod, $oRequest->getListModel(), 'list');
  294. }
  295. $params =& $oRequest->getParams();
  296. //$this->getPlugInGroup($type);
  297. $return = array();
  298. $usedPlugins = (array)$params->get('plugins');
  299. $usedLocations = (array)$params->get('plugin_locations');
  300. $usedEvents = (array)$params->get('plugin_events');
  301. $this->_data = array();
  302. if ($type != 'list') {
  303. if (method_exists($oRequest, 'getGroupsHiarachy')) {
  304. $groups =& $oRequest->getGroupsHiarachy();
  305. foreach ($groups as $groupModel) {
  306. $elementModels =& $groupModel->getPublishedElements();
  307. foreach ($elementModels as $elementModel) {
  308. if (method_exists($elementModel, $method)) {
  309. $elementModel->$method($oRequest);
  310. }
  311. }
  312. }
  313. }
  314. }
  315. $c = 0;
  316. $runPlugins = 0;
  317. // if true then a plugin has returned true from runAway() which means that any other plugin in the same group
  318. // should not be run.
  319. $runningAway = false;
  320. foreach ($usedPlugins as $usedPlugin) {
  321. if ($runningAway) {
  322. // "I soiled my armour I was so scared!"
  323. break;
  324. }
  325. if ($usedPlugin != '') {
  326. $plugin = $this->getPlugIn($usedPlugin, $type);
  327. //testing this if statement as onLoad was being called on form email plugin when no method availbale
  328. $plugin->renderOrder = $c;
  329. if (method_exists($plugin, $method)) {
  330. $modelTable = $oRequest->getTable();
  331. $pluginParams =& $plugin->setParams($params, $c);
  332. $location = JArrayHelper::getValue($usedLocations, $c);
  333. $event = JArrayHelper::getValue($usedEvents, $c);
  334. if ($plugin->canUse($oRequest, $location, $event) && method_exists($plugin, $method)) {
  335. $pluginArgs = array();
  336. if (func_num_args() > 3) {
  337. $t =& func_get_args();
  338. $pluginArgs =& array_splice($t, 3);
  339. }
  340. $preflightMethod = $method."_preflightCheck";
  341. $preflightCheck = method_exists($plugin, $preflightMethod) ? $plugin->$preflightMethod($pluginParams, $oRequest, $pluginArgs) : true;
  342. if ($preflightCheck) {
  343. $ok = $plugin->$method($pluginParams, $oRequest, $pluginArgs);
  344. if ($ok === false) {
  345. $return[] = false;
  346. } else {
  347. $thisreturn = $plugin->customProcessResult($method, $oRequest);
  348. $return[] = $thisreturn;
  349. $m = $method.'_result';
  350. if (method_exists($plugin, $m)) {
  351. $this->_data[] = $plugin->$m($c);
  352. }
  353. }
  354. $runPlugins ++;
  355. if ($plugin->runAway($method)) {
  356. $runningAway = true;
  357. }
  358. $mainData = $this->_data;
  359. if ($type == 'list' && $method !== 'observe') {
  360. $this->runPlugins('observe', $oRequest, 'list', $plugin, $method);
  361. }
  362. $this->_data = $mainData;
  363. }
  364. }
  365. }
  366. $c ++;
  367. }
  368. }
  369. $this->_runPlugins = $runPlugins;
  370. return array_unique($return);
  371. }
  372. /**
  373. * test if a plugin is installed
  374. * @param $group
  375. * @param $plugin
  376. * @return bol
  377. */
  378. function pluginExists($group, $plugin)
  379. {
  380. $plugins =& $this->loadPlugInGroup($group);
  381. if (in_array($plugin, array_keys($plugins))) {
  382. return true;
  383. }
  384. return false;
  385. }
  386. }
  387. ?>