From 09ec735e21e820f01ecc96193c975a6ed30ae843 Mon Sep 17 00:00:00 2001 From: Jeremy Dorn Date: Wed, 13 Apr 2016 07:20:07 -0700 Subject: [PATCH] Make 'twig_init_function' a lambda function instead --- config/config.php.sample | 33 +++---- lib/PhpReports/PhpReports.php | 172 +++++++++++++++++----------------- 2 files changed, 98 insertions(+), 107 deletions(-) diff --git a/config/config.php.sample b/config/config.php.sample index 49b45f8a..47ad314f 100644 --- a/config/config.php.sample +++ b/config/config.php.sample @@ -6,7 +6,7 @@ return array( //the root directory of all dashboards 'dashboardDir' => 'sample_dashboards', - + //the directory where things will be cached //this is relative to the project root by default, but can be set to an absolute path too //the cache has some relatively long lived data so don't use /tmp if you can avoid it @@ -23,10 +23,10 @@ return array( 'ado'=>'Ado', 'pivot'=>'AdoPivot', ), - + //this enables listing different types of download formats on the report page //to change that one can add or remove any format from the list below - //in order to create a divider a list entry have to be added with any key name and + //in order to create a divider a list entry have to be added with any key name and //a value of 'divider' 'report_formats' => array( 'csv'=>'CSV', @@ -53,23 +53,23 @@ return array( 'default', 'amelia', 'cerulean', 'cosmo', 'cyborg', 'flatly', 'journal', 'readable', 'simplex', 'slate', 'spacelab', 'united' ), - + //email settings 'mail_settings' => array( //set 'enabled' to true to enable the 'email this report' functionality 'enabled'=>false, - + 'from'=>'reports@yourdomain.com', - + //php's mail function 'method'=>'mail' - + //sendmail /* 'method'=>'sendmail', 'command'=>'/usr/sbin/sendmail -bs' //optional */ - + //smtp /* 'method'=>'smtp', @@ -80,7 +80,7 @@ return array( 'encryption'=>'ssl' //optional (either 'ssl' or 'tls') */ ), - + // Google Analytics API Integration /* 'ga_api'=>array( @@ -116,17 +116,8 @@ return array( ), ), ), -/* Extend twig by creating a function and setting the twig_init_function to it's name. - 'twig_init_function' => 'twig_extend', -// With function to add json_encode and json_decode -function twig_extend($twig) { - if (function_exists('json_encode') && function_exists('json_decode')) { - $function = new Twig_SimpleFunction('json_encode', 'json_encode'); - $twig->addFunction($function); - $function = new Twig_SimpleFunction('json_decode', 'json_decode'); - $twig->addFunction($function); - } -}*/ + 'twig_init_function' => function (Twig_Environment $twig) { + // This is called twice, once for each Twig_Environment that is used + } ); ?> - diff --git a/lib/PhpReports/PhpReports.php b/lib/PhpReports/PhpReports.php index 2cf07118..475bb296 100644 --- a/lib/PhpReports/PhpReports.php +++ b/lib/PhpReports/PhpReports.php @@ -4,11 +4,11 @@ class PhpReports { public static $request; public static $twig; public static $twig_string; - + public static $vars; - + private static $loader_cache; - + public static function init($config = 'config/config.php') { //set up our autoloader spl_autoload_register(array('PhpReports','loader'),true,true); @@ -25,28 +25,28 @@ public static function init($config = 'config/config.php') { $default_config = include('config/config.php.sample'); $config = include($config); - + self::$config = array_merge($default_config, $config); - + self::$request = Flight::request(); $path = self::$request->base; - + if (isset($_SERVER['HTTPS']) && ($_SERVER['HTTPS'] == 'on' || $_SERVER['HTTPS'] == 1) || isset($_SERVER['HTTP_X_FORWARDED_PROTO']) && $_SERVER['HTTP_X_FORWARDED_PROTO'] == 'https') { $protocol = 'https://'; } else { $protocol = 'http://'; } self::$request->base = $protocol.rtrim($_SERVER['HTTP_HOST'].self::$request->base,'/'); - + //the load order for templates is: "templates/local", "templates/default", "templates" //this means loading the template "html/report.twig" will load the local first and then the default //if you want to extend a default template from within a local template, you can do {% extends "default/html/report.twig" %} and it will fall back to the last loader $template_dirs = array('templates/default','templates'); if(file_exists('templates/local')) array_unshift($template_dirs, 'templates/local'); - + $loader = new Twig_Loader_Chain(array( - new Twig_Loader_Filesystem($template_dirs), + new Twig_Loader_Filesystem($template_dirs), new Twig_Loader_String() )); self::$twig = new Twig_Environment($loader); @@ -74,40 +74,40 @@ public static function init($config = 'config/config.php') { } // Extend twig. - if (isset($config['twig_init_function']) && function_exists($config['twig_init_function'])) { + if (isset($config['twig_init_function']) && is_callable($config['twig_init_function'])) { $config['twig_init_function'](self::$twig); $config['twig_init_function'](self::$twig_string); } } - + public static function setVar($key,$value) { if(!self::$vars) self::$vars = array(); - + self::$vars[$key] = $value; } public static function getVar($key, $default=null) { if(isset(self::$vars[$key])) return self::$vars[$key]; else return $default; } - - public static function dbdate($time, $database=null, $format=null) { + + public static function dbdate($time, $database=null, $format=null) { $report = self::getVar('Report',null); if(!$report) return strtotime('Y-m-d H:i:s',strtotime($time)); - + //if a variable name was passed in $var = null; if(isset($report->options['Variables'][$time])) { $var = $report->options['Variables'][$time]; $time = $report->macros[$time]; } - + $time = strtotime($time); - + $environment = $report->getEnvironment(); - + //determine time offset $offset = 0; - + if($database) { if(isset($environment[$database]['time_offset'])) $offset = $environment[$database]['time_offset']; } @@ -115,12 +115,12 @@ public static function dbdate($time, $database=null, $format=null) { $database = $report->getDatabase(); if(isset($database['time_offset'])) $offset = $database['time_offset']; } - + //if the time needs to be adjusted if($offset) { $time = strtotime((($offset > 0)? '+' : '-').abs($offset).' hours',$time); } - + //determine output format if($format) { $time = date($format,$time); @@ -132,7 +132,7 @@ public static function dbdate($time, $database=null, $format=null) { else { $time = date('Y-m-d H:i:s',$time); } - + return $time; } @@ -163,28 +163,28 @@ public static function render($template, $macros) { 'session'=>$_SESSION ); $macros = array_merge($default,$macros); - + //if a template path like 'html/report' is given, add the twig file extension if(preg_match('/^[a-zA-Z_\-0-9\/]+$/',$template)) $template .= '.twig'; return self::$twig->render($template,$macros); } - + public static function renderString($template, $macros) { return self::$twig_string->render($template,$macros); } - - public static function displayReport($report,$type) { + + public static function displayReport($report,$type) { $classname = ucfirst(strtolower($type)).'ReportFormat'; - + $error_header = 'An error occurred while running your report'; $content = ''; - + try { if(!class_exists($classname)) { $error_header = 'Unknown report format'; throw new Exception("Unknown report format '$type'"); } - + try { $report = $classname::prepareReport($report); } @@ -192,7 +192,7 @@ public static function displayReport($report,$type) { $error_header = 'An error occurred while preparing your report'; throw $e; } - + $classname::display($report,self::$request); if(isset($report->options['Query_Formatted'])) { @@ -209,13 +209,13 @@ public static function displayReport($report,$type) { )); } } - + public static function editReport($report) { $template_vars = array(); - + try { $report = ReportFormatBase::prepareReport($report); - + $template_vars = array( 'report'=>$report->report, 'options'=>$report->options, @@ -233,7 +233,7 @@ public static function editReport($report) { 'error'=>$e ); } - + if(isset($_POST['preview'])) { echo "
".SimpleDiff::htmlDiffSummary($template_vars['contents'],$_POST['contents'])."
"; } @@ -244,7 +244,7 @@ public static function editReport($report) { echo self::render('html/report_editor',$template_vars); } } - + public static function listReports() { $errors = array(); @@ -256,48 +256,48 @@ public static function listReports() { $start = microtime(true); echo self::render('html/report_list',$template_vars); } - + public static function listDashboards() { $dashboards = self::getDashboards(); - + uasort($dashboards,function($a,$b) { return strcmp($a['title'],$b['title']); }); - + echo self::render('html/dashboard_list',array( 'dashboards'=>$dashboards )); } - + public static function displayDashboard($dashboard) { $content = self::getDashboard($dashboard); - + echo self::render('html/dashboard',array( 'dashboard'=>$content )); } - + public static function getDashboards() { $dashboards = glob(PhpReports::$config['dashboardDir'].'/*.json'); - + $ret = array(); foreach($dashboards as $key=>$value) { $name = basename($value,'.json'); $ret[$name] = self::getDashboard($name); } - + return $ret; } - + public static function getDashboard($dashboard) { $file = PhpReports::$config['dashboardDir'].'/'.$dashboard.'.json'; if(!file_exists($file)) { throw new Exception("Unknown dashboard - ".$dashboard); } - + return json_decode(file_get_contents($file),true); } - + public static function getRecentReports() { $recently_run = FileSystemCache::retrieve(FileSystemCache::generateCacheKey('recently_run')); $recent = array(); @@ -364,7 +364,7 @@ public static function getReportListJSON($reports=null) { )); } } - + return '['.trim(implode(',',$parts),',').']'; } @@ -398,7 +398,7 @@ protected static function getReportHeaders($report) { return $data; } - + protected static function getReports($dir, &$errors = null) { $base = self::$config['reportDir'].'/'; @@ -406,21 +406,21 @@ protected static function getReports($dir, &$errors = null) { $return = array(); foreach($reports as $key=>$report) { $title = $description = false; - + if(is_dir($report)) { if(file_exists($report.'/TITLE.txt')) $title = file_get_contents($report.'/TITLE.txt'); if(file_exists($report.'/README.txt')) $description = file_get_contents($report.'/README.txt'); - + $id = str_replace(array('_','-','/',' '),array('','','_','-'),trim(substr($report,strlen($base)),'/')); - + $children = self::getReports($report.'/', $errors); - + $count = 0; foreach($children as $child) { if(isset($child['count'])) $count += $child['count']; else $count++; } - + $return[] = array( 'Name'=>ucwords(str_replace(array('_','-'),' ',basename($report))), 'Title'=>$title, @@ -452,7 +452,7 @@ protected static function getReports($dir, &$errors = null) { } } } - + usort($return,function(&$a,&$b) { if($a['is_dir'] && !$b['is_dir']) return 1; elseif($b['is_dir'] && !$a['is_dir']) return -1; @@ -460,17 +460,17 @@ protected static function getReports($dir, &$errors = null) { if(empty($a['Title']) && empty($b['Title'])) return strcmp($a['Name'],$b['Name']); elseif(empty($a['Title'])) return 1; elseif(empty($b['Title'])) return -1; - + return strcmp($a['Title'], $b['Title']); }); - + return $return; } - + /** * Emails a report given a TO address, a subject, and a message */ - public static function emailReport() { + public static function emailReport() { if(!isset($_REQUEST['email']) || !filter_var($_REQUEST['email'], FILTER_VALIDATE_EMAIL)) { echo json_encode(array('error'=>'Valid email address required')); return; @@ -487,7 +487,7 @@ public static function emailReport() { echo json_encode(array('error'=>'Email settings have not been properly configured on this server')); return; } - + $from = PhpReports::$config['mail_settings']['from']; $subject = $_REQUEST['subject']? $_REQUEST['subject'] : 'Database Report'; $body = $_REQUEST['message']? $_REQUEST['message'] : "You've been sent a database report!"; @@ -496,12 +496,12 @@ public static function emailReport() { $csv_link = str_replace('report/html/?','report/csv/?',$link); $table_link = str_replace('report/html/?','report/table/?',$link); $text_link = str_replace('report/html/?','report/text/?',$link); - + // Get the CSV file attachment and the inline HTML table $csv = self::urlDownload($csv_link); $table = self::urlDownload($table_link); $text = self::urlDownload($text_link); - + $email_text = $body."\n\n".$text."\n\nView the report online at $link"; $email_html = "

$body

$table

View the report online at ".htmlentities($link)."

"; @@ -515,15 +515,15 @@ public static function emailReport() { //html body ->addPart($email_html, 'text/html') ; - + $attachment = Swift_Attachment::newInstance() ->setFilename('report.csv') ->setContentType('text/csv') ->setBody($csv) ; - + $message->attach($attachment); - + // Create the Transport $transport = self::getMailTransport(); $mailer = Swift_Mailer::newInstance($transport); @@ -538,7 +538,7 @@ public static function emailReport() { )); return; } - + if($result) { echo json_encode(array( 'success'=>true @@ -550,14 +550,14 @@ public static function emailReport() { )); } } - + /** * Determines the email transport to use based on the configuration settings */ protected static function getMailTransport() { if(!isset(PhpReports::$config['mail_settings'])) PhpReports::$config['mail_settings'] = array(); if(!isset(PhpReports::$config['mail_settings']['method'])) PhpReports::$config['mail_settings']['method'] = 'mail'; - + switch(PhpReports::$config['mail_settings']['method']) { case 'mail': return Swift_MailTransport::newInstance(); @@ -571,32 +571,32 @@ protected static function getMailTransport() { PhpReports::$config['mail_settings']['server'], isset(PhpReports::$config['mail_settings']['port'])? PhpReports::$config['mail_settings']['port'] : 25 ); - + //if username/password if(isset(PhpReports::$config['mail_settings']['username'])) { $transport->setUsername(PhpReports::$config['mail_settings']['username']); $transport->setPassword(PhpReports::$config['mail_settings']['password']); } - + //if using encryption if(isset(PhpReports::$config['mail_settings']['encryption'])) { $transport->setEncryption(PhpReports::$config['mail_settings']['encryption']); } - + return $transport; default: throw new Exception("Mail method must be either 'mail', 'sendmail', or 'smtp'"); } } - + /** * Autoloader methods */ - public static function loader($className) { + public static function loader($className) { if(!isset(self::$loader_cache)) { self::buildLoaderCache(); } - + if(isset(self::$loader_cache[$className])) { require_once(self::$loader_cache[$className]); return true; @@ -613,13 +613,13 @@ public static function buildLoaderCache() { public static function load($dir, $skip=array()) { $files = glob($dir.'/*.php'); $dirs = glob($dir.'/*',GLOB_ONLYDIR); - - + + foreach($files as $file) { //for file names same as class name $className = basename($file,'.php'); if(!isset(self::$loader_cache[$className])) self::$loader_cache[$className] = $file; - + //for PEAR style: Path_To_Class.php $parts = explode('/',substr($file,0,-4)); array_shift($parts); @@ -628,17 +628,17 @@ public static function load($dir, $skip=array()) { if(preg_match('/(^|_)[a-z]/',$className)) continue; if(!isset(self::$loader_cache[$className])) self::$loader_cache[$className] = $file; } - + foreach($dirs as $dir2) { //directories to skip if($dir2[0]==='.') continue; if(in_array($dir2,$skip)) continue; if(in_array(basename($dir2),array('tests','test','example','examples','bin'))) continue; - + self::load($dir2,$skip); } } - + /** * A more lenient json_decode than the built-in PHP one. * It supports strict JSON as well as javascript syntax (i.e. unquoted/single quoted keys, single quoted values, trailing commmas) @@ -646,28 +646,28 @@ public static function load($dir, $skip=array()) { public static function json_decode($json, $assoc=false) { //replace single quoted values $json = preg_replace('/:\s*\'(([^\']|\\\\\')*)\'\s*([},])/e', "':'.json_encode(stripslashes('$1')).'$3'", $json); - + //replace single quoted keys $json = preg_replace('/\'(([^\']|\\\\\')*)\'\s*:/e', "json_encode(stripslashes('$1')).':'", $json); - + //remove any line breaks in the code $json = str_replace(array("\n","\r"),"",$json); - + //replace non-quoted keys with double quoted keys $json = preg_replace('#(?
\{|\[|,)\s*(?(?:\w|_)+)\s*:#im', '$1"$2":', $json);
-		
+
 		//remove trailing comma
 		$json = preg_replace('/,\s*\}/','}',$json);
-		
+
 		return json_decode($json, $assoc);
 	}
-	
+
 	protected static function urlDownload($url) {
 		$ch = curl_init();
 		curl_setopt($ch, CURLOPT_URL, $url);
 		curl_setopt($ch, CURLOPT_HEADER, 0);
 		curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
-		
+
 		$output = curl_exec($ch);
 		curl_close($ch);