function sample($msg, $type = PROFILE_RUNNING_TOTAL)
 {
     if ($type == PROFILE_RUNNING_TOTAL) {
         $this->_records[] = array($msg, precision_timer("stop", $this->_starttime), precision_timer());
     } else {
         $prev = end($this->_records);
         $this->_records[] = array($msg, precision_timer("stop", $prev[2]), precision_timer());
     }
 }
Example #2
0
 /**
  * Takes an SQL string and executes it. This function will apply query
  * caching if it is a read operation and if query caching is set. Symphony
  * will convert the `tbl_` prefix of tables to be the one set during installation.
  * A type parameter is provided to specify whether `$this->_lastResult` will be an array
  * of objects or an array of associative arrays. The default is objects. This
  * function will return boolean, but set `$this->_lastResult` to the result.
  *
  * @uses PostQueryExecution
  * @param string $query
  *  The full SQL query to execute.
  * @param string $type
  *  Whether to return the result as objects or associative array. Defaults
  *  to OBJECT which will return objects. The other option is ASSOC. If $type
  *  is not either of these, it will return objects.
  * @throws DatabaseException
  * @return boolean
  *  True if the query executed without errors, false otherwise
  */
 public function query($query, $type = "OBJECT")
 {
     if (empty($query) || self::isConnected() === false) {
         return false;
     }
     $start = precision_timer();
     $query = trim($query);
     $query_type = $this->determineQueryType($query);
     $query_hash = md5($query . $start);
     if (self::$_connection['tbl_prefix'] !== 'tbl_') {
         $query = preg_replace('/tbl_(\\S+?)([\\s\\.,]|$)/', self::$_connection['tbl_prefix'] . '\\1\\2', $query);
     }
     // TYPE is deprecated since MySQL 4.0.18, ENGINE is preferred
     if ($query_type == self::__WRITE_OPERATION__) {
         $query = preg_replace('/TYPE=(MyISAM|InnoDB)/i', 'ENGINE=$1', $query);
     } elseif ($query_type == self::__READ_OPERATION__ && !preg_match('/^SELECT\\s+SQL(_NO)?_CACHE/i', $query)) {
         if ($this->isCachingEnabled()) {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_CACHE ', $query);
         } else {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_NO_CACHE ', $query);
         }
     }
     $this->flush();
     $this->_lastQuery = $query;
     $this->_lastQueryHash = $query_hash;
     $this->_result = mysqli_query(self::$_connection['id'], $query);
     $this->_lastInsertID = mysqli_insert_id(self::$_connection['id']);
     self::$_query_count++;
     if (mysqli_error(self::$_connection['id'])) {
         $this->__error();
     } elseif ($this->_result instanceof mysqli_result) {
         if ($type == "ASSOC") {
             while ($row = mysqli_fetch_assoc($this->_result)) {
                 $this->_lastResult[] = $row;
             }
         } else {
             while ($row = mysqli_fetch_object($this->_result)) {
                 $this->_lastResult[] = $row;
             }
         }
         mysqli_free_result($this->_result);
     }
     $stop = precision_timer('stop', $start);
     /**
      * After a query has successfully executed, that is it was considered
      * valid SQL, this delegate will provide the query, the query_hash and
      * the execution time of the query.
      *
      * Note that this function only starts logging once the ExtensionManager
      * is available, which means it will not fire for the first couple of
      * queries that set the character set.
      *
      * @since Symphony 2.3
      * @delegate PostQueryExecution
      * @param string $context
      * '/frontend/' or '/backend/'
      * @param string $query
      *  The query that has just been executed
      * @param string $query_hash
      *  The hash used by Symphony to uniquely identify this query
      * @param float $execution_time
      *  The time that it took to run `$query`
      */
     if (self::$_logging === true) {
         if (Symphony::ExtensionManager() instanceof ExtensionManager) {
             Symphony::ExtensionManager()->notifyMembers('PostQueryExecution', class_exists('Administration', false) ? '/backend/' : '/frontend/', array('query' => $query, 'query_hash' => $query_hash, 'execution_time' => $stop));
             // If the ExceptionHandler is enabled, then the user is authenticated
             // or we have a serious issue, so log the query.
             if (GenericExceptionHandler::$enabled) {
                 self::$_log[$query_hash] = array('query' => $query, 'query_hash' => $query_hash, 'execution_time' => $stop);
             }
             // Symphony isn't ready yet. Log internally
         } else {
             self::$_log[$query_hash] = array('query' => $query, 'query_hash' => $query_hash, 'execution_time' => $stop);
         }
     }
     return true;
 }
Example #3
0
 /**
  * This function creates a new report in the `$_samples` array where the message
  * is the name of this report. By default, all samples are compared to the `$_starttime`
  * but if the `PROFILE_LAP` constant is passed, it will be compared to specific `$_seed`
  * timestamp. Samples can grouped by type (ie. Datasources, Events), but by default
  * are grouped by 'General'. Optionally, the number of SQL queries that have occurred
  * since either `$_starttime` or `$_seed` can be passed. Memory usage is taken with each
  * sample which measures the amount of memory used by this script by PHP at the
  * time of sampling.
  *
  * @param string $msg
  *  A description for this sample
  * @param integer $type
  *  Either `PROFILE_RUNNING_TOTAL` or `PROFILE_LAP`
  * @param string $group
  *  Allows samples to be grouped together, defaults to General.
  * @param integer $queries
  *  The number of MySQL queries that occurred since the `$_starttime` or `$_seed`
  */
 public function sample($msg, $type = PROFILE_RUNNING_TOTAL, $group = 'General', $queries = null)
 {
     if ($type == PROFILE_RUNNING_TOTAL) {
         Profiler::$_samples[] = array($msg, precision_timer('stop', Profiler::$_starttime), precision_timer(), $group, $queries, memory_get_usage());
     } else {
         if (!is_null(Profiler::$_seed)) {
             $start = Profiler::$_seed;
             Profiler::$_seed = null;
         } else {
             $start = null;
         }
         $prev = Profiler::retrieveLast();
         Profiler::$_samples[] = array($msg, precision_timer('stop', $start ? $start : $prev[2]), precision_timer(), $group, $queries, memory_get_usage());
     }
 }
Example #4
0
define('CORE', DOCROOT . '/symphony');
define('CAMPFIRE', DOCROOT . '/campfire');
define('WORKSPACE', DOCROOT . '/workspace');
define('LIBRARY', CORE . '/lib');
define('AJAX', CORE . '/ajax');
define('UPLOAD', WORKSPACE . '/upload');
define('DATASOURCES', WORKSPACE . '/data-sources');
define('EVENTS', WORKSPACE . '/events');
define('TEXTFORMATTERS', WORKSPACE . '/text-formatters');
define('CACHE', MANIFEST . '/cache');
define('TMP', MANIFEST . '/tmp');
define('LOGS', MANIFEST . '/logs');
define('CONFIG', MANIFEST . '/config.php');
define('TOOLKIT', LIBRARY . '/toolkit');
define('LANG', LIBRARY . '/lang');
define('STARTTIME', precision_timer());
define('TWO_WEEKS', 72576000);
//2 weeks in seconds. Used by cookies.
define('CACHE_LIFETIME', TWO_WEEKS);
define('HTTPS', $_SERVER['HTTPS']);
define('HTTP_HOST', $_SERVER['HTTP_HOST']);
define('REMOTE_ADDR', $_SERVER['REMOTE_ADDR']);
define('HTTP_USER_AGENT', $_SERVER['HTTP_USER_AGENT']);
define('__SECURE__', HTTPS == 'on');
if (!defined('URL')) {
    define('URL', 'http' . (defined('__SECURE__') && __SECURE__ ? 's' : '') . '://' . DOMAIN);
}
define('_CURL_AVAILABLE_', function_exists('curl_init'));
if (function_exists('domxml_xslt_stylesheet')) {
    define('_USING_DOMXML_XSLT_', true);
    define('_XSLT_AVAILABLE_', true);
 /**
  * Takes an SQL string and executes it. This function will apply query
  * caching if it is a read operation and if query caching is set. Symphony
  * will convert the `tbl_` prefix of tables to be the one set during installation.
  * A type parameter is provided to specify whether `$this->_lastResult` will be an array
  * of objects or an array of associative arrays. The default is objects. This
  * function will return boolean, but set `$this->_lastResult` to the result.
  *
  * @param string $query
  *  The full SQL query to execute.
  * @param string $type
  *  Whether to return the result as objects or associative array. Defaults
  *  to OBJECT which will return objects. The other option is ASSOC. If $type
  *  is not either of these, it will return objects.
  * @return boolean
  *  True if the query executed without errors, false otherwise
  */
 public function query($query, $type = "OBJECT")
 {
     if (empty($query)) {
         return false;
     }
     $query = trim($query);
     $query_type = $this->determineQueryType($query);
     if (MySQL::$_connection['tbl_prefix'] != 'tbl_') {
         $query = preg_replace('/tbl_(\\S+?)([\\s\\.,]|$)/', MySQL::$_connection['tbl_prefix'] . '\\1\\2', $query);
     }
     // TYPE is deprecated since MySQL 4.0.18, ENGINE is preferred
     if ($query_type == MySQL::__WRITE_OPERATION__) {
         $query = preg_replace('/TYPE=(MyISAM|InnoDB)/i', 'ENGINE=$1', $query);
     } else {
         if ($query_type == MySQL::__READ_OPERATION__ && !preg_match('/^SELECT\\s+SQL(_NO)?_CACHE/i', $query)) {
             if ($this->isCachingEnabled()) {
                 $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_CACHE ', $query);
             } else {
                 $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_NO_CACHE ', $query);
             }
         }
     }
     $query_hash = md5($query . microtime());
     self::$_log['query'][$query_hash] = array('query' => $query, 'start' => precision_timer());
     $this->flush();
     $this->_lastQuery = $query;
     $this->_result = mysql_query($query, MySQL::$_connection['id']);
     self::$_query_count++;
     if (mysql_error()) {
         $this->__error();
     } else {
         if (is_resource($this->_result)) {
             if ($type == "ASSOC") {
                 while ($row = mysql_fetch_assoc($this->_result)) {
                     $this->_lastResult[] = $row;
                 }
             } else {
                 while ($row = mysql_fetch_object($this->_result)) {
                     $this->_lastResult[] = $row;
                 }
             }
             mysql_free_result($this->_result);
         }
     }
     self::$_log['query'][$query_hash]['time'] = precision_timer('stop', self::$_log['query'][$query_hash]['start']);
     return true;
 }
    /**
     * This function sets the page's parameters, processes the Datasources and
     * Events and sets the `$xml` and `$xsl` variables. This functions resolves the `$page`
     * by calling the `resolvePage()` function. If a page is not found, it attempts
     * to locate the Symphony 404 page set in the backend otherwise it throws
     * the default Symphony 404 page. If the page is found, the page's XSL utility
     * is found, and the system parameters are set, including any URL parameters,
     * params from the Symphony cookies. Events and Datasources are executed and
     * any parameters  generated by them are appended to the existing parameters
     * before setting the Page's XML and XSL variables are set to the be the
     * generated XML (from the Datasources and Events) and the XSLT (from the
     * file attached to this Page)
     *
     * @uses FrontendPageResolved
     * @uses FrontendParamsResolve
     * @uses FrontendParamsPostResolve
     * @see resolvePage()
     */
    private function __buildPage()
    {
        $start = precision_timer();
        if (!($page = $this->resolvePage())) {
            throw new FrontendPageNotFoundException();
        }
        /**
         * Just after having resolved the page, but prior to any commencement of output creation
         * @delegate FrontendPageResolved
         * @param string $context
         * '/frontend/'
         * @param FrontendPage $page
         *  An instance of this class, passed by reference
         * @param array $page_data
         *  An associative array of page data, which is a combination from `tbl_pages` and
         *  the path of the page on the filesystem. Passed by reference
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendPageResolved', '/frontend/', array('page' => &$this, 'page_data' => &$page));
        $this->_pageData = $page;
        $path = explode('/', $page['path']);
        $root_page = is_array($path) ? array_shift($path) : $path;
        $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2);
        $current_path = '/' . ltrim(end($current_path), '/');
        $split_path = explode('?', $current_path, 3);
        $current_path = rtrim(current($split_path), '/');
        $querystring = '?' . next($split_path);
        // Get max upload size from php and symphony config then choose the smallest
        $upload_size_php = ini_size_to_bytes(ini_get('upload_max_filesize'));
        $upload_size_sym = Symphony::Configuration()->get('max_upload_size', 'admin');
        $this->_param = array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => DateTimeObj::get('P'), 'website-name' => Symphony::Configuration()->get('sitename', 'general'), 'page-title' => $page['title'], 'root' => URL, 'workspace' => URL . '/workspace', 'root-page' => $root_page ? $root_page : $page['handle'], 'current-page' => $page['handle'], 'current-page-id' => $page['id'], 'current-path' => $current_path, 'parent-path' => '/' . $page['path'], 'current-query-string' => XMLElement::stripInvalidXMLCharacters(utf8_encode(urldecode($querystring))), 'current-url' => URL . $current_path, 'upload-limit' => min($upload_size_php, $upload_size_sym), 'symphony-version' => Symphony::Configuration()->get('version', 'symphony'));
        if (is_array($this->_env['url'])) {
            foreach ($this->_env['url'] as $key => $val) {
                $this->_param[$key] = $val;
            }
        }
        if (is_array($_GET) && !empty($_GET)) {
            foreach ($_GET as $key => $val) {
                if (in_array($key, array('symphony-page', 'debug', 'profile'))) {
                    continue;
                }
                // If the browser sends encoded entities for &, ie. a=1&b=2
                // this causes the $_GET to output they key as amp;b, which results in
                // $url-amp;b. This pattern will remove amp; allow the correct param
                // to be used, $url-b
                $key = preg_replace('/(^amp;|\\/)/', null, $key);
                // If the key gets replaced out then it will break the XML so prevent
                // the parameter being set.
                if (!General::createHandle($key)) {
                    continue;
                }
                $this->_param['url-' . $key] = XMLElement::stripInvalidXMLCharacters(utf8_encode(urldecode($val)));
            }
        }
        if (is_array($_COOKIE[__SYM_COOKIE_PREFIX_]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX_])) {
            foreach ($_COOKIE[__SYM_COOKIE_PREFIX_] as $key => $val) {
                $this->_param['cookie-' . $key] = $val;
            }
        }
        // Flatten parameters:
        General::flattenArray($this->_param);
        /**
         * Just after having resolved the page params, but prior to any commencement of output creation
         * @delegate FrontendParamsResolve
         * @param string $context
         * '/frontend/'
         * @param array $params
         *  An associative array of this page's parameters
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendParamsResolve', '/frontend/', array('params' => &$this->_param));
        $xml_build_start = precision_timer();
        $xml = new XMLElement('data');
        $xml->setIncludeHeader(true);
        $events = new XMLElement('events');
        $this->processEvents($page['events'], $events);
        $xml->appendChild($events);
        $this->_events_xml = clone $events;
        $this->processDatasources($page['data_sources'], $xml);
        Symphony::Profiler()->seed($xml_build_start);
        Symphony::Profiler()->sample('XML Built', PROFILE_LAP);
        if (is_array($this->_env['pool']) && !empty($this->_env['pool'])) {
            foreach ($this->_env['pool'] as $handle => $p) {
                if (!is_array($p)) {
                    $p = array($p);
                }
                foreach ($p as $key => $value) {
                    if (is_array($value) && !empty($value)) {
                        foreach ($value as $kk => $vv) {
                            $this->_param[$handle] .= @implode(', ', $vv) . ',';
                        }
                    } else {
                        $this->_param[$handle] = @implode(', ', $p);
                    }
                }
                $this->_param[$handle] = trim($this->_param[$handle], ',');
            }
        }
        /**
         * Access to the resolved param pool, including additional parameters provided by Data Source outputs
         * @delegate FrontendParamsPostResolve
         * @param string $context
         * '/frontend/'
         * @param array $params
         *  An associative array of this page's parameters
         */
        Symphony::ExtensionManager()->notifyMembers('FrontendParamsPostResolve', '/frontend/', array('params' => &$this->_param));
        $params = new XMLElement('params');
        foreach ($this->_param as $key => $value) {
            // To support multiple parameters using the 'datasource.field'
            // we will pop off the field handle prior to sanitizing the
            // key. This is because of a limitation where General::createHandle
            // will strip '.' as it's technically punctuation.
            if (strpos($key, '.') !== false) {
                $parts = explode('.', $key);
                $field_handle = '.' . array_pop($parts);
                $key = implode('', $parts);
            } else {
                $field_handle = '';
            }
            $key = Lang::createHandle($key) . $field_handle;
            $param = new XMLElement($key);
            // DS output params get flattened to a string, so get the original pre-flattened array
            if (isset($this->_env['pool'][$key])) {
                $value = $this->_env['pool'][$key];
            }
            if (is_array($value) && !(count($value) == 1 && empty($value[0]))) {
                foreach ($value as $key => $value) {
                    $item = new XMLElement('item', General::sanitize($value));
                    $item->setAttribute('handle', Lang::createHandle($value));
                    $param->appendChild($item);
                }
            } else {
                if (is_array($value)) {
                    $param->setValue(General::sanitize($value[0]));
                } else {
                    $param->setValue(General::sanitize($value));
                }
            }
            $params->appendChild($param);
        }
        $xml->prependChild($params);
        Symphony::Profiler()->seed();
        $this->setXML($xml->generate(true, 0));
        Symphony::Profiler()->sample('XML Generation', PROFILE_LAP);
        $xsl = '<?xml version="1.0" encoding="UTF-8"?>
			<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
				<xsl:import href="./workspace/pages/' . basename($page['filelocation']) . '"/>
			</xsl:stylesheet>';
        $this->setXSL($xsl, false);
        $this->setRuntimeParam($this->_param);
        Symphony::Profiler()->seed($start);
        Symphony::Profiler()->sample('Page Built', PROFILE_LAP);
    }
$cache = new Cacheable(Symphony::Database());
$cachedData = $cache->check($cache_id);
$writeToCache = false;
$valid = true;
$creation = DateTimeObj::get('c');
$timeout = isset($this->dsParamTIMEOUT) ? (int) max(1, $this->dsParamTIMEOUT) : 6;
if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
    if (Mutex::acquire($cache_id, $timeout, TMP)) {
        $start = precision_timer();
        $ch = new Gateway();
        $ch->init();
        $ch->setopt('URL', $this->dsParamURL);
        $ch->setopt('TIMEOUT', $timeout);
        $xml = $ch->exec();
        $writeToCache = true;
        $end = precision_timer('stop', $start);
        $info = $ch->getInfoLast();
        Mutex::release($cache_id, TMP);
        $xml = trim($xml);
        // Handle any response that is not a 200, or the content type does not include xml, plain or text
        if ((int) $info['http_code'] != 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) {
            $writeToCache = false;
            if (is_array($cachedData) && !empty($cachedData)) {
                $xml = trim($cachedData['data']);
                $valid = false;
                $creation = DateTimeObj::get('c', $cachedData['creation']);
            } else {
                $result->setAttribute('valid', 'false');
                if ($end > $timeout) {
                    $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                } else {
Example #8
0
    $Author = new Author($Parent, $author_id);
} else {
    $xml = new XMLElement('error', 'You do not have permission to access this page');
}
if (is_object($Author)) {
    ##Run requested script, returning an error if the action was not found
    if (@is_file(AJAX . "/ajax." . $_REQUEST['action'] . ".php")) {
        $xml = new XMLElement($_REQUEST['action']);
        include_once AJAX . "/ajax." . $_REQUEST['action'] . ".php";
    } else {
        $action_parts = preg_split('/\\//', $_REQUEST['action'], -1, PREG_SPLIT_NO_EMPTY);
        $action_path = str_replace(end($action_parts) . '/', '', $_REQUEST['action']);
        $action_name = rtrim(str_replace($action_path, '', $_REQUEST['action']), '/');
        $file_path = CAMPFIRE . $action_path . "/ajax/ajax." . $action_name . ".php";
        if (@is_file($file_path)) {
            $xml = new XMLElement($action_name);
            include_once $file_path;
        } else {
            $xml = new XMLElement("error", "Ajax action '" . $_REQUEST['action'] . "' does not exist.");
        }
    }
}
#Close the database connections
@$db->close();
#Record the render time
$rendertime = precision_timer("stop", STARTTIME);
##XML is returned, make sure the browser knows it
header("Content-Type: text/xml");
$xml->setIncludeHeader(true);
print $xml->generate(true);
exit;
Example #9
0
 public function query($query)
 {
     if (empty($query)) {
         return false;
     }
     $query = trim($query);
     $query_type = $this->determineQueryType($query);
     if ($query_type == self::__READ_OPERATION__ && $this->isCachingEnabled() !== NULL && !preg_match('/^SELECT\\s+SQL(_NO)?_CACHE/i', $query)) {
         if ($this->isCachingEnabled() === false) {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_NO_CACHE ', $query);
         } elseif ($this->isCachingEnabled() === true) {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_CACHE ', $query);
         }
     }
     if ($this->_connection['tbl_prefix'] != 'tbl_') {
         $query = preg_replace('/tbl_(\\S+?)([\\s\\.,]|$)/', $this->_connection['tbl_prefix'] . '\\1\\2', $query);
     }
     $query_hash = md5($query . time());
     $this->_log['query'][$query_hash] = array('query' => $query, 'start' => precision_timer());
     $this->flush();
     $this->_lastQuery = $query;
     $this->_result = @mysql_query($query, $this->_connection['id']);
     $this->_query_count++;
     if (@mysql_error()) {
         $this->__error();
         return false;
     }
     while ($row = @mysql_fetch_object($this->_result)) {
         @array_push($this->_lastResult, $row);
     }
     if ($query_type == self::__WRITE_OPERATION__) {
         $this->_affectedRows = @mysql_affected_rows();
         if (stristr($query, 'insert') || stristr($query, 'replace')) {
             $this->_insertID = @mysql_insert_id($this->_connection['id']);
         }
     }
     @mysql_free_result($this->_result);
     $this->_log['query'][$query_hash]['time'] = precision_timer('stop', $this->_log['query'][$query_hash]['start']);
     if ($this->_logEverything) {
         $this->_log['query'][$query_hash]['lastResult'] = $this->_lastResult;
     }
     return true;
 }
Example #10
0
 private static function __precisionTimer($action = 'start', $start_time = null)
 {
     return precision_timer($action, $start_time);
 }
Example #11
0
# Delegate: SetTemplate
# Description: Template has been set, but this delegate will let you change it to whatever you wish
$CampfireManager->notifyMembers('SetTemplate', CURRENTPAGE, array('template' => &$template));
ob_start();
include $Admin->getContent(CURRENTPAGE);
$content = !defined("__SYM_FATAL_ERROR__") ? ob_get_contents() : __SYM_FATAL_ERROR__;
ob_end_clean();
####
# Delegate: GenerateHead
# Description: All head information is generated just after this call. This is where you can remove/add items
$CampfireManager->notifyMembers('GenerateHead', CURRENTPAGE);
$Admin->generateHeadExtras();
ob_start();
include CORE . "/template/" . $template . ".php";
$final_page = ob_get_clean();
$replace = array("<!-- CONTENT -->" => $content, "<!-- RENDER TIME -->" => precision_timer("stop", STARTTIME), "<!-- PAGE TITLE -->" => $GLOBALS['pageTitle'], "<!-- ONLOAD EVENT -->" => $GLOBALS['onloadEvent'], "<!-- HEAD EXTRAS -->" => "\t" . @implode("\n\t", $GLOBALS['headExtras']));
$final_page = str_replace(array_keys($replace), array_values($replace), $final_page);
$Admin->processLogs();
if ($template == "login" || $template == "update") {
    $final_page = str_replace("<!-- ERRORS -->", defined("__SYM_ERROR_MESSAGE__") ? "<p>" . __SYM_ERROR_MESSAGE__ . "</p>" : "", $final_page);
} else {
    $error = NULL;
    if (defined('__SYM_ERROR_MESSAGE__')) {
        $error = '<p id="notice" class="error">' . __SYM_ERROR_MESSAGE__ . '</p>';
    } elseif (defined('__SYM_NOTICE_MESSAGE__')) {
        $error = '<p id="notice">' . __SYM_NOTICE_MESSAGE__ . '</p>';
    }
    $final_page = str_replace("<!-- ERRORS -->", $error ? $error : "", $final_page);
}
$profiler->sample("Page Render Time");
##Generate page headers
 /**
  * Given an array of all the Datasources for this page, sort them into the
  * correct execution order and append the Datasource results to the
  * page XML. If the Datasource provides any parameters, they will be
  * added to the `$env` pool for use by other Datasources and eventual
  * inclusion into the page parameters.
  *
  * @param string $datasources
  *  A string of Datasource's attached to this page, comma separated.
  * @param XMLElement $wrapper
  *  The XMLElement to append the Datasource results to. Datasource
  *  results are contained in a root XMLElement that is the handlised
  *  version of their name.
  * @param array $params
  *  Any params to automatically add to the `$env` pool, by default this
  *  is an empty array. It looks like Symphony does not utilise this parameter
  *  at all
  * @throws Exception
  */
 public function processDatasources($datasources, XMLElement &$wrapper, array $params = array())
 {
     if (trim($datasources) == '') {
         return;
     }
     $datasources = preg_split('/,\\s*/i', $datasources, -1, PREG_SPLIT_NO_EMPTY);
     $datasources = array_map('trim', $datasources);
     if (!is_array($datasources) || empty($datasources)) {
         return;
     }
     $this->_env['pool'] = $params;
     $pool = $params;
     $dependencies = array();
     foreach ($datasources as $handle) {
         $pool[$handle] = DatasourceManager::create($handle, array(), false);
         $dependencies[$handle] = $pool[$handle]->getDependencies();
     }
     $dsOrder = $this->__findDatasourceOrder($dependencies);
     foreach ($dsOrder as $handle) {
         $startTime = precision_timer();
         $queries = Symphony::Database()->queryCount();
         // default to no XML
         $xml = null;
         $ds = $pool[$handle];
         // Handle redirect on empty setting correctly RE: #1539
         try {
             $ds->processParameters(array('env' => $this->_env, 'param' => $this->_param));
         } catch (FrontendPageNotFoundException $e) {
             // Work around. This ensures the 404 page is displayed and
             // is not picked up by the default catch() statement below
             FrontendPageNotFoundExceptionHandler::render($e);
         }
         /**
          * Allows extensions to execute the data source themselves (e.g. for caching)
          * and providing their own output XML instead
          *
          * @since Symphony 2.3
          * @delegate DataSourcePreExecute
          * @param string $context
          * '/frontend/'
          * @param DataSource $datasource
          *  The Datasource object
          * @param mixed $xml
          *  The XML output of the data source. Can be an `XMLElement` or string.
          * @param array $param_pool
          *  The existing param pool including output parameters of any previous data sources
          */
         Symphony::ExtensionManager()->notifyMembers('DataSourcePreExecute', '/frontend/', array('datasource' => &$ds, 'xml' => &$xml, 'param_pool' => &$this->_env['pool']));
         // if the XML is still null, an extension has not run the data source, so run normally
         if (is_null($xml)) {
             $xml = $ds->grab($this->_env['pool']);
         }
         if ($xml) {
             /**
              * After the datasource has executed, either by itself or via the
              * `DataSourcePreExecute` delegate, and if the `$xml` variable is truthy,
              * this delegate allows extensions to modify the output XML and parameter pool
              *
              * @since Symphony 2.3
              * @delegate DataSourcePostExecute
              * @param string $context
              * '/frontend/'
              * @param DataSource $datasource
              *  The Datasource object
              * @param mixed $xml
              *  The XML output of the data source. Can be an `XMLElement` or string.
              * @param array $param_pool
              *  The existing param pool including output parameters of any previous data sources
              */
             Symphony::ExtensionManager()->notifyMembers('DataSourcePostExecute', '/frontend/', array('datasource' => $ds, 'xml' => &$xml, 'param_pool' => &$this->_env['pool']));
             if ($xml instanceof XMLElement) {
                 $wrapper->appendChild($xml);
             } else {
                 $wrapper->appendChild('    ' . trim($xml) . PHP_EOL);
             }
         }
         $queries = Symphony::Database()->queryCount() - $queries;
         Symphony::Profiler()->seed($startTime);
         Symphony::Profiler()->sample($handle, PROFILE_LAP, 'Datasource', $queries);
         unset($ds);
     }
 }
$result = NULL;
$creation = DateTimeObj::get('c');
$timeout = 6;
if (isset($this->dsParamTIMEOUT)) {
    $timeout = (int) max(1, $this->dsParamTIMEOUT);
}
if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->dsParamCACHE * 60) {
    if (Mutex::acquire($cache_id, $timeout, TMP)) {
        $start = precision_timer();
        $ch = new Gateway();
        $ch->init();
        $ch->setopt('URL', $this->dsParamURL);
        $ch->setopt('TIMEOUT', $timeout);
        $xml = $ch->exec();
        $writeToCache = true;
        $end = precision_timer('STOP', $start);
        $info = $ch->getInfoLast();
        Mutex::release($cache_id, TMP);
        $xml = trim($xml);
        if ((int) $info['http_code'] != 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) {
            $writeToCache = false;
            if (is_array($cachedData) && !empty($cachedData)) {
                $xml = trim($cachedData['data']);
                $valid = false;
                $creation = DateTimeObj::get('c', $cachedData['creation']);
            } else {
                $result = new XMLElement($this->dsParamROOTELEMENT);
                $result->setAttribute('valid', 'false');
                if ($end > $timeout) {
                    $result->appendChild(new XMLElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                } else {
Example #14
0
 public function render(Register $ParameterOutput)
 {
     $result = null;
     $doc = new XMLDocument();
     if (isset($this->parameters()->url)) {
         $this->parameters()->url = self::replaceParametersInString($this->parameters()->url, $ParameterOutput);
     }
     if (isset($this->parameters()->xpath)) {
         $this->parameters()->xpath = self::replaceParametersInString($this->parameters()->xpath, $ParameterOutput);
     }
     $cache_id = md5($this->parameters()->url . serialize($this->parameters()->namespaces) . $this->parameters()->xpath);
     $cache = Cache::instance();
     $cachedData = $cache->read($cache_id);
     $writeToCache = false;
     $force_empty_result = false;
     $valid = true;
     $result = NULL;
     $creation = DateTimeObj::get('c');
     if (isset($this->parameters()->timeout)) {
         $timeout = (int) max(1, $this->parameters()->timeout);
     }
     if (!is_array($cachedData) || empty($cachedData) || time() - $cachedData['creation'] > $this->parameters()->{'cache-timeout'} * 60) {
         if (Mutex::acquire($cache_id, $timeout, TMP)) {
             $start = precision_timer();
             $ch = new Gateway();
             $ch->init();
             $ch->setopt('URL', $this->parameters()->url);
             $ch->setopt('TIMEOUT', $this->parameters()->timeout);
             $xml = $ch->exec();
             $writeToCache = true;
             $end = precision_timer('STOP', $start);
             $info = $ch->getInfoLast();
             Mutex::release($cache_id, TMP);
             $xml = trim($xml);
             if ((int) $info['http_code'] != 200 || !preg_match('/(xml|plain|text)/i', $info['content_type'])) {
                 $writeToCache = false;
                 if (is_array($cachedData) && !empty($cachedData)) {
                     $xml = trim($cachedData['data']);
                     $valid = false;
                     $creation = DateTimeObj::get('c', $cachedData['creation']);
                 } else {
                     $result = $doc->createElement($this->parameters()->{'root-element'});
                     $result->setAttribute('valid', 'false');
                     if ($end > $timeout) {
                         $result->appendChild($doc->createElement('error', sprintf('Request timed out. %d second limit reached.', $timeout)));
                     } else {
                         $result->appendChild($doc->createElement('error', sprintf('Status code %d was returned. Content-type: %s', $info['http_code'], $info['content_type'])));
                     }
                     return $result;
                 }
             } elseif (strlen($xml) > 0 && !General::validateXML($xml, $errors)) {
                 $writeToCache = false;
                 if (is_array($cachedData) && !empty($cachedData)) {
                     $xml = trim($cachedData['data']);
                     $valid = false;
                     $creation = DateTimeObj::get('c', $cachedData['creation']);
                 } else {
                     $result = $doc->createElement($this->parameters()->{'root-element'}, $doc->createElement('error', __('XML returned is invalid.')), array('valid' => 'false'));
                     return $result;
                 }
             } elseif (strlen($xml) == 0) {
                 $force_empty_result = true;
             }
         } elseif (is_array($cachedData) && !empty($cachedData)) {
             $xml = trim($cachedData['data']);
             $valid = false;
             $creation = DateTimeObj::get('c', $cachedData['creation']);
             if (empty($xml)) {
                 $force_empty_result = true;
             }
         } else {
             $force_empty_result = true;
         }
     } else {
         $xml = trim($cachedData['data']);
         $creation = DateTimeObj::get('c', $cachedData['creation']);
     }
     if (!$force_empty_result) {
         $result = new XMLDocument();
         $root = $result->createElement($this->parameters()->{'root-element'});
         //XPath Approach, saves Transforming the Document.
         $xDom = new XMLDocument();
         $xDom->loadXML($xml);
         if ($xDom->hasErrors()) {
             $root->setAttribute('valid', 'false');
             $root->appendChild($result->createElement('error', __('XML returned is invalid.')));
             $messages = $result->createElement('messages');
             foreach ($xDom->getErrors() as $e) {
                 if (strlen(trim($e->message)) == 0) {
                     continue;
                 }
                 $messages->appendChild($result->createElement('item', General::sanitize($e->message)));
             }
             $root->appendChild($messages);
         } else {
             if ($writeToCache) {
                 $cache->write($cache_id, $xml);
             }
             $xpath = new DOMXPath($xDom);
             ## Namespaces
             if (is_array($this->parameters()->namespaces) && !empty($this->parameters()->namespaces)) {
                 foreach ($this->parameters()->namespaces as $index => $namespace) {
                     $xpath->registerNamespace($namespace['name'], $namespace['uri']);
                 }
             }
             $xpath_list = $xpath->query($this->parameters()->xpath);
             foreach ($xpath_list as $node) {
                 if ($node instanceof XMLDocument) {
                     $root->appendChild($result->importNode($node->documentElement, true));
                 } else {
                     $root->appendChild($result->importNode($node, true));
                 }
             }
             $root->setAttribute('status', $valid === true ? 'fresh' : 'stale');
             $root->setAttribute('creation', $creation);
         }
     }
     if (!$root->hasChildNodes() || $force_empty_result) {
         $this->emptyXMLSet($root);
     }
     $result->appendChild($root);
     return $result;
 }
Example #15
0
 public function query($query)
 {
     if (empty($query)) {
         return false;
     }
     $query = trim($query);
     $query_type = $this->determineQueryType($query);
     if ($query_type == self::__READ_OPERATION__ && $this->isCachingEnabled() !== NULL && !preg_match('/^SELECT\\s+SQL(_NO)?_CACHE/i', $query)) {
         if ($this->isCachingEnabled() === false) {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_NO_CACHE ', $query);
         } elseif ($this->isCachingEnabled() === true) {
             $query = preg_replace('/^SELECT\\s+/i', 'SELECT SQL_CACHE ', $query);
         }
     }
     if ($this->_connection['tbl_prefix'] != 'tbl_') {
         $query = preg_replace('/tbl_(\\S+?)([\\s\\.,]|$)/', $this->_connection['tbl_prefix'] . '\\1\\2', $query);
     }
     $query_hash = md5($query . microtime());
     self::$_log['query'][$query_hash] = array('query' => $query, 'start' => precision_timer());
     $this->flush();
     $this->_lastQuery = $query;
     $this->_result = mysql_query($query, $this->_connection['id']);
     self::$_query_count++;
     if (mysql_error()) {
         $this->__error();
         return false;
     }
     if (is_resource($this->_result)) {
         while ($row = mysql_fetch_object($this->_result)) {
             $this->_lastResult[] = $row;
         }
         mysql_free_result($this->_result);
     }
     self::$_log['query'][$query_hash]['time'] = precision_timer('stop', self::$_log['query'][$query_hash]['start']);
     if ($this->_logEverything) {
         self::$_log['query'][$query_hash]['lastResult'] = $this->_lastResult;
     }
     return true;
 }
Example #16
0
    private function __buildPage()
    {
        $start = precision_timer();
        if (!($page = $this->resolvePage())) {
            $page = $this->_Parent->Database->fetchRow(0, "\n\t\t\t\t\t\t\t\tSELECT `tbl_pages`.* \n\t\t\t\t\t\t\t\tFROM `tbl_pages`, `tbl_pages_types` \n\t\t\t\t\t\t\t\tWHERE `tbl_pages_types`.page_id = `tbl_pages`.id \n\t\t\t\t\t\t\t\tAND tbl_pages_types.`type` = '404' \n\t\t\t\t\t\t\t\tLIMIT 1");
            if (empty($page)) {
                $this->_Parent->customError(E_USER_ERROR, __('Page Not Found'), __('The page you requested does not exist.'), false, true, 'error', array('header' => 'HTTP/1.0 404 Not Found'));
            }
            $page['filelocation'] = $this->resolvePageFileLocation($page['path'], $page['handle']);
            $page['type'] = $this->__fetchPageTypes($page['id']);
        }
        ####
        # Delegate: FrontendPageResolved
        # Description: Just after having resolved the page, but prior to any commencement of output creation
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendPageResolved', '/frontend/', array('page' => &$this, 'page_data' => &$page));
        $this->_pageData = $page;
        $root_page = @array_shift(explode('/', $page['path']));
        $current_path = explode(dirname($_SERVER['SCRIPT_NAME']), $_SERVER['REQUEST_URI'], 2);
        $current_path = '/' . ltrim(end($current_path), '/');
        // Get max upload size from php and symphony config then choose the smallest
        $upload_size_php = ini_size_to_bytes(ini_get('upload_max_filesize'));
        $upload_size_sym = Frontend::instance()->Configuration->get('max_upload_size', 'admin');
        $this->_param = array('today' => DateTimeObj::get('Y-m-d'), 'current-time' => DateTimeObj::get('H:i'), 'this-year' => DateTimeObj::get('Y'), 'this-month' => DateTimeObj::get('m'), 'this-day' => DateTimeObj::get('d'), 'timezone' => DateTimeObj::get('P'), 'website-name' => $this->_Parent->Configuration->get('sitename', 'general'), 'page-title' => $page['title'], 'root' => URL, 'workspace' => URL . '/workspace', 'root-page' => $root_page ? $root_page : $page['handle'], 'current-page' => $page['handle'], 'current-page-id' => $page['id'], 'current-path' => $current_path, 'parent-path' => '/' . $page['path'], 'current-url' => URL . $current_path, 'upload-limit' => min($upload_size_php, $upload_size_sym), 'symphony-build' => $this->_Parent->Configuration->get('build', 'symphony'));
        if (is_array($this->_env['url'])) {
            foreach ($this->_env['url'] as $key => $val) {
                $this->_param[$key] = $val;
            }
        }
        if (is_array($_GET) && !empty($_GET)) {
            foreach ($_GET as $key => $val) {
                if (!in_array($key, array('symphony-page', 'debug', 'profile'))) {
                    $this->_param['url-' . $key] = $val;
                }
            }
        }
        if (is_array($_COOKIE[__SYM_COOKIE_PREFIX_]) && !empty($_COOKIE[__SYM_COOKIE_PREFIX_])) {
            foreach ($_COOKIE[__SYM_COOKIE_PREFIX_] as $key => $val) {
                $this->_param['cookie-' . $key] = $val;
            }
        }
        // Flatten parameters:
        General::flattenArray($this->_param);
        ####
        # Delegate: FrontendParamsResolve
        # Description: Just after having resolved the page params, but prior to any commencement of output creation
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendParamsResolve', '/frontend/', array('params' => &$this->_param));
        $xml_build_start = precision_timer();
        $xml = new XMLElement('data');
        $xml->setIncludeHeader(true);
        $events = new XMLElement('events');
        $this->__processEvents($page['events'], $events);
        $xml->appendChild($events);
        $this->_events_xml = clone $events;
        $this->__processDatasources($page['data_sources'], $xml);
        $this->_Parent->Profiler->seed($xml_build_start);
        $this->_Parent->Profiler->sample('XML Built', PROFILE_LAP);
        if (is_array($this->_env['pool']) && !empty($this->_env['pool'])) {
            foreach ($this->_env['pool'] as $handle => $p) {
                if (!is_array($p)) {
                    $p = array($p);
                }
                foreach ($p as $key => $value) {
                    if (is_array($value) && !empty($value)) {
                        foreach ($value as $kk => $vv) {
                            $this->_param[$handle] .= @implode(', ', $vv) . ',';
                        }
                    } else {
                        $this->_param[$handle] = @implode(', ', $p);
                    }
                }
                $this->_param[$handle] = trim($this->_param[$handle], ',');
            }
        }
        ####
        # Delegate: FrontendParamsPostResolve
        # Description: Access to the resolved param pool, including additional parameters provided by Data Source outputs
        # Global: Yes
        $this->ExtensionManager->notifyMembers('FrontendParamsPostResolve', '/frontend/', array('params' => $this->_param));
        ## TODO: Add delegate for adding/removing items in the params
        $xsl = '<?xml version="1.0" encoding="UTF-8"?>
<xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform">
	<xsl:import href="./workspace/pages/' . basename($page['filelocation']) . '"/>
</xsl:stylesheet>';
        $this->_Parent->Profiler->seed();
        $this->setXML($xml->generate(true, 0));
        $this->_Parent->Profiler->sample('XML Generation', PROFILE_LAP);
        $this->setXSL($xsl, false);
        $this->setRuntimeParam($this->_param);
        $this->_Parent->Profiler->seed($start);
        $this->_Parent->Profiler->sample('Page Built', PROFILE_LAP);
    }
Example #17
0
 /**
  * Executes the request using Curl unless it is not available
  * or this function has explicitly been told not by providing
  * the `Gateway::FORCE_SOCKET` constant as a parameter. The function
  * will apply all the options set using `curl_setopt` before
  * executing the request. Information about the transfer is
  * available using the `getInfoLast()` function. Should Curl not be
  * available, this function will fallback to using Sockets with `fsockopen`
  *
  * @see toolkit.Gateway#getInfoLast()
  * @param string $force_connection_method
  *  Only one valid parameter, `Gateway::FORCE_SOCKET`
  * @return string|boolean
  *  The result of the transfer as a string. If any errors occur during
  *  a socket request, false will be returned.
  */
 public function exec($force_connection_method = null)
 {
     if ($force_connection_method !== self::FORCE_SOCKET && self::isCurlAvailable()) {
         $ch = curl_init();
         curl_setopt($ch, CURLOPT_URL, sprintf("%s://%s%s%s", $this->_scheme, $this->_host, !is_null($this->_port) ? ':' . $this->_port : null, $this->_path));
         curl_setopt($ch, CURLOPT_HEADER, $this->_returnHeaders);
         curl_setopt($ch, CURLOPT_USERAGENT, $this->_agent);
         curl_setopt($ch, CURLOPT_PORT, $this->_port);
         curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
         curl_setopt($ch, CURLOPT_TIMEOUT, $this->_timeout);
         if (ini_get('safe_mode') == 0 && ini_get('open_basedir') == '') {
             curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
         }
         switch ($this->_method) {
             case 'POST':
                 curl_setopt($ch, CURLOPT_POST, 1);
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_postfields);
                 break;
             case 'PUT':
                 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT');
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_postfields);
                 $this->setopt('HTTPHEADER', array('Content-Length:' => strlen($this->_postfields)));
                 break;
             case 'DELETE':
                 curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
                 curl_setopt($ch, CURLOPT_POSTFIELDS, $this->_postfields);
                 break;
         }
         if (is_array($this->_headers) && !empty($this->_headers)) {
             curl_setopt($ch, CURLOPT_HTTPHEADER, $this->_headers);
         }
         if (is_array($this->_custom_opt) && !empty($this->_custom_opt)) {
             foreach ($this->_custom_opt as $opt => $value) {
                 curl_setopt($ch, $opt, $value);
             }
         }
         // Grab the result
         $result = curl_exec($ch);
         $this->_info_last = curl_getinfo($ch);
         $this->_info_last['curl_error'] = curl_errno($ch);
         // Close the connection
         curl_close($ch);
         return $result;
     }
     $start = precision_timer();
     if (is_null($this->_port)) {
         $this->_port = !is_null($this->_scheme) ? self::$ports[$this->_scheme] : 80;
     }
     // No CURL is available, use attempt to use normal sockets
     $handle = @fsockopen($this->_host, $this->_port, $errno, $errstr, $this->_timeout);
     if ($handle === false) {
         return false;
     }
     $query = $this->_method . ' ' . $this->_path . ' HTTP/1.1' . PHP_EOL;
     $query .= 'Host: ' . $this->_host . PHP_EOL;
     $query .= 'Content-type: ' . $this->_content_type . PHP_EOL;
     $query .= 'User-Agent: ' . $this->_agent . PHP_EOL;
     $query .= @implode(PHP_EOL, $this->_headers);
     $query .= 'Content-length: ' . strlen($this->_postfields) . PHP_EOL;
     $query .= 'Connection: close' . PHP_EOL . PHP_EOL;
     if (in_array($this->_method, array('PUT', 'POST', 'DELETE'))) {
         $query .= $this->_postfields;
     }
     // send request
     if (!@fwrite($handle, $query)) {
         return false;
     }
     stream_set_blocking($handle, false);
     stream_set_timeout($handle, $this->_timeout);
     $status = stream_get_meta_data($handle);
     $response = $dechunked = '';
     // get header
     while (!preg_match('/\\r\\n\\r\\n$/', $header) && !$status['timed_out']) {
         $header .= @fread($handle, 1);
         $status = stream_get_meta_data($handle);
     }
     $status = socket_get_status($handle);
     // Get rest of the page data
     while (!feof($handle) && !$status['timed_out']) {
         $response .= fread($handle, 4096);
         $status = stream_get_meta_data($handle);
     }
     @fclose($handle);
     $end = precision_timer('stop', $start);
     if (preg_match('/Transfer\\-Encoding:\\s+chunked\\r\\n/', $header)) {
         $fp = 0;
         do {
             $byte = '';
             $chunk_size = '';
             do {
                 $chunk_size .= $byte;
                 $byte = substr($response, $fp, 1);
                 $fp++;
             } while ($byte !== "\r" && $byte !== "\\r");
             $chunk_size = hexdec($chunk_size);
             // convert to real number
             if ($chunk_size == 0) {
                 break 1;
             }
             $fp++;
             $dechunked .= substr($response, $fp, $chunk_size);
             $fp += $chunk_size;
             $fp += 2;
         } while (true);
         $response = $dechunked;
     }
     // Following code emulates part of the function curl_getinfo()
     preg_match('/Content-Type:\\s*([^\\r\\n]+)/i', $header, $match);
     $content_type = $match[1];
     preg_match('/HTTP\\/\\d+.\\d+\\s+(\\d+)/i', $header, $match);
     $status = $match[1];
     $this->_info_last = array('url' => $this->_url, 'content_type' => $content_type, 'http_code' => (int) $status, 'total_time' => $end);
     return ($this->_returnHeaders ? $header : null) . $response;
 }
Example #18
0
 function seed($time = NULL)
 {
     $this->_seed = $time ? $time : precision_timer();
 }