/** * @covers \Kisma\Core\Utility\Inflector::pluralize */ public function testPluralize() { $_words = array('mouse' => 'mice', 'dizzy' => 'dizzies', 'history' => 'histories', 'child' => 'children', 'quiz' => 'quizzes', 'person' => 'people', 'wart' => 'warts', 'ox' => 'oxen', 'louse' => 'lice', 'matrix' => 'matrices', 'vertex' => 'vertices', 'hive' => 'hives', 'thief' => 'thieves', 'tomato' => 'tomatoes', 'glass' => 'glasses', 'cows' => 'cows', 'geese' => 'geese', 'deer' => 'deer'); foreach ($_words as $_word => $_expected) { $this->assertEquals($_expected, Inflector::pluralize($_word)); } }
/** * @param int $code * @param string|null $message * @param \Exception|null $previous * @param mixed|null $context * * @throws \InvalidArgumentException */ public function __construct($code, $message = null, $previous = null, $context = null) { if (!\Kisma\Core\Enums\HttpResponse::contains($code)) { throw new \InvalidArgumentException('The code "' . $code . '" is not a valid HTTP response code.'); } if (null === $message) { $message = \Kisma\Core\Utility\Inflector::untag(\Kisma\Core\Enums\HttpResponse::nameOf($code)); } parent::__construct($message, $code, $previous, $context); }
/** * Dynamically generates the object from the declared properties of the given object or array * * @param array|object $object * * @return \stdClass */ public static function toObject($object) { // If we can't iterate over the thing, we bail if (!is_object($object) && !is_array($object) && !$object instanceof \Traversable) { return null; } if (is_array($object)) { // Convert to an object $_properties = new \stdClass(); foreach ($object as $_key => $_value) { $_properties->{$_key} = $_value; } } else { $_me = new \ReflectionObject($object); $_properties = $_me->getProperties(); } // We'll return this $_obj = new \stdClass(); if (!empty($_properties)) { if (is_object($object)) { $_myClass = get_class($object); } else { $_myClass = '_array_'; } foreach ($_properties as $_property) { // Only want properties of $object hierarchy... if (isset($_property->class)) { $_class = new \ReflectionClass($_property->class); if (!empty($_class) && !$_class->isInstance($object) && !$_class->isSubclassOf($_myClass)) { unset($_class); continue; } unset($_class); } try { $_realPropertyName = $_propertyName = ltrim($_property->name, '_ '); if (false !== strpos($_propertyName, '_')) { $_propertyName = Inflector::tag($_propertyName); } $_getter = 'get' . $_propertyName; if (method_exists($object, $_getter)) { $_propertyValue = $object->{$_getter}(); if (!is_scalar($_propertyValue)) { $_propertyValue = self::toObject($_propertyValue); } $_obj->{$_realPropertyName} = $_propertyValue; } } catch (\Exception $_ex) { // Just ignore, not a valid property if we can't read it with a getter } } } return $_obj; }
/** * Given a string, return it to neutral format (lowercase, period and underscores) * * @param string $item The string to neutralize * @param string $strip If provided, it's value is removed from item before it's neutralized. * Example: "REQUEST_URI" would be "URI" with $strip = "REQUEST_" * * @return string */ public static function neutralize($item, $strip = null) { if (is_numeric($item)) { return $item; } if (null !== $strip) { $item = str_ireplace($strip, null, $item); } // Split by forward slash, backslash, period, or space... $_parts = preg_split("/[. \\/\\\\]+/", $item); array_walk($_parts, function (&$part) { // Clean $part = Inflector::decamelize($part); }); return implode('.', $_parts); }
/** * @param array $schema * @param bool $returnHtml If true, HTML is returned, otherwise an array of fields * * @return string */ protected static function _buildFormFields($schema, $returnHtml = true) { $_form = null; $_fields = array(); foreach ($schema as $_field => $_settings) { // No private fields are ever rendered if (false !== Option::get($_settings, 'private', false)) { continue; } $_value = Option::get($_settings, 'value', Option::get($_settings, 'default')); $_label = Option::get($_settings, 'label', Inflector::display($_field)); $_labelAttributes = Option::get($_settings, 'label_attributes', array('for' => $_field)); $_attributes = array_merge(array('name' => $_field, 'id' => $_field), Option::get($_settings, 'attributes', array())); if (false !== ($_required = Option::get($_settings, 'required', false))) { $_attributes['class'] = HtmlMarkup::addValue(Option::get($_attributes, 'class'), 'required'); } $_form .= HtmlMarkup::label($_labelAttributes, $_label); $_fields[$_field]['label'] = array('value' => $_label, 'attributes' => $_labelAttributes); switch ($_settings['type']) { case 'text': $_form .= HtmlMarkup::tag('textarea', $_attributes, $_value) . PHP_EOL; $_fields[$_field] = array_merge($_fields[$_field], array('type' => 'textarea', 'contents' => $_value), $_attributes); break; case 'select': $_attributes['size'] = Option::get($_settings, 'size', 1); $_attributes['value'] = $_value; $_fields[$_field] = array_merge($_fields[$_field], array('type' => 'select', 'data' => Option::get($_settings, 'options', array())), $_attributes); $_form .= HtmlMarkup::select($_fields[$_field]['data'], $_attributes) . PHP_EOL; break; default: $_attributes['maxlength'] = Option::get($_settings, 'length'); $_attributes['value'] = $_value; $_attributes['type'] = 'text'; $_fields[$_field] = array_merge($_fields[$_field], array('type' => 'input', 'value' => $_value), $_attributes); $_form .= HtmlMarkup::tag('input', $_attributes, null, true, true) . PHP_EOL; break; } } return $returnHtml ? $_form : $_fields; }
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); } }
/** * Merges settings to pre-constructed provider config * * @param array|ProviderConfigLike $settings * * @return $this */ public function mergeSettings($settings = array()) { foreach ($settings as $_key => $_value) { if (property_exists($this, $_key)) { try { Option::set($this, $_key, $_value); unset($settings, $_key); continue; } catch (\Exception $_ex) { // Ignore... } } $_setter = Inflector::tag('set_' . $_key); if (method_exists($this, $_setter)) { call_user_func(array($this, $_setter), $_value); unset($settings, $_key, $_setter); } } return $this; }
/** * @return array * @throws DreamFactory\Platform\Exceptions\BadRequestException */ protected function _parseRequest() { $_resourceId = strtolower(trim(FilterInput::request('resource', null, FILTER_SANITIZE_STRING))); $_id = FilterInput::request('id', null, FILTER_SANITIZE_STRING); if (empty($_resourceId) || empty($_resourceId) && empty($_id)) { throw new BadRequestException(404, 'Not found.'); } // Handle a plural request if (false !== ($_tempId = Inflector::isPlural($_resourceId, true))) { $_resourceId = $_tempId; } $this->setModelClass('DreamFactory\\Platform\\Yii\\Models\\' . Inflector::deneutralize($_resourceId)); return array($_resourceId, $_id); }
/** * 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; }
<?php /** * @var WebController $this * @var array $schema * @var BasePlatformSystemModel $model * @var array $_formOptions Provided by includer * @var array $errors Errors if any * @var string $resourceName The name of this resource (i.e. App, AppGroup, etc.) Essentially the model name * @var string $displayName * @var array $_data_ */ use DreamFactory\Yii\Utility\BootstrapForm; use Kisma\Core\Utility\Inflector; $update = false; $_form = new BootstrapForm(); $_options = array('breadcrumbs' => array('Admin Dashboard' => '/admin', Inflector::display($resourceName) . 's' => '/admin', $displayName => false)); $_formOptions = $_form->pageHeader($_options); // Render the form $this->renderPartial('_' . $resourceName . '_form', $_data_);
/** * 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; }
$_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"> <head> <title>DreamFactory Portal Sandbox</title> <meta charset="utf-8" /> <meta http-equiv="Content-Type" content="text/html;charset=utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1" />
/** * 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.'); }
/** * Load up with presents */ protected function _loadRequest() { $_goodies = array(); // Fill up the bag if (isset($_SERVER) && !empty($_SERVER)) { foreach ($_SERVER as $_key => $_value) { if (false !== stripos($_key, 'HTTP_', 0)) { if (!isset($_goodies['server.headers']) || !is_array($_goodies['server.headers'])) { $_goodies['server.headers'] = array(); } $_tag = Inflector::tag($_key, true, 'HTTP_'); $_goodies['server.headers'][$_tag] = $_value; } else { $_tag = 'server.' . Inflector::tag($_key, true); $_goodies[$_tag] = $_value; } } } if (isset($_REQUEST) && !empty($_REQUEST)) { foreach ($_REQUEST as $_key => $_value) { $_tag = 'request.' . Inflector::tag($_key, true, 'REQUEST_'); $_goodies[$_tag] = $_value; } } $this->merge($_goodies); return true; }
/** * @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; }
/** * 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); } }
/** * @param array $data * * @return $this */ public function fromArray($data = array()) { foreach ($data as $_key => $_value) { // Event ID cannot be changed if ('event_id' != $_key) { if (method_exists($this, 'set' . ($_key = Inflector::deneutralize($_key)))) { $this->{'set' . $_key}($_value); } } } // Special propagation stopper if (isset($data['stop_propagation']) && false !== $data['stop_propagation']) { $this->stopPropagation(); } return $this; }
use DreamFactory\Common\Enums\PageLocation; use DreamFactory\Platform\Enums\ResponseFormats; use DreamFactory\Yii\Utility\Pii; use Kisma\Core\Utility\Inflector; use Kisma\Core\Utility\Option; $_state = $_content = $_tabs = null; Pii::scriptFile('/js/df.datatables.js', PageLocation::End); //if ( null !== ( $_state = Pii::getState( 'admin.state' ) ) ) $_state = array(); $_class = ' class="active"'; foreach ($resourceColumns as $_resource => $_config) { $_html = '<h3>Coming Soon!</h3>'; $_buttons = $_labels = null; $_active = $_resource == 'app' ? ' active' : null; // Get/create a menu name $_menuName = Option::get($_config, 'menu_name', Option::get($_config, 'header', Inflector::pluralize($_config['resource']))); if (isset($_config['labels']) && !empty($_config['labels'])) { $_id = 'tab-' . $_resource; $_count = 0; foreach ($_config['labels'] as $_label) { $_labels .= '<th>' . $_label . '</th>'; $_count++; } if (null !== ($_displayName = Option::get($_config, 'display_name'))) { $_buttons = '<button class="btn btn-success" id="create-' . $_resource . '">Add ' . $_displayName . '</button>'; } $_html = <<<HTML <h3>{$_config['header']}<div id="admin-toolbar" class=" pull-right">{$_buttons}</div></h3> <table class="table table-striped table-hover table-bordered table-resource" id="{$_resource}-table"> <thead> \t<tr>{$_labels}</tr>