/** * Outputs the given data to the RenderSurface. * This function supports two types of data: a string and a \System\Collection\Vector or an array. * If the first parameter is a string, then the function supports only 1 parameter; * If the first parameter is a \System\Collection\Vector, or an array, then this function uses the second parameter * as a delimiter. * @param mixed A string, \System\Collection\Vector, or array. */ public final function render() { $args = func_get_args(); if (count($args) == 0) { throw new \InvalidArgumentException('Invalid amount of arguments given.'); } $output = ''; switch (true) { case \System\Type::getType($args[0]) == \System\Type::TYPE_STRING: $output = $args[0]; break; case \System\Type::getType($args[0]) == \System\Type::TYPE_ARRAY: if (count($args) == 2) { $output = implode($args[1], $args[0]); } break; case \System\Type::getType($args[0]) == \System\Type::TYPE_OBJECT: if ($args[0] instanceof \System\Collection\Vector && count($args) == 2) { $output = implode($args[1], $args[0]->getArrayCopy()); } else { throw new \InvalidArgumentException('Invalid amount of arguments given.'); } break; default: throw new \InvalidArgumentException('Invalid amount of arguments given.'); } $this->addToBuffer($output); }
/** * This function executes the effect on the given image and its internal datastructure. * This function should not be called manually. For applying effects, see the applyEffect function in the given image. * @see \System\Image\Image::applyEffect() * @param \System\Image\Image An image or a subclass * @param mixed The image datastructure to work with */ public final function executeFilter(\System\Image\Image $image, $imageData) { $imagickClass = '\\System\\Image\\Imagick\\Image'; if ($image instanceof $imagickClass) { return $this->executeFilterImagick($imageData); } else { if ($image instanceof \System\Image\Image) { return $this->executeFilterGD($imageData); } else { throw new \System\Error\Exception\InvalidMethodException('Cannot execute a filter on the given input type: ' . \System\Type::getClass($image)); } } }
/** * This function checks the requirements for the system. Should not be called manually. */ function __requirements() { \System\Version::registerRequiredConfigDirective('DATABASE_HOST'); \System\Version::registerRequiredConfigDirective('DATABASE_USER'); \System\Version::registerRequiredConfigDirective('DATABASE_PASS'); \System\Version::registerRequiredConfigDirective('DATABASE_NAME'); \System\Version::registerRequiredConfigDirective('DATABASE_PORT'); \System\Version::registerRequiredConfigDirective('DATABASE_PERSISTANT'); \System\Version::registerRequiredConfigDirective('PERMABAN_HOST'); \System\Version::registerRequiredConfigDirective('PERMABAN_USER'); \System\Version::registerRequiredConfigDirective('PERMABAN_PASS'); \System\Version::registerRequiredConfigDirective('PERMABAN_NAME'); \System\Version::registerRequiredConfigDirective('PERMABAN_PORT'); \System\Version::registerRequiredConfigDirective('SITE_IDENTIFIER'); \System\Version::registerRequiredConfigDirective('SITE_EMAIL'); \System\Version::registerRequiredConfigDirective('SITE_NAMESPACE'); \System\Version::registerRequiredConfigDirective('PUBLIC_ROOT'); \System\Version::registerRequiredConfigDirective('DEFAULT_MODULES'); \System\Version::registerRequiredConfigDirective('MINIFY_ENABLE'); \System\Version::registerRequiredConfigDirective('AVAILABLE_LANGUAGES'); \System\Version::registerRequiredConfigDirective('DEFAULT_LANGUAGE'); if (version_compare(PHP_VERSION, SYSTEM_MINIMUM_PHP_VERSION) < 0) { throw new \System\Error\Exception\SystemException('The configuration is invalid: We need at least PHP ' . SYSTEM_MINIMUM_PHP_VERSION . ' in order to run.'); } if (mb_strlen(SITE_IDENTIFIER) < 3 || mb_strlen(SITE_IDENTIFIER) > 4) { throw new \System\Error\Exception\SystemException('The configuration is invalid: SITE_IDENTIFIER must be 3 or 4 chars.'); } if (!defined('LUTCACHE_CACHE')) { define('LUTCACHE_CACHE', \System\Cache\LUTCache\Types::CACHE_NONE); } else { if (LUTCACHE_CACHE != \System\Cache\LUTCache\Types::CACHE_NONE && LUTCACHE_CACHE != \System\Cache\LUTCache\Types::CACHE_MEMCACHE && LUTCACHE_CACHE != \System\Cache\LUTCache\Types::CACHE_APC) { throw new \System\Error\Exception\SystemException('The configuration is invalid: LUTCACHE_CACHE is invalid.'); } } if (!function_exists('curl_init')) { throw new \System\Error\Exception\SystemException('This system requires the cURL PHP module to be present. Please reconfigure your PHP.'); } if (!class_exists('\\XSLTProcessor')) { throw new \System\Error\Exception\SystemException('This system required the XSL PHP module to be present. Please reconfigure your PHP.'); } //load the modules from the config file $defaultModules = unserialize(DEFAULT_MODULES); if (\System\Type::getType($defaultModules) != \System\Type::TYPE_ARRAY) { throw new \System\Error\Exception\SystemException('The configuration is invalid: DEFAULT_MODULES not set or invalid.'); } foreach ($defaultModules as $defaultModule) { \System\Module\Module::load($defaultModule); } }
/** * Decodes the given content and converts it to a JSON object. * The JSON object(s) will be placed inside a Vector for easy handling. * @param string The content string to work with * @return \System\Collection\Vector A vector with JSON objects */ private static final function getJSONObjectVector($variable) { if ($variable) { $json = json_decode(html_entity_decode($variable), false); if (\System\Type::getType($json) == \System\Type::TYPE_NULL) { throw new \System\Error\Exception\NullPointerException('Could not decode the given json string: ' . $variable); } if (\System\Type::getType($json) == \System\Type::TYPE_ARRAY) { return new \System\Collection\Vector($json); } $vec = new \System\Collection\Vector(); $vec[] = $json; return $vec; } return new \System\Collection\Vector(); }
/** * Preoccupies the collection with data. This function supports different set of parameter types. * If there is one parameter, it supports a double, string, integer, array, or collection parameter. * The contents of the parameter is added to the current collection. * If there are multiple parameters, then only String, Double, Integer parameters are supported. * @param mixed Optional parameter for content filling * @param mixed Optional parameter for content filling * @param mixed ... */ public function __construct() { if (func_num_args() == 1) { switch (\System\Type::getType(func_get_arg(0))) { case \System\Type::TYPE_DOUBLE: case \System\Type::TYPE_STRING: case \System\Type::TYPE_INTEGER: $this[] = func_get_arg(0); break; case \System\Type::TYPE_ARRAY: $this->data = func_get_arg(0); break; case \System\Type::TYPE_OBJECT: switch (true) { case func_get_arg(0) instanceof \System\Collection\iCollection: case func_get_arg(0) instanceof \System\Base\BaseStruct: $this->constructWithCollection(func_get_arg(0)); break; default: throw new \InvalidArgumentException('Invalid argument given. Expected Double, String, Integer, Array or Collection'); } break; default: throw new \InvalidArgumentException('Invalid argument given. Expected Double, String, Integer, Array or Collection'); } } else { foreach (func_get_args() as $arg) { switch (\System\Type::getType($arg)) { case \System\Type::TYPE_DOUBLE: case \System\Type::TYPE_STRING: case \System\Type::TYPE_INTEGER: $this[] = $arg; break; default: throw new \InvalidArgumentException('Invalid argument given. Expected Double, String, Integer, Array or Collection'); } } } }
/** * String representation of the current object * @return string A string representation of the current object */ public function __toString() { return \System\Type::getClass($this) . ' (' . $this->count() . ')'; }
/** * Returns the current classname, excluding namespaces * @return string The name of the class */ public final function getBaseClassName() { return \System\Type::getClass($this, true); }
/** * Implements the function result value caching. This function is called by the __call * function and generates a key from the given parameters. It performs a simple and fast lookup * in an internal array and returns the value if needed. Otherwise the value is appended to the * lut by executing the function and storing its result. * Note: it is not possible to call functions that require parameters by reference * @param string The name of the function being called * @param array The arguments passed to the function * @return mixed The result of the function */ private final function functionCache($name, array $arguments) { //first we need a lut key from the given params $key = spl_object_hash($this) . '_' . $name . '('; //serialize the parameters foreach ($arguments as $arg) { $key .= \System\Type::getValue($arg); } $key .= ')'; //because we dont have a constructor, we must check the type of the cache and create it //if needed if ($this->functionCache === null) { $this->functionCache = new \System\Collection\Map(); } //lookup the key in the functionCache for fast calling and store the function result if (!isset($this->functionCache[$key])) { if (is_callable(array($this, $name))) { $this->functionCache[$key] = call_user_func_array(array($this, $name), $arguments); } else { throw new \System\Error\Exception\InvalidMethodException('Cannot access given method. Is it public or protected?: ' . $name); } } return $this->functionCache[$key]; }
/** * This function does a page request to a given url. The request is done using a regular HTTP GET request, and can be * optionally replaced by a POST request by passing in postdata. * This function tries to execute using the cURL library, but falls back to regular GET requests if that library isnt available. * If cURL is not available, then POST requests will be ignored. * Valid $postData parameter types are string, array, or \System\Collection\Map types. $postData is an urlencoded string like 'para1=val1¶2=val2&...' * or an array (or Map) with the field name as key and field data as value. If value is an array or Map, the Content-Type header will be set to multipart/form-data. * Support for proxies is built in. If there is no proxy url given, then no proxies will be used. * SSL certificates are ignored. * @param string The url to call. * @param mixed The postdata to send. If this is null, then a normal GET request is done. Not supported if cURL is not present. * @param string The user agent to use. Default is the Firefox 3.6 browser under a Win7 environment. * @param string The referer to use for redirects. Not supported if cURL is not present. * @param string A proxy url to connect through. This url requires a protocol (ex: http://localhost:8118). Without http://, it assumes SOCKS5 * @param array The return headers by reference * @param array Optional custom headers. If custom headers are given, no default headers will be used. * @param int The amount of seconds to wait before a timeout * @return mixed The html contents or false for an error. */ public static final function httpPageRequest($url, $postData = null, $userAgent = self::USERAGENT_FIREFOX_36, $referer = self::REFERER_GOOGLE, $proxyUrl = '', &$returnHeaders = array(), array $header = array(), $timeout = self::SYNC_TIMEOUT) { $returnValue = false; //only set default headers if no other custom headers are given if (count($header) == 0) { $header[] = "User-Agent: " . $userAgent; self::getHttpPageRequestDefaultHeaders($header); } if (function_exists('curl_init')) { $curl = curl_init(); curl_setopt($curl, CURLOPT_URL, $url); curl_setopt($curl, CURLOPT_HTTPHEADER, $header); curl_setopt($curl, CURLOPT_REFERER, $referer); curl_setopt($curl, CURLOPT_ENCODING, 'gzip,deflate'); curl_setopt($curl, CURLOPT_AUTOREFERER, true); curl_setopt($curl, CURLOPT_RETURNTRANSFER, true); curl_setopt($curl, CURLOPT_TIMEOUT, $timeout); curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true); curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); curl_setopt($curl, CURLOPT_HEADER, true); curl_setopt($curl, CURLINFO_HEADER_OUT, true); curl_setopt($curl, CURLOPT_VERBOSE, 1); if (!empty($proxyUrl)) { curl_setopt($curl, CURLOPT_PROXY, $proxyUrl); if (strpos($proxyUrl, 'http://') === false) { curl_setopt($curl, CURLOPT_PROXYTYPE, CURLPROXY_SOCKS5); } } //there is data we want to post, so we do a POST instead of a GET if ($postData) { switch (true) { case \System\Type::getType($postData) == \System\Type::TYPE_OBJECT && $postData instanceof \System\Collection\Map && $postData->count() > 0: $postData = $postData->getArrayCopy(); //fallthrough //fallthrough case \System\Type::getType($postData) == \System\Type::TYPE_STRING && mb_strlen($postData) > 0: //fallthrough //fallthrough case \System\Type::getType($postData) == \System\Type::TYPE_ARRAY && count($postData) > 0: curl_setopt($curl, CURLOPT_POST, true); curl_setopt($curl, CURLOPT_POSTFIELDS, $postData); break; default: throw new \InvalidArgumentException('The given POST argument is not of type: string, array, \\System\\Collection\\Map. Type given: ' . \System\Type::getType($postData)); } } $returnValue = curl_exec($curl); if ($returnValue) { $headerSize = curl_getinfo($curl, CURLINFO_HEADER_SIZE); $returnHeaders = preg_split('/$\\R?^/m', substr($returnValue, 0, $headerSize)); $returnValue = substr($returnValue, $headerSize); } curl_close($curl); } else { //fallback to manual http calls using file_get_contents. We only support GET calls here. //we add support for gzip,deflate $header[] = "Accept-Encoding: gzip,deflate"; $options = array('http' => array('method' => 'GET', 'header' => implode('\\r\\n', $header))); $context = stream_context_create($options); $returnValue = file_get_contents($url, NULL, $context); } return $returnValue; }
/** * Executes a given callback and any hooks associated with it. * The execution will be: * The PRE execution hooks in order of adding. * The execute callback * The POST execution hooks in order of adding. * Please note that this function will only return the returnvalue of the given execute function. * Also not that this function does work recursively; the hooks themselves are called using the call function. * The hooks are called using the same parameters as the execute function. * The hooks may or may not have their own returnvalues, but these will be ignored. * @param callback The callback to execute. * @param array The arguments to pass to the execute function */ public static final function call($execute, array $arguments = array()) { $handle = self::validateHandle(); $key = \System\Type::callbackToString($execute); if (mb_substr($key, 0, 1) == '\\') { $key = mb_substr($key, 1); } //pre hooks if ($handle->keyExists($key)) { foreach ($handle->{$key}->pre as $preHook) { if (is_callable($preHook)) { self::call($preHook, $arguments); } } } $returnValue = call_user_func_array($execute, $arguments); //post hooks if ($handle->keyExists($key)) { foreach ($handle->{$key}->post as $postHook) { if (is_callable($postHook)) { //add the return value to the parameters array_push($arguments, $returnValue); self::call($postHook, $arguments); } } } return $returnValue; }
/** * Returns the unique id of the object. This id is unique for every object and can be used as a index key. * Do note that once the object gets unset, its id is released and can be re-issued. * @param object The object to get the id from * @return string The id for the given object. */ public static final function getObjectId($instance) { if (\System\Type::getType($instance) == \System\Type::TYPE_OBJECT) { return spl_object_hash($instance); } else { throw new \InvalidArgumentException('The given parameter is not an instance of an object.'); } }
/** * Binds a parameter to the query. This is done immediatly so, the results are not delayed. * Multiple parameter types can be added to the query. * @param string The value to be added to the query. * @param integer The type of parameter to be added to the query. * @return \System\Db\Query Returns the current instance, so we can chain. */ public final function bind($parameterValue, $parameterType = \System\Db\QueryType::TYPE_INTEGER) { $count = 0; switch ($parameterType) { case QueryType::TYPE_INTEGER: if (!ctype_digit($parameterValue) && !is_int($parameterValue)) { throw new \System\Error\Exception\InvalidDatabaseQueryArgumentException('The given parameter needs to be of integer type, ' . \System\Type::getType($parameterValue) . ' given.'); } $this->sql = $this->str_replace_once(self::PARAMSTRING, $this->db->sanitize($parameterValue), $this->sql, $count); break; case QueryType::TYPE_QUERY: $this->sql = $this->str_replace_once(self::PARAMSTRING, $this->db->sanitize($parameterValue), $this->sql, $count); break; case QueryType::TYPE_STRING: if (!is_string($parameterValue)) { throw new \System\Error\Exception\InvalidDatabaseQueryArgumentException('The given parameter (' . $parameterValue . ') needs to be of string type, ' . \System\Type::getType($parameterValue) . ' given.'); } $this->sql = $this->str_replace_once(self::PARAMSTRING, '\'' . $this->db->sanitize($parameterValue) . '\'', $this->sql, $count); break; default: throw new \System\Error\Exception\InvalidDatabaseQueryArgumentException('Invalid parametertype given, ' . \System\Type::getType($parameterValue) . ' given.'); } if ($count == 0) { throw new \System\Error\Exception\InvalidDatabaseQueryArgumentException('The query has no more free parameter slots: ' . $this->sql); } return $this; }
/** * Sanitizes a given value using the given parameters. This function only sanitizes strings or arrays. Other types will be returned unchanged. * This function does not remove tags and only encodes the special characters. * @param mixed The value to sanitize. * @param boolean Encode the high ASCII values (128+) * @param boolean Remove the low ASCII values * @param boolean Remove the high ASCII values * @return mixed The sanitized value or the unchanged value */ public static final function entityString($value, $encodeHigh = true, $stripLow = false, $stripHigh = false) { if (\System\Type::getType($value) == \System\Type::TYPE_STRING) { $flags = 0; if ($encodeHigh) { $flags |= FILTER_FLAG_ENCODE_HIGH; } if ($stripLow) { $flags |= FILTER_FLAG_STRIP_LOW; } if ($stripHigh) { $flags |= FILTER_FLAG_STRIP_HIGH; } $value = filter_var($value, FILTER_SANITIZE_SPECIAL_CHARS, $flags); } else { if (\System\Type::getType($value) == \System\Type::TYPE_ARRAY) { foreach ($value as &$val) { $val = self::entityString($val, $encodeHigh, $stripLow, $stripHigh); } } } return $value; }
/** * This function removes the top of the stacktrace and formats the trace to a wellformed * string stracktrace. * @param string The original backtrace * @return string The stacktrace */ private static final function getFormattedTraceAsString($traces) { array_shift($traces); $outputString = ''; foreach ($traces as $index => $trace) { $outputString .= '#' . $index . ' '; if (isset($trace['file'])) { $outputString .= $trace['file'] . '('; if (isset($trace['line'])) { $outputString .= $trace['line']; } $outputString .= '): '; } else { $outputString .= '[internal]: '; } if (isset($trace['object'])) { $outputString .= $trace['object'] . $trace['type']; } $outputString .= $trace['function'] . '('; $params = array(); if (isset($trace['args'])) { foreach ($trace['args'] as $arg) { $type = \System\Type::getType($arg); switch ($type) { case \System\Type::TYPE_BOOLEAN: case \System\Type::TYPE_DOUBLE: case \System\Type::TYPE_INTEGER: case \System\Type::TYPE_NULL: $params[] = $type . '{' . \System\Type::getValue($arg) . '}'; break; case \System\Type::TYPE_STRING: $params[] = $type . '{"' . \System\Type::getValue($arg) . '"}'; break; default: $params[] = $type; } } } $outputString .= implode(', ', $params); $outputString .= ')'; $outputString .= "\r\n"; } return $outputString; }
/** * Adds class constants to the given code block. * @param string The string to append to. By reference. * @param array Constants in an array, the key is their name; the value its value. */ private static final function addClassConstants(&$code, array $constants) { foreach ($constants as $constantName => $constantValue) { $str = ''; switch (\System\Type::getType($constantValue)) { case \System\Type::TYPE_ARRAY: $str = 'array()'; break; case \System\Type::TYPE_STRING: $str = '\'' . $constantValue . '\''; break; case \System\Type::TYPE_INTEGER: case \System\Type::TYPE_DOUBLE: case \System\Type::TYPE_NULL: case \System\Type::TYPE_BOOLEAN: $str = \System\Type::getValue($constantValue); break; default: $str = '\'undefined\''; break; } $code .= 'const ' . $constantName . ' = ' . $str . ';' . "\r\n"; } }