| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160 |
- <?php
- declare(strict_types=1);
- /**
- * CakePHP(tm) : Rapid Development Framework (https://cakephp.org)
- * Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- *
- * Licensed under The MIT License
- * For full copyright and license information, please see the LICENSE.txt
- * Redistributions of files must retain the above copyright notice.
- *
- * @copyright Copyright (c) Cake Software Foundation, Inc. (https://cakefoundation.org)
- * @link https://cakephp.org CakePHP(tm) Project
- * @since 2.1.0
- * @license https://opensource.org/licenses/mit-license.php MIT License
- */
- namespace Cake\View;
- use Cake\Core\Configure;
- use Cake\Utility\Hash;
- use Cake\Utility\Xml;
- /**
- * A view class that is used for creating XML responses.
- *
- * By setting the 'serialize' option in view builder of your controller, you can specify
- * a view variable that should be serialized to XML and used as the response for the request.
- * This allows you to omit views + layouts, if your just need to emit a single view
- * variable as the XML response.
- *
- * In your controller, you could do the following:
- *
- * ```
- * $this->set(['posts' => $posts]);
- * $this->viewBuilder()->setOption('serialize', true);
- * ```
- *
- * When the view is rendered, the `$posts` view variable will be serialized
- * into XML.
- *
- * **Note** The view variable you specify must be compatible with Xml::fromArray().
- *
- * You can also set `'serialize'` as an array. This will create an additional
- * top level element named `<response>` containing all the named view variables:
- *
- * ```
- * $this->set(compact('posts', 'users', 'stuff'));
- * $this->viewBuilder()->setOption('serialize', true);
- * ```
- *
- * The above would generate a XML object that looks like:
- *
- * `<response><posts>...</posts><users>...</users></response>`
- *
- * You can also set `'serialize'` to a string or array to serialize only the
- * specified view variables.
- *
- * If you don't set the `serialize` option, you will need a view. You can use extended
- * views to provide layout like functionality.
- */
- class XmlView extends SerializedView
- {
- /**
- * XML layouts are located in the xml sub directory of `Layouts/`
- *
- * @var string
- */
- protected $layoutPath = 'xml';
- /**
- * XML views are located in the 'xml' sub directory for controllers' views.
- *
- * @var string
- */
- protected $subDir = 'xml';
- /**
- * Response type.
- *
- * @var string
- */
- protected $_responseType = 'xml';
- /**
- * Option to allow setting an array of custom options for Xml::fromArray()
- *
- * For e.g. 'format' as 'attributes' instead of 'tags'.
- *
- * @var array|null
- */
- protected $xmlOptions;
- /**
- * Default config options.
- *
- * Use ViewBuilder::setOption()/setOptions() in your controller to set these options.
- *
- * - `serialize`: Option to convert a set of view variables into a serialized response.
- * Its value can be a string for single variable name or array for multiple
- * names. If true all view variables will be serialized. If null or false
- * normal view template will be rendered.
- * - `xmlOptions`: Option to allow setting an array of custom options for Xml::fromArray().
- * For e.g. 'format' as 'attributes' instead of 'tags'.
- * - `rootNode`: Root node name. Defaults to "response".
- *
- * @var array{serialize:string|bool|null, xmlOptions: int|null, rootNode: string|null}
- */
- protected $_defaultConfig = [
- 'serialize' => null,
- 'xmlOptions' => null,
- 'rootNode' => null,
- ];
- /**
- * Serialize view vars.
- *
- * @param array|string $serialize The name(s) of the view variable(s) that need(s) to be serialized
- * @return string|false The serialized data
- */
- protected function _serialize($serialize)
- {
- $rootNode = $this->getConfig('rootNode', 'response');
- if (is_array($serialize)) {
- if (empty($serialize)) {
- $serialize = null;
- } elseif (count($serialize) === 1) {
- $serialize = current($serialize);
- }
- }
- if (is_array($serialize)) {
- $data = [$rootNode => []];
- foreach ($serialize as $alias => $key) {
- if (is_numeric($alias)) {
- $alias = $key;
- }
- if (array_key_exists($key, $this->viewVars)) {
- $data[$rootNode][$alias] = $this->viewVars[$key];
- }
- }
- } else {
- $data = $this->viewVars[$serialize] ?? null;
- if (is_array($data) && Hash::numeric(array_keys($data))) {
- $data = [$rootNode => [$serialize => $data]];
- }
- }
- $options = $this->getConfig('xmlOptions', []);
- if (Configure::read('debug')) {
- $options['pretty'] = true;
- }
- if (isset($options['return']) && strtolower($options['return']) === 'domdocument') {
- return Xml::fromArray($data, $options)->saveXML();
- }
- return Xml::fromArray($data, $options)->asXML();
- }
- }
|