* @version 2.05 2010/10/24 * @link http://www.newmanix.com/ * @license http://opensource.org/licenses/osl-3.0.php Open Software License ("OSL") v. 3.0 * @see common_inc.php * @see conn_inc.php * @todo none */ # START ERROR HANDLING (show or hide page errors, turn on/off error logging)--------------------------------------------- # We can un-comment the line below to either see default errors (1) or shut off visual errors completely (0). ini_set('error_reporting', E_ALL | E_STRICT); # E_ALL | E_STRICT = currently tracking all errors & warnings define('SHOW_ALL_ERRORS', TRUE); # TRUE = SHOW ALL SITE ERRORS - if FALSE must be logged in as ADMIN to view errors define('LOG_ALL_ERRORS', TRUE); # TRUE = TRACK ALL ERRORS IN ERROR LOG FILE loadErrorHandler('custom'); #can be set to 'custom', 'php' or 'none' # END ERROR HANDLING (show or hide page errors, turn on/off error logging)----------------------------------------------- # START SETTINGS (php.ini overrides & other enviroment settings)--------------------------------------------------------- ob_start(); #buffers our page to be prevent header errors. Call before INC files or ANY html! date_default_timezone_set('America/Los_Angeles'); #sets default date/timezone for this website ini_set('session.save_path',''); #optional folder set to 0700 outside webroot to store session data header("Cache-Control: no-cache");header("Expires: -1");#Helps stop browser & proxy caching $config = new Config(); #config object stores page properties, including meta tag & nav elements # END SETTINGS (php.ini overrides & other enviroment settings)------------------------------------------------------------ # START CONSTANTS (universal file paths & values)------------------------------------------------------------------------- /* automatic path settings - use the following 4 path settings for placing all code in one application folder */ define('VIRTUAL_PATH', 'http://www.abellsmith.com/classes/itc280/-FINISHED_CLASS_SITE/public_html/cartoons/'); # Virtual (web) 'root' of your application for images, JS & CSS files define('PHYSICAL_PATH', '/usr/www/users/fightr8f/abellsmith/classes/itc280/-FINISHED_CLASS_SITE/public_html/cartoons/'); # Physical (PHP) 'root' of your application for file & upload reference define('INCLUDE_PATH', PHYSICAL_PATH . 'inc_0700/'); # Path to PHP include files - INSIDE APPLICATION ROOT //define('INCLUDE_PATH', '/home/classes/horsey01/inc_sprockets/'); #Path to PHP include files - OUTSIDE WEB ROOT define('LOG_PATH', INCLUDE_PATH . 'log/'); # Log files are stored in the PHP include folder define('ADMIN_PATH', VIRTUAL_PATH . 'admin/'); # Admin files are in subfolder //define('THEME_PATH', VIRTUAL_PATH . 'themes/'); # Theme files are in subfolder define('SUPPORT_EMAIL', 'abell@abellsmith.com'); # Email of site support define('PREFIX', ''); #Prefix to add uniqueness to your DB table names. Limits hackability, naming collisions define('ADMIN_LOGIN', ADMIN_PATH . 'admin_login.php'); # Admin login page - all Admin pages part of nmAdmin package define('ADMIN_VALIDATE', ADMIN_PATH . 'admin_validate.php'); # Admin login validation page define('ADMIN_DASHBOARD', ADMIN_PATH . 'admin_dashboard.php'); # Administrative (dashboard) page define('ADMIN_LOGOUT', ADMIN_PATH . 'admin_logout.php'); # Administrative logout file define('ADMIN_ADD', ADMIN_PATH . 'admin_add.php'); # Add administrators here define('ADMIN_RESET', ADMIN_PATH . 'admin_reset.php'); # Reset admin passwords here define('ADMIN_EDIT', ADMIN_PATH . 'admin_edit.php'); # Edit admin data here define('TABLE_EDITOR', ADMIN_PATH . 'nmEdit.php'); # Table Editor part of nmEdit package define('THIS_PAGE', basename($_SERVER['PHP_SELF'])); # Current page name, stripped of folder info - (saves resources) # END CONSTANTS (universal file paths & values)---------------------------------------------------------------------------- # START INCLUDES (declare universal file paths & values)------------------------------------------------------------------- include INCLUDE_PATH . 'conn_inc.php'; # Provides database connectivity - part of nmCommon package include INCLUDE_PATH . 'common_inc.php'; # Provides common utility functions - part of nmCommon package //include INCLUDE_PATH . 'benchmark_inc.php'; # Provides benchmark log and speed of page in copyright for admins - part of nmBench package # END INCLUDES (declare universal file paths & values)--------------------------------------------------------------------- # CONTENT CONFIGURATION AREA (theme, content areas & nav arrays for header/footer )----------------------------------------- $config->theme = 'abell'; #default theme (header/footer combo) two included themes are 'TwoTone' and 'SmallPark' $config->titleTag = 'Political Cartoons by Abell Smith: editorial cartoons, political satire, freelance illustration, graphic design'; $config->metaDescription = 'Abell Smith is an editorial cartoonist and web developer based out of Seattle, WA. Smith likes to think of his political cartoons as "graphic columns," offering a combination of strong intellectual arguments and entertaining political satire.'; $config->metaKeywords = 'Political cartoon, editorial cartoon, graphic column, political commentary, argument, argumentation, graphic design, artwork, artist, web developer, web development, web designer, web design, graphic design, graphic designer, illustration, illustrator, Seattle, spot illustration, caricature, caricatures, political cartooning, editorial cartooning, comics, webcomics, webcartoon, cartoon, cartooning, comic, political satire, satire, political humor, historical cartoons, topical cartoons, educational cartoons, AAEC, Association of American Editorial Cartoonists, Attitude 3'; $config->metaRobots = 'no index, no follow'; $config->banner = 'Abell Smith Cartoons'; #goes inside header - can be overwritten $config->copyright = 'Abell Smith, © ' . date('Y'); #goes inside footer - can be overwritten $config->sidebar1 = ' <h3 align="center">Sidebar 1</h3> '; $config->sidebar2 = '<h3 align="center">Sidebar 2</h3>'; if(startSession() && isset($_SESSION['AdminID'])) {#add admin logged in info to sidebar $config->sidebar2 .= '<p align="center">' . $_SESSION['Privilege'] . ' <b>' . $_SESSION['FirstName'] . '</b> is logged in.</p>'; $config->sidebar2 .= '<p align="center"><a href="' . ADMIN_DASHBOARD . '">ADMIN</a></p>'; $config->sidebar2 .= '<p align="center"><a href="' . ADMIN_LOGOUT . '">LOGOUT</a></p>'; } $config->sidebar2 .= ' <p>Here is our sidebar area which is inside a header or footer include file. You can change it in the main config file or change it on a page by page basis by altering config settings inside individual pages.</p> '; // DECLARING ARRAY IN ADVANCE SHOULD BE UNNECESSARY - TRIP HAZARD!!$nav1 = array(); #nav1 is the current left nav - tilde separator below splits text of link from title attribute $muffinSidebar = ' <h3 align="center">Muffin Only Sidebar (too)</h3> <p>Our Muffins are so tasty, they deserve their own sidebar!</p> <p>This means that this sidebar, telling you how awesome our muffins are only appears on the <b>model_list.php</b> and <b>model_view.php</b> pages.</p> <p>This is due to a new function named <b>htmlSelector()</b> added to <b>common_inc.php</b> which allows us to add or replace the HTML in any part of our <b>$config</b> object, in this case <b>$config->sidebar2</b> on a page by page basis, or to match a string in a set of file names.</p> <p>Once matched (selected) the HTML we create replaces or adds to the previous HTML in the element.</p> '; htmlSelector("sidebar2",$muffinSidebar,"model_list.php~model_view.php","file","replace"); $appendModels = ' <h3 align="center">Appended To Models Pages</h3> <p>This bit of HTML gets appended to the bottom <b>sidebar2</b> when any page includes the string <b>model_</b> in the file name.</p> <p>This is due to the <b>htmlSelector()</b> function.</p> '; htmlSelector("sidebar2",$appendModels,"model_","string","after"); if(startSession() && isset($_SESSION['AdminID'])){$nav1[ADMIN_DASHBOARD] = "ADMIN~Go to Administrative Page";}#admin page added to link only if logged in $nav1['http://www.abellsmith.com'] = "Home~A model for building largely static web pages"; $nav1['model_list.php'] = "Cartoons~A tasty list/view application!"; $nav1['about.php'] = "About~About Abell and his cartoons"; $nav1['reprints.php'] = "Reprints~Abell's policies on reprints and publication of his work"; $nav1['links.php'] = "Links~Links to some of Abell's favorite sites"; $nav1['contact.php'] = "Contact~A model for building postback forms"; //$nav1['models/model_mysql.php'] = "mysql Classic~A model page for building mysql (classic) web applications"; //$nav1['models/model_mysqli.php'] = "mysqli Improved~A model page for building mysqli (improved) web applications"; //$nav1['models/model_idb.php'] = "MySQL Shared~A model page for building mysqli (improved) class based applications."; //$nav1['error_test.php'] = "Error Test~Click to see how errors are currently being handled"; $config->nav1 = $nav1; #add to global config object - now available in all header/footers # CONTENT CONFIGURATION AREA (theme, content areas & nav arrays for header/footer )----------------------------------------- # GENERAL CONFIG AREA ENDS HERE ############################################################################################ # START FUNCTIONS (error handling/logging functions)------------------------------------------------------------------------ /** * Allows developer choice of 'custom', 'php' or 'none' for error handler. * Overrides PHP's default error handler, if 'custom' is chosen. This function * in turn calls myErrorHandler(). * * Inherits error & logging info from default handler and allows us to display * custom error messages based on the following boolean constants: * * 1 SHOW_ALL_ERRORS * 2 LOG_ALL_ERRORS * * @param string $handler 'custom', 'php' or 'none' for error handler * @return void * @uses myErrorHandler() * @todo threshold email of admin not implemented */ function loadErrorHandler($handler) { $handler = strtolower($handler); switch($handler) { case 'custom': set_error_handler ('myErrorHandler'); # Override the default PHP error handler with our own. break; case 'php'; ini_set('display_errors', 1); # 1 = display PHP errors if(LOG_ALL_ERRORS) { ini_set('log_errors', 1); # 1 turns on error logging, 0 shuts it off ini_set('error_log', LOG_PATH . 'error_log'); #places PHP errors into a folder at this location } break; default: ini_set('display_errors', 0); # 0 turns off PHP error reporting entirely if(LOG_ALL_ERRORS) { ini_set('log_errors', 1); # 1 turns on error logging, 0 shuts it off ini_set('error_log', LOG_PATH . 'error_log'); #places PHP errors into a folder at this location } } }# End loadErrorHandler() /** * Overrides PHP's default error handler. This function is enabled/disabled * in the loadErrorHandler() function * * Inherits error & logging info from default handler and allows us to display * custom error messages based on the following boolean constants: * * 1 SHOW_ALL_ERRORS * 2 LOG_ALL_ERRORS * * @param string $e_number error number provided by PHP error handler * @param string $e_message error message provided by PHP error handler * @param string $e_file file name provided by PHP error handler * @param string $e_line line number of error provided by PHP error handler * @param array $e_vars variables present at time of error * @return void * @see loadErrorHandler() * @todo in production, send email to admin if threshold number/type of errors is exceeded */ function myErrorHandler ($e_number, $e_message, $e_file, $e_line, $e_vars) { #comment out one of the two $errFile variables - one for a single file, one for a new file every day $errFile = 'error_log_' . date('m-d-Y') . '.txt'; #new error file created every day #$errFile = 'error_log'; # same single error log file as PHP will write errors static $counter = 0; # Will identify if myError() was called more than once $counter++; if(LOG_ALL_ERRORS) {# Copy all error info to error log file try { $errInfo = "[" . date('M-d-Y G:i:s') . "] $e_message in $e_file on line $e_line" . "\n"; fileWrite(LOG_PATH . $errFile,'a+',$errInfo); /* if(substr(sprintf('%o', fileperms(LOG_PATH . $errFile)), -4)!= '0700') {//check file permission - if NOT set to 0700, fix it! chmod(LOG_PATH . $errFile,0700); }*/ } catch (Exception $e) { //echo 'Caught exception: ', $e->getMessage(), "\n"; } } if (SHOW_ALL_ERRORS || isset($_SESSION['AdminID'])) {# Display generic error message, with support email from config file printDeveloperError($e_file,$e_line,$e_message,$counter); }else{# Show errors directly on page. (troubleshooting purposes only!) if($counter < 2) { printUserError($e_file,$e_line); } #only print one error message to user } }# End myErrorHandler() /** * Create an error code out of the file name and line number of our error * * Will make upper case, strip out the vowels and create an * error of the file name (minus extension & vowels) + "x" + line number of error * * Will also replace any underscores with "x". This file would be: * * Example: CNFGxNCx41 * * The above would be the example for this file, plus an error at line 41 * This allows a user to report an error that identifies it, without compromising site security * * @param string $myFile file name provided by PHP error handler * @param string $myLine line number of error provided by PHP error handler * @return string File name and line number of error disguised vaguely as an error code * @see printUserError() * @todo none */ function createErrorCode($myFile,$myLine) { $mySlash = strrpos($myFile,"/"); //find position of last slash in path $myFile = substr($myFile,$mySlash + 1); //strip off all but file name $myFile = substr($myFile, 0, strripos($myFile, '.'));//remove extension $myFile = strtoupper($myFile); //change to upper case $vowels = array("A", "E", "I", "O", "U", "Y"); //array of vowels to remove $myFile = str_replace($vowels, "", $myFile); //remove vowels $myFile = str_replace("_", "x", $myFile); //replace underscore with "x" return $myFile . "x" . $myLine; //CNFGNCx50 }# End createErrorCode() /** * Prints a customized public error message * * Will use a custom error code created by calling * createErrorCode() function, and display it to the user * * @param string $myFile file name provided by PHP error handler * @param string $myLine line number of error provided by PHP error handler * @return void * @see createErrorCode() * @see printDeveloperError() * @todo none */ function printUserError($myFile,$myLine) { $errorCode = createErrorCode($myFile,$myLine); //Create error code out of file name & line number echo '<h2 align="center">Our page has encountered an error!</h2>'; echo '<table align="center" width="50%" style="border:#F00 1px solid;"><tr><td align="center">'; echo 'Please try again, or email support at <b>' . SUPPORT_EMAIL . '</b>,<br /> and let us know you are receiving '; echo 'the following Error Code: <b>' . $errorCode . '</b><br />'; echo 'This will help us identify the problem, and fix it as quickly as possible.<br />'; echo 'Thank you for your assistance and understanding!<br />'; echo 'Sincerely,<br />Support Staff<br />'; echo '<a href="index.php">Exit</a></td></tr></table>'; get_footer(); #add footer info! die(); #one error is enough! }# End printUserError() /** * Prints a customized developer error message * * This is what a developer will see when an error occurs * * @param string $myFile file name provided by PHP error handler * @param string $myLine line number of error provided by PHP error handler * @param string $errorMsg error text provided by mysql_error() or developer, etc. * @param array|string $vars array dump of page variables, if available * @return void * @see printUserError() * @todo none */ function printDeveloperError($myFile,$myLine,$errorMsg,$counter) { # Build the error message. echo '<div class="error">'; # No body or closing HTML allows multiple errors to show echo 'Error in file: <b>\'' . $myFile . '\'</b> on line: <font color="blue"><b>' . $myLine . '</b></font> '; echo 'Error message: <font color="red"><b>' . $errorMsg . '</b></font><br /><br />'; #only print one instance of backtrace of debug data: if($counter < 2) { echo 'BackTrace: <font color="purple"><pre>' . print_r(debug_backtrace(),1) . '</pre></font><br /><br />'; } echo '</div><br />'; }# End printDeveloperError() /** * Encapsulates PHP write capability for functions like errorLog() * * <code> * return fileWrite("path/tomyfile.php","a+","Here is a test string!"); * </code> * * @param string $filename The target file to be written * @param string $myMode context we use to write file, a+ is append/create, a is append, w is write/overwrite * @param string $myStr The string to write to the file * @return boolean returns true or false, success of writing file * @see errorLog() * @todo none */ function fileWrite($fileName,$myMode,$myStr) { $isOpen = fopen($fileName,$myMode); if($isOpen) { fwrite($isOpen,$myStr); fclose($isOpen); return TRUE; }else{ return FALSE; } }#End fileWrite() # END FUNCTIONS (error handling/logging functions)--------------------------------------------------------------------------- # CLASS AREA (helper classes)------------------------------------------------------------------------------------------------ /** * Allows configuration properties to be added on the fly, for example navigation * elements can now be globally available as properties of the main configuration object */ $config->loadhead = ''; #would not load in constructor, so loading here! if(!isset($config->benchmarking)){$config->benchmarking = FALSE;} if(!isset($config->timer)){$config->timer = '';} class Config { private $data = array();//Location for overloaded data. public function __set($name, $value) { $this->data[$name] = $value; } public function &__get($name) {//& is required for pass by reference on arrays if (array_key_exists($name, $this->data)) { return $this->data[$name]; } $trace = debug_backtrace(); trigger_error( 'Undefined property via __get(): ' . $name . ' in ' . $trace[0]['file'] . ' on line ' . $trace[0]['line'], E_USER_NOTICE); return null; } public function __isset($name) { return isset($this->data[$name]); } public function __unset($name) { unset($this->data[$name]); } } # CLASS AREA (helper classes)---------------------------------------------------------------------------------------------------- #no closing PHP tag, on purpose