public function testServiceRequestEvents() { // A post test Platform::on('user.list', 'http://dsp.local/web/eventReceiver', static::API_KEY); // An inline test Platform::on('user.list', function ($event, $eventName, $dispatcher) { $this->assertEquals('user.list', $eventName); $this->_actionEventFired = 1; echo 'event "user.list" has been fired.'; }, static::API_KEY); $this->_preProcessFired = $this->_postProcessFired = 0; $_config = (require dirname(dirname(__DIR__)) . '/config/web.php'); /** @var \RestController $_controller */ list($_controller, $_actionId) = Pii::app()->createController('rest/user'); try { $_controller->setService('user'); $_service = ServiceHandler::getService($_controller->getService()); $_service->on(PlatformServiceEvents::PRE_PROCESS, function ($event, $eventName, $dispatcher) { $this->assertEquals('user.get.pre_process', $eventName); $this->_preProcessFired = 1; }); $_service->on(PlatformServiceEvents::POST_PROCESS, function ($event, $eventName, $dispatcher) { $this->assertEquals('user.get.post_process', $eventName); $this->_postProcessFired = 1; }); // Test GET $_request = Pii::app()->getRequestObject(); $_request->query->set('app_name', Inflector::neutralize(__CLASS__)); $_request->overrideGlobals(); $_response = $_service->processRequest(null, HttpMethod::GET, false); $this->assertTrue(is_array($_response) && isset($_response['resource'])); $this->assertTrue(1 == $this->_preProcessFired && 1 == $this->_postProcessFired && 1 == $this->_actionEventFired); } catch (\Exception $ex) { RestResponse::sendErrors($ex); } }
/** * @param bool $returnAll If true, all configuration values are returned. Otherwise only a subset are available * * @param array $allowedProperties An array of properties to emit. If empty, all properties with getters will be emitted * * @return string JSON-encoded representation of this config * @return string */ public function toJson($returnAll = false, $allowedProperties = array()) { static $_baseProperties = array('type', 'endpointMap', 'userAgent'); $_properties = array_merge($_baseProperties, $allowedProperties); $_json = array(); foreach (get_object_vars($this) as $_key => $_value) { $_key = ltrim($_key, '_'); // Filter if (false === $returnAll && !in_array($_key, $_properties)) { continue; } if (method_exists($this, 'get' . $_key)) { $_json[Inflector::neutralize($_key)] = $_value; } } return json_encode($_json); }
/** * Makes a list of available templates * * @param string $pattern * * @return void */ protected static function _loadTemplates($pattern = self::DEFAULT_TEMPLATE_PATTERN) { if (array() !== (static::$_templateCache = Oasys::getStore()->get('oasys.template_cache', array()))) { // Loaded from cache... return; } $_list = array(); foreach (static::$_providerPaths as $_path) { $_templates = glob($_path . '/Templates/' . $pattern); foreach ($_templates as $_template) { $_templateName = str_ireplace('.template.php', null, basename($_template)); $_templateId = Inflector::neutralize($_templateName); // Skip base classes in these directories... if ('base_' == substr($_templateId, 0, 4)) { continue; } $_list[$_templateId] = $_path . '/Templates/' . $_template; unset($_template, $_templateId, $_templateName); } unset($_path, $_templates); } // Merge in the found templates Oasys::getStore()->set('oasys.template_cache', static::$_templateCache = array_merge(static::$_templateCache, $_list)); Log::debug('Cached templates: ' . implode(', ', array_keys(static::$_templateCache))); }
/** * @return array */ public function toArray() { $_properties = array(); $_mirror = new \ReflectionClass(get_class($this)); foreach ($_mirror->getMethods() as $_method) { $_methodName = $_method->getShortName(); if ($_method->isPublic() && 'get' == strtolower(substr($_methodName, 0, 3))) { $_key = Inflector::neutralize(substr($_methodName, 3)); $_properties[$_key] = $this->{$_methodName}(); } } return $_properties; }
/** * Creates a generic, consistent event for scripting and notifications * * The returned array is as follows: * * array( * // Basics * 'id' => 'A unique ID assigned to this event', * 'name' => 'event.name', * 'trigger' => '{api_name}/{resource}', * 'stop_propagation' => [true|false], * 'dispatcher' => array( * 'id' => 'A unique ID assigned to the dispatcher of this event', * 'type' => 'The class name of the dispatcher', * ), * // Information about the triggering request * 'request' => array( * 'timestamp' => 'timestamp of the initial request', * 'path' => '/full/path/that/triggered/event', * 'api_name' =>'The api_name of the called service', * 'resource' => 'The name of the resource requested', * 'body' => 'The body posted as part of the request (possibly normalized by the service)', * ), * // Information about the outgoing response. * 'response' => 'The response body returned to the calling service and eventually to the requesting client.', * // Access to the platform api * 'platform' => array( * 'api' => [wormhole to inline-REST API], * 'config' => [standard DSP configuration update], * 'session' => [the current session], * ), * 'extra' => [Extra information passed by caller], * ) * * Note that this structure is not passed to the script verbatim. Portions are extracted and exposed by the * Script resource as it sees fit. * * Please note that the format of the request and response bodies may differ slightly from the format passed in or * sent back to the client. Some service handlers normalize the data for convenience, i.e. see * BaseDbSvc::_determineRequestMembers(). * * Therefore the data exposed by the event system has been "normalized" to provide a reliable and consistent manner * in which to process said data. There should be no need for wasting time trying to determine if your data is * "maybe here, or maybe there, or maybe over there even" when received by your event handlers. * * * @param string $eventName The event name * @param PlatformEvent $event The event * @param EventDispatcher $dispatcher The dispatcher of the event * @param array $extra Any additional data to put into the event structure * @param bool $includeDspConfig If true, the current DSP config is added to container * @param bool $returnJson If true, the event will be returned as a JSON string, otherwise an * array. * * @return array|string */ public static function normalizeEvent($eventName, PlatformEvent $event, $dispatcher, array $extra = [], $includeDspConfig = true, $returnJson = false) { static $config = null; if (!$config) { $config = $includeDspConfig ? \Cache::get(Config::LAST_RESPONSE_CACHE_KEY, false) : false; } // Clean up the event extras, remove data portion $eventExtras = $event->getData(); $path = $dispatcher->getPathInfo(true); // Clean up the trigger $trigger = false !== strpos($path, 'rest', 0) || false !== strpos($path, '/rest', 0) ? str_replace(['/rest', 'rest'], null, $path) : $path; $request = static::buildRequestArray($event); $response = $event->getResponseData(); // Build the array $event = ['id' => $event->getEventId(), 'name' => $eventName, 'timestamp' => date('c', Option::server('REQUEST_TIME_FLOAT', Option::server('REQUEST_TIME', microtime(true)))), 'trigger' => $trigger, 'request_path' => $path, 'stop_propagation' => ArrayUtils::get($eventExtras, 'stop_propagation', false, true), 'dispatcher_id' => spl_object_hash($dispatcher), 'dispatcher_type' => Inflector::neutralize(get_class($dispatcher)), 'extra' => $extra, 'platform' => ['config' => $config, 'session' => static::getCleanedSession()], 'request' => $request, 'response' => $response]; return $returnJson ? json_encode($event, JSON_UNESCAPED_SLASHES) : $event; }
foreach ($_models as $_model) { $_attributes = array('value' => $_model->api_name, 'name' => $_model->api_name); if (APPLICATION_NAME == $_model->api_name) { $_attributes['selected'] = 'selected'; } $_apps .= HtmlMarkup::tag('option', $_attributes, $_model->name); unset($_model); } unset($_models); } $_models = ResourceStore::model('provider')->findAll(array('select' => 'id, provider_name, api_name', 'order' => 'provider_name')); if (!empty($_models)) { $_first = true; /** @var Provider[] $_models */ foreach ($_models as $_model) { $_attributes = array('name' => $_model->api_name, 'value' => $_model->api_name, 'data-provider-id' => $_model->id, 'data-provider-tag' => Inflector::neutralize($_model->provider_name) . ':' . $_model->api_name, 'data-profile-resource' => strtolower($_model->provider_name) == 'facebook' ? '/me' : '/user'); if ($_first) { $_attributes['selected'] = 'selected'; $_first = false; } $_providers .= HtmlMarkup::tag('option', $_attributes, $_model->api_name . ' (' . Inflector::display($_model->provider_name) . ')'); $_providerCache->{$_model->api_name} = $_model->getAttributes(); unset($_model, $_config, $_attributes, $_profileResource); } unset($_models); } // Default url $_defaultUrl = '/rest/system/user'; ?> <!DOCTYPE html> <html lang="en">
/** * Returns the constant name as a string * * @param string $constant * @param bool $flipped If false, the $constantValue should contain the constant name and the value will be returned * @param bool $pretty If true, returned value is prettified (acme.before_event becomes "Acme Before Event") * * @throws \InvalidArgumentException * @return string */ public static function nameOf($constant, $flipped = true, $pretty = true) { if (in_array($constant, array_keys($_constants = static::getDefinedConstants($flipped)))) { return $pretty ? Inflector::display(Inflector::neutralize($_constants[$constant])) : $_constants[$constant]; } throw new \InvalidArgumentException('A constant with the value of "' . $constant . '" does not exist.'); }
/** * Builds a hash of events and handlers that are present in this object based on the event handler signature. * This merely builds the hash, nothing is done with it. * * @param \Kisma\Core\Interfaces\SubscriberLike|string $object The object or class to scan * @param string $pattern The method listener pattern to scan for * @param bool $rediscover By default, the discoverer will not wire up the same object's events more than once. * Setting $rediscover to TRUE will force the rediscovery of the listeners, if any. * The default is false. * * @return array|bool The listeners discovered. True if already discovered, False on error */ public static function _discoverObjectListeners($object, $pattern = self::LISTENER_DISCOVERY_PATTERN, $rediscover = false) { static $_discovered = array(); $_listeners = array(); $_objectId = spl_object_hash(is_string($object) ? '_class.' . $object : $object); if (false === $rediscover && isset($_discovered[$_objectId])) { return true; } try { $_mirror = new \ReflectionClass($object); $_methods = $_mirror->getMethods(\ReflectionMethod::IS_PUBLIC | \ReflectionMethod::IS_PROTECTED); // Check each method for the event handler signature foreach ($_methods as $_method) { // Event handler? if (0 == preg_match($pattern, $_method->name, $_matches) || empty($_matches[1])) { continue; } // Neutralize the name $_eventName = Inflector::neutralize($_matches[1]); if (!isset($_listeners[$_eventName])) { $_listeners[$_eventName] = array(); } // Save off a callable $_listeners[$_eventName][] = array($object, $_method->name); // Clean up unset($_matches, $_method); } unset($_methods, $_mirror); $_discovered[$_objectId] = true; } catch (\Exception $_ex) { return false; } // Return the current map return $_listeners; }
/** * When unserializing an object, this will re-attach any event handlers... */ public function __wakeup() { // This is my hash. There are many like it, but this one is mine. $this->_id = hash('sha256', spl_object_hash($this) . getmypid() . microtime(true)); // Auto-set tag and name if empty $this->_tag = $this->_tag ?: Inflector::neutralize(get_called_class()); $this->_name = $this->_name ?: $this->_tag; if ($this instanceof SubscriberLike) { EventManager::discoverListeners($this); } // Publish after_construct event if ($this->_enableLifeEvents) { $this->trigger(LifeEvents::AFTER_CONSTRUCT); } }
/** * @return array */ public function toArray() { $_me = array('stop_propagation' => $this->isPropagationStopped()); foreach (get_object_vars($this) as $_key => $_value) { if (method_exists($this, 'get' . ($_cleanKey = ltrim($_key, '_')))) { $_me[Inflector::neutralize($_cleanKey)] = $_value; } } return $_me; }
/** * @param string $name Cleans up a user-supplied option key * * @return string */ protected static function _getKeyTag($name) { // If this is an array, apply to all keys if (is_array($name)) { $_items = array(); foreach ($name as $_key => $_value) { $_items[$_key] = $_value; } return $_items; } if (is_string($name)) { $_tag = Inflector::neutralize($name); if (false === strpos($_tag, CoreSettings::OPTION_KEY_PREFIX, 0)) { $_tag = CoreSettings::OPTION_KEY_PREFIX . ltrim($_tag, '.'); } return $_tag; } // Dunno, have it back the same I guess... return $name; }