CMS  Version 3.9
core.inc
Go to the documentation of this file.
1 <?php
2 /**************************************************************
3 
4  Copyright (c) 2010 Sonjara, Inc
5 
6  Permission is hereby granted, free of charge, to any person
7  obtaining a copy of this software and associated documentation
8  files (the "Software"), to deal in the Software without
9  restriction, including without limitation the rights to use,
10  copy, modify, merge, publish, distribute, sublicense, and/or sell
11  copies of the Software, and to permit persons to whom the
12  Software is furnished to do so, subject to the following
13  conditions:
14 
15  The above copyright notice and this permission notice shall be
16  included in all copies or substantial portions of the Software.
17 
18  Except as contained in this notice, the name(s) of the above
19  copyright holders shall not be used in advertising or otherwise
20  to promote the sale, use or other dealings in this Software
21  without prior written authorization.
22 
23  THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
24  EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
25  OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
26  NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
27  HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
28  WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
29  FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
30  OTHER DEALINGS IN THE SOFTWARE.
31 
32 *****************************************************************/
33 
34 
35 // Ensure that short open tags are enabled.
36 ini_set("short_open_tag", 1);
37 
38 register_shutdown_function(array('Fakoli', 'shutdownHandler'));
39 
40 require_once realpath(dirname(__FILE__)."/../framework/data_item.inc");
41 require_once realpath(dirname(__FILE__)."/../framework/cache.inc");
42 require_once realpath(dirname(__FILE__)."/components/component/datamodel/component.inc");
43 
44 // Default Font Awesome URL - free CDN version
45 $fontawesome = "https://use.fontawesome.com/releases/v5.1.1/css/all.css";
46 
53 class FakoliException extends Exception {}
54 
62 class FakoliEarlyExit extends Exception {}
63 
64 
69 class FakoliEventNotConsumed extends Exception {}
70 
79 class Fakoli
80 {
81  static $componentsUsed = array();
82  static $scanning = false;
83  static $outputBufferLevel = 0;
84  static $rollbackBuffers = true;
85  static $storage = array();
86  static $timestamp;
88  static $requestURI;
89  static $bodyClass = "";
90 
99  static function put($key, $obj) { Fakoli::$storage[$key] = $obj; }
100 
109  static function get($key) { return Fakoli::$storage[$key]; }
116  static function using()
117  {
118  global $config;
119 
120  $num = func_num_args();
121  for($i = 0; $i < $num; ++$i)
122  {
123  $component = func_get_arg($i);
124 
125  if (array_key_exists($component, Fakoli::$componentsUsed)) continue;
126 
128 
129  $includes = Cache::get("fakoli_includes_$component");
130  if ($includes)
131  {
132  if ($config['strict_includes'])
133  {
134  foreach ($includes as $include)
135  {
136  require_once $include;
137  }
138  }
139  else
140  {
141  foreach ($includes as $include)
142  {
143  include_once $include;
144  }
145  }
146  continue;
147  }
148 
150 
151  if (!$components[$component])
152  {
153  trace("Attempt to reference unknown or disabled component '$component'", 2);
154  continue;
155  }
156 
157  $includes = array();
158 
160 
161  $dm = $c->component_path . DIRECTORY_SEPARATOR . "datamodel";
162  if (is_dir($dm))
163  {
164  $handle = opendir($dm);
165  while(false !== ($file = readdir($handle)))
166  {
167  if (endsWith($file, ".inc"))
168  {
169  $f = $dm . DIRECTORY_SEPARATOR . $file;
170 
171  $includes[] = $f;
172  require_once $f;
173  }
174  }
175 
176  closedir($handle);
177  }
178 
179  trace($c->component_path, 4);
180 
181  $handle = opendir($c->component_path);
182 
183  if (!$handle) continue;
184 
185  while(false !== ($file = readdir($handle)))
186  {
187  if (endsWith($file, ".inc"))
188  {
189  $f = $c->component_path . DIRECTORY_SEPARATOR . $file;
190 
191  $includes[] = $f;
192  require_once $f;
193  }
194  }
195 
196  closedir($handle);
197 
198  Cache::put("fakoli_includes_$component", $includes);
199  }
200  }
201 
206  static function getComponents()
207  {
208  $components = Cache::get("fakoli_components");
209 
210  if (!$components)
211  {
212  $component = new Component();
213  if (!$component->tableExists()) Fakoli::bootstrap();
214 
215  $components = indexedQuery(Component, "WHERE enabled=1", "name");
216  if (count($components) == 0)
217  {
219  $components = Cache::get("fakoli_components");
220  }
221  else
222  {
223  Cache::put("fakoli_components", $components);
224  }
225  }
226 
227  return $components;
228  }
229 
235  static function getComponent($name)
236  {
238  return $components[$name];
239  }
240 
246  static function componentExists($name)
247  {
248  return array_key_exists($name, Fakoli::getComponents());
249  }
250 
255  static function initialComponentScan()
256  {
257  global $config;
258 
259  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component.inc");
260  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component_page.inc");
261  require_once realpath(dirname(__FILE__)."/components/component/datamodel/admin_page.inc");
262  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component_update_log.inc");
263  require_once realpath(dirname(__FILE__)."/components/component/serialization_manager.inc");
264  require_once realpath(dirname(__FILE__)."/components/component/component_manager.inc");
265  require_once realpath(dirname(__FILE__)."/components/component/upgrade_manager.inc");
266  require_once realpath(dirname(__FILE__)."/components/component/component_upgrade_manager.inc");
267 
268  $mgr = new ComponentManager();
269  $mgr->scan($config["scan_verbosity"]);
270  }
271 
276  static function bootstrap()
277  {
278  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component.inc");
279  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component_page.inc");
280  require_once realpath(dirname(__FILE__)."/components/component/datamodel/admin_page.inc");
281  require_once realpath(dirname(__FILE__)."/components/component/datamodel/component_update_log.inc");
282  require_once realpath(dirname(__FILE__)."/components/component/serialization_manager.inc");
283  require_once realpath(dirname(__FILE__)."/components/component/component_manager.inc");
284  require_once realpath(dirname(__FILE__)."/components/component/upgrade_manager.inc");
285  require_once realpath(dirname(__FILE__)."/components/component/component_upgrade_manager.inc");
286 
288  $mgr->bootstrap();
289  }
290 
297  static function assertRole($role, $redirect = "", $message = "")
298  {
299  global $user;
300  global $isAction;
301 
302  if (!$redirect && !$message) $redirect = "/index";
303 
304  if (!checkRole($role))
305  {
306  if ($redirect)
307  {
308  if (!$user)
309  {
310  $mgr = new LoginManager();
311  $mgr->storeRedirectPage();
312  }
313 
314  redirect($redirect);
315  }
316  else
317  {
318  if ($isAction)
319  {
321  }
322  else
323  {
324  throw new FakoliException($message);
325  }
326  }
327  }
328  }
329 
338  static function checkRole($role, $msg = null)
339  {
340  $access = checkRole($role);
341  if (!$access && $msg) throw new FakoliException($msg);
342  return $access;
343  }
344 
349  static function isUserActive($user)
350  {
351  $mgr = new UserManager();
352  if (method_exists($mgr, "isActive")) return $mgr->isActive($user);
353  if ($user->hasField("active")) return $user->active;
354  return false;
355  }
356 
360  static function getLocalIP()
361  {
362  $ip = Settings::getValue("settings", "local_IP_address");
363  return ($ip) ? $ip : $_SERVER["SERVER_ADDR"];
364  }
365 
369  static function usingFile()
370  {
371  $num = func_num_args();
372 
373  for($i = 0; $i < $num; ++$i)
374  {
375  $file = func_get_arg($i);
376 
377  $f = realpath(dirname(__FILE__)."/../$file");
378  require_once $f;
379  }
380  }
381 
388  static function usingFeature()
389  {
390  $num = func_num_args();
391 
392  for($i = 0; $i < $num; ++$i)
393  {
394  $file = func_get_arg($i);
395 
396  $f = realpath(dirname(__FILE__)."/../framework/{$file}.inc");
397  require_once $f;
398  }
399  }
400 
405  static function getAdminMenu()
406  {
407  $menu = Cache::get("fakoli_admin_menu");
408  if ($menu) return $menu;
409 
410  $menu = array("Site Content" => array(),
411  "Site Configuration" => array(),
412  "Collaboration" => array(),
413  "Classification" => array(),
414  "Email Management" => array(),
415  "User Management" => array());
416 
418  foreach($components as $name => $component)
419  {
420  $manifest = $component->loadManifest();
421  if (method_exists($manifest, getAdminMenu))
422  {
423  $componentMenuItems = $manifest->getAdminMenu();
424  if ($componentMenuItems)
425  {
426  foreach($componentMenuItems as $category => $items)
427  {
428  if (!$menu[$category])
429  {
430  $menu[$category] = $items;
431  }
432  else
433  {
434  $menu[$category] = array_merge($menu[$category], $items);
435  }
436  }
437  }
438  }
439  }
440 
441  foreach($menu as $category => $items)
442  {
443  uasort($menu[$category], array(Fakoli, compareByWeight));
444  }
445 
446  Cache::put("fakoli_admin_menu", $menu);
447 
448  return $menu;
449  }
450 
456  static function getAdminIcons()
457  {
458  $icons = Cache::get("fakoli_admin_icons");
459  if ($icons) return $icons;
460 
461  $icons = array("Site Content" => "file-alt",
462  "Site Configuration" => "cogs",
463  "Collaboration" => "comments",
464  "Classification" => "tags",
465  "Email Management" => "envelope",
466  "User Management" => "users",
467  "Users" => "user",
468  "Public Site" => "home"
469  );
470 
471  $icons = ComponentManager::fireEvent("RegisterAdminIcons", $icons);
472 
473  Cache::put("fakoli_admin_icons", $icons);
474  return $icons;
475  }
476 
477  private static function getAdminPageRoles()
478  {
479  $pageRoles = Cache::get("fakoli_admin_page_roles");
480  if ($pageRoles) return $pageRoles;
481 
482  $pageRoles = array();
484  foreach($components as $name => $component)
485  {
486  $manifest = $component->loadManifest();
487 
488  if (method_exists($manifest, "getAdminPageRoles"))
489  {
490  $pageRoles = array_merge($pageRoles, $manifest->getAdminPageRoles());
491  }
492  }
493 
494  Cache::put("fakoli_admin_page_roles", $pageRoles);
495 
496  return $pageRoles;
497  }
498 
514  {
515  $uri = "/admin/$identifier";
516 
517  $role = "admin";
519  foreach($menu as $heading => $items)
520  {
521  foreach($items as $item)
522  {
523  if ($item["page"] == $uri)
524  {
525  if ($item["role"])
526  {
527  $role = $item["role"];
528  break;
529  }
530  }
531  }
532  }
533 
534  trace("###Role: $role", 3);
535 
536  $pageRoles = Fakoli::getAdminPageRoles();
537  trace(print_r($pageRoles, true), 3);
538 
539  if ($pageRoles[$uri])
540  {
541  $role = $pageRoles[$uri];
542  }
543 
544  trace("###ADMIN PAGE ROLE: $identifier $role", 3);
545  return $role;
546  }
547 
548  private static $includedScripts = array();
549 
554  static function getScripts()
555  {
556  $scripts = Cache::get("fakoli_scripts");
557  if ($scripts) return $scripts;
558 
559  $scriptArray = Fakoli::loadScripts();
560  foreach($scriptArray as $s)
561  {
562  Fakoli::$includedScripts[$s] = true;
563  }
564 
565  $scriptArray = ComponentManager::fireEvent("PreProcessScripts", $scriptArray);
566 
567  $scripts = "";
568  foreach($scriptArray as $s)
569  {
570  $scripts .= " <script type='text/javascript' src='$s'></script>\n";
571  }
572 
573  Cache::put("fakoli_scripts", $scripts);
574  return $scripts;
575  }
576 
581  static function loadScripts()
582  {
583  $scriptArray = array();
584 
585  $components = Query::create(Component, "WHERE enabled=1 ORDER BY priority")->execute();
586  foreach($components as $component)
587  {
588  $manifest = $component->loadManifest();
589  if (method_exists($manifest, getScripts))
590  {
591  // Calculate union of scripts
592  $scriptArray = array_merge($scriptArray, array_diff($manifest->getScripts(), $scriptArray));
593  }
594  }
595 
596  return $scriptArray;
597  }
598 
603  static function getStyles()
604  {
605  $styles = Cache::get("fakoli_styles");
606  if ($styles) return $styles;
607 
608  $styleArray = Fakoli::loadStyles();
609  $styleArray = ComponentManager::fireEvent("PreProcessStyles", $styleArray);
610 
611  $styles = "";
612  foreach($styleArray as $s)
613  {
614  $styles .= " <link href='$s' rel='stylesheet' type='text/css' media='all'/>\n";
615  }
616 
617  Cache::put("fakoli_styles", $styles);
618  return $styles;
619  }
620 
625  static function loadStyles()
626  {
627  $styleArray = array();
628 
629  $components = Query::create(Component, "WHERE enabled=1 ORDER BY priority")->execute();
630  foreach($components as $component)
631  {
632  $manifest = $component->loadManifest();
633  if (method_exists($manifest, getStyles))
634  {
635  // Calculate union of styles
636  $styleArray = array_merge($styleArray, array_diff($manifest->getStyles(), $styleArray));
637  }
638  }
639 
640  return $styleArray;
641  }
642 
650  static function evaluateFile($filePath)
651  {
652  global $config;
653  global $method;
654  global $user;
655  global $script;
656  global $styles;
657  global $breadcrumbs;
658  global $dialogs;
659  global $page;
660  global $site;
661  global $menu_identifier;
662  global $identifier;
663  global $section;
664 
665  ob_start();
666 
667  $codePath = explode(",", $filePath);
668  if (count($codePath) == 2)
669  {
670  $name = $codePath[0];
671  $php_code_file = $codePath[1];
673  if (array_key_exists($name, $components))
674  {
675 
676  $path = $components[$name]->component_path."/{$php_code_file}";
677  trace("Evaluating $path", 3);
678  include $path;
679  }
680  else
681  {
682  throw new FakoliException("Unknown component");
683  }
684  }
685  else
686  {
687  $matches = array();
688  if (preg_match('/^\/components\/(.*?)\//', $filePath, $matches))
689  {
690  $c = $matches[1];
691  $path = str_replace("/components/{$c}", "", $filePath);
693  if ($component)
694  {
695  $path = $component->component_path . $path;
696  include $path;
697  }
698  }
699  else
700  {
701  include $config['homedir']."/{$filePath}";
702  }
703  }
704  $output = ob_get_contents();
705  ob_end_clean();
706 
707  return $output;
708  }
709 
714  static function includeScript($src)
715  {
716  global $isResource;
717  global $script;
718  if (!array_key_exists($src, Fakoli::$includedScripts))
719  {
720  $script .= "<script type='text/javascript' src='$src'></script>\n";
721  Fakoli::$includedScripts[$src] = true;
722  }
723  }
724 
730  static function includeStylesheet($src, $media="all")
731  {
732  global $styles;
733  $styles .= "<link href='$src' rel='stylesheet' type='text/css' media='$media'/>\n";
734  }
735 
742  static function compareByWeight($item1, $item2)
743  {
744  return $item1["weight"] - $item2["weight"];
745  }
746 
752  static function getComponentClassRoot($name)
753  {
754  return str_replace(" ", "", prettify($name));
755  }
756 
765  static function sendResource($uri, $component = "")
766  {
768  if (!$resource)
769  {
770  throw new FakoliException("Cannot find resource '$uri'");
771  }
772 
773  Fakoli::sendFile($resource);
774  }
775 
780  static function sendFile($resource)
781  {
782  $last_modified = filemtime($resource);
783 
784  $mimeType = DocumentHandler::getMIMEType($resource);
785 
786  if(array_key_exists("HTTP_IF_MODIFIED_SINCE",$_SERVER))
787  {
788 
789  $if_modified_since=strtotime($_SERVER["HTTP_IF_MODIFIED_SINCE"]);
790  //$if_modified_since=strtotime(preg_replace('/;.*$/','',$_SERVER["HTTP_IF_MODIFIED_SINCE"]));
791 
792  if($if_modified_since >= $last_modified)
793  {
794  header("HTTP/1.0 304 Not Modified");
795  $noChange = true;
796  }
797  }
798 
799  header("Content-Type: $mimeType");
800  header("Last-Modified: ".date('r', $last_modified));
801  header("Cache-Control: max-age=300, must-revalidate");
802  header("Pragma: private");
803  header("Expires: " . date(DATE_RFC822,strtotime(" 2 day")));
804 
805  if (!$noChange)
806  {
808  {
809  header("X-SendFile: $resource");
810  return;
811  }
812  else
813  {
814  $f = fopen($resource, "r");
815 
816  $size = filesize($resource);
817  header("Content-Length: $size");
818 
819  fpassthru($f);
820  fclose($f);
821  }
822  }
823 
824  ComponentManager::fireEvent("RequestComplete");
825  }
826 
834  static function detectXSendFileSupport()
835  {
836  if (function_exists("apache_get_modules"))
837  {
838  $support = in_array('mod_xsendfile', apache_get_modules());
839  }
840 
841  return $support;
842  }
843 
850  static function resolveResource($resource, $component = "")
851  {
852  global $config;
853 
854  if (strpos("../", $resource) !== FALSE)
855  {
856  throw new FakoliException("Attempt to resolve illegal resource path");
857  }
858 
859  if (endsWith($resource, ".inc") || endsWith($resource, ".php"))
860  {
861  header("HTTP/1.0 403 Forbidden");
862  throw new FakoliException("Access Forbidden");
863  }
864 
865  $resource = sanitizePath($resource);
866 
867  $dir = dirname($resource);
868 
869  // Exclude the following component sub-directories
870  if ($dir == "datamodel" || $dir == "updates" || $dir == "admin") return null;
871 
873 
874  if ($component)
875  {
876  if (!$components[$component])
877  {
878  throw new FakoliException("Attempt to reference unknown or disabled component '$component'");
879  }
880 
882 
883  $file = $c->component_path . DIRECTORY_SEPARATOR . $resource;
884 
885  return (file_exists($file)) ? $file : null;
886  }
887 
888  $file = Cache::get("resource:$resource");
889  if ($file) return $file;
890 
891  $path = $config['homedir'] . PATH_SEPARATOR . ini_get("include_path");
892  if (isset($config["extra_includes"])) $path .= PATH_SEPARATOR . $config["extra_includes"];
893 
894  $roots = explode(PATH_SEPARATOR, $path);
895 
896  foreach($roots as $root)
897  {
898  $file = sanitizePath($root . DIRECTORY_SEPARATOR . $resource);
899  if (file_exists($file))
900  {
901  Cache::put("resource:$resource", $file);
902  return $file;
903  }
904 
905  $file = sanitizePath($root . DIRECTORY_SEPARATOR . "cms" . DIRECTORY_SEPARATOR . $resource);
906  if (file_exists($file))
907  {
908  Cache::put("resource:$resource", $file);
909  return $file;
910  }
911  }
912 
913  foreach($components as $name => $c)
914  {
915  $file = sanitizePath($c->component_path . DIRECTORY_SEPARATOR . $resource);
916  if (file_exists($file))
917  {
918  Cache::put("resource:$resource", $file);
919  return $file;
920  }
921  }
922 
923  trace("Cannot resolve $file", 2);
924 
925  return null;
926  }
927 
932  static function loadResource($resource, $component = "")
933  {
935  if ($path) return file_get_contents($path);
936  return null;
937  }
938 
949  static function applyTemplate($target, $templateFile, $component = "")
950  {
951  $template = Fakoli::loadResource($templateFile, $component);
952  return $target->format($template);
953  }
954 
958  static function checkSSL()
959  {
960  $https = false;
961  $https = $_SERVER['HTTPS'];
962  if ($https == "off") $https = false;
963  if (isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] === 'https')
964  {
965  $https = true;
966  }
967 
968  return $https;
969  }
970 
978  static function sendPage($sectionIdentifier, $identifier, $page_id = null)
979  {
980  trace("Send Page: '$sectionIdentifier', '$identifier', '$page_id'", 2);
981 
982  $site = Site::getSite();
983 
984  if (!$sectionIdentifier) $sectionIdentifier = "/";
985 
986  if ($sectionIdentifier == "/" && $identifier == "admin")
987  {
988  redirect("/admin/index");
989  }
990 
991  if (!$identifier && $page_id)
992  {
993  throw new FakoliException("Page ID access has been deprecated.");
994  }
995 
996  global $config;
997  global $section;
998 
999  try
1000  {
1001  $section = Section::createFromIdentifier($sectionIdentifier);
1002 
1003  ComponentManager::fireEvent("OverrideResource", $identifier);
1004 
1005  if (!$section)
1006  {
1007  throw new FakoliException("The section you were attempting to access could not be found.");
1008  }
1009 
1010  $contentManager = $section->getContentManager();
1011 
1012  if (!$identifier)
1013  {
1014  $url = $section->getSectionURL();
1015  redirect($url.$contentManager->getDefaultPage($section));
1016  }
1017  else
1018  {
1019  $alias = ComponentManager::fireEvent("PreprocessURI", $identifier);
1020  if ($alias) $identifier = $alias;
1021  }
1022 
1023  $content = $section->getContent($identifier);
1024  if (!$content)
1025  {
1026  ComponentManager::fireEvent("ResourceNotFound", $identifier);
1027 
1028  throw new FakoliException("The page you were attempting to access could not be found.");
1029  }
1030 
1031  $permissions = $section->getPermissions($content);
1032  if ($permissions)
1033  {
1034  trace("Checking Permissions: [{$permissions}]", 4);
1036  {
1038  }
1039  }
1040  else if (!checkRole($section->getRole($content)))
1041  {
1043  }
1044 
1045  trace("\$_SERVER['HTTPS'] = {$_SERVER['HTTPS']}", 3);
1046  trace("\$_SERVER['REQUEST_URI'] = {$_SERVER['REQUEST_URI']}", 3);
1047 
1048  $https = Fakoli::checkSSL();
1049 
1050  $useSSL = $section->use_SSL || $content->use_SSL;
1051 
1052  if ($useSSL && !$https )
1053  {
1054  redirect("https://".$config['http_host'].$_SERVER['REQUEST_URI']);
1055  }
1056  else if (!$useSSL && $https && $identifier != "login" && !isset($_REQUEST["login"]))
1057  {
1058  redirect("http://".$config['http_host'].$_SERVER['REQUEST_URI']);
1059  }
1060 
1061  ComponentManager::fireEvent("StartPage");
1062  $contentManager->sendContent($section, $identifier);
1063  ComponentManager::fireEvent("RequestComplete");
1064  }
1065  catch(FakoliEarlyExit $exit)
1066  {
1067  echo $exit->getMessage();
1068  }
1069  }
1070 
1074  static function getAdminAccessRoles()
1075  {
1076  global $config;
1077  $adminAccess = $config["admin_access_roles"];
1078  if (!$adminAccess) $adminAccess = "admin";
1079  return $adminAccess;
1080  }
1081 
1085  static function countActiveSessions()
1086  {
1087  $sessions = scandir(ini_get("session.save_path"));
1088  trace("SESSIONS: ".print_r($session, true), 1);
1089  $number_of_users = count($sessions) - 2;
1090  return $number_of_users;
1091  }
1092 
1097  static function sendAdminPage($identifier)
1098  {
1100 
1102 
1103  if ($identifier != "login" && $identifier != "password_help")
1104  {
1105  Fakoli::assertRole($adminAccess, "/admin/login");
1106  Fakoli::assertRole($pageRole, "/admin/login");
1107  }
1108 
1109  $https = Fakoli::checkSSL();
1110 
1111  if ($config['admin_SSL'] && !$https )
1112  {
1113  redirect("https://".$config['http_host'].$_SERVER['REQUEST_URI']);
1114  }
1115 
1117  $view->drawView();
1118  }
1119 
1123  static function getComponentForClass($class)
1124  {
1125  $reflector = new ReflectionClass($class);
1126  $file = $reflector->getFileName();
1127  trace("File for $class: $file", 3);
1128 
1129  if ($file)
1130  {
1131  $file = str_replace(DIRECTORY_SEPARATOR, "/", $file);
1132 
1133  $matches = array();
1134  if (preg_match("/components\\/(.*?)\\//", $file, $matches))
1135  {
1136  trace("Component for $class is {$matches[1]}", 3);
1137  return $matches[1];
1138  }
1139  }
1140 
1141  throw new FakoliException("Failed to determine component for $class");
1142  }
1143 
1149  static function end($message = "")
1150  {
1151  throw new FakoliEarlyExit($message);
1152  }
1153 
1160  static function JSONreturn($object, $sendType = true, $wrap = true)
1161  {
1162  if ($sendType) header("Content-Type: application/json");
1163  if (method_exists($object, "toJSON"))
1164  {
1165  $out = ($wrap) ? '{"result": '.$object->toJSON().'}' : $object->toJSON();
1166  }
1167  else
1168  {
1169  $out = ($wrap) ? '{"result": '.json_encode($object).'}' : json_encode($object);
1170  }
1171 
1172  throw new FakoliEarlyExit($out);
1173  }
1174 
1180  static function JSONerror($error, $sendType = true)
1181  {
1182  if ($sendType) header("Content-Type: application/json");
1183 
1184  $errorObject = (object)array('error' => $error);
1185 
1186  throw new FakoliEarlyExit(json_encode($errorObject));
1187  }
1188 
1198  static function notify($message, $blocking = false, $button = "OK", $onClick = "null")
1199  {
1200  $message = jsSafe($message);
1201 
1202  if ($blocking)
1203  {
1204  $options = ", {blocking: true, buttonText: '$button', onClick: $onClick}";
1205  }
1206  global $script;
1207  $script .=
1208 <<<ENDSCRIPT
1209  <script type='text/javascript'>
1210  window.addEvent('load', function()
1211  {
1212  notification("$message"$options);
1213  });
1214  </script>
1215 ENDSCRIPT;
1216  }
1217 
1223  static function notifyOnNextPage($message, $blocking = false, $button = "OK", $onClick = "null")
1224  {
1225  $_SESSION["notification_pending"] = $message;
1226  $_SESSION["notification_pending_blocking"] = $blocking;
1227  $_SESSION["notification_pending_button"] = $button;
1228  $_SESSION["notification_pending_onclick"] = $onClick;
1229  }
1230 
1234  static function showPendingNotification()
1235  {
1236  global $isAction;
1237  global $isResource;
1238 
1239  if (!$isAction && !$isResource && isset($_SESSION["notification_pending"]))
1240  {
1241  Fakoli::notify($_SESSION["notification_pending"],
1242  $_SESSION["notification_pending_blocking"],
1243  $_SESSION["notification_pending_button"],
1244  $_SESSION["notification_pending_onclick"]);
1245  unset($_SESSION["notification_pending"]);
1246  unset($_SESSION["notification_pending_blocking"]);
1247  unset($_SESSION["notification_pending_button"]);
1248  unset($_SESSION["notification_pending_onclick"]);
1249  }
1250  }
1251 
1259  function scrollTo($element, $offset = 0)
1260  {
1261  global $script;
1262  $script .=
1263 <<<ENDSCRIPT
1264  <script type='text/javascript'>
1265  window.addEvent('domready', function()
1266  {
1267  window.scrollToElement('{$element}', $offset);
1268  });
1269  </script>
1270 ENDSCRIPT;
1271  }
1272 
1279  function scrollToOnNextPage($element, $offset = 0)
1280  {
1281  $_SESSION["scrollto_pending"] = $element;
1282  $_SESSION["scrollto_offset"] = $offset;
1283  }
1284 
1288  static function showPendingScrollTo()
1289  {
1290  global $isAction;
1291  global $isResource;
1292 
1293  if (!$isAction && !$isResource && isset($_SESSION["scrollto_pending"]))
1294  {
1295  Fakoli::scrollTo($_SESSION["scrollto_pending"], $_SESSION["scrollto_offset"]);
1296  unset($_SESSION["scrollto_pending"]);
1297  unset($_SESSION["scrollto_offset"]);
1298  }
1299  }
1300 
1305  function scriptOnNextPage($s)
1306  {
1307  $_SESSION["script_pending"] .= $s;
1308  }
1309 
1313  static function writePendingScripts()
1314  {
1315  global $isAction;
1316  global $isResource;
1317  global $script;
1318 
1319  if (!$isAction && !$isResource && isset($_SESSION["script_pending"]))
1320  {
1321  $script .= $_SESSION["script_pending"];
1322  unset($_SESSION["script_pending"]);
1323  }
1324  }
1325 
1329  static function setTraceLevel($level)
1330  {
1331  global $config;
1332  $config["trace_level"] = $level;
1333  }
1334 
1338  static function applicationTraceLevel()
1339  {
1340  Fakoli::setTraceLevel(Settings::getValue("debug", "application_trace_level"));
1341  }
1342 
1346  static function coreTraceLevel()
1347  {
1348  Fakoli::setTraceLevel(Settings::getValue("debug", "trace_level"));
1349  }
1350 
1354  static function scheduledTaskTraceLevel()
1355  {
1356  Fakoli::setTraceLevel(Settings::getValue("debug", "scheduled_task_trace_level"));
1357  }
1358 
1368  static function errorHandler($errLevel, $errMsg, $errFile, $errLine)
1369  {
1370  // Transform XML DOM warning messages into exceptions for easier handling
1371  if ($errLevel==E_WARNING && (substr_count($errMsg,"DOMDocument::loadXML()")>0))
1372  {
1373  throw new DOMException($errMsg);
1374  }
1375 
1376  if ($errLevel & (E_NOTICE | E_WARNING | E_USER_WARNING | E_STRICT | E_DEPRECATED)) return;
1377 
1378  throw new ErrorException($errMsg, $errLevel, $errLevel, $errFile, $errLine);
1379  }
1380 
1386  static function exceptionHandler($exception)
1387  {
1388  global $isAction;
1389  global $config;
1390 
1391  try
1392  {
1393  //Getting exception information
1394  $errMsg = $exception->getMessage();
1395  $errLevel = $exception->getCode();
1396  $errFile = $exception->getFile();
1397  $errLine = $exception->getLine();
1398 
1399  if ($errLevel & (E_NOTICE | E_WARNING | E_USER_WARNING | E_STRICT | E_DEPRECATED)) return;
1400 
1401  trace("ZIP: Winding back output buffers from ".ob_get_level(), 3);
1402 
1404  {
1405  while(ob_get_level() > Fakoli::$outputBufferLevel) // Clear all output buffers.
1406  {
1407  ob_end_clean();
1408  }
1409  }
1410 
1411  $msg = $exception->getMessage();
1412  if ($config["bootstrap_error_stack_trace"])
1413  {
1414  $msg .= "<br/><b>Stack trace:</b><br/>".$exception->getTraceAsString();
1415  }
1416 
1417  if ($isAction)
1418  {
1419  echo $msg;
1420  }
1421  else
1422  {
1423  $err = Fakoli::resolveResource("/fakoli/error.tpl");
1424  $template = file_get_contents($err);
1425  $out = str_replace("{message}", $msg, $template);
1426  echo $out;
1427  }
1428 
1429  ComponentManager::fireEvent("RequestComplete");
1430  }
1431  catch (Exception $ex)
1432  {
1433  echo $ex->getMessage();
1434  //Do nothing.
1435  //Avoiding error from error handling...
1436  }
1437 
1438  /* Don't execute PHP internal error handler */
1439  return true;
1440  }
1441 
1446  static function scriptName()
1447  {
1448  list ($s, $qs) = explode("?", $_SERVER['REQUEST_URI']);
1449  return $s;
1450  }
1451 
1455  static function detectWindowsOS()
1456  {
1457  return (strtolower(substr(PHP_OS, 0, 3)) == "win");
1458  }
1459 
1469  static function getServerLoad()
1470  {
1471  $out = "";
1472 
1473  if (Fakoli::detectWindowsOS())
1474  {
1475  if (class_exists("COM"))
1476  {
1477  $wmi = new COM("Winmgmts:{impersonationlevel=impersonate}!\\Root\\Cimv2");
1478  $cpus = $wmi->InstancesOf("Win32_Processor");
1479 
1480  foreach ($cpus as $cpu)
1481  {
1482  $out .= $cpu->LoadPercentage."% ";
1483  }
1484  }
1485  else
1486  {
1487  $out .= "Not Available";
1488  }
1489  }
1490  else
1491  {
1492  $sys_load = sys_getloadavg();
1493  $load0 = number_format($sys_load[0], 2);
1494  $load1 = number_format($sys_load[1], 2);
1495  $load2 = number_format($sys_load[2], 2);
1496  $out = "$load0&nbsp;&nbsp;&nbsp;$load1&nbsp;&nbsp;&nbsp;$load2";
1497  }
1498 
1499  return $out;
1500  }
1501 
1506  static function getFileSystemInfo()
1507  {
1508  global $config;
1509 
1510  if (isset($config['filesystems']))
1511  {
1512  $fs = explode(",", $config['filesystems']);
1513  }
1514  else if (Fakoli::detectWindowsOS())
1515  {
1516  $fs = array("C:");
1517  }
1518  else
1519  {
1520  $fs = array("/");
1521  }
1522 
1523  $out = "<table class='list'><thead><tr><th>File System</th><th>Size</th><th>Available</th><th>% Free</th></tr></thead><tbody>";
1524  foreach($fs as $f)
1525  {
1526  $free = disk_free_space($f);
1527  $total = disk_total_space($f);
1528  $percent = number_format($free * 100 / $total, 1);
1529  $style = ($percent < 10) ? " style='background-color: #f00;color: #fff'" : (($percent < 25) ? " style='background-color: #ff0'" : "");
1530  $out .= "<tr$style><td>$f</td><td style='text-align: right'>" . getScaledSize($total) .
1531  "</td><td style='text-align: right'>" . getScaledSize($free) .
1532  "</td><td style='text-align: right'>" . $percent . "%</td></tr>";
1533  }
1534 
1535  $out .= "</tbody></table>";
1536  return $out;
1537  }
1538 
1542  static function shutdownHandler()
1543  {
1544  global $config;
1545  $error = error_get_last();
1546 
1547  trace("## Shutdown", 4);
1548 
1549  if ($error)
1550  {
1551  switch($error['type'])
1552  {
1553  case E_ERROR:
1554  case E_CORE_ERROR:
1555  case E_COMPILE_ERROR:
1556  case E_USER_ERROR:
1557 
1558  trace($error['message']." at ".$error['file'].":".$error['line'], 1);
1559 
1560  if ($config["dump_includes"])
1561  {
1562  printIncludes();
1563  }
1564  break;
1565  }
1566  }
1567  }
1568 }
1569 
1573 $method = $_SERVER["REQUEST_METHOD"];
1574 
1575 Fakoli::$timestamp = microtime(true);
1577 Fakoli::$requestURI = $_SERVER["REQUEST_URI"];
1578 
1579 if ($config["default_content_type"])
1580 {
1581  header("Content-Type: {$config['default_content_type']}");
1582 }
1583 
1584 $isAction = (basename($_SERVER["SCRIPT_FILENAME"]) == "action.php" || php_sapi_name() == "cli");
1585 $isResource = basename($_SERVER["SCRIPT_FILENAME"]) == "resource.php";
1586 
1587 if ($isAction)
1588 {
1589  registerURLRewriteParameters("component", "identifier");
1590 }
1591 else if ($isResource)
1592 {
1593  registerURLRewriteParameters("component", "path");
1594 }
1595 else if ($isAdmin)
1596 {
1597  registerURLRewriteParameters("identifier");
1598 }
1599 else
1600 {
1601  registerURLRewriteParameters("section", "identifier");
1602 }
1603 
1604 Fakoli::$outputBufferLevel = ob_get_level(); // Initial level of output buffer nesting
1605 
1606 set_error_handler(array("Fakoli", "errorHandler"));
1607 set_exception_handler(array("Fakoli", "exceptionHandler"));
1608 
1609 Fakoli::using("component", "user", "login");
1610 
1611 ComponentManager::fireEvent("ConfigurationBootstrap");
1612 
1613 
1614 // Automatically import commonly used features
1615 Fakoli::usingFeature("auto_form", "auto_form_layout", "data_view", "grouped_data_view", "join", "search_form", "tab_bar", "paged_list", "expanding_list", "date_utils");
1616 
1617 $user = null;
1618 
1619 // Import Standard Features
1620 Fakoli::usingFeature("data_item", "auto_form", "field_renderers", "cache", "data_view", "grouped_data_view", "filter_form", "search_form",
1621  "paged_list", "grouped_list", "facet_manager", "join", "tab_bar", "tree");
1622 
1623 $config["trace_level"] = Settings::getValue("debug", "trace_level");
1624 
1625 ComponentManager::fireEvent("RegisterErrorHandler");
1626 ComponentManager::fireEvent("RegisterActivityTracker");
1627 ComponentManager::fireEvent("RegisterSessionPersistance");
1628 ComponentManager::fireEvent("RegisterLoginExtension");
1629 
1630 session_start();
1631 
1632 if (isset($_SESSION["user"]))
1633 {
1634  if ($_POST["Logout"])
1635  {
1636  session_destroy();
1637  unset($user);
1638  }
1639  else
1640  {
1641  $user = $_SESSION["user"];
1642  }
1643 }
1644 else
1645 {
1646 
1647  if ($method == "POST" && $_POST["Login"])
1648  {
1649  $mgr = new LoginManager();
1650  $mgr->validateLogin();
1651 
1652  }
1653 }
1654 
1658 ComponentManager::fireEvent("Initialize");
1659 
1660 ?>
if($user_id) $sessions
$redirect
$_POST["owner_id"]
Definition: blog_form.inc:54
$err
Definition: error_log.inc:9
$section
Definition: event_form.inc:44
$page
Definition: help.inc:39
$component
Definition: help.inc:38
$view
Definition: help.inc:42
$out
Definition: page.inc:66
if(! $page) $path
Definition: page.inc:57
$src
Definition: page.inc:37
$components
Definition: tree.inc:41
$menu
Definition: menu_form.inc:47
if(! $class||! $itemID) $adminAccess
Definition: approve.inc:12
$dir
Definition: delete.inc:44
$file
Definition: delete.inc:47
$f
Definition: download.inc:46
$mimeType
Definition: download.inc:43
$size
Definition: download.inc:47
$name
Definition: upload.inc:54
ComponentManager provides the core functionality for building the component map describing the applic...
static fireEvent($event, $parameter=null, $mustBeConsumed=false)
Fire an event to all subscribers as detailed in their manifests.
FakoliEarlyExit is an internal exception class used to provide for controlled early exits during page...
Definition: core.inc:62
FakoliEventNotConsumed is thrown when no subscriber has handled an event that was fired with $mustBeC...
Definition: core.inc:69
FakoliException is the base exception class for all Fakoli errors.
Definition: core.inc:53
This class provides the Fakoli CMS core.
Definition: core.inc:80
static scriptName()
Returns the name of the currently executing script.
Definition: core.inc:1446
static compareByWeight($item1, $item2)
Sorting callback function that sorts two admin menu items by their specified weights.
Definition: core.inc:742
static getStyles()
Returns the HTML link tags for CSS files specified by the registered components in their manifest fil...
Definition: core.inc:603
static componentExists($name)
Test whether the specified component has been registered.
Definition: core.inc:246
static coreTraceLevel()
Change to the configured trace level for Fakoli core code.
Definition: core.inc:1346
static applyTemplate($target, $templateFile, $component="")
Format the target DataItem or JoinResult using the specified template file.
Definition: core.inc:949
static $requestStartTime
Start of request in DateTime format.
Definition: core.inc:87
static sendAdminPage($identifier)
Send the admin page for the given identifier.
Definition: core.inc:1097
static shutdownHandler()
Custom shutdown handler.
Definition: core.inc:1542
scrollTo($element, $offset=0)
Automatically scroll the page to the specified element (by DOM ID) when the page loads.
Definition: core.inc:1259
static errorHandler($errLevel, $errMsg, $errFile, $errLine)
Custom Error Handler.
Definition: core.inc:1368
static resolveResource($resource, $component="")
Resolves the path to a web resource based on the PHP include path.
Definition: core.inc:850
static usingFeature()
Uses the specified framework feature(s).
Definition: core.inc:388
static $timestamp
Microsecond Timestamp for start of request.
Definition: core.inc:86
static getScripts()
Returns the HTML scripts tags for Javascript files specified by the registered components in their ma...
Definition: core.inc:554
static exceptionHandler($exception)
Custom Exception Handler.
Definition: core.inc:1386
static setTraceLevel($level)
Set the trace log level.
Definition: core.inc:1329
static getServerLoad()
Retrieves information about the Server CPU load.
Definition: core.inc:1469
static detectWindowsOS()
Returns true if running on Windows, false otherwise.
Definition: core.inc:1455
static $bodyClass
Override for the body class of the page currently being served.
Definition: core.inc:89
static detectXSendFileSupport()
Determines whether the mod_xsendfile extension is present, when running under Apache.
Definition: core.inc:834
static sendPage($sectionIdentifier, $identifier, $page_id=null)
Serves the page with the specified section and identifier.
Definition: core.inc:978
static $outputBufferLevel
Records the level at which gzip output buffering began.
Definition: core.inc:83
static checkRole($role, $msg=null)
Check that the user has one of the specified roles.
Definition: core.inc:338
getAdminPageRole($identifier)
Get the applicable access roles for a given admin page, based on information supplied by components i...
Definition: core.inc:513
static getLocalIP()
Returns the local IP address for the server.
Definition: core.inc:360
static getComponent($name)
Return the component record by name.
Definition: core.inc:235
static JSONerror($error, $sendType=true)
Return an error code to the client in JSON format, as an object with the single property 'error'.
Definition: core.inc:1180
static checkSSL()
Checks if SSL is enabled on the current request.
Definition: core.inc:958
static loadStyles()
Load the list of CSS files from the manifests of all registered, active components.
Definition: core.inc:625
static writePendingScripts()
Outputs any pending scripts submitted by Fakoli::scriptOnNextPage()
Definition: core.inc:1313
static $rollbackBuffers
Specifies whether to rollback output buffers when there is an unhandled exception.
Definition: core.inc:84
static isUserActive($user)
Checks if the given user is active.
Definition: core.inc:349
static $requestURI
The initial request URI.
Definition: core.inc:88
static sendFile($resource)
Sends the contents of the specified file to the client.
Definition: core.inc:780
static loadScripts()
Load the list of JS scripts from the manifests of all registered, active components.
Definition: core.inc:581
static notifyOnNextPage($message, $blocking=false, $button="OK", $onClick="null")
Schedules a notification message to be displayed to the user at the next full page load.
Definition: core.inc:1223
static getComponents()
Retrieve an array of all the currently enabled components, indexed by component name.
Definition: core.inc:206
static loadResource($resource, $component="")
Load the specified resource into memory.
Definition: core.inc:932
static scheduledTaskTraceLevel()
Changed to the configured trace level for scheduled task worker code.
Definition: core.inc:1354
static getAdminIcons()
Builds the admin icon map.
Definition: core.inc:456
static getComponentForClass($class)
Find the component containing the specified class.
Definition: core.inc:1123
static applicationTraceLevel()
Change to the configured trace level for application code.
Definition: core.inc:1338
static getAdminMenu()
Builds the administration menu, combining menu items supplied by the registered components in their m...
Definition: core.inc:405
static getAdminAccessRoles()
Returns the user roles that have access to the admin section.
Definition: core.inc:1074
static includeStylesheet($src, $media="all")
Utility function to pull in a specific CSS Stylesheet for the current page.
Definition: core.inc:730
scriptOnNextPage($s)
Schedules the provided script fragment to be output when the next page is loaded.
Definition: core.inc:1305
scrollToOnNextPage($element, $offset=0)
Schedules a scrollTo event when the next page is loaded.
Definition: core.inc:1279
static getFileSystemInfo()
Returns formatted summary information regarding usage of the server's filesystem.
Definition: core.inc:1506
static using()
Import the datamodels, views and manifest for the specified component(s).
Definition: core.inc:116
static put($key, $obj)
Stores a value or object at the given key.
Definition: core.inc:99
static getComponentClassRoot($name)
Retrieves the capitalized camlCase name for the specified component.
Definition: core.inc:752
static includeScript($src)
Utility function to pull in a specific Javascript file for the current page.
Definition: core.inc:714
static $storage
General storage (volatile). See Fakoli::put and Fakoli::get.
Definition: core.inc:85
static end($message="")
Use this method to terminate execution of a script instead of using the php keywords exit() or die().
Definition: core.inc:1149
static countActiveSessions()
Returns the number of active user sessions.
Definition: core.inc:1085
static usingFile()
Uses the specified framework file(s) from the framework directory.
Definition: core.inc:369
static showPendingNotification()
Display any previously scheduled notification message.
Definition: core.inc:1234
static initialComponentScan()
Performs a complete component scan if the component table is found to be empty.
Definition: core.inc:255
static sendResource($uri, $component="")
Sends the resource at the specified URI to the client.
Definition: core.inc:765
static JSONreturn($object, $sendType=true, $wrap=true)
Return a DataItem to the client in JSON format.
Definition: core.inc:1160
static notify($message, $blocking=false, $button="OK", $onClick="null")
Utility method to display a notification message to the user when the page has finished loading.
Definition: core.inc:1198
static showPendingScrollTo()
Display any previously scheduled scrollto event.
Definition: core.inc:1288
static bootstrap()
Bootstraps the creation of the database schema if the component table does not exist.
Definition: core.inc:276
static evaluateFile($filePath)
Evaluates a PHP include file and returns the generated content.
Definition: core.inc:650
static $scanning
Semaphore indicating that a component scan is in progress.
Definition: core.inc:82
static $componentsUsed
Array of the components that have been referenced in this page request.
Definition: core.inc:81
static assertRole($role, $redirect="", $message="")
Assert that the user has one of the specified roles.
Definition: core.inc:297
LoginManager provides the authentication workflow for logging users into the system.
Definition: login.inc:95
static redirectToLogin()
Redirect the user to the login page.
Definition: login.inc:526
static createFromIdentifier($identifier)
Definition: section.inc:95
static checkPermissions($permissions, $account=null)
Check all the permissions specified in the given string.
Definition: settings.inc:270
static getValue($component, $name)
Retrieve the value of the specified Setting.
Definition: settings.inc:104
static getSite()
Returns the Site object that describes the currently active site (i.e.
Definition: site.inc:103
Provides the interface to the user model for the application.
$fontawesome
Definition: core.inc:45
$method
Pull out a simple reference to the request method.
Definition: core.inc:1573
$config["trace_level"]
Definition: core.inc:1623
$isResource
Definition: core.inc:1585
$user
Definition: core.inc:1617
if($config["default_content_type"]) $isAction
Definition: core.inc:1584
if(!checkRole("admin")) $c
$root
$error
$output
Definition: generate.inc:9
$message
Definition: mail_to.inc:49
$_SESSION["useMobile"]
Definition: override.inc:7
$styles
$role
Definition: role_form.inc:41
$identifier
Definition: rss.inc:37
if(! $blog->published||! $blog->enable_rss_feed||!checkRole($blog->allow_read)) $url
Definition: rss.inc:58
$msg
Definition: save.inc:10
while(ob_get_level()) $last_modified
Definition: scripts.inc:7
$contentManager
if(array_key_exists("HTTP_IF_MODIFIED_SINCE", $_SERVER)) $content
Definition: styles.css.inc:24
$uri
Definition: tearoff.inc:4
$button
Definition: show.inc:6