public static function view($removefieldset = false) { if (!self::$_started) { return; } self::$timeEnd = self::getmicrotime(); $time = sprintf('%.5f', self::$timeEnd - self::$timeStart); $files = sprintf('%.5f', self::$filesTime); $rapportSQL = sprintf('%.2f', 100 * self::$totalTime / $time); $rapportPHP = 100 - $rapportSQL; $memoryPeak = round(memory_get_peak_usage() / 1048576, 3); $content = 'File ' . $_SERVER['SCRIPT_NAME'] . "\n" . 'Loaded in ' . $time . ' seconds' . "\n" . 'Loaded PHP files : ' . self::$filesLoaded . "\n" . 'SQL requests : ' . sprintf('%.5f', self::$totalTime) . ' seconds (' . self::$sqlNbRequests . ' requests)' . "\n" . '% SQL/PHP : ' . $rapportSQL . ' / ' . $rapportPHP . ' %' . "\n" . 'Memory Peak : ' . $memoryPeak . 'Mo' . "\n"; if (function_exists('xdebug_get_profiler_filename') && xdebug_get_profiler_filename()) { $content .= 'XDebug Profile : ' . xdebug_get_profiler_filename() . "\n"; } if (function_exists('xdebug_get_profiler_filename') && xdebug_get_tracefile_name()) { $content .= 'XDebug Trace : ' . xdebug_get_tracefile_name() . "\n"; } $content .= 'User : '******' (' . CMS_session::getUserId() . ')' : 'none') . "\n"; $content .= 'Session Id ' . Zend_Session::getId() . "\n"; //$content .= 'Current page '.CMS_session::getPageID()."\n"; if (VIEW_SQL && $_SERVER["SCRIPT_NAME"] != PATH_ADMIN_WR . '/stat.php') { $stat = array('stat_time_start' => self::$timeStart, 'stat_time_end' => self::$timeEnd, 'stat_total_time' => self::$totalTime, 'stat_sql_nb_requests' => self::$sqlNbRequests, 'stat_sql_table' => self::$sqlTable, 'stat_content_name' => basename($_SERVER["SCRIPT_NAME"]), 'stat_files_table' => self::$filesTable, 'stat_memory_table' => self::$memoryTable, 'stat_memory_peak' => $memoryPeak, 'stat_files_loaded' => self::$filesLoaded); $statName = 'stat_' . md5(rand()); //save stats to cache (for 10 min) $cache = new CMS_cache($statName, 'atm-stats', 600, false); if ($cache) { $cache->save($stat); } } $content = !$removefieldset ? '<fieldset style="width:200px;" class="atm-debug"><legend>Debug Statistics</legend><pre>' . $content . '</pre>' : 'Debug Statistics :' . "\n" . $content; if (isset($statName)) { $content .= '<a href="' . PATH_ADMIN_WR . '/stat.php?stat=' . $statName . '" target="_blank">View statistics detail</a>'; } //end xhprof profiling if (defined('APPLICATION_ENABLE_PROFILING') && APPLICATION_ENABLE_PROFILING && function_exists('xhprof_disable')) { $xhprof_data = xhprof_disable(); include_once APPLICATION_XHPROF_ROOT_FS . "/xhprof_lib/utils/xhprof_lib.php"; include_once APPLICATION_XHPROF_ROOT_FS . "/xhprof_lib/utils/xhprof_runs.php"; $xhprof_runs = new XHProfRuns_Default(); $profileName = md5($_SERVER['REQUEST_URI']); $run_id = $xhprof_runs->save_run($xhprof_data, md5($_SERVER['REQUEST_URI'])); $content .= '<br /><a href="' . APPLICATION_XHPROF_URI . 'xhprof_html/index.php?run=' . $run_id . '&source=' . $profileName . '" target="_blank">View profiling detail</a>'; } $content .= !$removefieldset ? '</fieldset>' : ''; return $content; }
/** * Raises an error. Shows it to the screen * Deprecated, use raiseError instead * @param string $errorMessage the error message. * @param boolean $encodeOutput, does the screen output should be encoded (default : false) * @return void * @access public */ public function _raiseError($errorMessage, $encodeOutput = false, $error = true) { static $errorNumber; $systemDebug = !defined('SYSTEM_DEBUG') ? true : SYSTEM_DEBUG; if (isset($this) && isset($this->_debug) && $this->_debug === NULL) { $this->_debug = $systemDebug; } if ($errorMessage) { //second condition are for static calls (made by static methods) if (!defined('APPLICATION_EXEC_TYPE') || APPLICATION_EXEC_TYPE == 'http' && (!isset($this) && $systemDebug || isset($this) && isset($this->_debug) && $this->_debug)) { $backTrace = $backTraceLink = ''; if (version_compare(phpversion(), "5.2.5", "<")) { $bt = @array_reverse(debug_backtrace()); } else { $bt = @array_reverse(debug_backtrace(false)); } $backtrace = array('summary' => sensitiveIO::printBackTrace($bt), 'backtrace' => @print_r($bt, true)); $backtraceName = 'bt_' . md5(rand()); $backTraceLink = PATH_ADMIN_WR . '/backtrace.php?bt=' . $backtraceName; //save backtrace to cache (for 10 min) $cache = new CMS_cache($backtraceName, 'atm-backtrace', 600, false); if ($cache) { $cache->save($backtrace); } unset($backtrace, $cache, $bt); //append error to current view $view = CMS_view::getInstance(); $outputMessage = $encodeOutput ? io::htmlspecialchars($errorMessage) : $errorMessage; $view->addError(array('error' => $outputMessage, 'backtrace' => $backTraceLink)); } //second condition are for static calls (made by static methods) if (!isset($this) || !isset($this->_log) || $this->_log) { if (@file_put_contents(PATH_MAIN_FS . '/' . self::ERROR_LOG, date("Y-m-d H:i:s", time()) . '|' . APPLICATION_EXEC_TYPE . '|' . $errorMessage . "\n", FILE_APPEND) !== false) { CMS_file::chmodFile(FILES_CHMOD, PATH_MAIN_FS . '/' . self::ERROR_LOG); } else { die('<pre><b>' . CMS_view::SYSTEM_LABEL . ' ' . AUTOMNE_VERSION . ' error : /automne dir is not writable' . "</b></pre>\n"); } } } //must be at the end because it interferes with the static calls conditions above if ($error && isset($this)) { $this->_errRaised = true; } }
/** * Get object Definition (CMS_poly_object_definition) * * @return CMS_poly_object_definition * @access public */ function getObjectDefinition() { //create cache object $cache = new CMS_cache('object' . $this->_objectID, 'atm-polymod-structure', 2592000, false); $datas = ''; if (!$cache->exist() || !($datas = $cache->load())) { //datas does not exists : load it $datas = CMS_poly_object_catalog::getObjectDefinition($this->_objectID); if ($cache) { $cache->save($datas, array('type' => 'object')); } } return $datas; }
/** * Return all fields for a given object ID * * @param integer $objectID the object ID to get fields * @return array of CMS_object_fields * @access public * @static */ static function getFieldsDefinition($objectID, $reset = false) { static $datas; if (!$reset && isset($datas[$objectID])) { return $datas[$objectID]; } $datas[$objectID] = array(); if (sensitiveIO::isPositiveInteger($objectID)) { //create cache object $cache = new CMS_cache('fields' . $objectID, 'atm-polymod-structure', 2592000, false); if ($reset || !$cache->exist() || !($datas[$objectID] = $cache->load())) { //datas does not exists : load them $sql = "\n\t\t\t\t\tselect\n\t\t\t\t\t\t*\n\t\t\t\t\tfrom\n\t\t\t\t\t\tmod_object_field,\n\t\t\t\t\t\tmod_object_definition\n\t\t\t\t\twhere\n\t\t\t\t\t\tobject_id_mof = '" . $objectID . "'\n\t\t\t\t\t\tand object_id_mof = id_mod\n\t\t\t\t\torder by \n\t\t\t\t\t\torder_mof\n\t\t\t\t"; $q = new CMS_query($sql); while ($r = $q->getArray()) { $datas[$objectID][$r["id_mof"]] = new CMS_poly_object_field($r["id_mof"], $r); } if ($cache) { $cache->save($datas[$objectID], array('type' => 'fields')); } } } return $datas[$objectID]; }
/** * Retrieve current media datas from provider * * @return boolean * @access protected */ protected function _retrieveDatas() { if ($this->_datas) { return true; } //load provider if (!$this->_getProvider()) { return false; } //set cache lifetime $lifetime = 86400; //(default : 24 hours) //create cache id from files, compression status and last time files access $cacheId = md5(serialize(array('url' => $this->_url, 'maxwidth' => io::isPositiveInteger($this->_maxwidth) ? $this->_maxwidth : '', 'maxheight' => io::isPositiveInteger($this->_maxheight) ? $this->_maxheight : ''))); //create cache object $cache = new CMS_cache($cacheId, 'oembed', $lifetime, false); $datas = ''; if (!$cache->exist() || !($datas = $cache->load())) { try { $client = new Zend_Http_Client(); $client->setUri($this->getProvider()); //HTTP config $httpConfig = array('maxredirects' => 5, 'timeout' => 10, 'useragent' => 'Mozilla/5.0 (compatible; Automne/' . AUTOMNE_VERSION . '; +http://www.automne-cms.org)'); if (defined('APPLICATION_PROXY_HOST') && APPLICATION_PROXY_HOST) { $httpConfig['adapter'] = 'Zend_Http_Client_Adapter_Proxy'; $httpConfig['proxy_host'] = APPLICATION_PROXY_HOST; if (defined('APPLICATION_PROXY_PORT') && APPLICATION_PROXY_PORT) { $httpConfig['proxy_port'] = APPLICATION_PROXY_PORT; } } $client->setConfig($httpConfig); $client->setParameterGet(array('url' => $this->_url, 'format' => 'json')); if (io::isPositiveInteger($this->_maxwidth)) { $client->setParameterGet('maxwidth', $this->_maxwidth); } if (io::isPositiveInteger($this->_maxheight)) { $client->setParameterGet('maxheight', $this->_maxheight); } $client->request(); $response = $client->getLastResponse(); } catch (Zend_Http_Client_Exception $e) { $this->raiseError('Error for url: ' . $this->_url . ' - ' . $e->getMessage()); } if (isset($response) && $response->isSuccessful()) { $jsonString = $response->getBody(); $datas = json_decode($jsonString, true); } else { if (isset($response)) { $this->raiseError('Error for oembed url: ' . $this->_url . ' (Provider: ' . $this->getProvider() . ') - ' . $response->getStatus() . ' - ' . $response->getMessage()); } else { $this->raiseError('Error for oembed url: ' . $this->_url . ' (Provider: ' . $this->getProvider() . ') - no response object'); } //create error datas $datas = array('error' => isset($response) ? $response->getStatus() : '500', 'cache_age' => 7200, 'type' => 'error'); } if ($cache) { if (isset($datas['cache_age']) && io::isPositiveInteger($datas['cache_age']) && $datas['cache_age'] != 86400) { //create cache object with new lifetime $cache = new CMS_cache($cacheId, 'oembed', $datas['cache_age'], false); } $cache->save($datas, array('type' => 'oembed', 'provider' => $this->getProvider())); } } if (!$datas) { return false; } $this->_datas = $datas; return true; }
/** * Send a group of files to client (ie : JS or CSS files) * Provide coherent user caching infos (1 month) for files and allow gzip when possible * * @param array $files : array of files path to send to client (FS relative) * @param string $contentType : the content type to send to client (default : text/html) * @return void * @access public * @static */ static function sendFiles($files, $contentType = 'text/html') { //check for the closest last modification date $lastdate = ''; //check for included files in less files $includes = array(); if ($contentType == 'text/css') { foreach ($files as $key => $file) { if (pathinfo($file, PATHINFO_EXTENSION) == 'less') { $lessCache = new CMS_cache(md5($file), 'lessphp', 2592000, false); if ($lessCache->exist()) { $includes = array_merge($includes, $lessCache->load()); } } } } if ($includes) { foreach ($includes as $key => $file) { if (file_exists($file) && is_file($file)) { $lastdate = filemtime($file) > $lastdate ? filemtime($file) : $lastdate; } } } foreach ($files as $key => $file) { if (file_exists($file) && is_file($file)) { $lastdate = filemtime($file) > $lastdate ? filemtime($file) : $lastdate; } else { CMS_grandFather::raiseError('Can\'t find file : ' . $file . ', skip it.'); unset($files[$key]); } } if (file_exists($_SERVER['SCRIPT_FILENAME'])) { $lastdate = filemtime($_SERVER['SCRIPT_FILENAME']) > $lastdate ? filemtime($_SERVER['SCRIPT_FILENAME']) : $lastdate; } //check If-Modified-Since header if exists then return a 304 if needed if (isset($_SERVER['IF-MODIFIED-SINCE'])) { $ifModifiedSince = strtotime($_SERVER['IF-MODIFIED-SINCE']); } elseif (isset($_SERVER['HTTP_IF_MODIFIED_SINCE'])) { $ifModifiedSince = strtotime($_SERVER['HTTP_IF_MODIFIED_SINCE']); } if (isset($ifModifiedSince) && $lastdate <= $ifModifiedSince) { header('HTTP/1.1 304 Not Modified'); header('Content-Type: ' . $contentType); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastdate) . ' GMT'); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); //30 days header("Cache-Control: must-revalidate"); header("Pragma: public"); exit; } $compress = 'ob_gzhandler' != ini_get('output_handler') && extension_loaded('zlib') && !ini_get('zlib.output_compression') && strpos(strtolower(@$_SERVER['HTTP_ACCEPT_ENCODING']), 'gzip') !== false; //create cache id from files, compression status and last time files access $id = md5(implode(',', $files) . '-' . $compress . '-' . $lastdate); //create cache object $cache = new CMS_cache($id, $contentType, 2592000, false); $datas = ''; if (!$cache->exist() || !($datas = $cache->load())) { // datas cache missing so create it foreach ($files as $file) { $fileData = file_get_contents($file); //strip BOM from file if exists if (substr($fileData, 0, 3) === '') { $fileData = substr($fileData, 3); } //append file origin comment if ($contentType == 'text/javascript') { $fileData = '//<<' . "\n" . '//JS file: ' . str_replace(PATH_REALROOT_FS, '', $file) . '' . "\n" . '//!>>' . "\n" . $fileData; } //append file origin comment if ($contentType == 'text/css') { //compile less files if needed if (pathinfo($file, PATHINFO_EXTENSION) == 'less') { $less = new lessc($file); $fileData = $less->parse(); $lessIncludes = $less->allParsedFiles(); if (sizeof($lessIncludes) > 1) { $lessCache = new CMS_cache(md5($file), 'lessphp', 2592000, false); $lessCache->save(array_keys($lessIncludes), array('type' => 'lessphp')); } } $fileData = '/*<<*/' . "\n" . '/* CSS file: ' . str_replace(PATH_REALROOT_FS, '', $file) . ' */' . "\n" . '/*!>>*/' . "\n" . $fileData; } $datas .= $fileData . "\n"; } //minimize JS files if needed if (!SYSTEM_DEBUG && $contentType == 'text/javascript') { $datas = JSMin::minify($datas); } //minimize CSS files if needed if (!SYSTEM_DEBUG && $contentType == 'text/css') { $datas = cssmin::minify($datas); } //compres data if needed if ($compress) { $datas = gzencode($datas, 3); } if ($cache) { $cache->save($datas, array('type' => $contentType)); } } //send headers header('Content-Type: ' . $contentType); header('Last-Modified: ' . gmdate('D, d M Y H:i:s', $lastdate) . ' GMT'); header('Expires: ' . gmdate('D, d M Y H:i:s', time() + 2592000) . ' GMT'); //30 days header("Cache-Control: must-revalidate"); header("Pragma: public"); //send gzip header if needed if ($compress) { header('Vary: Accept-Encoding'); // Handle proxies header("Content-Encoding: gzip"); } //send content echo $datas; exit; }