start.php 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291
  1. <?php
  2. /**
  3. * Elgg developer tools
  4. */
  5. // we want to run this as soon as possible - other plugins should not need to do this
  6. developers_process_settings();
  7. elgg_register_event_handler('init', 'system', 'developers_init');
  8. function developers_init() {
  9. elgg_register_event_handler('pagesetup', 'system', 'developers_setup_menu');
  10. elgg_extend_view('css/admin', 'developers/css');
  11. elgg_extend_view('css/elgg', 'developers/css');
  12. elgg_register_page_handler('theme_sandbox', 'developers_theme_sandbox_controller');
  13. elgg_register_external_view('developers/ajax'); // for lightbox in sandbox
  14. $sandbox_css = elgg_get_simplecache_url('css', 'theme_sandbox.css');
  15. elgg_register_css('dev.theme_sandbox', $sandbox_css);
  16. $action_base = elgg_get_plugins_path() . 'developers/actions/developers';
  17. elgg_register_action('developers/settings', "$action_base/settings.php", 'admin');
  18. elgg_define_js('jquery.jstree', array(
  19. 'src' => '/mod/developers/vendors/jsTree/jquery.jstree.js',
  20. 'exports' => 'jQuery.fn.jstree',
  21. 'deps' => array('jquery'),
  22. ));
  23. elgg_register_css('jquery.jstree', '/mod/developers/vendors/jsTree/themes/default/style.css');
  24. elgg_require_js('elgg/dev');
  25. }
  26. function developers_process_settings() {
  27. $settings = elgg_get_plugin_from_id('developers')->getAllSettings();
  28. ini_set('display_errors', (int)!empty($settings['display_errors']));
  29. if (!empty($settings['screen_log'])) {
  30. // don't show in action/simplecache
  31. $path = substr(current_page_url(), strlen(elgg_get_site_url()));
  32. if (!preg_match('~^(cache|action)/~', $path)) {
  33. $cache = new ElggLogCache();
  34. elgg_set_config('log_cache', $cache);
  35. elgg_register_plugin_hook_handler('debug', 'log', array($cache, 'insertDump'));
  36. elgg_register_plugin_hook_handler('view_vars', 'page/elements/html', function($hook, $type, $vars, $params) {
  37. $vars['body'] .= elgg_view('developers/log');
  38. return $vars;
  39. });
  40. }
  41. }
  42. if (!empty($settings['show_strings'])) {
  43. // first and last in case a plugin registers a translation in an init method
  44. elgg_register_event_handler('init', 'system', 'developers_clear_strings', 1000);
  45. elgg_register_event_handler('init', 'system', 'developers_clear_strings', 1);
  46. }
  47. if (!empty($settings['show_modules'])) {
  48. elgg_require_js('elgg/dev/amd_monitor');
  49. }
  50. if (!empty($settings['wrap_views'])) {
  51. elgg_register_plugin_hook_handler('view', 'all', 'developers_wrap_views');
  52. }
  53. if (!empty($settings['log_events'])) {
  54. elgg_register_event_handler('all', 'all', 'developers_log_events', 1);
  55. elgg_register_plugin_hook_handler('all', 'all', 'developers_log_events', 1);
  56. }
  57. if (!empty($settings['show_gear']) && elgg_is_admin_logged_in() && !elgg_in_context('admin')) {
  58. elgg_require_js('elgg/dev/gear');
  59. elgg_load_js('lightbox');
  60. elgg_load_css('lightbox');
  61. elgg_register_ajax_view('developers/gear_popup');
  62. // TODO use ::class in 2.0
  63. $handler = ['Elgg\DevelopersPlugin\Hooks', 'alterMenuSectionVars'];
  64. elgg_register_plugin_hook_handler('view_vars', 'navigation/menu/elements/section', $handler);
  65. $handler = ['Elgg\DevelopersPlugin\Hooks', 'alterMenuSections'];
  66. elgg_register_plugin_hook_handler('view', 'navigation/menu/elements/section', $handler);
  67. }
  68. }
  69. function developers_setup_menu() {
  70. if (elgg_in_context('admin')) {
  71. elgg_register_admin_menu_item('develop', 'inspect');
  72. elgg_register_admin_menu_item('develop', 'sandbox', 'develop_tools');
  73. elgg_register_admin_menu_item('develop', 'unit_tests', 'develop_tools');
  74. elgg_register_menu_item('page', array(
  75. 'name' => 'dev_settings',
  76. 'href' => 'admin/developers/settings',
  77. 'text' => elgg_echo('settings'),
  78. 'context' => 'admin',
  79. 'priority' => 10,
  80. 'section' => 'develop'
  81. ));
  82. $inspect_options = developers_get_inspect_options();
  83. foreach ($inspect_options as $key => $value) {
  84. elgg_register_menu_item('page', array(
  85. 'name' => 'dev_inspect_' . elgg_get_friendly_title($key),
  86. 'href' => "admin/develop_tools/inspect?inspect_type={$key}",
  87. 'text' => $value,
  88. 'context' => 'admin',
  89. 'section' => 'develop',
  90. 'parent_name' => 'inspect'
  91. ));
  92. }
  93. }
  94. }
  95. /**
  96. * Clear all the strings so the raw descriptor strings are displayed
  97. */
  98. function developers_clear_strings() {
  99. global $CONFIG;
  100. $language = get_language();
  101. $CONFIG->translations[$language] = array();
  102. $CONFIG->translations['en'] = array();
  103. }
  104. /**
  105. * Post-process a view to add wrapper comments to it
  106. *
  107. * 1. Only process views served with the 'default' viewtype.
  108. * 2. Does not wrap views that begin with js/ or css/ as they are not HTML.
  109. * 3. Does not wrap views that are images (start with icon/). Is this still true?
  110. * 4. Does not wrap input and output views (why?).
  111. * 5. Does not wrap html head or the primary page shells
  112. *
  113. * @warning this will break views in the default viewtype that return non-HTML data
  114. * that do not match the above restrictions.
  115. */
  116. function developers_wrap_views($hook, $type, $result, $params) {
  117. if (elgg_get_viewtype() != "default") {
  118. return;
  119. }
  120. $excluded_bases = array('css', 'js', 'input', 'output', 'embed', 'icon', 'json', 'xml');
  121. $excluded_views = array(
  122. 'page/default',
  123. 'page/admin',
  124. 'page/elements/head',
  125. );
  126. $view = $params['view'];
  127. $view_hierarchy = explode('/',$view);
  128. if (in_array($view_hierarchy[0], $excluded_bases)) {
  129. return;
  130. }
  131. if (in_array($view, $excluded_views)) {
  132. return;
  133. }
  134. if ($result) {
  135. $result = "<!-- developers:begin $view -->$result<!-- developers:end $view -->";
  136. }
  137. return $result;
  138. }
  139. /**
  140. * Log the events and plugin hooks
  141. */
  142. function developers_log_events($name, $type) {
  143. // filter out some very common events
  144. if ($name == 'view' || $name == 'display' || $name == 'log' || $name == 'debug') {
  145. return;
  146. }
  147. if ($name == 'session:get' || $name == 'validate') {
  148. return;
  149. }
  150. // 0 => this function
  151. // 1 => call_user_func_array
  152. // 2 => hook class trigger
  153. $stack = debug_backtrace();
  154. if (isset($stack[2]['class']) && $stack[2]['class'] == 'Elgg\EventsService') {
  155. $event_type = 'Event';
  156. } else {
  157. $event_type = 'Plugin hook';
  158. }
  159. if ($stack[3]['function'] == 'elgg_trigger_event' || $stack[3]['function'] == 'elgg_trigger_plugin_hook') {
  160. $index = 4;
  161. } else {
  162. $index = 3;
  163. }
  164. if (isset($stack[$index]['class'])) {
  165. $function = $stack[$index]['class'] . '::' . $stack[$index]['function'] . '()';
  166. } else {
  167. $function = $stack[$index]['function'] . '()';
  168. }
  169. if ($function == 'require_once()' || $function == 'include_once()') {
  170. $function = $stack[$index]['file'];
  171. }
  172. $msg = elgg_echo('developers:event_log_msg', array(
  173. $event_type,
  174. $name,
  175. $type,
  176. $function,
  177. ));
  178. elgg_dump($msg, false);
  179. unset($stack);
  180. }
  181. /**
  182. * Serve the theme sandbox pages
  183. *
  184. * @param array $page
  185. * @return bool
  186. */
  187. function developers_theme_sandbox_controller($page) {
  188. if (!isset($page[0])) {
  189. forward('theme_sandbox/intro');
  190. }
  191. elgg_load_css('dev.theme_sandbox');
  192. $pages = array(
  193. 'buttons',
  194. 'components',
  195. 'forms',
  196. 'grid',
  197. 'icons',
  198. 'javascript',
  199. 'layouts',
  200. 'modules',
  201. 'navigation',
  202. 'typography',
  203. );
  204. foreach ($pages as $page_name) {
  205. elgg_register_menu_item('theme_sandbox', array(
  206. 'name' => $page_name,
  207. 'text' => elgg_echo("theme_sandbox:$page_name"),
  208. 'href' => "theme_sandbox/$page_name",
  209. ));
  210. }
  211. elgg_require_js('elgg/dev/theme_sandbox');
  212. $title = elgg_echo("theme_sandbox:{$page[0]}");
  213. $body = elgg_view("theme_sandbox/{$page[0]}");
  214. $layout = elgg_view_layout('theme_sandbox', array(
  215. 'title' => $title,
  216. 'content' => $body,
  217. ));
  218. echo elgg_view_page("Theme Sandbox : $title", $layout, 'theme_sandbox');
  219. return true;
  220. }
  221. /**
  222. * Get the available inspect options
  223. *
  224. * @return array
  225. */
  226. function developers_get_inspect_options() {
  227. $options = array(
  228. 'Actions' => elgg_echo('developers:inspect:actions'),
  229. 'Events' => elgg_echo('developers:inspect:events'),
  230. 'Menus' => elgg_echo('developers:inspect:menus'),
  231. 'Plugin Hooks' => elgg_echo('developers:inspect:pluginhooks'),
  232. 'Simple Cache' => elgg_echo('developers:inspect:simplecache'),
  233. 'Views' => elgg_echo('developers:inspect:views'),
  234. 'Widgets' => elgg_echo('developers:inspect:widgets'),
  235. );
  236. if (elgg_is_active_plugin('web_services')) {
  237. $options['Web Services'] = elgg_echo('developers:inspect:webservices');
  238. }
  239. ksort($options);
  240. return $options;
  241. }