├── .gitignore
├── .gitmodules
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── classes
├── Dataflow.php
├── Dataflow
│ ├── Decode.php
│ ├── Decode
│ │ ├── JSON.php
│ │ ├── JSONP.php
│ │ ├── PHP.php
│ │ ├── XML.php
│ │ └── YAML.php
│ ├── Encode.php
│ └── Encode
│ │ ├── JSON.php
│ │ ├── JSONP.php
│ │ ├── PHP.php
│ │ ├── XML.php
│ │ └── YAML.php
└── Kohana
│ ├── Dataflow.php
│ └── Dataflow
│ ├── Decode.php
│ ├── Decode
│ ├── JSON.php
│ ├── JSONP.php
│ ├── PHP.php
│ ├── XML.php
│ └── YAML.php
│ ├── Encode.php
│ └── Encode
│ ├── JSON.php
│ ├── JSONP.php
│ ├── PHP.php
│ ├── XML.php
│ └── YAML.php
├── config
└── userguide.php
├── guide
└── dataflow
│ ├── basics.md
│ ├── drivers
│ └── xml.md
│ ├── index.md
│ └── menu.md
└── tests
└── kohana
├── DataflowTest.php
└── dataflow
├── JSONPTest.php
├── JSONTest.php
├── PHPTest.php
├── XMLTest.php
└── YAMLTest.php
/.gitignore:
--------------------------------------------------------------------------------
1 | .DS_Store
2 |
--------------------------------------------------------------------------------
/.gitmodules:
--------------------------------------------------------------------------------
1 | [submodule "vendor/yaml"]
2 | path = vendor/yaml
3 | url = git://github.com/fabpot/yaml.git
4 |
--------------------------------------------------------------------------------
/CHANGELOG.md:
--------------------------------------------------------------------------------
1 | # 0.5.0 - 07/23/2013
2 |
3 | - Resolved separate issues with encoding and decoding of XML attributes
4 | - Added unit tests to test against newly resolved issues
5 | - Added documentation on how to encode and decode XML attributes
6 | - Updated copyright years
7 | - All tests pass: "OK (27 tests, 27 assertions)"
8 |
9 | # 0.4.1 - 12/10/2012
10 |
11 | - Resolved class case (correctly renamed class files and directories)
12 | - Updated documentation to reflect new driver case
13 | - All tests pass: "OK (25 tests, 25 assertions)"
14 |
15 | # 0.4.0 - 12/06/2012
16 |
17 | - Renamed `Encode::get_content_type` to `Encode::content_type`
18 | - Removed `Encode::_setup` and `Decode::_setup` due to limited usage, using constructor instead
19 | - Resolved issue with decoding XML attributes
20 | - Upgraded to support Kohana 3.3
21 | - Renamed class files and directories to support PSR-0
22 | - Resolved pass by reference issue (now testing in strict mode)
23 | - Expanded user guide documentation and unit test coverage
24 | - All tests pass: "OK (25 tests, 25 assertions)"
25 |
26 | # 0.3.0 - 04/09/2012
27 |
28 | - Added JSON-P encode and decode support.
29 | - Added "pluralize" option for XML encode. This enables children indexes to be wrapped in a plural key
30 | while children dynamically use singular keys. Example `array('values' => array('a', 'b'))` to
31 | `ab`. This keeps other serialized formats free of
32 | the singular keys when using more than one driver for output.
33 | - All tests pass: "OK (20 tests, 20 assertions)"
34 |
35 | # 0.2.0 - 10/19/2011
36 |
37 | - Added support for XML, YAML and serialized PHP
38 | - Renamed `Dataflow_Input` to `Dataflow_Decode` and `Dataflow_Output` to `Dataflow_Encode`
39 | - Encode and decode abstracts more consistent including expected variable types
40 | - `Dataflow_Encode::render` now accepts `Request` for modifying Content-Type header
41 | - Added `Dataflow::as_array` to return input array
42 | - Refactored unit tests into an abstract for consistent sampling across drivers
43 |
44 | # 0.1.0 - 06/04/2011
45 |
46 | - Initial release of Dataflow with support for JSON
47 | - `Dataflow_Input` abstraction for converting serialized format into an associative array
48 | - `Dataflow_Output` abstraction for converting associative array into serialized format
49 | - `Dataflow` acts as a bridge for handling input and output
50 | - Unit test coverage
51 |
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | The MIT License
2 |
3 | Copyright (c) 2011-2012 by Micheal Morgan
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
6 |
7 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
8 |
9 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | :warning: **Notice**: The Kohana Framework announced official retirement on 07/01/2017. Therefore, this repository is no longer maintained.
2 |
3 | ----
4 |
5 | # Dataflow Module
6 |
7 | Simple way of translating to or from XML, YAML, JSON, JSON-P and serialized PHP. Great for general
8 | usage or incorporating into a REST API.
9 |
10 | // Set drivers (each key is config that passes through to its respective library,
11 | // `decode` to `Dataflow_Decode` and `encode` to `Dataflow_Encode`)
12 | $config = array
13 | (
14 | 'decode' => array('driver' => 'YAML'),
15 | 'encode' => array('driver' => 'XML')
16 | );
17 |
18 | // Example of converting XML to YAML and outputting results
19 | echo Dataflow::factory($config)->set($xml);
20 |
21 | // Convert any supported format to a standardized array
22 | Dataflow::factory()
23 | ->set($input)
24 | ->as_array();
25 |
26 | // Decode XML to an associative array
27 | $array = Dataflow_Decode::factory(array('driver' => 'XML'))
28 | ->set($xml)
29 | ->get();
30 |
31 | // Encode associative array to XML
32 | $xml = Dataflow_Encode::factory(array('driver' => 'XML'))
33 | ->set($array)
34 | ->get();
35 |
36 | ## Getting Started
37 |
38 | Recommend starting out with Dataflow documentation using the User Guide module.
39 |
40 | ## Learning & References
41 |
42 | - User Guide
43 | - API Browser
44 | - Unit Tests
45 |
46 | ## Version 0.5.0
47 |
48 | This is release version 0.5.0 of [Dataflow](https://github.com/morgan/kohana-dataflow).
49 |
--------------------------------------------------------------------------------
/classes/Dataflow.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow extends Kohana_Dataflow {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | abstract class Dataflow_Decode extends Kohana_Dataflow_Decode {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode/JSON.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Decode_JSON extends Kohana_Dataflow_Decode_JSON {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode/JSONP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Decode_JSONP extends Kohana_Dataflow_Decode_JSONP {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode/PHP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Decode_PHP extends Kohana_Dataflow_Decode_PHP {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode/XML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Decode_XML extends Kohana_Dataflow_Decode_XML {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Decode/YAML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Decode_YAML extends Kohana_Dataflow_Decode_YAML {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | abstract class Dataflow_Encode extends Kohana_Dataflow_Encode {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode/JSON.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Encode_JSON extends Kohana_Dataflow_Encode_JSON {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode/JSONP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2012-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Encode_JSONP extends Kohana_Dataflow_Encode_JSONP {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode/PHP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Encode_PHP extends Kohana_Dataflow_Encode_PHP {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode/XML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Encode_XML extends Kohana_Dataflow_Encode_XML {}
12 |
--------------------------------------------------------------------------------
/classes/Dataflow/Encode/YAML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Dataflow_Encode_YAML extends Kohana_Dataflow_Encode_YAML {}
12 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @static
18 | * @access public
19 | * @return Dataflow
20 | */
21 | public static function factory(array $config = array())
22 | {
23 | return new Dataflow($config);
24 | }
25 |
26 | /**
27 | * Configuration
28 | *
29 | * @access protected
30 | * @var array
31 | */
32 | protected $_config = array
33 | (
34 | 'decode' => array(),
35 | 'encode' => array()
36 | );
37 |
38 | /**
39 | * Decoded input as array
40 | *
41 | * @access protected
42 | * @var array
43 | */
44 | protected $_input = array();
45 |
46 | /**
47 | * Dataflow Output
48 | *
49 | * @access protected
50 | * @var Dataflow_Encode|NULL
51 | */
52 | protected $_output;
53 |
54 | /**
55 | * Initialize Dataflow
56 | *
57 | * @access public
58 | * @return void
59 | */
60 | public function __construct(array $config = array())
61 | {
62 | $this->_config = Arr::merge($config, $this->_config);
63 | }
64 |
65 | /**
66 | * Set input
67 | *
68 | * @access public
69 | * @return $this
70 | */
71 | public function set($input)
72 | {
73 | if (is_array($input))
74 | {
75 | $this->_input = $input;
76 | }
77 | else
78 | {
79 | $this->_input = Dataflow_Decode::factory($this->_config['decode'])
80 | ->set($input)
81 | ->get();
82 | }
83 |
84 | // Reset output due to new input
85 | $this->_output = NULL;
86 |
87 | return $this;
88 | }
89 |
90 | /**
91 | * Get output
92 | *
93 | * @access public
94 | * @param bool Whether to return encoded string or Dataflow_Encode
95 | * @return mixed string|Dataflow_Encode
96 | */
97 | public function get($encoded = TRUE)
98 | {
99 | if ($this->_output === NULL)
100 | {
101 | $this->_output = Dataflow_Encode::factory($this->_config['encode'])->set($this->_input);
102 | }
103 |
104 | return ($encoded) ? $this->_output->get() : $this->_output;
105 | }
106 |
107 | /**
108 | * Return array
109 | *
110 | * @access public
111 | * @return array
112 | */
113 | public function as_array()
114 | {
115 | return $this->_input;
116 | }
117 |
118 | /**
119 | * Magic method for converting object to string
120 | *
121 | * @access public
122 | * @return string
123 | */
124 | public function __toString()
125 | {
126 | return (string) $this->get(FALSE);
127 | }
128 |
129 | /**
130 | * Render output
131 | *
132 | * @access public
133 | * @param bool
134 | * @param mixed Request|NULL
135 | * @return $this
136 | */
137 | public function render($headers = TRUE, Request $request = NULL)
138 | {
139 | $this->get(FALSE)->render($headers, $request);
140 |
141 | return $this;
142 | }
143 | }
144 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | abstract class Kohana_Dataflow_Decode
12 | {
13 | /**
14 | * Default driver
15 | *
16 | * @static
17 | * @access public
18 | * @var string
19 | */
20 | public static $default = 'JSON';
21 |
22 | /**
23 | * Factory pattern
24 | *
25 | * @static
26 | * @access public
27 | * @return Dataflow_Input
28 | */
29 | public static function factory(array $config = array())
30 | {
31 | $config['driver'] = (isset($config['driver'])) ? $config['driver'] : Dataflow_Decode::$default;
32 |
33 | $class = 'Dataflow_Decode_' . $config['driver'];
34 |
35 | return new $class($config);
36 | }
37 |
38 | /**
39 | * Parsed data
40 | *
41 | * @access protected
42 | * @var array
43 | */
44 | protected $_decoded = array();
45 |
46 | /**
47 | * Cache driver type
48 | *
49 | * @access protected
50 | * @var string
51 | */
52 | protected $_type;
53 |
54 | /**
55 | * Default config
56 | *
57 | * @access protected
58 | * @var array
59 | */
60 | protected $_config = array();
61 |
62 | /**
63 | * Initialize
64 | *
65 | * @access public
66 | * @return void
67 | */
68 | public function __construct(array $config)
69 | {
70 | $this->_config = Arr::merge($this->_config, $config);
71 |
72 | $this->_type = $config['driver'];
73 | }
74 |
75 | /**
76 | * Decode
77 | *
78 | * @access protected
79 | * @return array
80 | */
81 | abstract protected function _decode($data);
82 |
83 | /**
84 | * Parsed input
85 | *
86 | * @access public
87 | * @return $this
88 | * @throws Kohana_Exception
89 | */
90 | public function set($data)
91 | {
92 | if ( ! is_array($this->_decoded = $this->_decode($data)))
93 | throw new Kohana_Exception('Expecting `Dataflow_Decode_' . $this->type() . '::_decode` to return an array.');
94 |
95 | return $this;
96 | }
97 |
98 | /**
99 | * Abstract getter
100 | *
101 | * @access public
102 | * @return array
103 | */
104 | public function & get()
105 | {
106 | return $this->_decoded;
107 | }
108 |
109 | /**
110 | * Type
111 | *
112 | * @access public
113 | * @return string
114 | */
115 | public function type()
116 | {
117 | return $this->_type;
118 | }
119 | }
120 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode/JSON.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Decode_JSON extends Dataflow_Decode
12 | {
13 | /**
14 | * Decode
15 | *
16 | * @access protected
17 | * @return array
18 | */
19 | protected function _decode($data)
20 | {
21 | return json_decode($data, TRUE);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode/JSONP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Decode_JSONP extends Dataflow_Decode
12 | {
13 | /**
14 | * Decode
15 | *
16 | * @access protected
17 | * @return array
18 | */
19 | protected function _decode($data)
20 | {
21 | if (FALSE !== $position = strpos($data, '('))
22 | {
23 | // remove "any_callback_name(" and trim ")"
24 | $data = rtrim(substr($data, ++$position, strlen($data)), ')');
25 | }
26 |
27 | return json_decode($data, TRUE);
28 | }
29 | }
30 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode/PHP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Decode_PHP extends Dataflow_Decode
12 | {
13 | /**
14 | * Decode
15 | *
16 | * @access protected
17 | * @return array
18 | */
19 | protected function _decode($data)
20 | {
21 | return unserialize($data);
22 | }
23 | }
24 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode/XML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Decode_XML extends Dataflow_Decode
12 | {
13 | /**
14 | * Default config
15 | *
16 | * @access protected
17 | * @var array
18 | */
19 | protected $_config = array
20 | (
21 | ':attributes' => ':attributes'
22 | );
23 |
24 | /**
25 | * Parser
26 | *
27 | * @access protected
28 | * @var NULL|resource
29 | */
30 | protected $_parser;
31 |
32 | /**
33 | * Decode
34 | *
35 | * @access protected
36 | * @return array
37 | */
38 | protected function _decode($data)
39 | {
40 | $this->_parser = xml_parser_create();
41 |
42 | xml_set_object($this->_parser, $this);
43 | xml_set_element_handler($this->_parser, '_open', '_close');
44 | xml_set_character_data_handler($this->_parser, '_data');
45 |
46 | xml_parser_set_option($this->_parser, XML_OPTION_CASE_FOLDING, FALSE);
47 |
48 | xml_parse($this->_parser, $data);
49 |
50 | if (is_array($this->_decoded))
51 | return $this->_decoded;
52 |
53 | return array();
54 | }
55 |
56 | /**
57 | * Handle open
58 | *
59 | * @access protected
60 | * @param resource
61 | * @param string
62 | * @param array
63 | * @return void
64 | */
65 | protected function _open($parser, $index, $attributes)
66 | {
67 | if (isset($this->_decoded[$index][$this->_config[':attributes']]))
68 | {
69 | $key = 1;
70 |
71 | $this->_decoded[$index] = array($this->_decoded[$index]);
72 | }
73 | else if (isset($this->_decoded[$index]))
74 | {
75 | $key = count($this->_decoded[$index]);
76 | }
77 |
78 | if (isset($key))
79 | {
80 | $this->_decoded[$index][$key] = array
81 | (
82 | 'key' => $key,
83 | 'parent' => & $this->_decoded
84 | );
85 |
86 | $this->_decoded =& $this->_decoded[$index][$key];
87 | }
88 | else
89 | {
90 | $this->_decoded[$index] = array
91 | (
92 | 'parent' => & $this->_decoded
93 | );
94 |
95 | $this->_decoded =& $this->_decoded[$index];
96 | }
97 |
98 | if ( ! empty($attributes))
99 | {
100 | $this->_decoded[$this->_config[':attributes']] = $attributes;
101 | }
102 | }
103 |
104 | /**
105 | * Handle close
106 | *
107 | * @access protected
108 | * @param resource
109 | * @param string
110 | * @return void
111 | */
112 | protected function _close($parser, $index)
113 | {
114 | $pointer =& $this->_decoded;
115 |
116 | if (isset($this->_decoded['key']))
117 | {
118 | unset($pointer['key']);
119 | }
120 |
121 | $this->_decoded =& $this->_decoded['parent'];
122 |
123 | unset($pointer['parent']);
124 |
125 | if (isset($pointer['data']) AND count($pointer) == 1)
126 | {
127 | $pointer = $pointer['data'];
128 | }
129 | else if (empty($pointer['data']) OR $pointer['data'] == 0)
130 | {
131 | unset($pointer['data']);
132 | }
133 | }
134 |
135 | /**
136 | * Handle data
137 | *
138 | * @access protected
139 | * @param resource
140 | * @param array
141 | * @return void
142 | */
143 | protected function _data($parser, $data)
144 | {
145 | $this->_decoded['data'] = $data;
146 | }
147 | }
148 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Decode/YAML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Decode_YAML extends Dataflow_Decode
12 | {
13 | /**
14 | * Initialize
15 | *
16 | * @access public
17 | * @return void
18 | */
19 | public function __construct(array $config)
20 | {
21 | parent::__construct($config);
22 |
23 | require_once Kohana::find_file('vendor', 'yaml/lib/sfYaml');
24 | }
25 |
26 | /**
27 | * Decode
28 | *
29 | * @access protected
30 | * @return array
31 | */
32 | protected function _decode($data)
33 | {
34 | return sfYaml::load($data);
35 | }
36 | }
37 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | abstract class Kohana_Dataflow_Encode
12 | {
13 | /**
14 | * Default driver
15 | *
16 | * @static
17 | * @access public
18 | * @var string
19 | */
20 | public static $default = 'JSON';
21 |
22 | /**
23 | * Factory pattern
24 | *
25 | * @static
26 | * @access public
27 | * @return Dataflow_Output
28 | */
29 | public static function factory(array $config = array())
30 | {
31 | $config['driver'] = (isset($config['driver'])) ? $config['driver'] : Dataflow_Encode::$default;
32 |
33 | $class = 'Dataflow_Encode_' . $config['driver'];
34 |
35 | return new $class($config);
36 | }
37 |
38 | /**
39 | * Data array
40 | *
41 | * @access protected
42 | * @var string
43 | */
44 | protected $_encoded = '';
45 |
46 | /**
47 | * Cache driver type
48 | *
49 | * @access protected
50 | * @var string|NULL
51 | */
52 | protected $_type;
53 |
54 | /**
55 | * Default config
56 | *
57 | * @access protected
58 | * @var array
59 | */
60 | protected $_config = array();
61 |
62 | /**
63 | * Initialize
64 | *
65 | * @access public
66 | * @return void
67 | */
68 | public function __construct(array $config)
69 | {
70 | $this->_config = Arr::merge($this->_config, $config);
71 |
72 | $this->_type = $config['driver'];
73 | }
74 |
75 | /**
76 | * Abstract content type for headers
77 | *
78 | * @access public
79 | * @return string
80 | */
81 | abstract public function content_type();
82 |
83 | /**
84 | * Transform array to driver format. Return value.
85 | *
86 | * @access protected
87 | * @param array
88 | * @return string
89 | */
90 | abstract protected function _encode(array $data);
91 |
92 | /**
93 | * Encode array to string
94 | *
95 | * @access public
96 | * @return array
97 | */
98 | public function set(array $data)
99 | {
100 | if ( ! is_string($this->_encoded = $this->_encode($data)))
101 | throw new Kohana_Exception('Expecting `Dataflow_Encode_' . $this->type() . '::_encode` to return a string.');
102 |
103 | return $this;
104 | }
105 |
106 | /**
107 | * Get encoded
108 | *
109 | * @access public
110 | * @return string
111 | */
112 | public function & get()
113 | {
114 | return $this->_encoded;
115 | }
116 |
117 | /**
118 | * Magic method for converting object to string. Intentionally not passing headers because
119 | * object is casted to a string.
120 | *
121 | * @access public
122 | * @return string
123 | */
124 | public function __toString()
125 | {
126 | $this->_headers();
127 |
128 | return $this->get();
129 | }
130 |
131 | /**
132 | * Render output to screen using proper headers.
133 | *
134 | * @access public
135 | * @param bool Whether or not to handle headers
136 | * @param mixed Request|NULL Request object for modifying headers
137 | * @return $this
138 | */
139 | public function render($headers = TRUE, Request $request = NULL)
140 | {
141 | if ($headers)
142 | {
143 | $this->_headers($request);
144 | }
145 |
146 | echo $this->get();
147 |
148 | return $this;
149 | }
150 |
151 | /**
152 | * Type
153 | *
154 | * @access public
155 | * @return string
156 | */
157 | public function type()
158 | {
159 | return $this->_type;
160 | }
161 |
162 | /**
163 | * Handle headers
164 | *
165 | * @access public
166 | * @return $this
167 | */
168 | protected function _headers(Request $request = NULL)
169 | {
170 | $request = ($request) ? $request : Request::current();
171 |
172 | // Suppress passing of headers when no request - example during CLI for unit testing
173 | if ($request)
174 | {
175 | $request->response()->headers('content-type', $this->get_content_type());
176 | }
177 |
178 | return $this;
179 | }
180 | }
181 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode/JSON.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Encode_JSON extends Dataflow_Encode
12 | {
13 | /**
14 | * Get content type
15 | *
16 | * @access public
17 | * @return string
18 | */
19 | public function content_type()
20 | {
21 | return 'application/json';
22 | }
23 |
24 | /**
25 | * Encode
26 | *
27 | * @access protected
28 | * @return string
29 | */
30 | protected function _encode(array $data)
31 | {
32 | // Force return of object if array empty
33 | if (empty($data))
34 | return '{}';
35 | else
36 | return json_encode($data);
37 | }
38 | }
39 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode/JSONP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2012-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Encode_JSONP extends Dataflow_Encode
12 | {
13 | /**
14 | * Default config
15 | *
16 | * @access protected
17 | * @var array
18 | */
19 | protected $_config = array
20 | (
21 | 'callback' => 'callback'
22 | );
23 |
24 | /**
25 | * Get content type
26 | *
27 | * @access public
28 | * @return string
29 | */
30 | public function content_type()
31 | {
32 | return 'application/json-p';
33 | }
34 |
35 | /**
36 | * Encode
37 | *
38 | * @access protected
39 | * @return string
40 | */
41 | protected function _encode(array $data)
42 | {
43 | // Force return of object if array empty
44 | $data = empty($data) ? '{}' : json_encode($data);
45 |
46 | return $this->_config['callback'] . '(' . $data . ')';
47 | }
48 | }
49 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode/PHP.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Encode_PHP extends Dataflow_Encode
12 | {
13 | /**
14 | * Get content type
15 | *
16 | * @access public
17 | * @return string
18 | */
19 | public function content_type()
20 | {
21 | return 'application/php';
22 | }
23 |
24 | /**
25 | * Encode
26 | *
27 | * @access protected
28 | * @return string
29 | */
30 | protected function _encode(array $data)
31 | {
32 | return serialize($data);
33 | }
34 | }
35 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode/XML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Encode_XML extends Dataflow_Encode
12 | {
13 | /**
14 | * Default config
15 | *
16 | * @access protected
17 | * @var array
18 | */
19 | protected $_config = array
20 | (
21 | ':content' => ':content',
22 | ':attributes' => ':attributes',
23 | ':xml' => ':xml',
24 | 'pluralize' => FALSE
25 | );
26 |
27 | /**
28 | * XML Writer
29 | *
30 | * @access protected
31 | * @var NULL|XMLWriter
32 | */
33 | protected $_writer;
34 |
35 | /**
36 | * Get content type
37 | *
38 | * @access public
39 | * @return string
40 | */
41 | public function content_type()
42 | {
43 | return 'application/xml';
44 | }
45 |
46 | /**
47 | * Encode
48 | *
49 | * @access protected
50 | * @return string
51 | */
52 | protected function _encode(array $data)
53 | {
54 | $this->_writer = new XMLWriter;
55 |
56 | $this->_writer->openMemory();
57 | $this->_writer->setIndent(TRUE);
58 | $this->_writer->setIndentString(' ');
59 | $this->_writer->startDocument('1.0', 'UTF-8');
60 |
61 | $keys = array_keys($data);
62 |
63 | if ( ! empty($data) AND $key = array_shift($keys))
64 | {
65 | $this->_writer->startElement($key);
66 |
67 | $this->_attributes($data[$key]);
68 |
69 | $data =& $data[$key];
70 | }
71 |
72 | $this->_process($data);
73 |
74 | $this->_writer->endElement();
75 | $this->_writer->endDocument();
76 |
77 | return $this->_writer->outputMemory();
78 | }
79 |
80 | /**
81 | * Process array
82 | *
83 | * @access protected
84 | * @param array
85 | * @param boolean
86 | * @return void
87 | */
88 | protected function _process($data)
89 | {
90 | if (is_array($data) AND ! empty($data))
91 | {
92 | foreach ($data as $index => $element)
93 | {
94 | if (is_array($element))
95 | {
96 | if ( ! $this->_indexed($index, $element))
97 | {
98 | $this->_writer->startElement($index);
99 |
100 | $this->_attributes($element);
101 | $this->_content($element);
102 |
103 | if ( ! empty($element))
104 | {
105 | $this->_process($element);
106 | }
107 |
108 | $this->_writer->endElement();
109 | }
110 | }
111 | else
112 | {
113 | $this->_writer->startElement($index);
114 | $this->_writer->text($element);
115 | $this->_writer->endElement();
116 | }
117 | }
118 | }
119 | }
120 |
121 | /**
122 | * Handle nested
123 | *
124 | * @access protected
125 | * @param string
126 | * @param array
127 | * @return boolean
128 | */
129 | protected function _indexed($index, $element)
130 | {
131 | if (is_array($element) AND isset($element[0]))
132 | {
133 | // If "pluralize" enabled, wrap children using plural index and set children to use
134 | // singular index
135 | if ($this->_config['pluralize'])
136 | {
137 | $this->_writer->startElement($index);
138 |
139 | $index = Inflector::singular($index);
140 | }
141 |
142 | foreach ($element as $key => $name)
143 | {
144 | $this->_writer->startElement($index);
145 |
146 | $this->_attributes($name);
147 | $this->_content($name);
148 |
149 | if ( ! empty($name))
150 | {
151 | $this->_process($name);
152 | }
153 |
154 | $this->_writer->endElement();
155 | }
156 |
157 | if ($this->_config['pluralize'])
158 | {
159 | $this->_writer->endElement();
160 | }
161 |
162 | return TRUE;
163 | }
164 |
165 | return FALSE;
166 | }
167 |
168 | /**
169 | * Handle content
170 | *
171 | * @access protected
172 | * @param mixed
173 | * @return boolean
174 | */
175 | protected function _content($element)
176 | {
177 | if (is_array($element))
178 | {
179 | if (is_array($element) AND isset($element[$this->_config[':content']]))
180 | {
181 | $this->_writer->text($element[$this->_config[':content']]);
182 |
183 | unset($element[$this->_config[':content']]);
184 |
185 | return TRUE;
186 | }
187 | else if (is_array($element) AND isset($element[$this->_config[':xml']]))
188 | {
189 | $this->_writer->writeRaw($element[$this->_config[':xml']]);
190 |
191 | unset($element[$this->_config[':xml']]);
192 |
193 | return TRUE;
194 | }
195 | }
196 | else if ( ! is_array($element))
197 | {
198 | $this->_writer->text($element);
199 |
200 | unset($element);
201 |
202 | return TRUE;
203 | }
204 |
205 | return FALSE;
206 | }
207 |
208 | /**
209 | * Handle attributes
210 | *
211 | * @access protected
212 | * @param array
213 | * @return boolean
214 | */
215 | protected function _attributes( & $element)
216 | {
217 | if (is_array($element) AND isset($element[$this->_config[':attributes']]))
218 | {
219 | foreach ($element[$this->_config[':attributes']] as $key => $value)
220 | {
221 | $this->_writer->writeAttribute($key, $value);
222 | }
223 |
224 | unset($element[$this->_config[':attributes']]);
225 |
226 | return TRUE;
227 | }
228 |
229 | return FALSE;
230 | }
231 | }
232 |
--------------------------------------------------------------------------------
/classes/Kohana/Dataflow/Encode/YAML.php:
--------------------------------------------------------------------------------
1 |
8 | * @copyright (c) 2011-2013 Micheal Morgan
9 | * @license MIT
10 | */
11 | class Kohana_Dataflow_Encode_YAML extends Dataflow_Encode
12 | {
13 | /**
14 | * Initialize
15 | *
16 | * @access public
17 | * @return void
18 | */
19 | public function __construct(array $config)
20 | {
21 | parent::__construct($config);
22 |
23 | require_once Kohana::find_file('vendor', 'yaml/lib/sfYaml');
24 | }
25 |
26 | /**
27 | * Get content type
28 | *
29 | * @access public
30 | * @return string
31 | */
32 | public function content_type()
33 | {
34 | return 'application/yaml';
35 | }
36 |
37 | /**
38 | * Encode
39 | *
40 | * @access protected
41 | * @return string
42 | */
43 | protected function _encode(array $data)
44 | {
45 | return sfYaml::dump($data);
46 | }
47 | }
48 |
--------------------------------------------------------------------------------
/config/userguide.php:
--------------------------------------------------------------------------------
1 | array
5 | (
6 | 'dataflow' => array
7 | (
8 | 'enabled' => TRUE,
9 | 'name' => 'Dataflow',
10 | 'description' => 'Translate data from one encoded format to another.',
11 | 'copyright' => '© 2011-2013 Micheal Morgan',
12 | )
13 | )
14 | );
--------------------------------------------------------------------------------
/guide/dataflow/basics.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | ## Basic Usage
4 |
5 | $dataflow = Dataflow::factory();
6 |
7 | // Set basic JSON
8 | $dataflow->set('{}');
9 |
10 | // Get input as array
11 | var_dump($dataflow->as_array());
12 |
13 | // Get input as another format
14 | var_dump($dataflow->get());
15 |
16 | ## Setting drivers
17 |
18 | $config = array
19 | (
20 | 'decode' => array('driver' => 'YAML'),
21 | 'encode' => array('driver' => 'XML')
22 | );
23 |
24 | $dataflow = Dataflow::factory($config);
25 |
26 | ## Rendering output
27 |
28 | Simply echo contents:
29 |
30 | echo $dataflow;
31 |
32 | Render passing headers based on driver. Uses default Request object:
33 |
34 | $dataflow->render();
35 |
36 | Render without passing headers:
37 |
38 | $dataflow->render(FALSE);
39 |
40 | Apply headers to custom Request object:
41 |
42 | $dataflow->render(TRUE, $request);
43 |
--------------------------------------------------------------------------------
/guide/dataflow/drivers/xml.md:
--------------------------------------------------------------------------------
1 | # XML Driver
2 |
3 | ## Encoding Attributes
4 |
5 | Encoding attributes requires using the `:attributes` key.
6 |
7 | // Setup XML encode driver
8 | $encode = Dataflow_Encode::factory(array('driver' => 'XML'));
9 |
10 | $decoded = array
11 | (
12 | 'parent' => array
13 | (
14 | 'child' => array
15 | (
16 | ':attributes' => array('key1' => 'value1', 'key2' => 'value2')
17 | )
18 | )
19 | );
20 |
21 | // Set decoded array
22 | $encode->set($decoded);
23 |
24 | // Output result
25 | echo Debug::vars($encode->get());
26 |
27 | // Debug output
28 | string(96) "
29 |
30 |
31 |
32 | "
33 |
34 | ## Decoding Attributes
35 |
36 | Decoding attributes will put the attributes in the `:attributes` key.
37 |
38 | // Setup XML decode driver
39 | $decode = Dataflow_Decode::factory(array('driver' => 'XML'));
40 |
41 | $encoded = '
42 |
43 |
44 | ';
45 |
46 | // Set encoded string
47 | $decode->set($encoded);
48 |
49 | // Output result
50 | echo Debug::vars($decode->get());
51 |
52 | // Debug output
53 | array(1) (
54 | "parent" => array(1) (
55 | "child" => array(1) (
56 | ":attributes" => array(2) (
57 | "key1" => string(6) "value1"
58 | "key2" => string(6) "value2"
59 | )
60 | )
61 | )
62 | )
63 |
--------------------------------------------------------------------------------
/guide/dataflow/index.md:
--------------------------------------------------------------------------------
1 | # Getting Started
2 |
3 | Dataflow is built to decode data from one type and encode it to another. A byproduct of this
4 | allows for the decoding of data into a standardized array. [Click here to get started](basics).
5 |
6 | # Additional Resources
7 |
8 | - API Browser
9 | - Unit Tests
10 |
--------------------------------------------------------------------------------
/guide/dataflow/menu.md:
--------------------------------------------------------------------------------
1 | ## [Dataflow]()
2 | - [The Basics](basics)
3 | - [XML Attributes](drivers/xml)
4 |
--------------------------------------------------------------------------------
/tests/kohana/DataflowTest.php:
--------------------------------------------------------------------------------
1 |
11 | * @copyright (c) 2011-2013 Micheal Morgan
12 | * @license MIT
13 | */
14 | abstract class Kohana_DataflowTest extends Unittest_TestCase
15 | {
16 | /**
17 | * Factory to return Dataflow object configured for driver.
18 | *
19 | * @access public
20 | * @return Dataflow
21 | */
22 | abstract public function factory();
23 |
24 | /**
25 | * Sample provider
26 | *
27 | * @access public
28 | * @return array
29 | */
30 | public function provider_samples()
31 | {
32 | return array
33 | (
34 | array
35 | (
36 | // test empty array
37 | array()
38 | ),
39 | array
40 | (
41 | // test indexed array with a variety of variable types
42 | array
43 | (
44 | 'samples' => array
45 | (
46 | 'sample' => array('string(value)', 1)
47 | )
48 | )
49 | ),
50 | array
51 | (
52 | // test associative array
53 | array
54 | (
55 | 'key1' => array
56 | (
57 | 'key2_1' => 'value2_1',
58 | 'key2_2' => array
59 | (
60 | 'key3_1' => 'value_3_1',
61 | 'key3_2' => 'value_3_2'
62 | )
63 | )
64 | )
65 | ),
66 | array
67 | (
68 | // test attribute handling
69 | array
70 | (
71 | 'parent' => array
72 | (
73 | ':attributes' => array('key1' => 'value1'),
74 | 'child' => array
75 | (
76 | 'value1',
77 | 'value2'
78 | )
79 | )
80 | )
81 | ),
82 | array
83 | (
84 | // Test nesting with attributes
85 | 'parent' => array
86 | (
87 | 'child' => array
88 | (
89 | ':attributes' => array('key1' => 'value1', 'key2' => 'value2'),
90 | 'child_child' => array
91 | (
92 | 'key1' => 'value2'
93 | )
94 | )
95 | )
96 | )
97 | );
98 | }
99 |
100 | /**
101 | * Test by encoding sample and comparing original array with decoded
102 | *
103 | * @covers Dataflow::factory
104 | * @covers Dataflow::set
105 | * @covers Dataflow::get
106 | * @covers Dataflow::as_array
107 | * @covers Dataflow_Decode::factory
108 | * @covers Dataflow_Decode::get
109 | * @covers Dataflow_Decode::set
110 | * @covers Dataflow_Decode::_decode
111 | * @covers Dataflow_Encode::factory
112 | * @covers Dataflow_Encode::get
113 | * @covers Dataflow_Encode::set
114 | * @covers Dataflow_Encode::_encode
115 | * @dataProvider provider_samples
116 | * @access public
117 | * @param array
118 | * @return void
119 | */
120 | public function test_samples(array $sample)
121 | {
122 | $dataflow = $this->factory();
123 |
124 | // Set sample input
125 | $dataflow->set($sample);
126 |
127 | // Get encoded
128 | $encoded = $dataflow->get();
129 |
130 | // Decode encoded
131 | $dataflow->set($encoded);
132 |
133 | // Test decoded matches original sample
134 | $this->assertEquals($sample, $dataflow->as_array());
135 | }
136 | }
137 |
--------------------------------------------------------------------------------
/tests/kohana/dataflow/JSONPTest.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow_JSONPTest extends Kohana_DataflowTest
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @access public
18 | * @return Dataflow
19 | */
20 | public function factory()
21 | {
22 | return Dataflow::factory(array('encode' => array('driver' => 'JSONP'), 'decode' => array('driver' => 'JSONP')));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/kohana/dataflow/JSONTest.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow_JSONTest extends Kohana_DataflowTest
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @access public
18 | * @return Dataflow
19 | */
20 | public function factory()
21 | {
22 | return Dataflow::factory(array('encode' => array('driver' => 'JSON'), 'decode' => array('driver' => 'JSON')));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/kohana/dataflow/PHPTest.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow_PHPTest extends Kohana_DataflowTest
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @access public
18 | * @return Dataflow
19 | */
20 | public function factory()
21 | {
22 | return Dataflow::factory(array('encode' => array('driver' => 'PHP'), 'decode' => array('driver' => 'PHP')));
23 | }
24 | }
25 |
--------------------------------------------------------------------------------
/tests/kohana/dataflow/XMLTest.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow_XMLTest extends Kohana_DataflowTest
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @access public
18 | * @return Dataflow
19 | */
20 | public function factory()
21 | {
22 | return Dataflow::factory(array('encode' => array('driver' => 'XML'), 'decode' => array('driver' => 'XML')));
23 | }
24 |
25 | /**
26 | * Sample provider
27 | *
28 | * @access public
29 | * @return array
30 | */
31 | public function provider_xml()
32 | {
33 | return array
34 | (
35 | array
36 | (
37 | array
38 | (
39 | 'parent' => array
40 | (
41 | 'child' => array
42 | (
43 | ':attributes' => array('key1' => 'value1', 'key2' => 'value2')
44 | )
45 | )
46 | ),
47 | '
48 |
49 |
50 |
51 | '
52 | )
53 | );
54 | }
55 |
56 | /**
57 | * Test XML encoding
58 | *
59 | * @covers Dataflow_Encode::factory
60 | * @covers Dataflow_Encode::get
61 | * @covers Dataflow_Encode::set
62 | * @covers Dataflow_Encode::_encode
63 | * @dataProvider provider_xml
64 | * @access public
65 | * @param array
66 | * @return void
67 | */
68 | public function test_xml_encode($decoded, $encoded)
69 | {
70 | // Setup XML encode driver
71 | $encode = Dataflow_Encode::factory(array('driver' => 'XML'));
72 |
73 | // Set decoded array
74 | $encode->set($decoded);
75 |
76 | // Test newly encoded matches decoded
77 | $this->assertEquals($encode->get(), $encoded);
78 | }
79 |
80 | /**
81 | * Test XML decoding
82 | *
83 | * @covers Dataflow_Encode::factory
84 | * @covers Dataflow_Encode::get
85 | * @covers Dataflow_Encode::set
86 | * @covers Dataflow_Encode::_encode
87 | * @dataProvider provider_xml
88 | * @access public
89 | * @param array
90 | * @return void
91 | */
92 | public function test_xml_decode($decoded, $encoded)
93 | {
94 | // Setup XML decode driver
95 | $decode = Dataflow_Decode::factory(array('driver' => 'XML'));
96 |
97 | // Set decoded array
98 | $decode->set($encoded);
99 |
100 | // Test newly decoded matches decoded
101 | $this->assertEquals($decode->get(), $decoded);
102 | }
103 | }
104 |
--------------------------------------------------------------------------------
/tests/kohana/dataflow/YAMLTest.php:
--------------------------------------------------------------------------------
1 |
9 | * @copyright (c) 2011-2013 Micheal Morgan
10 | * @license MIT
11 | */
12 | class Kohana_Dataflow_YAMLTest extends Kohana_DataflowTest
13 | {
14 | /**
15 | * Factory pattern
16 | *
17 | * @access public
18 | * @return Dataflow
19 | */
20 | public function factory()
21 | {
22 | return Dataflow::factory(array('encode' => array('driver' => 'YAML'), 'decode' => array('driver' => 'YAML')));
23 | }
24 | }
--------------------------------------------------------------------------------