本文整理汇总了PHP中lithium\util\Set::merge方法的典型用法代码示例。如果您正苦于以下问题:PHP Set::merge方法的具体用法?PHP Set::merge怎么用?PHP Set::merge使用的例子?那么恭喜您, 这里精选的方法代码示例或许可以为您提供帮助。您也可以进一步了解该方法所在类lithium\util\Set
的用法示例。
在下文中一共展示了Set::merge方法的15个代码示例,这些例子默认根据受欢迎程度排序。您可以为喜欢或者感觉有用的代码点赞,您的评价将有助于系统推荐出更棒的PHP代码示例。
示例1: __construct
/**
* Sets up the adapter with the configuration assigned by the `Session` class.
*
* @param array $config Available configuration options for this adapter:
* - `'config'` _string_: The name of the model that this adapter should use.
*/
public function __construct(array $config = array())
{
$this->config = Set::merge($this->config, $config);
if (empty($this->config['model']) || !class_exists($this->config['model'])) {
throw new ConfigException("No valid model \"{$this->config['model']}\" available to use for Session interaction");
} elseif (empty($this->config['entityManager']) && (!method_exists($this->config['model'], 'getEntityManager') || !is_callable($this->config['model'] . '::getEntityManager'))) {
throw new ConfigException("The session model {$this->config['model']} must define a getEntityManager() static method, or you must set the entityManager session config variable");
}
$reflection = new \ReflectionClass($this->config['model']);
if (!$reflection->implementsInterface('li3_doctrine2\\models\\ISession')) {
throw new ConfigException("The model {$this->config['model']} must implement ISession");
}
$this->entityManager = $this->config['entityManager'] ?: call_user_func($this->config['model'] . '::getEntityManager');
if (!isset($this->entityManager) || !$this->entityManager instanceof EntityManager) {
throw new ConfigException('Not a valid entity manager');
}
$this->repository = $this->entityManager->getRepository($this->config['model']);
foreach ($this->config['ini'] as $key => $config) {
if (isset($this->config['ini'][$key]) && ini_set("session.{$key}", $this->config['ini'][$key]) === false) {
throw new ConfigException("Could not initialize the session variable {$key}");
}
}
session_set_save_handler(array(&$this, '_open'), array(&$this, '_close'), array(&$this, '_read'), array(&$this, '_write'), array(&$this, '_destroy'), array(&$this, '_gc'));
register_shutdown_function('session_write_close');
if ($this->config['start']) {
$this->_startup();
}
}
示例2: __construct
/**
*
*/
public function __construct($config = array())
{
$defaults = array('proxy' => array('auto' => true, 'path' => LITHIUM_APP_PATH . '/resources/tmp/cache/Doctrine/Proxies', 'namespace' => 'Doctrine\\Proxies'), 'useModelDriver' => true, 'mapping' => array('class' => null, 'path' => LITHIUM_APP_PATH . '/models'), 'configuration' => null, 'eventManager' => null, 'utf-8' => true);
$config = Set::merge($defaults, $config);
$configuration = $config['configuration'] ?: new Configuration();
$eventManager = $config['eventManager'] ?: new EventManager();
$configuration->setProxyDir($config['proxy']['path']);
$configuration->setProxyNamespace($config['proxy']['namespace']);
$configuration->setAutoGenerateProxyClasses($config['proxy']['auto']);
$configuration->setMetadataCacheImpl(new ArrayCache());
// Annotation Driver
$driver = $configuration->newDefaultAnnotationDriver(array(LITHIUM_APP_PATH . '/models'));
$configuration->setMetadataDriverImpl($driver);
// TODO: Not sure if this is required or not!
// if (!$config['useModelDriver']) {
// $configuration->setMetadataDriverImpl(new ModelDriver());
// }
$configuration->setSqlLogger(new SqlLogger());
$mapping = array('adapter' => 'driver', 'login' => 'user', 'database' => 'dbname');
foreach ($mapping as $source => $dest) {
if (isset($config[$source]) && !isset($config[$dest])) {
$config[$dest] = $config[$source];
unset($config[$source]);
}
}
$this->_em = EntityManager::create($config, $configuration, $eventManager);
$this->_sm = $this->_em->getConnection()->getSchemaManager();
if ($this->_em->getConnection()->getDriver() instanceof Driver\PDOMySql\Driver && $config['utf-8']) {
$this->_em->getEventManager()->addEventSubscriber(new MysqlSessionInit('utf8', 'utf8_unicode_ci'));
}
parent::__construct($config);
}
示例3: testArrayConfiguration
public function testArrayConfiguration()
{
$result = Configurations::create(Set::merge($this->_default, array('type' => 'array', 'value' => 'foo=bar')));
$this->assertEqual(array('foo' => 'bar'), $result->val());
$this->assertEqual('bar', $result->val('foo'));
$result = Configurations::create(Set::merge($this->_default, array('type' => 'array', 'value' => "foo.bar=baz\nfoo.baz=bar")));
$this->assertEqual(array('foo' => array('bar' => 'baz', 'baz' => 'bar')), $result->val());
$this->assertEqual(array('bar' => 'baz', 'baz' => 'bar'), $result->val('foo'));
$this->assertEqual('baz', $result->val('foo.bar'));
}
示例4: __construct
/**
* Object constructor.
* Instantiates the Memcached object, adds appropriate servers to the pool,
* and configures any optional settings passed.
*
* @see lithium\storage\Cache::config()
* @param array $config Configuration parameters for this cache adapter.
* These settings are indexed by name and queryable
* through `Cache::config('name')`.
* @return void
*/
public function __construct(array $config = array())
{
$defaults = array('prefix' => '', 'expiry' => '+1 hour', 'servers' => array(array('127.0.0.1', 11211, 100)));
if (is_null(static::$connection)) {
static::$connection = new \Memcached();
}
$configuration = Set::merge($defaults, $config);
parent::__construct($configuration);
static::$connection->addServers($this->_config['servers']);
}
示例5: _recaptchaOptions
/**
* Create `RecaptchaOptions` javascript object if you have additional options configured
* @param array $options `'key' => 'value'` pairs to be converted to javascript
* object as `RecaptchaOptions`
* @see https://developers.google.com/recaptcha/docs/customization
* @return null|string Return null if you don't have additional options
* or script with `RecaptchaOptions` object
*/
protected function _recaptchaOptions(array $options = array())
{
$defaults = Libraries::get('li3_recaptcha', 'options');
if ($defaults) {
$options = Set::merge($defaults, $options);
}
if (empty($options)) {
return null;
}
$script = '<script type="text/javascript">';
$script .= 'var RecaptchaOptions = ' . json_encode($options) . ';';
$script .= '</script>';
return $script;
}
示例6: _init
/**
* Pulls request data from superglobals.
*
* @return void
*/
protected function _init()
{
parent::_init();
$mobile = array('iPhone', 'MIDP', 'AvantGo', 'BlackBerry', 'J2ME', 'Opera Mini', 'DoCoMo', 'NetFront', 'Nokia', 'PalmOS', 'PalmSource', 'portalmmm', 'Plucker', 'ReqwirelessWeb', 'iPod', 'SonyEricsson', 'Symbian', 'UP\\.Browser', 'Windows CE', 'Xiino', 'Android');
if (!empty($this->_config['detectors']['mobile'][1])) {
$mobile = array_merge($mobile, (array) $this->_config['detectors']['mobile'][1]);
}
$this->_detectors['mobile'][1] = $mobile;
$this->_env += (array) $_SERVER + (array) $_ENV + array('REQUEST_METHOD' => 'GET');
$envs = array('isapi' => 'IIS', 'cgi' => 'CGI', 'cgi-fcgi' => 'CGI');
$this->_env['PLATFORM'] = isset($envs[PHP_SAPI]) ? $envs[PHP_SAPI] : null;
$this->_base = isset($this->_base) ? $this->_base : $this->_base();
$this->url = '/';
if (isset($this->_config['url'])) {
$this->url = rtrim($this->_config['url'], '/');
} elseif (!empty($_GET['url'])) {
$this->url = rtrim($_GET['url'], '/');
unset($_GET['url']);
}
if (!empty($this->_config['query'])) {
$this->query = $this->_config['query'];
}
if (isset($_GET)) {
$this->query += $_GET;
}
if (!empty($this->_config['data'])) {
$this->data = $this->_config['data'];
} elseif (isset($_POST)) {
$this->data += $_POST;
}
if (isset($this->data['_method'])) {
$this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'] = strtoupper($this->data['_method']);
unset($this->data['_method']);
}
if (!empty($this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->_env['REQUEST_METHOD'] = $this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'];
}
$method = strtoupper($this->_env['REQUEST_METHOD']);
if (($method == 'POST' || $method == 'PUT') && !$this->data) {
if (($type = $this->type()) && $type !== 'html') {
$this->_stream = $this->_stream ?: fopen('php://input', 'r');
$media = $this->_classes['media'];
$this->data = (array) $media::decode($type, stream_get_contents($this->_stream));
fclose($this->_stream);
}
}
if (isset($_FILES) && $_FILES) {
$result = array();
$normalize = function ($key, $value) use($result, &$normalize) {
foreach ($value as $param => $content) {
foreach ($content as $num => $val) {
if (is_numeric($num)) {
$result[$key][$num][$param] = $val;
continue;
}
if (is_array($val)) {
foreach ($val as $next => $one) {
$result[$key][$num][$next][$param] = $one;
}
continue;
}
$result[$key][$num][$param] = $val;
}
}
return $result;
};
foreach ($_FILES as $key => $value) {
if (isset($value['name'])) {
if (is_string($value['name'])) {
$result[$key] = $value;
continue;
}
if (is_array($value['name'])) {
$result += $normalize($key, $value);
}
}
}
$this->data = Set::merge((array) $this->data, $result);
}
}
示例7: create
/**
* Instantiates a new record or document object, initialized with any data passed in. For
* example:
*
* {{{
* $post = Posts::create(array('title' => 'New post'));
* echo $post->title; // echoes 'New post'
* $success = $post->save();
* }}}
*
* Note that while this method creates a new object, there is no effect on the database until
* the `save()` method is called.
*
* In addition, this method can be used to simulate loading a pre-existing object from the
* database, without actually querying the database:
*
* {{{
* $post = Posts::create(array('id' => $id, 'moreData' => 'foo'), array('exists' => true));
* $post->title = 'New title';
* $success = $post->save();
* }}}
*
* This will create an update query against the object with an ID matching `$id`. Also note that
* only the `title` field will be updated.
*
* @param array $data Any data that this object should be populated with initially.
* @param array $options Options to be passed to item.
* @return object Returns a new, _un-saved_ record or document object. In addition to the values
* passed to `$data`, the object will also contain any values assigned to the
* `'default'` key of each field defined in `$_schema`.
* @filter
*/
public static function create(array $data = array(), array $options = array())
{
return static::_filter(__FUNCTION__, compact('data', 'options'), function ($self, $params) {
$data = Set::merge(Set::expand($self::schema()->defaults()), $params['data']);
return $self::connection()->item($self, $data, $params['options']);
});
}
示例8: testMerge
public function testMerge() {
$result = Set::merge(array('foo'), array());
$this->assertIdentical($result, array('foo'));
$result = Set::merge((array) 'foo', (array) 'bar');
$this->assertIdentical($result, array('foo', 'bar'));
$result = Set::merge((array) 'foo', array('user' => 'bob', 'no-bar'));
$this->assertIdentical($result, array('foo', 'user' => 'bob', 'no-bar'));
$a = array('foo', 'foo2');
$b = array('bar', 'bar2');
$this->assertIdentical(Set::merge($a, $b), array('foo', 'foo2', 'bar', 'bar2'));
$a = array('foo' => 'bar', 'bar' => 'foo');
$b = array('foo' => 'no-bar', 'bar' => 'no-foo');
$this->assertIdentical(Set::merge($a, $b), array('foo' => 'no-bar', 'bar' => 'no-foo'));
$a = array('users' => array('bob', 'jim'));
$b = array('users' => array('lisa', 'tina'));
$this->assertIdentical(
Set::merge($a, $b), array('users' => array('bob', 'jim', 'lisa', 'tina'))
);
$a = array('users' => array('jim', 'bob'));
$b = array('users' => 'none');
$this->assertIdentical(Set::merge($a, $b), array('users' => 'none'));
$a = array('users' => array('lisa' => array('id' => 5, 'pw' => 'secret')), 'lithium');
$b = array('users' => array('lisa' => array('pw' => 'new-pass', 'age' => 23)), 'ice-cream');
$this->assertIdentical(
Set::merge($a, $b),
array(
'users' => array('lisa' => array('id' => 5, 'pw' => 'new-pass', 'age' => 23)),
'lithium',
'ice-cream'
)
);
$c = array(
'users' => array(
'lisa' => array('pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog')
),
'chocolate'
);
$expected = array(
'users' => array(
'lisa' => array(
'id' => 5, 'pw' => 'you-will-never-guess', 'age' => 25, 'pet' => 'dog'
)
),
'lithium',
'ice-cream',
'chocolate'
);
$this->assertIdentical($expected, Set::merge(Set::merge($a, $b), $c));
$this->assertIdentical($expected, Set::merge(Set::merge($a, $b), Set::merge(array(), $c)));
$result = Set::merge($a, Set::merge($b, $c));
$this->assertIdentical($expected, $result);
$a = array('Tree', 'CounterCache', 'Upload' => array(
'folder' => 'products', 'fields' => array(
'image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id'
)
));
$b = array(
'Cacheable' => array('enabled' => false),
'Limit', 'Bindable', 'Validator', 'Transactional'
);
$expected = array('Tree', 'CounterCache', 'Upload' => array(
'folder' => 'products', 'fields' => array(
'image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id'
)),
'Cacheable' => array('enabled' => false),
'Limit',
'Bindable',
'Validator',
'Transactional'
);
$this->assertIdentical(Set::merge($a, $b), $expected);
$expected = array('Tree' => null, 'CounterCache' => null, 'Upload' => array(
'folder' => 'products', 'fields' => array(
'image_1_id', 'image_2_id', 'image_3_id', 'image_4_id', 'image_5_id'
)),
'Cacheable' => array('enabled' => false),
'Limit' => null,
'Bindable' => null,
'Validator' => null,
'Transactional' => null
);
$this->assertIdentical(Set::normalize(Set::merge($a, $b)), $expected);
}
示例9: _init
/**
* Initialize request object, pulling request data from superglobals.
*
* Defines an artificial `'PLATFORM'` environment variable as either
* `'IIS'`, `'CGI'` or `null` to allow checking for the SAPI in a
* normalized way.
*
* @return void
*/
protected function _init()
{
parent::_init();
$mobile = array('iPhone', 'MIDP', 'AvantGo', 'BlackBerry', 'J2ME', 'Opera Mini', 'DoCoMo', 'NetFront', 'Nokia', 'PalmOS', 'PalmSource', 'portalmmm', 'Plucker', 'ReqwirelessWeb', 'iPod', 'SonyEricsson', 'Symbian', 'UP\\.Browser', 'Windows CE', 'Xiino', 'Android');
if (!empty($this->_config['detectors']['mobile'][1])) {
$mobile = array_merge($mobile, (array) $this->_config['detectors']['mobile'][1]);
}
$this->_detectors['mobile'][1] = $mobile;
$defaults = array('REQUEST_METHOD' => 'GET', 'CONTENT_TYPE' => 'text/html');
$this->_env += (array) $_SERVER + (array) $_ENV + $defaults;
$envs = array('isapi' => 'IIS', 'cgi' => 'CGI', 'cgi-fcgi' => 'CGI');
$this->_env['PLATFORM'] = isset($envs[PHP_SAPI]) ? $envs[PHP_SAPI] : null;
$this->_base = $this->_base();
$this->url = $this->_url();
if (!empty($this->_config['query'])) {
$this->query = $this->_config['query'];
}
if (isset($_GET)) {
$this->query += $_GET;
}
if (!empty($this->_config['data'])) {
$this->data = $this->_config['data'];
}
if (isset($_POST)) {
$this->data += $_POST;
}
if (isset($this->data['_method'])) {
$this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'] = strtoupper($this->data['_method']);
unset($this->data['_method']);
}
if (!empty($this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'])) {
$this->_env['REQUEST_METHOD'] = $this->_env['HTTP_X_HTTP_METHOD_OVERRIDE'];
}
$type = $this->type($this->_env['CONTENT_TYPE']);
$this->method = $method = strtoupper($this->_env['REQUEST_METHOD']);
if (!$this->data && ($method == 'POST' || $method == 'PUT')) {
if ($type !== 'html') {
$this->_stream = $this->_stream ?: fopen('php://input', 'r');
$media = $this->_classes['media'];
$this->data = (array) $media::decode($type, stream_get_contents($this->_stream));
fclose($this->_stream);
}
}
$this->data = Set::merge((array) $this->data, $this->_parseFiles());
}
示例10: create
/**
* Instantiates a new record or document object, initialized with any data passed in. For
* example:
*
* {{{
* $post = Posts::create(array("title" => "New post"));
* echo $post->title; // echoes "New post"
* $success = $post->save();
* }}}
*
* Note that while this method creates a new object, there is no effect on the database until
* the `save()` method is called.
*
* In addition, this method can be used to simulate loading a pre-existing object from the
* database, without actually querying the database:
*
* {{{
* $post = Posts::create(array("id" => $id, "moreData" => "foo"), array("exists" => true));
* $post->title = "New title";
* $success = $post->save();
* }}}
*
* This will create an update query against the object with an ID matching `$id`. Also note that
* only the `title` field will be updated.
*
* @param array $data Any data that this object should be populated with initially.
* @param array $options Options to be passed to item.
* @return object Returns a new, _un-saved_ record or document object. In addition to the values
* passed to `$data`, the object will also contain any values assigned to the
* `'default'` key of each field defined in `$_schema`.
* @filter
*/
public static function create(array $data = array(), array $options = array())
{
$self = static::_object();
$params = compact('data', 'options');
return static::_filter(__FUNCTION__, $params, function ($self, $params) {
$data = $params['data'];
$options = $params['options'];
$defaults = array();
foreach ((array) $self::schema() as $field => $config) {
if (isset($config['default'])) {
$defaults[$field] = $config['default'];
}
}
$data = Set::merge(Set::expand($defaults), $data);
return $self::connection()->item($self, $data, $options);
});
}
示例11: _appendObject
protected static function _appendObject($changes, $path, $key, $object)
{
$options = array('finalize' => false);
if ($object->exists()) {
return Set::merge($changes, static::_update($object->export()));
}
$changes['update']["{$path}{$key}"] = static::_create($object->export(), $options);
return $changes;
}
示例12: add
/**
* Adds an Access rule. This works much like the Validator class.
* All rules should be anonymous functions and will be passed
* $request, $resource, and $options which will contain the entire
* rule array which contains its own name plus other data that
* could be used to determine access.
*
* @param string $name The rule name.
* @param function $rule The closure for the rule, which has to return true or false.
*/
public static function add($name, $rule = null) {
if (!is_array($name)) {
$name = array($name => $rule);
}
self::$_rules = Set::merge(self::$_rules, $name);
}
示例13: manage
/**
* The manage method serves as both an index listing of all galleries as well
* as a management tool for items within the gallery.
*
* If no $id is passed, then an indexed listing of galleries (with links) will appear.
* Clicking on one of these listed galleries will then return to this method with
* and $id value present.
*
* When an $id is present, the user will be able to add existing gallery items to
* the gallery as well as upload new gallery items to be associated with the gallery.
*
* @param string $id The Page id for the gallery
* @return
*/
public function manage($id = null)
{
// TODO: Use Minerva's access system (li3_access)
// Bigger todo: update li3_acess (Nate's changes) and redo Minerva's access system completely.
$user = Auth::check('minerva_user');
if ($user['role'] != 'administrator' && $user['role'] != 'content_editor') {
$this->redirect('/');
return;
}
if (empty($id)) {
// Default options for pagination, merge with URL parameters
$defaults = array('page' => 1, 'limit' => 10, 'order' => 'created.desc');
$params = Set::merge($defaults, $this->request->params);
if (isset($params['page']) && $params['page'] == 0) {
$params['page'] = 1;
}
list($limit, $page, $order) = array($params['limit'], $params['page'], $params['order']);
// Never allow a limit of 0
$limit = $limit < 0 ? 1 : $limit;
// Only pull back minerva_gallery pages
$conditions = array('document_type' => 'minerva_gallery');
// For search queries
if (isset($this->request->query['q']) && !empty($this->request->query['q'])) {
$search_schema = Page::searchSchema();
$search_conditions = array();
// For each searchable field, adjust the conditions to include a regex
foreach ($search_schema as $k => $v) {
$search_regex = new \MongoRegex('/' . $this->request->query['q'] . '/i');
$conditions['$or'][] = array($k => $search_regex);
}
}
// Get the documents and the total
$documents = Page::find('all', array('conditions' => $conditions, 'limit' => (int) $limit, 'offset' => ((int) $page - 1) * (int) $limit, 'order' => $params['order']));
$total = Page::find('count', array('conditions' => $conditions));
$page_number = (int) $page;
$total_pages = (int) $limit > 0 ? ceil($total / $limit) : 0;
// Use the manage_index template in this case
$this->_render['template'] = 'manage_index';
// Set data for the view template
$this->set(compact('documents', 'limit', 'page_number', 'total_pages', 'total'));
} else {
// Only pull the latest 30 gallery items from the entire system...
// Because it's reasonable. There could be thousands of items and paging
// through is an option, but not practical for the design and user experience.
// 30 of the latest is enough and the user can make a search to find what
// they are after. The point of this listing of items is to allow the user to
// associate an existing item in the system with the current gallery.
// It's not going to be as common as adding brand new items instead.
// Well, unless the user really goes back to share items across multiple
// galleries on a regular basis...I don't think it's common, but possible.
// So showing 30 plus a search is plenty.
$conditions = array('published' => true, '_galleries' => array('$nin' => array($id)));
// For search queries for items
if (isset($this->request->query['q']) && !empty($this->request->query['q'])) {
$search_schema = Item::searchSchema();
$search_conditions = array();
// For each searchable field, adjust the conditions to include a regex
foreach ($search_schema as $k => $v) {
$search_regex = new \MongoRegex('/' . $this->request->query['q'] . '/i');
$conditions['$or'][] = array($k => $search_regex);
}
}
// Find the unassociated gallery items
$items = Item::find('all', array('conditions' => $conditions, 'limit' => 30, 'order' => array('created' => 'desc')));
// Find all items for the current gallery
$gallery_items = Item::find('all', array('conditions' => array('_galleries' => $id)));
// Find the gallery document itself
$document = Page::find('first', array('conditions' => array('_id' => $id)));
// Order those gallery items based on the gallery document's gallery_item_order field (if set)
if (isset($document->gallery_item_order) && !empty($document->gallery_item_order)) {
// This sort() method is the awesome.
$ordering = $document->gallery_item_order->data();
// data() must be called so that the iterator loads up all the documents...
// Something that has to be fixed I guess. Then data() doesn't need to be called.
$gallery_items->data();
$gallery_items->sort(function ($a, $b) use($ordering) {
if ($a['_id'] == $b['_id']) {
return strcmp($a['_id'], $b['_id']);
}
$cmpa = array_search($a['_id'], $ordering);
$cmpb = array_search($b['_id'], $ordering);
return $cmpa > $cmpb ? 1 : -1;
});
}
$this->set(compact('document', 'items', 'gallery_items'));
}
//.........这里部分代码省略.........
示例14: _strategies
/**
* Strategies used to query related objects, indexed by key.
*/
protected function _strategies()
{
return array(static::LINK_EMBEDDED => function ($object, $relationship) {
$fieldName = $relationship->fieldName();
return $object->{$fieldName};
}, static::LINK_CONTAINED => function ($object, $relationship) {
$isArray = $relationship->type() === "hasMany";
return $isArray ? $object->parent()->parent() : $object->parent();
}, static::LINK_KEY => function ($object, $relationship, $options) {
$model = $relationship->to();
if (!($query = $relationship->query($object))) {
return;
}
$method = $relationship->type() === "hasMany" ? 'all' : 'first';
return $model::$method(Set::merge((array) $query, (array) $options));
}, static::LINK_KEY_LIST => function ($object, $relationship, $options) {
$model = $relationship->to();
$query = $relationship->query($object);
return $model::all(Set::merge($query, $options));
});
}
示例15: type
//.........这里部分代码省略.........
* order to produce the best representation of the requested resource for the client; in other
* words, the resource that most closely matches what the client is asking for.
*
* Content negotiation with media types is made possible through the `'conditions'` key of the
* `$options` parameter, which contains an array of assertions made against the `Request`
* object. Each assertion (array key) can be one of three different things:
*
* - `'type'` _boolean_: In the default routing, some routes have `{:type}` keys, which are
* designed to match file extensions in URLs. These values act as overrides for the HTTP
* `Accept` header, allowing different formats to be served with the same content type. For
* example, if you're serving [ JSONP](http://en.wikipedia.org/wiki/JSON#JSONP), you'll want
* to serve it with the same content-type as JavaScript (since it is JavaScript), but you
* probably won't want to use the same template(s) or other settings. Therefore, when serving
* JSONP content, you can specify that the extension defined in the type must be present in
* the URL:
* {{{
* Media::type('jsonp', array('text/html'), array(
* // template settings...
* 'conditions' => array('type' => true)
* ));
* }}}
* Then, JSONP content will only ever be served when the request URL ends in `.jsonp`.
*
* - `'<prefix>:<key>'` _string_: This type of assertion can be used to match against arbitrary
* information in the request, including headers (i.e. `'http:user_agent'`), environment
* variables (i.e. `'env:home'`), GET and POST data (i.e. `'query:foo'` or `'data:foo'`,
* respectively), and the HTTP method (`'http:method'`) of the request. For more information
* on possible keys, see `lithium\action\Request::get()`.
*
* - `'<detector>'` _boolean_: Uses detector checks added to the `Request` object to make
* boolean assertions against the request. For example, if a detector called `'iPhone'` is
* attached, you can add `'iPhone' => true` to the `'conditions'` array in order to filter for
* iPhone requests only. See `lithium\action\Request::detect()` for more information on adding
* detectors.
*
* @see lithium\net\http\Media::$_types
* @see lithium\net\http\Media::$_handlers
* @see lithium\net\http\Media::negotiate()
* @see lithium\action\Request::get()
* @see lithium\action\Request::is()
* @see lithium\action\Request::detect()
* @see lithium\util\String::insert()
* @param string $type A file-extension-style type name, i.e. `'txt'`, `'js'`, or `'atom'`.
* Alternatively, a mapped content type, i.e. `'text/html'`,
* `'application/atom+xml'`, etc.; in which case, the matching type name (i.e.
* '`html'` or `'atom'`) will be returned.
* @param mixed $content Optional. A string or array containing the content-type(s) that
* `$type` should map to. If `$type` is an array of content-types, the first one listed
* should be the "primary" type, and will be used as the `Content-type` header of any
* `Response` objects served through this type.
* @param array $options Optional. The handling options for this media type. Possible keys are:
* - `'view'` _string_: Specifies the view class to use when rendering this content.
* Note that no `'view'` class is specified by default. If you want to
* render templates using Lithium's default view class, use
* `'lithium\template\View'`
* - `'decode'` _mixed_: A (string) function name or (object) closure that handles
* decoding or unserializing content from this format.
* - `'encode'` _mixed_: A (string) function name or (object) closure that handles
* encoding or serializing content into this format.
* - `'cast'` _boolean_: Used with `'encode'`. If `true`, all data passed into the
* specified encode function is first cast to array structures.
* - `'paths'` _array_: Optional key/value pairs mapping paths for
* `'template'`, `'layout'`, and `'element'` template files. Any keys ommitted
* will use the default path. The values should be `String::insert()`-style
* paths or an array of `String::insert()`-style paths. If it is an array,
* each path will be tried in the order specified until a template is found.
* This is useful for allowing custom templates while falling back on
* default templates if no custom template was found. If you want to
* render templates without a layout, use a `false` value for `'layout'`.
* - `'conditions'` _array_: Optional key/value pairs used as assertions in content
* negotiation. See the above section on **Content Negotiation**.
* @return mixed If `$content` and `$options` are empty, returns an array with `'content'` and
* `'options'` keys, where `'content'` is the content-type(s) that correspond to
* `$type` (can be a string or array, if multiple content-types are available), and
* `'options'` is the array of options which define how this content-type should be
* handled. If `$content` or `$options` are non-empty, returns `null`.
*/
public static function type($type, $content = null, array $options = array())
{
$defaults = array('view' => false, 'paths' => array('template' => '{:library}/views/{:controller}/{:template}.{:type}.php', 'layout' => '{:library}/views/layouts/{:layout}.{:type}.php', 'element' => '{:library}/views/elements/{:template}.{:type}.php'), 'encode' => false, 'decode' => false, 'cast' => true, 'conditions' => array());
if ($content === false) {
unset(static::$_types[$type], static::$_handlers[$type]);
}
if (!$content && !$options) {
if (!($content = static::_types($type))) {
return;
}
if (strpos($type, '/')) {
return $content;
}
if (is_array($content) && isset($content['alias'])) {
return static::type($content['alias']);
}
return compact('content') + array('options' => static::_handlers($type));
}
if ($content) {
static::$_types[$type] = (array) $content;
}
static::$_handlers[$type] = $options ? Set::merge($defaults, $options) : array();
}