/** * "Smart" Escape String * * Escapes data based on type * * @param string $str * @return mixed */ public function escape($str) { if (Core::isPHP('5.4.4') && (is_string($str) or is_object($str) && method_exists($str, '__toString'))) { return pg_escape_literal($this->conn_id, $str); } elseif (is_bool($str)) { return $str ? 'TRUE' : 'FALSE'; } return parent::escape($str); }
/** * Set Cache Directory Path * * @param string $path Path to the cache directory * @return bool */ public function check_path($path = '') { $path = $path === '' ? Core::$tempDir . DS . 'Database' : $path; // Add a trailing slash to the path if needed $path = realpath($path) ? rtrim(realpath($path), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR : rtrim($path, '/') . '/'; if (!is_dir($path)) { if (!mkdir($path, 0777, false)) { Logger::logDebug('DB cache path error: ' . $path); // If the path is wrong we'll turn off caching return $this->db->cache_off(); } } if (!Core::isReallyWritable($path)) { Logger::logDebug('DB cache dir not writable: ' . $path); // If the path is not really writable we'll turn off caching return $this->db->cache_off(); } $this->db->cachedir = $path; return TRUE; }
/** * Create the container which holds FuzeWorks. * * Due to the static nature of FuzeWorks, this is not yet possible. * When issue #101 is completed, this should be resolved. * * @return void */ public function createContainer() { // First set all the directories Core::$appDir = $this->parameters['appDir']; Core::$wwwDir = $this->parameters['wwwDir']; Core::$tempDir = $this->parameters['tempDir']; Core::$logDir = $this->parameters['logDir']; // Then set debug mode if ($this->parameters['debugMode']) { define('ENVIRONMENT', 'DEVELOPMENT'); } else { define('ENVIRONMENT', 'PRODUCTION'); } // And enable Tracy Debugger if (class_exists('Tracy\\Debugger', true)) { Debugger::enable(!$this->parameters['debugMode'], realpath($this->parameters['logDir'])); Logger::$useTracy = true; } // Then load the framework Core::init(); }
/** * Database connection * * @param bool $persistent * @return object */ public function db_connect($persistent = FALSE) { /* Prior to PHP 5.3.6, even if the charset was supplied in the DSN * on connect - it was ignored. This is a work-around for the issue. * * Reference: http://www.php.net/manual/en/ref.pdo-mysql.connection.php */ if (!Core::isPHP('5.3.6') && !empty($this->char_set)) { $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET NAMES ' . $this->char_set . (empty($this->dbcollat) ? '' : ' COLLATE ' . $this->dbcollat); } if (isset($this->stricton)) { if ($this->stricton) { $sql = 'CONCAT(@@sql_mode, ",", "STRICT_ALL_TABLES")'; } else { $sql = 'REPLACE(REPLACE(REPLACE(REPLACE(REPLACE(REPLACE( @@sql_mode, "STRICT_ALL_TABLES,", ""), ",STRICT_ALL_TABLES", ""), "STRICT_ALL_TABLES", ""), "STRICT_TRANS_TABLES,", ""), ",STRICT_TRANS_TABLES", ""), "STRICT_TRANS_TABLES", "")'; } if (!empty($sql)) { if (empty($this->options[PDO::MYSQL_ATTR_INIT_COMMAND])) { $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] = 'SET SESSION sql_mode = ' . $sql; } else { $this->options[PDO::MYSQL_ATTR_INIT_COMMAND] .= ', @@session.sql_mode = ' . $sql; } } } if ($this->compress === TRUE) { $this->options[PDO::MYSQL_ATTR_COMPRESS] = TRUE; } // SSL support was added to PDO_MYSQL in PHP 5.3.7 if (is_array($this->encrypt) && Core::isPHP('5.3.7')) { $ssl = array(); empty($this->encrypt['ssl_key']) or $ssl[PDO::MYSQL_ATTR_SSL_KEY] = $this->encrypt['ssl_key']; empty($this->encrypt['ssl_cert']) or $ssl[PDO::MYSQL_ATTR_SSL_CERT] = $this->encrypt['ssl_cert']; empty($this->encrypt['ssl_ca']) or $ssl[PDO::MYSQL_ATTR_SSL_CA] = $this->encrypt['ssl_ca']; empty($this->encrypt['ssl_capath']) or $ssl[PDO::MYSQL_ATTR_SSL_CAPATH] = $this->encrypt['ssl_capath']; empty($this->encrypt['ssl_cipher']) or $ssl[PDO::MYSQL_ATTR_SSL_CIPHER] = $this->encrypt['ssl_cipher']; // DO NOT use array_merge() here! // It re-indexes numeric keys and the PDO_MYSQL_ATTR_SSL_* constants are integers. empty($ssl) or $this->options += $ssl; } // Prior to version 5.7.3, MySQL silently downgrades to an unencrypted connection if SSL setup fails if (($pdo = parent::db_connect($persistent)) !== FALSE && !empty($ssl) && version_compare($pdo->getAttribute(PDO::ATTR_CLIENT_VERSION), '5.7.3', '<=') && empty($pdo->query("SHOW STATUS LIKE 'ssl_cipher'")->fetchObject()->Value)) { $message = 'PDO_MYSQL was configured for an SSL connection, but got an unencrypted connection instead!'; Logger::logError($message); return $this->db->db_debug ? $this->db->display_error($message, '', TRUE) : FALSE; } return $pdo; }
/** * Begin Transaction * * @return bool */ protected function _trans_begin() { $this->commit_mode = Core::isPHP('5.3.2') ? OCI_NO_AUTO_COMMIT : OCI_DEFAULT; return TRUE; }
/** * Error * * Returns an array containing code and message of the last * database error that has occurred. * * @return array */ public function error() { if (!empty($this->_mysqli->connect_errno)) { return array('code' => $this->_mysqli->connect_errno, 'message' => Core::isPHP('5.2.9') ? $this->_mysqli->connect_error : mysqli_connect_error()); } return array('code' => $this->conn_id->errno, 'message' => $this->conn_id->error); }
/** * Class constructor * * @return void */ public function __construct() { $this->config = Config::get('routing'); // Determine the base_url if (empty(Config::get('main')->base_url)) { if (isset($_SERVER['SERVER_ADDR'])) { if (strpos($_SERVER['SERVER_ADDR'], ':') !== FALSE) { $server_addr = '[' . $_SERVER['SERVER_ADDR'] . ']'; } else { $server_addr = $_SERVER['SERVER_ADDR']; } $base_url = (Core::isHttps() ? 'https' : 'http') . '://' . $server_addr . substr($_SERVER['SCRIPT_NAME'], 0, strpos($_SERVER['SCRIPT_NAME'], basename($_SERVER['SCRIPT_FILENAME']))); } else { $base_url = 'http://localhost/'; } Config::get('main')->base_url = $base_url; } // If query strings are enabled, we don't need to parse any segments. // However, they don't make sense under CLI. if (Core::isCli() or $this->config->enable_query_strings !== TRUE) { $this->_permitted_uri_chars = $this->config->permitted_uri_chars; // If it's a CLI request, ignore the configuration if (Core::isCli()) { $uri = $this->_parse_argv(); } else { $protocol = $this->config->uri_protocol; empty($protocol) && ($protocol = 'REQUEST_URI'); switch ($protocol) { case 'AUTO': // For BC purposes only // For BC purposes only case 'REQUEST_URI': $uri = $this->_parse_request_uri(); break; case 'QUERY_STRING': $uri = $this->_parse_query_string(); break; case 'PATH_INFO': default: $uri = isset($_SERVER[$protocol]) ? $_SERVER[$protocol] : $this->_parse_request_uri(); break; } } $this->_set_uri_string($uri); } }
/** * HTML Entities Decode * * A replacement for html_entity_decode() * * The reason we are not using html_entity_decode() by itself is because * while it is not technically correct to leave out the semicolon * at the end of an entity most browsers will still interpret the entity * correctly. html_entity_decode() does not convert entities without * semicolons, so we are left with our own little solution here. Bummer. * * @link http://php.net/html-entity-decode * * @param string $str Input * @param string $charset Character set * @return string */ public function entity_decode($str, $charset = NULL) { if (strpos($str, '&') === FALSE) { return $str; } static $_entities; isset($charset) or $charset = $this->charset; $flag = Core::isPHP('5.4') ? ENT_COMPAT | ENT_HTML5 : ENT_COMPAT; do { $str_compare = $str; // Decode standard entities, avoiding false positives if (preg_match_all('/&[a-z]{2,}(?![a-z;])/i', $str, $matches)) { if (!isset($_entities)) { $_entities = array_map('strtolower', Core::isPHP('5.3.4') ? get_html_translation_table(HTML_ENTITIES, $flag, $charset) : get_html_translation_table(HTML_ENTITIES, $flag)); // If we're not on PHP 5.4+, add the possibly dangerous HTML 5 // entities to the array manually if ($flag === ENT_COMPAT) { $_entities[':'] = ':'; $_entities['('] = '('; $_entities[')'] = ')'; $_entities["\n"] = '&newline;'; $_entities["\t"] = '&tab;'; } } $replace = array(); $matches = array_unique(array_map('strtolower', $matches[0])); foreach ($matches as &$match) { if (($char = array_search($match . ';', $_entities, TRUE)) !== FALSE) { $replace[$match] = $char; } } $str = str_ireplace(array_keys($replace), array_values($replace), $str); } // Decode numeric & UTF16 two byte entities $str = html_entity_decode(preg_replace('/(&#(?:x0*[0-9a-f]{2,5}(?![0-9a-f;])|(?:0*\\d{2,4}(?![0-9;]))))/iS', '$1;', $str), $flag, $charset); } while ($str_compare !== $str); return $str; }
/** * Prep Quoted Printable * * Prepares string for Quoted-Printable Content-Transfer-Encoding * Refer to RFC 2045 http://www.ietf.org/rfc/rfc2045.txt * * @param string * @return string */ protected function _prep_quoted_printable($str) { // ASCII code numbers for "safe" characters that can always be // used literally, without encoding, as described in RFC 2049. // http://www.ietf.org/rfc/rfc2049.txt static $ascii_safe_chars = array(39, 40, 41, 43, 44, 45, 46, 47, 58, 61, 63, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122); // We are intentionally wrapping so mail servers will encode characters // properly and MUAs will behave, so {unwrap} must go! $str = str_replace(array('{unwrap}', '{/unwrap}'), '', $str); // RFC 2045 specifies CRLF as "\r\n". // However, many developers choose to override that and violate // the RFC rules due to (apparently) a bug in MS Exchange, // which only works with "\n". if ($this->crlf === "\r\n") { if (Core::isPHP('5.3')) { return quoted_printable_encode($str); } elseif (function_exists('imap_8bit')) { return imap_8bit($str); } } // Reduce multiple spaces & remove nulls $str = preg_replace(array('| +|', '/\\x00+/'), array(' ', ''), $str); // Standardize newlines if (strpos($str, "\r") !== FALSE) { $str = str_replace(array("\r\n", "\r"), "\n", $str); } $escape = '='; $output = ''; foreach (explode("\n", $str) as $line) { $length = strlen($line); $temp = ''; // Loop through each character in the line to add soft-wrap // characters at the end of a line " =\r\n" and add the newly // processed line(s) to the output (see comment on $crlf class property) for ($i = 0; $i < $length; $i++) { // Grab the next character $char = $line[$i]; $ascii = ord($char); // Convert spaces and tabs but only if it's the end of the line if ($ascii === 32 or $ascii === 9) { if ($i === $length - 1) { $char = $escape . sprintf('%02s', dechex($ascii)); } } elseif ($ascii === 61) { $char = $escape . strtoupper(sprintf('%02s', dechex($ascii))); // =3D } elseif (!in_array($ascii, $ascii_safe_chars, TRUE)) { $char = $escape . strtoupper(sprintf('%02s', dechex($ascii))); } // If we're at the character limit, add the line to the output, // reset our temp variable, and keep on chuggin' if (strlen($temp) + strlen($char) >= 76) { $output .= $temp . $escape . $this->crlf; $temp = ''; } // Add the character to our temporary line $temp .= $char; } // Add our completed line to the output $output .= $temp . $this->crlf; } // get rid of extra CRLF tacked onto the end return substr($output, 0, strlen($this->crlf) * -1); }
/** * Class constructor * * @param array $params Configuration parameters * @return void */ public function __construct(array $params = array()) { Logger::newLevel('Initializing Encryption Library'); $this->_drivers = array('mcrypt' => defined('MCRYPT_DEV_URANDOM'), 'openssl' => Core::isPHP('5.3.3') && extension_loaded('openssl')); if (!$this->_drivers['mcrypt'] && !$this->_drivers['openssl']) { throw new LibraryException('Encryption: Unable to find an available encryption driver.', 1); } isset(self::$func_override) or self::$func_override = extension_loaded('mbstring') && ini_get('mbstring.func_override'); $this->initialize($params); if (!isset($this->_key) && self::strlen($key = Config::get('encryption')->encryption_key) > 0) { $this->_key = $key; } Logger::log('Encryption Class Initialized'); Logger::stopLevel(); }