/fastpage/lib/fastpage.php
PHP | 3412 lines | 1755 code | 443 blank | 1214 comment | 435 complexity | 3843cee3f4221c92b69b0ff3ddc27fc0 MD5 | raw file
Possible License(s): LGPL-2.1
Large files files are truncated, but you can click here to view the full file
- <?php
- /**
- * FastPage
- *
- * Licensed under the MIT License
- *
- * @copyright Copyright 2011, ideaman's Inc. (http://www.ideamans.com)
- * @license MIT License (http://www.opensource.org/licenses/mit-license.php)
- */
- /**
- * Version.
- */
- define( 'FASTPAGE_VERSION', '1.0.0 RC4' );
- /**
- * Error constant for profiling.
- */
- define( 'E_FP_PROFILE', 0x00 );
- /**
- * A class gathering utility static functions.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideaman's Inc.
- */
- class FastPage_Util {
- /**
- * Time units.
- */
- const minute = 60;
- const hour = 3600;
- const day = 86400;
- const week = 604800;
- const month = 2592000;
- const year = 31536000;
- /**
- * Aliases of server variables.
- */
- public static $server_aliases = array(
- 'HTTP_HOST' => array( 'HTTP_HOST', 'SERVER_NAME' ),
- 'SCRIPT_NAME' => array( 'SCRIPT_NAME', 'PHP_SELF' ),
- );
- /**
- * Returns millisecond time.
- *
- * @return float Current epoc time in millisecond.
- */
- public static function millisec() {
- return function_exists('microtime')? microtime(true) * 1000.0: time() / 1000.0;
- }
- /**
- * Returns memory_usege safety.
- *
- * @return integer Memory usage.
- */
- public static function memory_usage() {
- return function_exists('memory_get_usage')? memory_get_usage(): 0;
- }
- /**
- * Splits path like url or directory, and resolves periods.
- *
- * @param string $path A target path as string.
- * @param string $separator Separator of target such as / or DIRECTORY_SEPARATOR. The default is '/'.
- * @return array Partials of the path as an array.
- */
- public static function split_path( $path, $separator = '/' ) {
- // Split path with separator.
- if ( strlen($separator) == 1 ) {
- $paths = explode( $separator, $path );
- } else {
- $regex = '![' . preg_quote($separator) . ']!';
- $paths = preg_split( $regex, $path );
- }
- $result = array( array_shift($paths) );
- // Join path partials.
- $count = count($paths);
- for ( $i = 0; $i < $count; $i++ ) {
- $partial = $paths[$i];
- if ( $partial == '..' && $i != 0 ) {
- // Back to the parent.
- array_pop( $result );
- } else if ( !$partial && $i > 0 && $i < $count - 1 ) {
- // Skip a blank not the first or the last.
- } else if ( $partial == '.' ) {
- // Skip as same directory.
- } else {
- // Push to the last.
- $result []= $partial;
- }
- }
- return $result;
- }
- /**
- * Catenate some path partials and normalize it.
- *
- * @param variable $PARTIALS Partials of path as variable numbers arguments.
- * @return string Catenated path.
- */
- public static function cat_path( ) {
- if ( func_num_args() < 1 ) return '';
- // Expand args.
- $args = func_get_args();
- $paths = array();
- foreach ( $args as $arg ) {
- if ( is_array($arg) ) {
- $paths = array_merge( $paths, $arg );
- } else if ( is_string($arg) ) {
- $paths []= $arg;
- }
- }
- $path = join( DIRECTORY_SEPARATOR, $paths );
- // Path maybe contains mixed separators in windows.
- $separator = DIRECTORY_SEPARATOR;
- if ( $separator != '/' ) $separator .= '/';
- $partials = self::split_path( $path, $separator );
- return join( DIRECTORY_SEPARATOR, $partials );
- }
- /**
- * Ensure include_path.
- *
- * @param string $path Path to set include path.
- */
- public static function ensure_include_path( $path ) {
- // Check if include_path has the path.
- $include_path = ini_get('include_path');
- $include_paths = explode( PATH_SEPARATOR, $include_path );
- // Append if the path does not exists.
- if ( false === array_search( $path, $include_paths ) ) {
- $include_path .= PATH_SEPARATOR . $path;
- ini_set( 'include_path', $include_path );
- }
- }
- /**
- * Enclose string with quotes.
- *
- * @param string $value A string to quote.
- * @param string $quotation Optional. Character of quotation. Default is double quotation.
- */
- public static function quote( $value, $quotation = '"' ) {
- if ( !isset($value) ) $value = '';
- return $quotation . $value . $quotation;
- }
- /**
- * Gets the Etag(entity tag) of a file formated like Apache.
- *
- * @param string $path A path of file to get Etag.
- * @param boolean $quote If true, double-quote the result.
- * @return string The Etag of the file.
- */
- public static function file_etag( $path, $quote = true ) {
- if ( file_exists($path) && false !== ( $stats = stat($path) ) ) {
- $etag = sprintf('%x-%x-%x', $stats['ino'], $stats['size'], $stats['mtime'] * 1000000 );
- if ( $quote ) $etag = self::quote( $etag );
- return $etag;
- }
- return null;
- }
- /**
- * Strips single and double quotes at the head and at the last.
- *
- * @param string $value A string to remove quotation.
- * @return string The string removed quotation.
- */
- public static function strip_quotes( $value ) {
- // FIXME: Shoud return blank string ''?
- if ( !$value ) return $value;
- // Remove the first quote.
- $first = substr( $value, 0, 1 );
- if ( $first == '"' || $first == "'" ) {
- $value = substr( $value, 1 );
- } else {
- $first == '';
- }
- // Remove the last quote.
- $last = substr( $value, -1, 1 );
- if ( $last == $first || ( !$first && ( $last == '"' || $last == "'" ) ) ) {
- $value = substr( $value, 0, -1 );
- }
- return $value;
- }
- /**
- * Strip URL parameters.
- *
- * @param string $url A URL to remove parameters.
- * @return string The URL removed parameters.
- */
- public static function strip_url_params( $url ) {
- if ( !$url ) return $url;
- $url = preg_replace( '![\?#].*!', '', $url );
- return $url;
- }
- /**
- * Get server variable by a key or some keys.
- *
- * @param mixed $name A key string or an array of keys.
- * @param mixed $default The default value if server variable not found.
- * @return mixed The server value. Return null if not found.
- */
- public static function server( $name, $default = null ) {
- // Search alias.
- if ( is_string($name) && isset(self::$server_aliases[$name]) ) {
- $name = self::$server_aliases[$name];
- }
- if ( is_array($name) ) {
- foreach ( $name as $var ) {
- if ( isset($_SERVER[$var]) && $_SERVER[$var] ) {
- return $_SERVER[$var];
- }
- }
- } else if ( isset($_SERVER[$name]) && $_SERVER[$name] ) {
- return $_SERVER[$name];
- }
- return $default;
- }
- /**
- * Match IP address with patterns.
- *
- * @param mixed $patterns IP address patterns as a string or an array.
- * @param string $ip IP address to match.
- * @param boolean $include_self Add IP address of myself.
- * @return boolean Matched or not.
- */
- public static function match_ips( $patterns, $ip, $include_self = true ) {
- // Normalize patterns to an array.
- if ( !is_array($patterns) ) {
- $patterns = preg_split( '!\\s*,\\s*!', $patterns );
- }
- // Add myself to patterns.
- if ( $include_self ) {
- $patterns []= '127.0.0.1';
- if ( $server_addr = self::server('SERVER_ADDR') ) {
- $patterns []= $server_addr;
- }
- }
- // Check each pattern.
- foreach ( $patterns as $p ) {
- // Prefix matching.
- if ( !$p ) continue;
- if ( $p == substr( $ip, 0, strlen($p) ) ) {
- return true;
- }
- }
- return false;
- }
- /**
- * Unserialize as object of a class.
- *
- * @param string $serialized Serialized string.
- * @param string $class Class required.
- * @return mixed The unserialized value.
- */
- public static function unserialize_as( &$value, $class = null ) {
- if ( !$value ) return null;
- $result = @unserialize($value);
- if ( $class ) {
- if ( !is_a( $result, $class ) ) {
- return null;
- }
- }
- return $result;
- }
- }
- /**
- * Exception class.
- *
- * Currently almost empty and not to be used.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga
- */
- class FastPage_Exception extends Exception { }
- /**
- * Base object class supports basic accessors.
- *
- * Properties stored in $_vars member.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideaman's Inc.
- */
- class FastPage_Object {
- /**
- * Members store.
- */
- protected $_vars = array();
- /**
- * Constructor.
- *
- * @param array $defaults Default values of object.
- */
- public function __construct( $defaults = null ) {
- if ( isset($defaults) && is_array($defaults) ) {
- $this->_vars = $defaults;
- }
- }
- /**
- * Property getter.
- *
- * Implimentatin of getter. Get named property from $_vars member.
- *
- * @param string $name Name of the property.
- * @return mixed The property value. If not defined, return null.
- */
- public function __get( $name ) {
- if ( isset($this->_vars[$name]) ) {
- return $this->_vars[$name];
- }
- return null;
- }
- /**
- * Property setter.
- *
- * Implimentation of setter. Set named property to $_vars member. Not to be used directory.
- *
- * @param string $name Name of the property.
- * @param mixed $value Value of the property.
- * @return mixed The value echoed back.
- */
- public function __set( $name, $value ) {
- $this->_vars[$name] = $value;
- return $value;
- }
- /**
- * Dictionary accessor.
- *
- * Implimentation of dictionary type accessor.
- * Get and set dictionary type named property.
- * Usually to be wrapped as other function.
- *
- * @param string $namespace Name of the dictionary.
- * @param string $name Key of the dictionary value.
- * @param mixed $value The dictionary value to set. If you set null, this function behaves as a getter. Default is null.
- * @return mixed The dictionary value. No match found, return null.
- */
- public function __dictionary( $namespace, $name, $value = null ) {
- if ( isset($value) ) {
- // As a setter.
- $this->_vars[$namespace][$name] = $value;
- return $value;
- }
- // As a getter.
- if ( isset($this->_vars[$namespace][$name]) ) {
- return $this->_vars[$namespace][$name];
- }
- return null;
- }
- /**
- * Name keys of all properties.
- *
- * @return Array Names of all properties as an array.
- */
- public function keys() {
- return array_keys( $this->_vars );
- }
- /**
- * Get all properties as an array.
- *
- * @return Array Properties of the object.
- */
- public function to_array() {
- return $_vars;
- }
- /**
- * Sets values from an array or another object.
- *
- * @param mixed $values An array of properties or an another obejct.
- * @param boolean $override To be overridden each properties already exists. Default is true.
- */
- public function merge_values( $values, $override = true ) {
- if ( is_array($values) ) {
- foreach ( $values as $name => $value ) {
- if ( $override || !isset($this->_vars[$name]) ) {
- $this->_vars[$name] = $value;
- }
- }
- } else if ( is_object($values) && is_a( $values, 'FastPage_Object' ) ) {
- $this->merge_values( $values->to_array(), $override );
- }
- }
- }
- /**
- * Log record.
- *
- * Currently, a simple class of basic object.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var integer $timestamp Timestamp in milli second.
- * @var integer $memory_usage Memory usage.
- * @var integer $level Lovel of log in PHP constant like E_ERROR.
- * @var integer $message The log message human readable.
- */
- class FastPage_LogRecord extends FastPage_Object { }
- /**
- * Profile record.
- *
- * Current, a simple class of basic object.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var string $name Process name.
- * @var integer $start Timestamp started in milli second.
- * @var integer $end Timestamp ended in milli second.
- * @var integer $duration Duration in milli second.
- */
- class FastPage_Profile extends FastPage_Object { }
- /**
- * Debugger.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var boolean $enabled Enabled debugging.
- * @var array $logs Log records.
- * @var integer $error_message_type Message type to call error_log on error record added.
- * @var string $error_destination Destination to call error_log on error record added.
- * @var float $start Starting timestamp.
- * @var float $last Last logging timestamp.
- * @var FastPage_LogRecord $last Last log record.
- * @var float $debugging_time Total debugging time.
- * @var integer $debbuggin_memory_usage Total debugging memory usage.
- * @var integer $debugging_in_nest Nesting depth of debugging time.
- */
- class FastPage_Debug extends FastPage_Object {
- public $logs = array();
- public $start = 0.0;
- public $last = 0.0;
- public $debugging_time = 0.0;
- public $debugging_memory_usage = 0;
- public $debugging_in_nest = 0;
- /**
- * Singleton instance.
- */
- public static $instance;
- /**
- * Numeric log members.
- *
- * These members will be computed delta and sum.
- */
- public static $numeric_log_members = array( 'timestamp', 'memory_usage', 'memory_peak_usage' );
- /**
- * Get singleton instance.
- *
- * @return FastPage_Debug The instance.
- */
- public static function instance() {
- return self::$instance;
- }
- /**
- * Start debug.
- *
- * @param integer $message_type Optional. Passed to error_log function.
- * @param integer $destination Optional. Passed to error_log function.
- * @return boolean Current debug mode.
- */
- public static function start( $message_type = 0, $destination = '' ) {
- // Starting time. If set the time, set global $FASTPAGE_START;
- $time = FastPage_Util::millisec();
- global $FASTPAGE_START;
- if ( $FASTPAGE_START ) $time = $FASTPAGE_START;
- $debug = new self;
- $in = $debug->debug_in();
- $debug->start = $debug->last = $time;
- $debug->error_message_type = $message_type;
- $debug->error_destination = $destination;
- // Enabled debug.
- $debug->enabled = true;
- // Singleton.
- self::$instance = $debug;
- $debug->debug_out($in);
- return $debug;
- }
- /**
- * Start to debugging time.
- *
- * @return array Current time in millisecond and memory usage.
- */
- public function debug_in() {
- if ( !$this->enabled ) return null;
- $this->debugging_in_nest++;
- return array( FastPage_Util::millisec(), FastPage_Util::memory_usage() );
- }
- /**
- * Stop to debugging time.
- *
- * @param array $in Time and memory usage to debug in.
- */
- public function debug_out( $in ) {
- if ( !is_array($in) ) return;
- $this->debugging_in_nest--;
- if ( $this->debugging_in_nest == 0 ) {
- $out = FastPage_Util::millisec();
- $this->debugging_time += ( $out - $in[0] );
- $out = FastPage_Util::memory_usage();
- $this->debugging_memory_usage += ( $out - $in[1] );
- }
- }
- /**
- * Add new log record.
- *
- * @param FastPage $fastpage FastPage instance.
- * @param integer $level Log level in PHP constants.
- * @param string $message Log message human readable.
- * @param mixed $hint Hint value for the log record.
- */
- public function add_log( $fastpage, $level, $message, $hint = null ) {
- // Not in debugging, do nothing.
- if ( !$this->enabled ) return;
- $in = $this->debug_in();
- // Timestamp and usage.
- $msec = FastPage_Util::millisec();
- $usage = FastPage_Util::memory_usage();
- $peak_usage = function_exists('memory_get_peak_usage')? memory_get_peak_usage(true): $usage;
- // Log record.
- $record = new FastPage_LogRecord;
- $record->timestamp = $msec - $this->start;
- $record->memory_usage = $usage;
- $record->memory_peak_usage = $peak_usage;
- $record->level = $level;
- $record->message = $message;
- $record->hint = $hint;
- // Run callbacks if FastPage instance passed.
- if ( isset($fastpage) ) {
- $fastpage->run_callbacks( 'debug_log', FastPage_Callback::all, $record );
- }
- $this->last = $record;
- $this->logs []= $record;
- // Pass through to error_log() if E_ERROR or E_USER_ERROR.
- if ( $level | E_ERROR | E_USER_ERROR ) {
- error_log( $message, $this->error_message_type, $this->error_destination );
- }
- $this->debug_out($in);
- return $record;
- }
- /**
- * Add new log record (short hand to singleton instance add_log).
- */
- public static function log( $fastpage, $level, $message, $hint = null ) {
- if ( !self::$instance ) return;
- self::$instance->add_log( $fastpage, $level, $message, $hint );
- }
- /**
- * Merge another debug for forking.
- *
- * @param FastPage_Debug $debug Debug object to merge.
- */
- public function merge( $debug ) {
- $in = $this->debug_in();
- // Make profiles unique.
- $profiles = array();
- foreach ( $this->logs as $log ) {
- if ( $log->level == E_FP_PROFILE ) {
- $profiles[$log->message] = true;
- }
- }
- foreach ( $debug->logs as $log ) {
- if ( $log->level == E_FP_PROFILE ) {
- if ( !isset($profiles[$log->message]) ) {
- $this->logs []= $log;
- }
- } else {
- $this->logs []= $log;
- }
- }
- // Sum debugging time.
- $this->debugging_time += $debug->debugging_time;
- $this->debug_out($in);
- }
- /**
- * Get log records.
- *
- * @param $mask Mask to filter log level like E_ALL.
- * @return array Log records. If not started logging, return empty array.
- */
- public function log_records( $mask = E_ALL ) {
- // If logging not started, do nothing.
- if ( !$this->enabled ) return array();
- $in = $this->debug_in();
- $records = array();
- $lasts = array();
- $sums = array();
- foreach ( $this->logs as $record ) {
- if ( $record->level & $mask ) {
- // Get delta and sum of timestamp and memory usage.
- foreach ( self::$numeric_log_members as $prop ) {
- $delta = 'delta_' . $prop;
- $sum = 'sum_' . $prop;
- $record->$delta = isset($lasts[$prop])? $record->$prop - $lasts[$prop]: 0;
- $lasts[$prop] = $record->$prop;
- $sums[$prop] = isset($sums[$prop])? $sums[$prop] + $record->$delta: $record->$delta;
- $record->$sum = $sums[$prop];
- }
- $records []= $record;
- }
- }
- $this->debug_out($in);
- return $records;
- }
- /**
- * Get profiling records.
- *
- * @return array Profiling results.
- */
- public function log_profiles() {
- // If logging not started, do nothing.
- if ( !$this->enabled ) return array();
- $in = $this->debug_in();
- // Gather profiles.
- $profiles = array();
- $last = $this->last;
- foreach ( $this->logs as $log ) {
- if ( $log->level != E_FP_PROFILE ) continue;
- if ( isset($profiles[$log->message]) ) {
- // Update profile result.
- $profile = $profiles[$log->message];
- foreach ( self::$numeric_log_members as $prop ) {
- $to = $prop . '_to';
- $from = $prop . '_from';
- $delta = 'delta_' . $prop;
- $profile->$to = $log->$prop;
- $profile->$delta = $profile->$to - $profile->$from;
- }
- } else {
- // New profile result.
- $profile = new FastPage_Profile;
- $profile->name = $log->message;
- foreach ( self::$numeric_log_members as $prop ) {
- $to = $prop . '_to';
- $from = $prop . '_from';
- $delta = 'delta_' . $prop;
- $profile->$from = $log->$prop;
- $profile->$to = $last->$prop;
- $profile->$delta = $profile->$to - $profile->$from;
- }
- $profiles[$log->message] = $profile;
- }
- }
- $this->debug_out($in);
- return $profiles;
- }
- }
- /**
- * Text filters.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- */
- class FastPage_TextFilters extends FastPage_Object {
- /**
- * Filter definitions.
- */
- protected $filters = array();
- /**
- * Add a new condition to filters.
- *
- * @param string $condition Condition string usable wildcard(*) and regular expressions starts with ~.
- * @param boolean $ignore_case Set true, if ignore charactors case.
- */
- public function add( $condition, $ignore_case = false, $options = null ) {
- $args = array( $condition, $ignore_case, $options );
- $this->filters []= $args;
- }
- /**
- * Test if match a text for each filters.
- *
- * @param string $text An string to test.
- * @return boolean True, if one of filters is matched at least.
- */
- public function match( $text ) {
- // Has no filters, return false.
- if ( count($this->filters) < 1 ) return false;
- // Evaluate conditions.
- foreach ( $this->filters as $array ) {
- // Filter properties.
- $filter = $array[0];
- if ( !isset($filter) ) continue;
- $ignore_case = $array[1];
- $options = $array[2];
- // Convert to regular expression.
- $regex = null;
- if ( substr( $filter, 0, 1 ) == '~' ) {
- // By regular expression.
- $regex = substr( $filter, 1 );
- } else if ( strchr( $filter, '*' ) !== false ) {
- // Include wildcard.
- $regex = str_replace( '*', '(.*?)', $filter );
- } else if ( $options ) {
- // Has options.
- $regex = '^' . preg_quote($filter) . '$';
- }
- if ( $regex ) {
- // Regex compare.
- if ( !isset($options) ) $options = '';
- if ( $ignore_case ) $options .= 'i';
- // Escape.
- $regex = str_replace( '!', '\!', $regex );
- // Regular expression matched?
- $regex = '!' . $regex . '!' . $options;
- if ( preg_match( $regex, $text ) ) return true;
- } else if ( $ignore_case ) {
- if ( strtolower($text) == strtolower($filter) ) return true;
- } else {
- // String compare.
- if ( $text == $filter ) return true;
- }
- }
- // Return false, if no match.
- return false;
- }
- }
- /**
- * Base of a helper class.
- *
- * Helper classes has a reference of FastPage instance to access FastPage configurations.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideamans's Inc.
- */
- class FastPage_Helper extends FastPage_Object {
- /**
- * Constructor.
- *
- * @param FastPage $fastpage FastPage instance.
- */
- public function __construct( $fastpage ) {
- parent::__construct();
- // Store FastPage instance.
- $this->fastpage = $fastpage;
- }
- }
- /**
- * Plugin base class.
- *
- * Currently just an alias of FastPage_Helper.
- *
- * @var string $version Version of the plugin.
- */
- class FastPage_Plugin extends FastPage_Helper {
- /**
- * Constructor.
- */
- public function __construct( $fastpage ) {
- parent::__construct($fastpage);
- $this->version = '[UNKNOWN]';
- }
- }
- /**
- * Tree structured configuration.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- */
- class FastPage_Config extends FastPage_Helper {
- /**
- * Child configs.
- */
- protected $sub_configs = array();
- /**
- * Parent config.
- */
- public $parent_config = null;
- /**
- * Get a sub config.
- *
- * @param string $name Name of sub config.
- * @return FastPage_Config Sub config object. If not exist, return new object.
- */
- public function sub( $name ) {
- if ( !isset($this->sub_configs[$name]) ) {
- $class = get_class($this);
- $this->sub_configs[$name] = new $class( $this->fastpage );
- $this->sub_configs[$name]->parent_config = $this;
- }
- return $this->sub_configs[$name];
- }
- /**
- * Undefined function behaves as dictionary.
- */
- public function __call( $name, $args ) {
- $count = count($args);
- $key = $count > 0? $args[0]: null;
- $value = $count > 1? $args[1]: null;
- if ( $key ) {
- return $this->__dictionary( $name, $key, $value );
- }
- }
- /**
- * Set default value.
- *
- * Update self value if not set yet.
- *
- * @param string $name Name of config value.
- * @param mixed $value Default value of the config.
- */
- public function _default( $name, $value ) {
- $current = $this->$name;
- if ( !isset($current) ) {
- $this->$name = $value;
- }
- }
- }
- /**
- * Simple HTTP client helper.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga
- * @var string $library HTTP client library: builtin, curl or http_request.
- */
- class FastPage_SimpleHTTP extends FastPage_Helper {
- /**
- * Get url content.
- *
- * Return null if failed.
- *
- * @param string $url URL to get.
- * @return string Response body.
- */
- public function get( $url ) {
- // Detect library.
- $config_lib = $this->fastpage->config('http')->library;
- $config_lib = $config_lib? strtolower($config_lib): 'builtin';
- $enabled = array();
- if ( ini_get('allow_url_fopen') ) {
- $enabled['builtin'] = 'builtin';
- }
- if ( function_exists('curl_init') ) {
- $enabled['curl'] = 'curl';
- }
- $enabled['http_request'] = 'http_request';
- $this->library = $library = $enabled[$config_lib]? $config_lib: array_shift($enabled);
- // Timeout.
- $timeout = $this->fastpage->config('http')->timeout;
- if ( !$timeout ) $timeout = 60;
- $result = null;
- try {
- if ( $library == 'builtin' ) {
- // Use builtin function.
- $context = stream_context_create( array(
- 'http' => array(
- 'timeout' => $timeout,
- 'header' => array( 'Accept-Encoding:' )
- )
- ) );
- $result = file_get_contents( $url, false, $context );
- } else if ( $library == 'curl' ) {
- // Use cURL.
- $ch = curl_init( $url );
- $opts = array(
- CURLOPT_HEADER => false,
- CURLOPT_RETURNTRANSFER => true,
- CURLOPT_BINARYTRANSFER => true,
- CURLOPT_FOLLOWLOCATION => true,
- CURLOPT_MAXREDIRS => 10,
- CURLOPT_SSL_VERIFYPEER => true,
- CURLOPT_CONNECTTIMEOUT => $timeout,
- CURLOPT_TIMEOUT => $timeout,
- CURLOPT_HTTPHEADER => array( 'Accept-Encoding:' )
- );
- // CURLOPT_MUTE maybe deprecated.
- if ( defined('CURLOPT_MUTE') ) $opts[CURLOPT_MUTE] = true;
- foreach ( $opts as $key => $value ) {
- curl_setopt( $ch, $key, $value );
- }
- $result = curl_exec($ch);
- curl_close($ch);
- } else {
- // Try to use Pear HTTP_Request.
- require_once('HTTP/Request.php');
- $opts = array(
- 'timeout' => $timeout,
- 'allowRedirects' => true,
- 'maxRedirects' => 10
- );
- $http = new HTTP_Request( $url, $opts );
- $http->removeHeader('accept-encoding');
- $res = $http->sendRequest();
- if ( !PEAR::isError($res) ) {
- $result = $http->getResponseBody();
- }
- }
- } catch ( Exception $ex ) {
- FastPage_Debug::log( $this->fastpage, E_USER_ERROR, "Simple HTTP get $url because: " . $ex->getMessage() );
- }
- return $result;
- }
- }
- /**
- * User agent helper.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var string $full_string Full user agent string.
- * @var boolean $data_uri_enabled If data URI schema is enabled on the user agent.
- */
- class FastPage_UserAgent extends FastPage_Helper {
- /**
- * Constructor.
- */
- public function __construct( $fastpage, $ua = null ) {
- parent::__construct($fastpage);
- if ( !isset($ua) ) {
- // Detect user agent.
- $ua = FastPage_Util::server( 'HTTP_USER_AGENT', '' );
- }
- // Default.
- $this->full_string = $ua;
- $this->data_uri_enabled = false;
- // Data URI scheme ability.
- // Supported on WebKit, Gecko, Opera and IE8+.
- if ( preg_match( '!WebKit|Gecko|Opera!i', $ua ) ) {
- $this->data_uri_enabled = true;
- } else if ( preg_match( '!MSIE ([0-9\.]+)!', $ua, $matches ) ) {
- $version = (float)$matches[1];
- if ( $version >= 8.0 ) {
- $this->data_uri_enabled = true;
- }
- }
- // Run callbacks.
- $fastpage->run_callbacks( 'parse_user_agent', FastPage_Callback::all, $this );
- // Logging.
- if ( !$this->data_uri_enabled ) {
- FastPage_Debug::log( $fastpage, E_USER_NOTICE, 'The use agent does not support Data URI scheme: ' . $ua );
- }
- }
- }
- /**
- * A helper class to parse and modify an HTML element simply.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideaman's Inc.
- */
- class FastPage_HTMLElement extends FastPage_Helper {
- public $_attribute = array();
- public $_attributes = null;
- // Common regular expressions.
- const attribute_regex_prefix = '!(?<=\\s';
- const attribute_regex_suffix = '=)(["\'])(.*?)(?=\\1|>)!i';
- const remove_attribute_regex_prefix = '!(?<=\\s)';
- const remove_attribute_regex_suffix = '=(["\'])(.*?)(\\1\\s*)!i';
- const attributes_regex = '!(?<=\\s)([^=]+)=(["\'])(.*?)(?=\\2|>)!i';
- /**
- * Constructor.
- *
- * @param FastPage $fastpage An instance of FastPage class.
- * @param string $fragment A source of HTML element fragment.
- */
- public function __construct( $fastpage, $fragment ) {
- parent::__construct($fastpage);
- // Initialize.
- $this->original = $this->html = $fragment;
- // Check format.
- if ( substr( $this->html, 0, 1 ) != '<' || substr( $this->html, -1, 1 ) != '>' ) {
- FastPage_Debug::log( $fastpage, E_USER_WARNING, 'Not a wellformed HTML element: ' . $this->html );
- throw new FastPage_Exception( 'Not a wellformed HTML element: ' . $this->html );
- }
- // Parse tag name.
- if ( preg_match( '!^</?([^\s]+)!', $this->html, $matches ) ) {
- $this->tag_name = $matches[1];
- }
- }
- /**
- * Gets values of an attribute.
- *
- * @param string $name Name of an attribute.
- * @param string $value Value of the attribute. If set null, this function behaves as a getter.
- * @return string Value of the attribute. If not found, returns null.
- */
- public function attribute($name, $value = null) {
- // Regulara expression to find an atribute.
- $regex = self::attribute_regex_prefix . preg_quote($name) . self::attribute_regex_suffix;
- if ( isset($value) ) {
- // Replace attribute value.
- $this->html = preg_replace( $regex, "\\1$value", $this->html, -1, $count );
- // Cache the result if replaced.
- if ( $count > 0 ) {
- $this->_attribute[$name] = $value;
- $this->_attributes = null;
- }
- } else {
- // Get attribute value.
- if ( !isset($this->_attribute[$name]) ) {
- // Not cached, find the value from HTML.
- if ( preg_match( $regex, $this->html, $matches ) ) {
- $this->_attribute[$name] = $matches[2];
- } else {
- // Not found, cache false as boolean.
- $this->_attribute[$name] = false;
- }
- }
- $value = $this->_attribute[$name];
- return $value !== false? $value: null;
- }
- }
- /**
- * Remove an attribute.
- *
- * @param string $name Name of an attribute to remove.
- */
- public function remove_attribute($name) {
- // Regulara expression to find an atribute.
- $regex = self::remove_attribute_regex_prefix . preg_quote($name) . self::remove_attribute_regex_suffix;
- $this->html = preg_replace( $regex, '', $this->html, -1, $count );
- // Cache the result if replaced.
- if ( $count > 0 ) {
- unset($this->_attribute[$name]);
- $this->_attributes = null;
- }
- }
- /**
- * Gets all attribute as an array.
- *
- * @return Attributes name and values as an array.
- */
- public function attributes() {
- if ( !isset($this->_attributes) ) {
- // Not cached, find with regular expression.
- $this->_attributes = array();
- if ( preg_match_all( self::attributes_regex, $this->html, $matches, PREG_SET_ORDER ) ) {
- foreach ( $matches as $match ) {
- $this->_attributes[$match[1]] = $match[3];
- }
- }
- }
- return $this->_attributes;
- }
- }
- /**
- * Cache helper.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var integer $default_expires Default second to expire cache.
- */
- class FastPage_Cache extends FastPage_Helper {
- protected $_cache = array();
- /**
- * Constructor.
- */
- public function __construct( $fastpage ) {
- parent::__construct($fastpage);
- $config = $this->fastpage->config('cache');
- // Max key length.
- $this->max_key_length = $config->max_key_length;
- if ( !isset($this->max_key_length) ) $this->max_key_length = 128;
- // Cache key normalization algorithm.
- $this->normalize_key_algorithm = $config->normalize_key_algorithm;
- if ( !isset($this->normalize_key_algorithm) ) $this->normalize_key_algorithm = 'md5';
- // Default expire.
- $this->default_expire = $config->default_expire;
- if ( !isset($this->default_expire) ) $this->default_expire = 60 * 60; // 1 hour
- }
- /**
- * Normalize cache key.
- *
- * Convert long key with md5 or sha1.
- *
- * @param string $raw_key Raw cache key.
- * @return string Normalized key.
- */
- public function normalize_key( $raw_key ) {
- if ( strlen($raw_key) > $this->max_key_length ) {
- $algorithm = $this->normalize_key_algorithm;
- if ( $algorithm != 'sha1' ) $algorithm = 'md5';
- $key = $algorithm($raw_key);
- } else {
- $key = $raw_key;
- }
- return $key;
- }
- /**
- * Check if exist key.
- *
- * @param string $namespace Namespace.
- * @param string $raw_key Cache key.
- * @return boolean True if exists key.
- */
- public function exist( $namespace, $raw_key ) {
- if ( !array_key_exists( $namespace, $this->_cache ) ) {
- return false;
- }
- // Check array.
- $key = $this->normalize_key($raw_key);
- return array_key_exists( $key, $this->_cache[$namespace] );
- }
- /**
- * Get cached value.
- *
- * * This is reference implementation not effective as cache.
- *
- * @param string $namespace Namespace of cache.
- * @param string $key Key of cache item.
- * @return mixed Cached value. If not cached, return null.
- */
- public function get( $namespace, $raw_key ) {
- // Convert a key.
- $key = $this->normalize_key($raw_key);
- // Search cached value.
- if ( isset($this->_cache[$namespace]) ) {
- if ( isset($this->_cache[$namespace][$key]) ) {
- $entry = $this->_cache[$namespace][$key];
- if ( $entry['expire'] > time() ) {
- return $entry['value'];
- } else {
- unset( $this->_cache[$namespace][$key] );
- }
- }
- }
- return null;
- }
- /**
- * Set cache value.
- *
- * * This is reference implementation not effective as cache.
- *
- * @param string $namespace Namespace of cache.
- * @param string $raw_key Key of cache entry.
- * @param mixed $value Value of cache entry.
- * @param integer $expire Second to expire the cache. If null, use default_expire.
- */
- public function set( $namespace, $raw_key, $value, $expire = null ) {
- // Expire.
- if ( !isset($expire) ) {
- $expire = $this->default_expire;
- }
- // Convert a key.
- $key = $this->normalize_key($raw_key);
- $this->_cache[$namespace][$key] = array( 'expire' => time() + $expire, 'value' => $value );
- }
- /**
- * Delete value.
- *
- * @param string $namespace Namespace.
- * @param string $raw_key Cache key.
- */
- public function delete( $namespace, $raw_key ) {
- if ( !isset($this->_cache[$namespace]) ) return;
- $key = $this->normalize_key($raw_key);
- unset( $this->_cache[$namespace][$key] );
- }
- /**
- * Flush all cache entries.
- *
- * * This is reference implementation not effective as cache.
- *
- * @param string $namespace Namespace of cache. If null, clear all cache.
- */
- public function flush( $namespace = null ) {
- if ( isset($namespace) ) {
- $this->_cache[$namespace] = array();
- } else {
- $this->_cache = array();
- }
- }
- /**
- * Purge expired cache.
- *
- * * This is reference implementation not effective as cache.
- *
- * @param string $namespace Namespace of cache. If null, purge all cache.
- */
- public function purge( $namespace = null ) {
- if ( isset($namespace) ) {
- if ( is_array($this->_cache[$namespace]) ) {
- $now = time();
- foreach ( $this->_cache[$namespace] as $key => $entry ) {
- if ( $entry['expire'] <= $now ) {
- unset( $this->_cache[$namespace][$key] );
- }
- }
- }
- } else {
- foreach ( $this->_cache as $ns => $caches ) {
- $this->purge( $ns );
- }
- }
- }
- }
- /**
- * File cache helper.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var string $extension An extension of cache file.
- */
- class FastPage_FileCache extends FastPage_Cache {
- protected $paths_to_ready = array();
- /**
- * Constructor.
- *
- * Check if ready to use directory.
- */
- public function __construct( $fastpage ) {
- parent::__construct($fastpage);
- $config = $this->fastpage->config('cache');
- // Cache dir.
- $this->cache_dir = $config->cache_dir;
- if ( !isset($this->cache_dir) ) $this->cache_dir = './cache';
- // Cache key index charactors, default is 2.
- $this->key_index_chars = $config->key_index_chars;
- if ( !isset($this->key_index_chars) || !$this->key_index_chars )
- $this->key_index_chars = 2;
- // Extension.
- $this->extension = $config->extension;
- if ( !isset($this->extension) || strlen($this->extension) < 1 )
- $this->extension = 'cache';
- // Permissions.
- $this->file_perms = $config->file_perms;
- if ( !isset($this->file_perms) ) $this->file_perms = 0644;
- $this->dir_perms = $config->dir_perms;
- if ( !isset($this->dir_perms) ) $this->dir_perms = 0755;
- // Ready to use paths.
- $this->paths_to_ready = array();
- // Ready?
- $this->ready();
- }
- /**
- * Check if ready to use.
- *
- * Check existence, directory and writable.
- */
- protected function ready( $namespace = null, $key_index = null ) {
- $path = $this->cache_dir;
- if ( isset($namespace) ) {
- if ( isset($key_index) ) {
- $path = FastPage_Util::cat_path( $path, urlencode($namespace), $key_index );
- } else {
- $path = FastPage_Util::cat_path( $path, urlencode($namespace) );
- }
- }
- // Lookup cache.
- if ( isset($this->paths_to_ready[$path]) ) return;
- if ( file_exists($path) && is_dir($path) && is_writable($path) ) {
- // Ready to use.
- $this->paths_to_ready[$path] = true;
- return;
- }
- if ( file_exists($path) ) {
- // Is directory?
- if ( !is_dir($path) ) {
- throw new FastPage_Exception( "Path: $path is already exists as not a directory." );
- }
- // Is writable?
- if ( !is_writable($path) ) {
- throw new FastPage_Exception( "Path: $path is not writable." );
- }
- } else {
- // Try to make directory.
- if ( false === mkdir( $path, $this->dir_perms, true ) ) {
- throw new FastPage_Exception( "Can not create $path as directory." );
- }
- }
- // Mark as ready.
- $this->paths_to_ready[$path] = true;
- }
- /**
- * Get index of key.
- */
- protected function key_index( $key ) {
- $index = substr( $key, 0, $this->key_index_chars );
- $index = str_pad( $index, $this->key_index_chars, '_' );
- return $index;
- }
- /**
- * Get file path for key.
- */
- protected function cache_path( $namespace, $raw_key ) {
- // Normalize the key.
- $key = $this->normalize_key($raw_key);
- // Build cache path.
- // Replace periods for security reason.
- $file = urlencode($key);
- $file = str_replace( '.', '%2e', $file );
- $index = $this->key_index( $file );
- if ( $this->extension ) $file .= '.' . $this->extension;
- // Ready to use?
- $this->ready( $namespace );
- $this->ready( $namespace, $index );
- return FastPage_Util::cat_path( $this->cache_dir, urlencode($namespace), $index, $file );
- }
- /**
- * Override exist method.
- */
- public function exist( $namespace, $raw_key ) {
- $path = $this->cache_path( $namespace, $raw_key );
- return file_exists($path);
- }
- /**
- * Override get method.
- */
- public function get( $namespace, $raw_key ) {
- $path = $this->cache_path( $namespace, $raw_key );
- if ( file_exists($path) && is_file($path) && is_readable($path) ) {
- if ( filemtime($path) > time() ) return @file_get_contents($path);
- @unlink($path);
- }
- return null;
- }
- /**
- * Override set method.
- */
- public function set( $namespace, $raw_key, $value, $expire = null ) {
- // Expires.
- if ( !isset($expire) ) {
- $expire = $this->default_expire;
- }
- // Put a file.
- $path = $this->cache_path( $namespace, $raw_key );
- @file_put_contents( $path, $value );
- if ( file_exists($path) ) {
- @chmod( $path, $this->file_perms );
- @touch( $path, time() + $expire );
- }
- }
- /**
- * Override delete method.
- */
- public function delete( $namespace, $raw_key ) {
- $path = $this->cache_path( $namespace, $raw_key );
- if ( file_exists($path) && is_file($path) ) {
- @unlink($path);
- $dir = dirname($path);
- $dh = opendir( $dir );
- $entries = 0;
- while ( false !== ( $file = readdir($dh) ) ) {
- if ( $file != '.' && $file != '..' ) {
- $entries++;
- break;
- }
- }
- closedir($dh);
- if ( $entries == 0 ) @rmdir($dir);
- }
- }
- /**
- * Clear files and directories recursively.
- */
- protected function clear_recursive( $dir, $expire = null ) {
- if ( !file_exists($dir) || !is_dir($dir) ) return;
- $dh = opendir($dir);
- $entries = 0;
- while ( false !== ( $file = readdir($dh) ) ) {
- // Skip . or ..
- if ( $file == '.' || $file == '..' )
- continue;
- // Increment at once.
- $entries++;
- $path = FastPage_Util::cat_path( $dir, $file );
- if ( is_file( $path ) ) {
- // Skip if not expired.
- if ( isset($expire) && filemtime($path) > $expire )
- continue;
- // Delete a file.
- if ( @unlink($path) ) $entries--;
- } else if ( is_dir( $path ) ) {
- // Clear resursively.
- $sub_entries = $this->clear_recursive( $path, $expire );
- if ( $sub_entries == 0 ) {
- // Remove directory if empty.
- if ( @rmdir($path) ) $entries--;
- }
- }
- }
- closedir($dh);
- return $entries;
- }
- /**
- * Flush and purge proxy.
- */
- public function clear( $namespace = null, $expire = null ) {
- $dir = $this->cache_dir;
- if ( isset($namespace) ) $dir = FastPage_Util::cat_path( $dir, urlencode($namespace) );
- $this->clear_recursive( $dir, $expire );
- }
- /**
- * Override flush method.
- */
- public function flush( $namespace = null ) {
- $this->clear( $namespace, null );
- }
- /**
- * Override clear method.
- */
- public function purge( $namespace = null ) {
- $this->clear( $namespace, time() );
- }
- }
- /**
- * Callback object.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideamans.com
- * @var FastPage_Core $fastpage FastPage_Core instance.
- * @var string $event Callback event.
- * @var integer $priority Callback priority.
- * @var mixed $function Callable function as string, or array of object and method..
- * @var mixed $hint Callback hint.
- * @var integer $index Callback index in priority chain.
- */
- class FastPage_Callback extends FastPage_Object {
- /**
- * Callback option: Run only the first callback returns a value not null.
- */
- const first_one = 0x01;
- /**
- * Callback option: Run all callbacks and return nothing.
- */
- const all = 0x02;
- /**
- * Callback option: Run all callbacks and return those results that is not null as an array.
- */
- const results_array = 0x04;
- /**
- * Callback option: Run all callbacks and operate logically with 'OR'.
- */
- const results_and = 0x08;
- /**
- * Callback option: Run all callbacks and operate logically with 'AND'.
- */
- const results_or = 0x10;
- /**
- * Constructor.
- *
- * @param FastPage_Core $fastpage FastPage_Core object contains the callback.
- * @param string $event Callback event.
- * @param integer $priority Callback priority.
- * @param mixed $function Callable function.
- * @param mixed $hint Callback hint.
- */
- public function __construct( $fastpage, $event, $priority, $function, $hint ) {
- $this->fastpage = $fastpage;
- $this->event = $event;
- $this->priority = $priority;
- $this->function = $function;
- $this->hint = $hint;
- }
- }
- /**
- * Onetime task object.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga <miyanaga@ideamans.com>
- * @var FastPage_Core $fastpage FastPage_Core instance.
- * @var string $name Task name.
- * @var integer $index Index in task queue.
- * @var mixed $function Callable function as string, or array of object and method.
- * @var mixed $args Arguments to call function.
- * @var mixed $result Task result.
- */
- class FastPage_OnetimeTask extends FastPage_Object {
- /**
- * Constructor.
- *
- * @param FastPage_Core $fastpage FastPage_Core object queueing the task.
- * @param string $name Name of the task.
- * @param mixed $function Task function.
- * @param mixed $args Arguments to call function.
- */
- public function __construct( $fastpage, $name, $function, $args ) {
- $this->fastpage = $fastpage;
- $this->name = $name;
- $this->function = $function;
- $this->args = $args;
- }
- }
- /**
- * Core features of FastPage like callback and helpers system.
- *
- * @package FastPage
- * @author Kunihiko Miyanaga@ideaman's Inc.
- */
- class FastPage_Core extends FastPage_Object {
- /**
- * Callbacks chain.
- */
- protected $_callbacks = array();
- /**
- * Onetime tasks queue.
- */
- protected $_onetime_tasks = array();
- /**
- * Helper singleton instances.
- */
- protected $_helper_instance = array();
- /**
- * Plugins.
- */
- protected $_plugins = array();
- /**
- * Constructor
- */
- public function __construct() {
- parent::__construct();
- // Built-in helpers.
- $helpers = array(
- 'config' => 'Config',
- 'cache' => 'FileCache',
- 'html_element' => 'HTMLElement',
- 'user_agent' => 'UserAgent',
- 'simple_http' => 'SimpleHTTP'
- );
- foreach ( $helpers as $helper => $class ) {
- $this->helper_class( $helper, 'FastPage_' . $class );
- }
- // MIME types.
- $mime_types = array(
- 'jpeg' => 'image/jpeg',
- 'jpg' => 'image/jpeg',
- 'gif' => 'image/gif',
- 'png' => 'image/png',
- 'css' => 'text/css',
- 'js' => 'text/javascript',
- 'html' => 'text/html',
- 'htm' => 'text/html'
- );
- foreach ( $mime_types as $name => $value ) {
- $this->config()->mime_type( $name, $value );
- }
- }
- /*
- * Helper class accessor.
- *
- */
- public function helper_class( $name, $value = null ) {
- // Remove current singleton instance.
- unset( $this->_helper_instance[$name] );
- return $this->__dictionary( 'helper_class', $name, $value );
- }
- /**
- * Create new helper object.
- *
- * @param Array $name Name of helper.
- * @param boolean $singleton Optional. If true, the instance will be stored and reused as singleton.
- * @param mixed $param1 Optional. The first parameter for constructor.
- * @param mixed $param2 Optional. The second parameter for constructor.
- * @return mixed A new object of helper class.
- */
- public function helper_instance( $helper, $singleton = false, $param1 = null, $param2 = null ) {
- // If singleton and already exists, return the instance.
- if ( $singleton && array_key_exists( $helper, $this->_helper_instance ) ) {
- return $this->_helper_instance[$helper];
- }
- // Helper class.
- $class = $this->helper_class($helper);
- // Create instance with params.
- // FIXME: Which is a better way?
- $obj = null;
- if ( class_exists($class) ) {
- if ( isset($param1) && isset($param2) ) {
- $obj = new $class( $this, $param1, $param2 );
- } else if ( isset($param1) ) {
- $obj = new $class( $this, $param1 );
- } else {
- $obj = new $class( $this );
- }
- }
- // Store instance if singleton.
- if ( $singleton ) {
- $this->_helper_instance[$helper] = $obj;
- }
- // Run callbacks.
- $this->run_callbacks( 'helper_created.' . $helper, FastPage_Callback::all, $obj );
- return $obj;
- }
- /**
- * Document root by host.
- */
- public function document_root( $host = '', $value = null ) {
- // Is as default?
- if ( $host == '' || $host == $this->config()->default_host ) {
- if ( isset($value) )
- return $this->config()->default_document_root = $value;
- else
- return $this->config()->default_document_root;
- }
- return $this->config()->document_root( $host, $value );
- }
- /**
- * MIME type
- */
- public function mime_type( $ext, $value = null ) {
- return $this->config()->mime_type( $ext, $value );
- }
- /**
- * Add callback to chain.
- *
- * Callback has an event name and priority.
- * Callback will be called by order priority value is smaller in each event.
- *
- * @param string $event Name of an event.
- * @param integer $priority Priority of the callback.
- * @param mixed $function Function locator: Name of the function as a string or array of an object and method name.
- * @param mixed $hint Hint value that will be passed to calling.
- * @return FastPage_Callback Callback object added to chain.
- */
- public function add_callback( $event, $priority, $function, $hint = null ) {
- // Ensure chain.
- if ( !isset($this->_callbacks[$event][$priority]) ) {
- $this->_callbacks[$event][$priority] = array();
- }
- // Create callback object and push to chain.
- $callback = new FastPage_Callback( $this, $event, $priority, $function, $hint );
- $callback->index = array_push( $this->_callbacks[$event][$priority], $callback );
- return $callback;
- }
- /**
- * Remove callback.
- *
- * @param FastPage_Callback $callback Callback object.
- */
- public function remove_callback( $callback ) {
- if ( isset( $this->_callbacks[$callback->event][$callback->priority][$callback->index] ) ) {
- unset( $this->_callbacks[$callback->event][$callback->priority][$callback->index] );
- }
- }
- /**
- * Run callbacks.
- *
- * @param string $event Name of an event.
- * @param integer $flags Options to…
Large files files are truncated, but you can click here to view the full file