Beispiel #1
0
 /**
  * factory method to create a rpc server instance by either passing an server
  * instance in first parameter or string with server driver name, e.g. "json"
  * or null value which will return the last added instance. will return instance
  * of Xapp_Rpc_Server in all cases
  *
  * @error 13901
  * @param null|string|Xapp_Rpc_Server $mixed expects value as explained above
  * @param null|array|object $options expects optional options to pass to server instance when constructing
  * @return Xapp_Rpc_Server
  * @throws Xapp_Rpc_Exception
  */
 public static final function server($mixed = null, $options = null)
 {
     if ($mixed !== null) {
         self::getServer();
         if ($mixed instanceof Xapp_Rpc_Server) {
             $driver = strtolower(substr($mixed, strrpos($mixed, '_') + 1));
             if (!array_key_exists($driver, self::$_instances)) {
                 self::$_instances[$driver] = $mixed;
             }
             return self::$_instances[$driver];
         } else {
             $driver = strtolower(trim($mixed));
             if (!array_key_exists($driver, self::$_instances)) {
                 $class = 'Xapp_Rpc_Server_' . ucfirst($driver);
                 if (class_exists($class, true)) {
                     self::$_instances[$driver] = new $class($options);
                 } else {
                     throw new Xapp_Rpc_Exception(xapp_sprintf(_("rpc server class: %s does not exist"), $class), 1390101);
                 }
             }
             return self::$_instances[$driver];
         }
     } else {
         return self::$_instances[sizeof(self::$_instances) - 1];
     }
 }
Beispiel #2
0
 /**
  * get and create static driver instance. if the first parameter is null will try to get
  * the current active instance created regardless of the driver. will throw error if no instance has
  * been created yet. if the second parameter is a driver string like "file" or "apc" will check
  * if instance has already been created and if not will do so with the passed options in second
  * parameter. this method is the preferred way to create cache instances when using multiple instances
  * with different namespaces and/or driver since the factory method will create an instance but not get
  * it at a later stage. the first parameter can be null meaning no namespace identifier which equals to
  * current instance - should only be used when using one instance!
  *
  * @error 15301
  * @param null|string $ns expects optional instance namespace identifier
  * @param null|string $driver expects the cache driver string
  * @param null|mixed $options expects xapp option array or object
  * @return Xapp_Cache_Driver concrete xapp cache driver implementation instance
  * @throws Xapp_Cache_Exception
  */
 public static function instance($ns = null, $driver = null, $options = null)
 {
     if (func_num_args() > 0) {
         //setting
         if ($driver !== null) {
             self::factory($driver, $options, $ns);
         }
         //getting
         if ($ns !== null) {
             if (array_key_exists($ns, self::$_instances)) {
                 return self::$_instances[trim((string) $ns)];
             } else {
                 throw new Xapp_Cache_Exception(xapp_sprintf(_("no cache instance under ns: %s registered"), $ns), 1530102);
             }
         } else {
             return self::$_instance;
         }
     } else {
         //getting
         if (self::$_instance !== null) {
             return self::$_instance;
         } else {
             throw new Xapp_Cache_Exception(_("can not get current cache class instance since no instance has been set yet"), 1530101);
         }
     }
 }
Beispiel #3
0
 /**
  * class constructor sets std flag to init valid str resource. std
  * flag can be err, out
  *
  * @error 12001
  * @param string $type expects the std flag
  * @throws Xapp_Log_Writer_Exception
  */
 public function __construct($type = 'err')
 {
     $type = 'STD' . strtoupper(trim((string) $type));
     if (defined($type)) {
         $this->_std = constant($type);
     } else {
         throw new Xapp_Log_Writer_Exception(xapp_sprintf(_("std type: %s is not defined"), $type), 1200101);
     }
 }
Beispiel #4
0
 /**
  * load config from php array of php file containing a single array like:
  *
  * return array
  * (
  *    "foo" => 1,
  *    "test" => "test",
  *    ...
  * );
  *
  * @error 12701
  * @param array|string $php expects php array or php file pointer
  * @return array
  * @throws Xapp_Config_Exception
  */
 public static function load($php)
 {
     if (!is_array($php) && (bool) preg_match('/\\.phtml|\\.php([0-9]{1,})?|\\.inc$/i', $php)) {
         if (is_file($php)) {
             $php = (require $php);
             if ($php === 1) {
                 $php = array_slice(get_defined_vars(), 1);
             }
         } else {
             throw new Xapp_Config_Exception(xapp_sprintf(_("unable to load php config file: %s"), $php), 1270101);
         }
     }
     return (array) $php;
 }
Beispiel #5
0
 /**
  * init class instance by validating cache directory for being readable and writable
  *
  * @error 16202
  * @return void
  * @throws Xapp_Cache_Driver_Exception
  */
 protected function init()
 {
     try {
         $dir = new SplFileInfo(xapp_get_option(self::PATH, $this));
         if (!$dir->isReadable()) {
             throw new Xapp_Cache_Driver_Exception(_("cache directory is not readable"), 1620201);
         }
         if (!$dir->isWritable()) {
             throw new Xapp_Cache_Driver_Exception(_("cache directory is not writable"), 1620202);
         }
         xapp_set_option(self::PATH, rtrim($dir->getRealPath(), DS) . DS, $this);
     } catch (Exception $e) {
         throw new Xapp_Cache_Driver_Exception(xapp_sprintf(_("cache directory file info error: %d, %s"), $e->getCode(), $e->getMessage()), 1620203);
     }
 }
Beispiel #6
0
 /**
  * load xml config structure from xml string or xml file pointer converting the xml
  * to json and back to array to get xml to array result
  *
  * @error 12801
  * @param string $xml expects xml string or xml file pointer
  * @return array
  * @throws Xapp_Config_Exception
  */
 public static function load($xml)
 {
     if ((bool) preg_match('/\\.xml$/i', $xml)) {
         if (is_file($xml) && ($xml = simplexml_load_file($xml, 'SimpleXMLElement', LIBXML_NOBLANKS | LIBXML_NOCDATA)) === false) {
             throw new Xapp_Config_Exception(xapp_sprintf(_("unable to load xml config from file: %s, error: %s"), $xml, libxml_get_last_error()), 1280101);
         }
     } else {
         if (($xml = simplexml_load_string($xml, 'SimpleXMLElement', LIBXML_NOBLANKS | LIBXML_NOCDATA)) === false) {
             throw new Xapp_Config_Exception(xapp_sprintf(_("unable to load xml config from string, error: %s"), libxml_get_last_error()), 1280102);
         }
     }
     if (($json = json_encode($xml)) !== false) {
         return json_decode($json, true);
     } else {
         throw new Xapp_Config_Exception(xapp_sprintf(_("unable to parse xml config: %s"), json_last_error()), 1280103);
     }
 }
Beispiel #7
0
 /**
  * load and parse json format string or file pointer and return cleaned
  * array
  *
  * @error 12601
  * @param string $json expects a encoded json string or json file pointer
  * @return array
  * @throws Xapp_Config_Exception
  */
 public static function load($json)
 {
     $_json = json_decode(self::clean($json), true);
     if ($_json !== false && $_json !== null) {
         return $_json;
     } else {
         if (is_file($json)) {
             $json = json_decode(self::clean(file_get_contents($json)), true);
             if ($json !== false && $json !== null) {
                 throw new Xapp_Config_Exception(xapp_sprintf(_("unable to load and decode json from: %s"), $json), 1260102);
             } else {
                 return $json;
             }
         } else {
             throw new Xapp_Config_Exception(xapp_sprintf(_("passed json file: %s is neither json string not json file pointer"), $json), 1260101);
         }
     }
 }
Beispiel #8
0
 /**
  * save object encoded to file passed in first parameter which is expected to be a valid file pointer. will throw
  * exception if file is not writeable
  *
  * @error 17026
  * @param string $file expects absolute file path to store object at
  * @return bool
  * @throws Xapp_Util_Std_Exception
  */
 public function saveTo($file)
 {
     if (file_put_contents($file, self::encode($this->_object), LOCK_EX)) {
         return true;
     } else {
         throw new Xapp_Util_Std_Exception(xapp_sprintf(_("unable to save to file: %s"), $file), 1702601);
     }
 }
Beispiel #9
0
 /**
  * log to console directly with this method passing only the first required parameter and to change
  * the log type the third parameter according to allowed log types. pass a lable for second parameter
  * to describe the message send to console.
  *
  * @error 10908
  * @param null|mixed $mixed expects the message of any type to send to console
  * @param null|string $label expects the optional label to describe the first parameter
  * @param string $type expects the log type - see log type array
  * @param array $options expects optional parameters
  * @return void
  * @throws Xapp_Error
  */
 public function log($mixed = null, $label = null, $type = 'info', array $options = array())
 {
     $type = strtolower((string) $type);
     if (array_key_exists($type, self::$_typeMap)) {
         if ($type === 'ini') {
             $this->ini($mixed, $label, $options);
         }
         if ($label !== null) {
             $label = trim(trim($label), ':') . ':';
         }
         switch ($this->_driver) {
             case 'chromephp':
                 switch ($type) {
                     case $type === 'ungroup' || $mixed === null:
                         $this->console->groupEnd();
                         break;
                     case 'group':
                         $this->console->group($mixed);
                         break;
                     case 'trace':
                         $this->console->log((string) $label, $mixed, 'info');
                         break;
                     default:
                         $this->console->log((string) $label, $mixed, self::$_typeMap[$type]);
                 }
                 break;
             case 'firephp':
                 switch ($type) {
                     case $type === 'ungroup' || $mixed === null:
                         $this->console->groupEnd();
                         break;
                     case 'group':
                         $this->console->group($mixed, $options);
                         break;
                     case 'trace':
                         $this->console->trace($label);
                         break;
                     default:
                         $this->console->{$type}($mixed, (string) $label, $options);
                 }
                 break;
         }
     } else {
         throw new Xapp_Error(xapp_sprintf(_("xapp console log type: %s not supported"), $type), 1090801);
     }
 }
Beispiel #10
0
 /**
  * get component from url as you would do with phps native function parse url expecting
  * the component flag in second argument which also cab be -1 returning all components as array.
  * if first parameter is not set will get url from current request. the url will not include
  * everything after the path variable
  *
  * @error 14420
  * @param null|string $url expects the optional url to parse
  * @param null|int $component expects optional php parse_url component flag
  * @return null|string|array
  * @throws Xapp_Rpc_Request_Exception
  */
 public static function url($url = null, $component = null)
 {
     $tmp = array();
     if ($url === null) {
         if (strtolower(php_sapi_name()) !== 'cli') {
             if ((int) $_SERVER['SERVER_PORT'] === 443 || !empty($_SERVER['HTTPS']) && strtolower(trim($_SERVER['HTTPS'])) == 'on') {
                 $tmp[] = 'https://';
             } else {
                 $tmp[] = 'http://';
             }
             if (isset($_SERVER['PHP_AUTH_USER']) && isset($_SERVER['PHP_AUTH_PW'])) {
                 $tmp[] = $_SERVER['PHP_AUTH_USER'] . ':' . $_SERVER['PHP_AUTH_PW'] . '@';
             }
             if (!empty($_SERVER['SERVER_NAME'])) {
                 $tmp[] = $_SERVER['SERVER_NAME'];
             } else {
                 $tmp[] = $_SERVER['HTTP_HOST'];
             }
             if (isset($_SERVER['SERVER_PORT']) && (int) $_SERVER['SERVER_PORT'] !== 80) {
                 $tmp[] = ':' . (int) $_SERVER['SERVER_PORT'];
             }
             $tmp[] = '/' . ltrim($_SERVER['REQUEST_URI'], '/ ');
         }
         $url = implode('', $tmp);
     }
     if ($component !== null) {
         if (($u = parse_url($url, (int) $component)) !== false) {
             return $u;
         } else {
             throw new Xapp_Rpc_Request_Exception(xapp_sprintf(_("url: %s is not a valid url"), $url), 1442001);
         }
     } else {
         return $url;
     }
 }
Beispiel #11
0
 /**
  * will preload passed directories to map class name (with optional namespace) to full path to class file
  * so autoload function will include class by looking into cached map called by this function instead of
  * iterating though all directories anew. see further explanation in class constructor. function will
  * return the class map as key => value array.
  *
  * @error 01705
  * @param null|array|string $dir expects valid dir
  * @return array
  * @throws Xapp_Error
  */
 public function preload($dir = null)
 {
     $separator = xapp_get_option(self::PATH_SEPARATOR, $this);
     $extensions = xapp_get_option(self::INCLUDE_EXTENSIONS, $this);
     $classes = xapp_get_option(self::EXCLUDE_CLASSES, $this);
     if ($dir === null) {
         $dir = $this->_dirs;
     }
     foreach ((array) $dir as $k => $v) {
         $v = (array) $v;
         if (is_dir($v[0])) {
             try {
                 $iterator = new RecursiveIteratorIterator(new RecursiveDirectoryIterator($v[0]), RecursiveIteratorIterator::CHILD_FIRST);
                 foreach ($iterator as $i) {
                     if (stripos($i->__toString(), '.svn') === false && stripos($i->__toString(), 'branches') === false) {
                         if (!$i->isDir()) {
                             //for xapp ext package limit iteration to first level only
                             if (stripos($i->__toString(), 'Xapp' . DS . 'Ext' . DS . 'src') !== false && substr($i->__toString(), strrpos($i->__toString(), DS) - 3, 3) !== 'src') {
                                 continue;
                             }
                             $class = '';
                             $file = trim($i->__toString());
                             $path = trim((string) substr(substr($file, 0, strrpos($file, DS)), strlen($v[0])), DS);
                             $paths = explode(DS, str_replace(DS . 'src', '', $path));
                             $name = substr(basename($file), 0, strpos(basename($file), '.'));
                             $ext = strtolower(substr($file, strrpos($file, '.') + 1));
                             $div = isset($v[2]) ? strtolower(trim($v[2])) : $separator;
                             $ns = isset($v[1]) && !empty($v[1]) ? trim(trim($v[1]), $div) : '';
                             if (empty($path)) {
                                 $class = (!empty($ns) && $name !== 'xapp' ? $ns . $div : '') . $name;
                             } else {
                                 $class .= !empty($ns) && $ns !== array_shift($paths) ? $ns . $div : '';
                                 $paths = explode(DS, str_replace(DS . 'src', '', $path));
                                 if (end($paths) === $name) {
                                     $class .= implode($div, $paths);
                                 } else {
                                     $class .= implode($div, array_merge($paths, array($name)));
                                 }
                             }
                             $class = strtolower($class);
                             if (in_array($ext, $extensions) && !in_array($class, (array) $classes)) {
                                 if (!isset($this->_classes[$k])) {
                                     $this->_classes[$k] = array();
                                 }
                                 if (!array_key_exists($class, $this->_classes[$k])) {
                                     $this->_classes[$k][$class] = $file;
                                 }
                             }
                         }
                     }
                 }
             } catch (Exception $e) {
                 throw new Xapp_Error(xapp_sprintf(_("iterator exception: %d, %s"), $e->getCode(), $e->getMessage()), 0170501);
             }
         } else {
             throw new Xapp_Error(xapp_sprintf(_("unable to preload dir: %s since dir is not valid"), $v[0]), 0170501);
         }
     }
     return $this->_classes;
 }
Beispiel #12
0
 /**
  * json implementation of saveTo method, see Xapp_Util_Std_Store::saveTo for more details
  *
  * @error 16905
  * @param string $file expects absolute file path to store object at
  * @param bool $pretty expects boolean value whether to store json string pretty or non pretty
  * @return bool
  * @throws Xapp_Util_Json_Exception
  */
 public function saveTo($file, $pretty = true)
 {
     $result = null;
     if ((bool) $pretty) {
         $result = file_put_contents($file, Xapp_Util_Json::prettify(Xapp_Util_Json::encode($this->_object)), LOCK_EX);
     } else {
         $result = file_put_contents($file, Xapp_Util_Json::encode($this->_object), LOCK_EX);
     }
     if ($result !== false) {
         $result = null;
         return true;
     } else {
         throw new Xapp_Util_Json_Exception(xapp_sprintf(_("unable to save to file: %s"), $file), 1690501);
     }
 }
Beispiel #13
0
 /**
  * get the smd target path in absolute or relative mode for services or base url for smd
  * output if first parameter is not set. this function will return target in htaccess rewrite
  * style if the option REWRITE_URL is set. this option can be either boolean true let the smd
  * resolve the rewrite pattern automatically which is nothing but extending the base path of
  * the url to contain the service class and function parameter like: "/base/rpc/index.php"
  * becomes "/base/rpc/class.function" or "/base/rpc/function" because rewrite will remap this
  * rule to "/base/rpc/index.php?service=class.function". you can also pass a string with your
  * rewrite rule as "/base/rpc/foo/{$class}/{$function}" with {($|%)} $ or % placeholder values.
  * always make sure your htaccess rule reflects the rewrite rule and vice versa and that service
  * values are always rewritten to $_GET "service" parameter. the second parameter defines whether
  * to return the url as relative or absolute or if not set will look for global option RELATIVE_TARGETS
  *
  * @error 14113
  * @param null|string $service expects optional the service method/function and class in dot notation
  * @param null|bool $relative defined whether to return path absolute or relative
  * @return string
  * @throws Xapp_Rpc_Smd_Exception
  */
 protected function getTarget($service = null, $relative = null)
 {
     $class = null;
     $function = null;
     $separator = xapp_get_option(self::CLASS_METHOD_SEPARATOR, $this);
     $url = Xapp_Rpc_Request::url(null, -1);
     $host = rtrim($url['host'], '/ ');
     $path = trim($url['path'], '/ ');
     if (preg_match('/(\\.([^\\/]+|$))/i', $path, $m, PREG_OFFSET_CAPTURE)) {
         if (isset($m[1]) && is_array($m[1])) {
             $path = substr($path, 0, $m[1][1] + strlen($m[1][0]));
         }
     }
     if (xapp_is_option(self::REWRITE_URL, $this) && strpos($path, 'index.') !== false) {
         $path = substr($path, 0, strpos($path, 'index.'));
     }
     if ($service !== null) {
         if (strpos($service, $separator) !== false) {
             $class = substr($service, 0, strpos($service, $separator));
             $function = substr($service, strpos($service, $separator) + 1);
         } else {
             $class = null;
             $function = $service;
         }
     }
     if ($service !== null) {
         if (xapp_is_option(self::REWRITE_URL, $this)) {
             $_url = xapp_get_option(self::REWRITE_URL, $this);
             if (is_bool($_url) && $_url) {
                 $_url = rtrim($path, '/') . '/{$class}{$separator}{$function}';
             }
             $_url = trim($_url, '/ ');
             if (($_url = parse_url($_url)) !== false) {
                 $path = trim(preg_replace(array('/\\{(?:\\$|\\%)([^\\}]+)\\}/ie', '/\\/+/'), array("\$\$1", '/'), $_url['path']), '/ ');
             } else {
                 throw new Xapp_Rpc_Smd_Exception(xapp_sprintf(_("smd rewrite rule: %s is not a valid url or url path value"), $_url), 1411301);
             }
         } else {
             $path = $path . "?service={$service}";
         }
     }
     if ($relative === null) {
         $relative = xapp_get_option(self::RELATIVE_TARGETS, $this);
     }
     if ((bool) $relative) {
         return '/' . ltrim($path, '/ ');
     } else {
         return $url['scheme'] . '://' . $host . (isset($url['port']) && !empty($url['port']) ? ':' . $url['port'] : '') . '/' . $path;
     }
 }
Beispiel #14
0
 /**
  * invoke class/method or function via rpc or outside rpc functionality for testing purposes. the first parameter
  * thus can be a valid callable when used outside of rpc service or the internal array containing all call parameters
  * from concrete rpc server implementation. throws exception with extended exception properties if in debug mode.
  * summarizes all caught applications exceptions when invoking callable to a general application error so sensitive
  * error messages can be omitted. when invoked with named parameters will reorder parameters to reflect
  * order of method/function call since call_user_func_array needs to pass parameter named or unnamed in
  * correct order
  *
  * @error 14211
  * @param array|callable $call expects either valid callable or array with all call parameters
  * @param array $params expects the parameters to pass to function/method to invoke
  * @return mixed
  * @throws Xapp_Rpc_Server_Exception
  * @throws Xapp_Rpc_Fault
  * @throws Exception
  */
 public function invoke($call, $params = null)
 {
     $key = null;
     $hash = null;
     $class = null;
     $return = null;
     $result = null;
     $callable = null;
     try {
         //invoke from outside of rpc service
         if (is_callable($call)) {
             $callable = $call;
             if (is_array($call)) {
                 $call = array(null, $call[1], is_object($call[0]) ? get_class($call[0]) : $call[0]);
                 $class = new ReflectionClass($call[2]);
             } else {
                 if (strpos((string) $call, '::') !== false) {
                     $call = array(null, substr($call, strpos($call, '::') + 2), substr($call, 0, strpos($call, '::')));
                     $class = new ReflectionClass($call[2]);
                 } else {
                     $call = array(null, $call, $call);
                     $class = null;
                 }
             }
         } else {
             if (is_array($call)) {
                 if ($call[2] !== null) {
                     if (xapp_get_option(self::NAMESPACE_IDENTIFIER, $this) === NAMESPACE_SEPARATOR) {
                         if (strpos($call[2], NAMESPACE_SEPARATOR) !== false) {
                             $call[2] = NAMESPACE_SEPARATOR . str_replace(array('\\', '/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2], ' ' . NAMESPACE_SEPARATOR));
                         } else {
                             $call[2] = str_replace(array('/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2]));
                         }
                     } else {
                         $call[2] = str_replace(array('\\', '/', '_', '.'), xapp_get_option(self::NAMESPACE_IDENTIFIER, $this), trim($call[2]));
                     }
                     $key = "{$call[2]}.{$call[1]}";
                     try {
                         if (array_key_exists(strtolower($call[2]), $this->_objects)) {
                             $class = new ReflectionClass($this->_objects[strtolower($call[2])]);
                         } else {
                             $class = new ReflectionClass($call[2]);
                         }
                         if ($class->hasMethod($call[1])) {
                             $method = $class->getMethod($call[1]);
                             if ($method->isPublic()) {
                                 if ($method->isStatic()) {
                                     $callable = array($class->getName(), $call[1]);
                                 } else {
                                     $callable = array(array_key_exists(strtolower($call[2]), $this->_objects) ? $this->_objects[strtolower($call[2])] : $class->newInstance(), $call[1]);
                                 }
                             } else {
                                 Xapp_Rpc_Fault::t("method: {$call[1]} of class: {$call[2]} is not public", array(1421105, -32601));
                             }
                         } else {
                             Xapp_Rpc_Fault::t("method: {$call[1]} of class: {$call[2]} does not exist", array(1421104, -32601));
                         }
                     } catch (ReflectionException $e) {
                         throw new Xapp_Rpc_Server_Exception(xapp_sprintf(_("unable to initialize class due to reflection error: %d, %s"), $e->getCode(), $e->getMessage()), 1421103);
                     }
                 } else {
                     $key = $call[1];
                     $callable = $call[1];
                 }
             } else {
                 throw new Xapp_Rpc_Server_Exception(_("invalid callable passed to invoke method"), 1421106);
             }
         }
         if (is_callable($callable)) {
             if (is_array($callable) && is_object($callable[0])) {
                 $this->_class = $callable[0];
             }
             if (!is_null($key) && !is_null($params) && array_values((array) $params) !== (array) $params) {
                 $tmp = array();
                 $arr = (array) $params;
                 $map = $this->smd()->get($key);
                 if (!is_null($map)) {
                     foreach ((array) $map->parameters as $p) {
                         if (array_key_exists($p->name, $arr)) {
                             $tmp[$p->name] = $arr[$p->name];
                         }
                     }
                 }
                 $params = $tmp;
                 $tmp = null;
                 $arr = null;
                 $map = null;
             }
             if (!is_null($key) && xapp_is_option(self::CACHE, $this) && preg_match(Xapp_Rpc::regex(xapp_get_option(self::CACHE_SERVICES, $this)), $call[0])) {
                 if (xapp_get_option(self::CACHE_BY_TRANSACTION_ID, $this)) {
                     $hash = $call[3]['id'];
                 } else {
                     $hash = Xapp_Cache::hash(serialize($call[0]) . serialize($params));
                 }
                 if (xapp_get_option(self::CACHE, $this)->has($hash)) {
                     return xapp_get_option(self::CACHE, $this)->get($hash);
                 }
             }
             if (!xapp_get_option(self::PARAMS_AS_ARRAY, $this)) {
                 $params = xapp_array_to_object($params);
             }
             xapp_event('xapp.rpc.server.beforeCall', array($this, array(&$result, $call[1], $call[2], $params)));
             if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onBeforeCall($this, array(&$result, $call[1], $call[2], &$params));
             }
             if ($return !== false && $result === null) {
                 $this->response()->result($result = call_user_func_array($callable, (array) $params));
             }
             if ($return === false && $this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onAbort($this, array(&$result, $call[1], $call[2], &$params));
             } else {
                 $return = null;
             }
             if ($return !== null) {
                 $result = $return;
             }
             if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
                 $return = $this->getClass()->onAfterCall($this, array(&$result));
             }
             if ($return !== null) {
                 $result = $return;
             }
             xapp_event('xapp.rpc.server.afterCall', array($this, array(&$result)));
             if (!is_null($hash)) {
                 if (!xapp_get_option(self::CACHE, $this)->has($hash)) {
                     xapp_get_option(self::CACHE, $this)->set($hash, $result);
                 }
             }
             $callable = null;
             $return = null;
             $params = null;
             $class = null;
             $hash = null;
             return $result;
         } else {
             throw new Xapp_Rpc_Server_Exception(_("unable to invoke function since first argument is not a callable"), 1421102);
         }
     } catch (Exception $e) {
         if ($this->hasClass() && $class->implementsInterface('Xapp_Rpc_Interface_Callable')) {
             $error = $this->getClass()->onError($this, $e);
             if ($error instanceof Exception) {
                 $e = $error;
                 $error = null;
             }
         }
         if (!$e instanceof Xapp_Rpc_Server_Exception) {
             $data = array();
             $debug = xapp_get_option(self::DEBUG, $this);
             if (is_bool($debug) && $debug === true || is_int($debug) && $debug === 1) {
                 $data['message'] = $e->getMessage();
                 $data['code'] = $e->getCode();
                 $data['class'] = get_class($e);
                 $data['file'] = $e->getFile();
                 $data['line'] = $e->getLine();
                 if ($e instanceof ErrorException) {
                     $data['severity'] = $e->getSeverity();
                 }
                 if ($e instanceof Xapp_Rpc_Fault && $e->hasData()) {
                     $data['data'] = $e->getData();
                 }
             } else {
                 if (is_int($debug) && $debug === 2) {
                     $data['message'] = $e->getMessage();
                     $data['code'] = $e->getCode();
                     if ($e instanceof ErrorException) {
                         $data['severity'] = $e->getSeverity();
                     }
                     if ($e instanceof Xapp_Rpc_Fault && $e->hasData()) {
                         $data['data'] = $e->getData();
                     }
                 }
             }
             if (xapp_is_option(self::APPLICATION_ERROR, $this)) {
                 if ($e instanceof Xapp_Rpc_Fault && $e->hasFault()) {
                     $f = $e->getFault();
                 } else {
                     $f = -32500;
                 }
                 if (($code = (int) $e->getCode()) !== 0) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("application error: %d", array($code)), array(1421101, $f), XAPP_ERROR_IGNORE, $data);
                 } else {
                     Xapp_Rpc_Fault::t("application error", array(1421101, $f), XAPP_ERROR_IGNORE, $data);
                 }
             } else {
                 if ((bool) $debug) {
                     Xapp_Rpc_Fault::t($e->getMessage(), $e->getCode(), XAPP_ERROR_IGNORE, $data);
                 } else {
                     throw $e;
                 }
             }
         } else {
             throw $e;
         }
     }
     return null;
 }
Beispiel #15
0
 /**
  * init instance by checking for memcached extension and validating server options
  *
  * @error 15801
  * @return void
  * @throws Xapp_Cache_Driver_Exception
  */
 protected function init()
 {
     if (!extension_loaded('memcached')) {
         throw new Xapp_Cache_Driver_Exception(_("memcached is not supported by this system"), 1580101);
     }
     if (xapp_is_option(self::COMPRESS, $this)) {
         xapp_set_option(self::OPTIONS, array(Memcached::OPT_COMPRESSION => xapp_get_option(self::COMPRESS, $this)), $this);
     }
     if (xapp_is_option(self::CONNECTION_TIMEOUT, $this)) {
         xapp_set_option(self::OPTIONS, array(Memcached::OPT_CONNECT_TIMEOUT => xapp_get_option(self::CONNECTION_TIMEOUT, $this)), $this);
     }
     if (xapp_is_option(self::INSTANCE, $this)) {
         $this->_memcached = xapp_get_option(self::INSTANCE, $this);
     } else {
         if (xapp_is_option(self::PERSISTENT_ID, $this)) {
             $this->_memcached = new Memcached(xapp_get_option(self::PERSISTENT_ID, $this));
         } else {
             $this->_memcached = new Memcached();
         }
         if (xapp_is_option(self::OPTIONS, $this)) {
             foreach (xapp_get_option(self::OPTIONS, $this) as $k => $v) {
                 if (!$this->_memcached->setOption((int) $k, $v)) {
                     throw new Xapp_Cache_Driver_Exception(xapp_sprintf(_("unable to set memcached option: %s"), $k), 1580102);
                 }
             }
         }
         $server = xapp_get_option(self::SERVER, $this);
         if (is_object($server)) {
             xapp_set_option(self::SERVER, array($server), $this, true);
         } else {
             if (is_array($server) && !array_key_exists(0, $server)) {
                 xapp_set_option(self::SERVER, array($server), $this, true);
             }
         }
         foreach ((array) xapp_get_option(self::SERVER, $this) as $server) {
             $server = (array) $server;
             if (!array_key_exists('host', $server)) {
                 throw new Xapp_Cache_Driver_Exception(_("memcached parameter: host must be set"), 1580103);
             }
             if (!array_key_exists('port', $server)) {
                 throw new Xapp_Cache_Driver_Exception(_("memcached parameter: port must be set"), 1580104);
             }
             if (!$this->_memcached->addServer($server['host'], (int) $server['port'], array_key_exists('weight', $server) ? (int) $server['weight'] : 0)) {
                 throw new Xapp_Cache_Driver_Exception(xapp_sprintf(_("unable to add server for host: %s and port: %d"), array($server['host'], $server['port'])), 1580105);
             }
         }
     }
 }
Beispiel #16
0
 /**
  * use overloading for all methods that are supported by ArrayAccess interface
  *
  * @see ArrayAccess
  * @error 10306
  * @param string $name expects overload function name
  * @param null|array $args expects overloading function arguments
  * @return null|mixed
  * @throws Xapp_Error
  */
 public function __call($name, $args = null)
 {
     $name = strtolower(trim($name));
     if (in_array($name, array('get', 'set', 'unset', 'exists'))) {
         return call_user_func_array(array('parent', 'offset' . ucfirst($name)), (array) $args);
     } else {
         throw new Xapp_Error(xapp_sprintf(_("unable to overload class with: %s"), $name), 1030601);
     }
 }
Beispiel #17
0
 /**
  * use the static create function to create a config instance of subclass implementation for
  * config handling. using the static method will ensure static access at any point of the application
  * or script. there are two ways of using config handling with namespace and public/protected access
  * 1)   use namespace "global" or leave ns blank. by doing so all loaded config structures (key => value pairs) are loaded
  *      into the same global public available namespace array. all values are shared and can be set/get by anyone.
  *      this is the default behaviour
  * 2)   use your own namespace. by doing so access to config values (set/get) is only possible if you know the namespace
  *      identifier since all config values are stored in protected array only for that namespace. access is not possible
  *      unless you know the namespace
  * If you pass the third parameter a config structure type hint is expected, e.g. json to load config with json loader
  * multiple config values can be passes in first parameter array merging multiple config files/buffers. NOTE: when using
  * multiple config values use different keys since in merging array keys will be merged!
  *
  * @error 12402
  * @param string|array|mixed $config expects config structure as buffer, file pointer or any other readable value or array of multiple of the same
  * @param string $ns expects the namespace as explained above
  * @param null|string $type expects optional config type hint
  * @return array|null
  * @throws Xapp_Config_Exception
  */
 public static function create($config, $ns = 'global', $type = null)
 {
     if ($type != null) {
         $type = strtolower(trim($type));
     } else {
         if (is_array($config)) {
             $type = 'php';
         } else {
             if ((bool) preg_match('/\\.([a-z0-9]{2,4})$/i', $config, $m)) {
                 $type = strtolower(trim($m[1]));
             } else {
                 $type = self::detect($config);
             }
         }
     }
     $class = __CLASS__ . '_' . $type;
     if (class_exists($class, true)) {
         if (strtolower($ns) === 'global') {
             if (array_key_exists(0, $config) && is_array($config[0])) {
                 foreach ($config as $c) {
                     self::$_globalConfig = array_merge_recursive(self::$_globalConfig, (array) $class::load($c));
                 }
             } else {
                 self::$_globalConfig = (array) $class::load($config);
             }
             return self::$_globalConfig;
         } else {
             if (!array_key_exists($ns, self::$_instances)) {
                 self::$_instances[$ns] = new $class($config);
             }
             return self::$_instances[$ns];
         }
     } else {
         throw new Xapp_Config_Exception(xapp_sprintf(_("config class: %s does not exist"), $class), 1240201);
     }
 }
Beispiel #18
0
 /**
  * validate jsonp request testing for request parameter to be valid and checking all
  * additional parameters
  *
  * @error 14705
  * @param array $call expects the call to validate
  * @return void
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($call)
 {
     $get = $this->request()->getGet();
     $service = null;
     if ($this->smd()->has($call[2], $call[1])) {
         if ($call[2] !== null) {
             $service = $this->smd()->get($call[2] . '.' . $call[1]);
         } else {
             $service = $this->smd()->get($call[1]);
         }
     } else {
         Xapp_Rpc_Fault::t("method or function is not registered as service", array(1470501, -32601));
     }
     if (!empty($service->parameters)) {
         foreach ($service->parameters as $k => $v) {
             if (!$v->optional && (!array_key_exists($v->name, $get) || !xapp_is_value($get[$v->name]))) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be set", array($v->name)), array(1470503, -32602));
             }
             if (isset($v->type) && array_key_exists($v->name, $get) && !in_array('mixed', (array) $v->type) && !in_array(xapp_type($get[$v->name], true), (array) $v->type)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be of the following types: %s", array($v->name, implode('|', (array) $v->type))), array(1470504, -32602));
             }
         }
     }
     if (xapp_is_option(self::ADDITIONAL_PARAMETERS, $this)) {
         foreach (xapp_get_option(self::ADDITIONAL_PARAMETERS, $this) as $k => $v) {
             $type = isset($v[0]) ? (array) $v[0] : false;
             $optional = isset($v[1]) ? (bool) $v[1] : true;
             if (!$optional && !array_key_exists($k, $get)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be set", array($k)), array(1470505, -32602));
             }
             if ($type && !in_array('mixed', $type) && !in_array(xapp_type($get[$k], true), $type)) {
                 Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be of the following types: %s", array($k, implode('|', $type))), array(1470506, -32602));
             }
         }
     }
 }
Beispiel #19
0
 /**
  * factory method to create new response instance defined by first parameter driver
  * which must contain a string with the driver name, e.g. "json"
  *
  * @error 14502
  * @param string $driver expects the driver name
  * @param null $options expects optional options to pass to class instance
  * @return Xapp_Rpc_Response
  * @throws Xapp_Rpc_Response_Exception
  */
 public static function factory($driver, $options = null)
 {
     $class = __CLASS__ . '_' . ucfirst(strtolower(trim($driver)));
     if (class_exists($class, true)) {
         return new $class($options);
     } else {
         throw new Xapp_Rpc_Response_Exception(xapp_sprintf(_("rpc response class: %s does not exist"), $class), 1450201);
     }
 }
Beispiel #20
0
 /**
  * write a message to all registered log writers or a specific log writer in pool by passing an alias. pass optional
  * parameters to log writer instance write method. see log writer implementation for more info. the $message parameter
  * can be string or array/object (std) with key => values pairs. the log writer will try to construct a valid loggable
  * message formatting the incoming message. the function will return whatever the log writer in stack return - either
  * a single value or array if calling all registered writers.
  *
  * @error 11510
  * @param string|array|object $message expects message object see explanation above
  * @param null|string $alias expects optional alias to just write to specific writer
  * @param null|mixed $params expects optional options object
  * @return array|mixed the result of the log writers write function
  * @throws Xapp_Log_Exception
  */
 public function write($message, $alias = null, $params = null)
 {
     $return = array();
     if ($alias !== null) {
         $alias = strtolower(trim((string) $alias));
         if (array_key_exists($alias, $this->_writer)) {
             return $this->_writer[$alias]->write($message, $params);
         } else {
             throw new Xapp_Log_Exception(xapp_sprintf(_("log writer for alias: %s does not exist"), $alias), 1151001);
         }
     } else {
         foreach ($this->_writer as $k => $writer) {
             $return[$k] = $writer->write($message, $params);
         }
     }
     return $return;
 }
Beispiel #21
0
 /**
  * get value from registry by key for the passed namespace ns or
  * get whole registry for ns if key is passed null
  *
  * @error 11103
  * @param null|string $key expects optional key to retrieve value for
  * @param null|string $ns expects the optional ns
  * @return null|mixed value for key
  * @throws Xapp_Error
  */
 public static function get($key = null, $ns = null)
 {
     $self = self::instance();
     if ($ns !== null) {
         $ns = strtolower(trim((string) $ns));
     } else {
         $ns = xapp_get_option(self::DEFAULT_NS, $self);
     }
     if (isset($self->_registry[$ns])) {
         if ($key !== null && array_key_exists($key, $self->_registry[$ns])) {
             return $self->_registry[$ns][$key];
         } else {
             return $self->_registry[$ns];
         }
     } else {
         throw new Xapp_Error(xapp_sprintf(_("unable to get registry since namespace: %s does not exist"), $ns), 1110301);
     }
 }
Beispiel #22
0
 /**
  * retrieve constant value or constant values for class. pass the class name as string or instance
  * of class in first parameter. expects either no value to return all constants or the constant
  * name to return the value of that constant. when passing a constant to get value for will look
  * for constant regardless of upper/lower case.
  *
  * @error 10605
  * @param string|object $class expects class name as string or instance of class
  * @param null $const expects optional constant name or no value to get all constants
  * @return null|string|array
  * @throws Xapp_Error
  */
 public static final function constantFactory($class = null, $const = null)
 {
     try {
         $_class = is_object($class) ? get_class($class) : $class;
         if (!is_object($class)) {
             $class = (string) $class;
         }
         $obj = new ReflectionClass($class);
         if ($const !== null) {
             $const = trim((string) $const);
             if ($obj->hasConstant(strtolower($const)) || $obj->hasConstant(strtoupper($const))) {
                 if ($obj->hasConstant(strtolower($const))) {
                     return $obj->getConstant(strtolower($const));
                 }
                 if ($obj->hasConstant(strtoupper($const))) {
                     return $obj->getConstant(strtoupper($const));
                 }
             } else {
                 throw new Xapp_Error(xapp_sprintf(_("const: %s does not exist in class: %s"), $const, $_class), 1060502);
             }
         } else {
             return $obj->getConstants();
         }
     } catch (ReflectionException $e) {
         throw new Xapp_Error($e, 1060501);
     }
     return null;
 }
Beispiel #23
0
 /**
  * init class instance by validating cache directory for being readable and writable
  *
  * @error 15502
  * @return void
  * @throws Xapp_Cache_Driver_Exception
  */
 protected function init()
 {
     try {
         $dir = new SplFileInfo(xapp_get_option(self::PATH, $this));
         if (!$dir->isReadable()) {
             throw new Xapp_Cache_Driver_Exception("cache directory is not readable", 1550201);
         }
         if (!$dir->isWritable()) {
             throw new Xapp_Cache_Driver_Exception("cache directory is not writable", 1550202);
         }
         xo_set(self::PATH, rtrim($dir->getRealPath(), DIRECTORY_SEPARATOR) . DIRECTORY_SEPARATOR, $this);
         $complete_path = xo_get(self::PATH, $this) . DIRECTORY_SEPARATOR . xo_get(self::SUBPATH, $this);
         if (!is_dir($complete_path)) {
             @mkdir($complete_path);
         }
         $subpath = xo_get(self::SUBPATH, $this) . DS;
         xo_set(self::SUBPATH, $subpath, $this);
     } catch (Exception $e) {
         throw new Xapp_Cache_Driver_Exception(xapp_sprintf("cache directory file info error: %d - %s", $e->getCode(), $e->getMessage()), 1550203);
     }
 }
Beispiel #24
0
 /**
  * resets the whole event listener storage array, all listeners for one event or
  * listeners for an event at a specific index. the index can be a numerical index or
  * a value "first" for shifting array one down, or "last" to pop of last.
  * NOTE: resetting instead of overriding can accidently lead to mal function of xapp
  *
  * @error 10405
  * @param null|string $event expects event name
  * @param null|int|string $index expects index value as explained above
  * @return void
  * @throws Xapp_Error
  */
 public static function reset($event = null, $index = null)
 {
     if ($event !== null) {
         if (isset(self::$_events[$event])) {
             if ($index !== null) {
                 if (is_int($index) && array_key_exists($index, self::$_events[$event])) {
                     self::$_events[$event][$index] = array();
                 } else {
                     if (strtolower((string) $index) === 'first') {
                         array_shift(self::$_events[$event]);
                     } else {
                         if (strtolower((string) $index) === 'last') {
                             array_pop(self::$_events[$event]);
                         } else {
                             throw new Xapp_Error(xapp_sprintf(_("unable to reset listener for event name and index: %s"), $index), 1040501);
                         }
                     }
                 }
             } else {
                 self::$_events[$event] = array();
             }
         }
     } else {
         self::$_events = array();
     }
 }
Beispiel #25
0
 /**
  * validate json request object testing all request object parameters for validity. also checking all additional
  * parameters for validity and throwing fault if necessary
  *
  * @error 14604
  * @param array $call expects the call to validate
  * @return void
  * @throws Xapp_Rpc_Fault
  */
 protected function validate($call)
 {
     if (!xapp_get_option(self::VALIDATE, $this)) {
         return;
     }
     if ($this->request()->isPost()) {
         if ($this->request()->getRaw() === "") {
             Xapp_Rpc_Fault::t("empty or invalid request object", array(1460401, -32600));
         }
         if ($this->request()->getVersion($call[3]) != xapp_get_option(self::VERSION, $this)) {
             Xapp_Rpc_Fault::t("rpc version not set or version miss match", array(1460402, -32013));
         }
         if (!xapp_get_option(self::ALLOW_NOTIFICATIONS, $this) || array_key_exists('id', $call[3])) {
             if (!array_key_exists('id', $call[3])) {
                 Xapp_Rpc_Fault::t("rpc transaction id must be set", array(1460405, -32015));
             }
             if (!is_numeric($call[3]['id']) && !is_string($call[3]['id'])) {
                 Xapp_Rpc_Fault::t("rpc transaction id must be string or integer", array(1460406, -32016));
             }
             if (xapp_is_option(self::TRANSACTION_ID_REGEX, $this) && !preg_match(trim((string) xapp_get_option(self::TRANSACTION_ID_REGEX, $this)), $call[3]['id'])) {
                 Xapp_Rpc_Fault::t("rpc transaction id does not match transaction id regex pattern", array(1460411, -32017));
             }
         }
         if (!xapp_get_option(self::ALLOW_FUNCTIONS, $this) && empty($call[2])) {
             Xapp_Rpc_Fault::t("php functions as service are not supported by this rpc service", 1460412, -32018);
         }
         if (!array_key_exists('method', $call[3])) {
             Xapp_Rpc_Fault::t("rpc method must be set", array(1460403, -32014));
         }
         if (!$this->smd()->has($call[2], $call[1])) {
             Xapp_Rpc_Fault::t("method or function is not registered as service", array(1460404, -32601));
         }
         if (!is_null($call[2])) {
             $service = $this->smd()->get($call[2] . '.' . $call[1]);
         } else {
             $service = $this->smd()->get($call[1]);
         }
         if (!empty($service->parameters)) {
             $params = array_key_exists('params', $call[3]) ? $call[3]['params'] : null;
             $p = (array) $params;
             $k = is_null($params) || array_values($p) !== $p ? 'n' : 'i';
             $i = 0;
             foreach ($service->parameters as $v) {
                 $n = $v->name;
                 if (!$v->optional && (!array_key_exists(${$k}, $p) || !xapp_is_value($p[${$k}]))) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be set", array(${$k})), array(1460407, -32602));
                 }
                 if (isset($v->type) && array_key_exists(${$k}, $p) && !in_array('mixed', (array) $v->type) && !in_array(xapp_type($p[${$k}]), (array) $v->type)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("param: %s must be of the following types: %s", array(${$k}, implode('|', (array) $v->type))), array(1460408, -32602));
                 }
                 $i++;
             }
         }
         if (xapp_is_option(self::ADDITIONAL_PARAMETERS, $this)) {
             foreach (xapp_get_option(self::ADDITIONAL_PARAMETERS, $this) as $k => $v) {
                 $type = isset($v[0]) ? (array) $v[0] : false;
                 $optional = isset($v[1]) ? (bool) $v[1] : true;
                 if (!$optional && !$this->request()->hasParam($k)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be set", array($k)), array(1460409, -32602));
                 }
                 if ($type && !in_array('mixed', $type) && !in_array(xapp_type($this->request()->getParam($k)), $type)) {
                     Xapp_Rpc_Fault::t(xapp_sprintf("additional param: %s must be of the following types: %s", array($k, implode('|', $type))), array(1460410, -32602));
                 }
             }
         }
     }
 }