PageRenderTime 49ms CodeModel.GetById 23ms RepoModel.GetById 0ms app.codeStats 0ms

/core/Utils/Exporter.class.php

https://github.com/Neerrar/onphp-toolkit
PHP | 226 lines | 199 code | 18 blank | 9 comment | 23 complexity | 4e906d69b1f3e0ddd32ad6287436aad8 MD5 | raw file
  1. <?php
  2. /**
  3. * Exporter factory
  4. * @author Alex Gorbylev <alex@gorbylev.ru>
  5. * @date 2013.08.03
  6. */
  7. class Exporter extends StaticFactory {
  8. const MAX_NESTING_DEPTH = 3;
  9. public static function null() {
  10. return function () {
  11. return null;
  12. };
  13. }
  14. public static function int() {
  15. return function ($value) {
  16. return intval($value);
  17. };
  18. }
  19. public static function float() {
  20. return function ($value) {
  21. return floatval($value);
  22. };
  23. }
  24. public static function double() {
  25. return function ($value) {
  26. return doubleval($value);
  27. };
  28. }
  29. public static function string() {
  30. return function ($value) {
  31. return strval($value);
  32. };
  33. }
  34. public static function set($level = 0) {
  35. return function(array $set) use ($level) {
  36. if( $level>=self::MAX_NESTING_DEPTH ) {
  37. return count($set);
  38. }
  39. $result = array();
  40. foreach($set as $key=>$value) {
  41. $result[$key] = call_user_func(Exporter::smart($level), $value);
  42. }
  43. return $result;
  44. };
  45. }
  46. public static function object($level = 0) {
  47. return function ($object) use ($level) {
  48. $properties = self::getObjectProperties($object);
  49. return call_user_func(Exporter::set($level), $properties);
  50. };
  51. }
  52. public static function date($format = null) {
  53. return function (Date $date) use ($format) {
  54. if( is_null($format) ) {
  55. return $date->toString($format);
  56. } else {
  57. return $date->toFormatString($format);
  58. }
  59. };
  60. }
  61. public static function hstore($filter = null, $asKeyVal = false) {
  62. return function (Hstore $hstore) use ($filter, $asKeyVal) {
  63. $result = null;
  64. if( is_string($filter) && $hstore->isExists($filter) ) {
  65. $result = $hstore->get($filter);
  66. } elseif( is_array($filter) ) {
  67. $result = array();
  68. foreach($filter as $key) {
  69. if( $asKeyVal ) {
  70. $result[$key] = $hstore->isExists($key) ? $hstore->get($key) : null;
  71. } else {
  72. $result[] = array(
  73. 'key'=>$key,
  74. 'value'=>$hstore->isExists($key) ? $hstore->get($key) : null,
  75. );
  76. }
  77. }
  78. } else {
  79. foreach($hstore->getList() as $key=>$value) {
  80. if( $asKeyVal ) {
  81. $result[$key] = $value;
  82. } else {
  83. $result[] = array(
  84. 'key'=>$key,
  85. 'value'=>$value,
  86. );
  87. }
  88. }
  89. }
  90. return $result;
  91. };
  92. }
  93. public static function prototypedAuto($level = 0) {
  94. return function (Prototyped $object) use ($level) {
  95. $result = array();
  96. /** @var LightMetaProperty $property */
  97. foreach($object->proto()->getPropertyList() as $property) {
  98. $value = null;
  99. $exporter = Exporter::null();
  100. if( $property->isIdentifier() ) {
  101. $value = call_user_func(array($object, $property->getGetter()));
  102. if( Assert::checkInteger($value) ) {
  103. $exporter = Exporter::int($level);
  104. } else {
  105. $exporter = Exporter::string($level);
  106. }
  107. } elseif( $property->isGenericType() ) {
  108. $value = call_user_func(array($object, $property->getGetter()));
  109. $exporter = Exporter::smart($level);
  110. } elseif( $property->getRelationId()===MetaRelation::ONE_TO_ONE ) {
  111. if( $level < self::MAX_NESTING_DEPTH ) {
  112. $value = call_user_func(array($object, $property->getGetter()));
  113. $exporter = Exporter::smart($level);
  114. } else {
  115. $value = call_user_func(array($object, $property->getGetter().'Id'));
  116. if( Assert::checkInteger($value) ) {
  117. $exporter = Exporter::int($level);
  118. } else {
  119. $exporter = Exporter::string($level);
  120. }
  121. }
  122. } elseif( $property->getRelationId()===MetaRelation::ONE_TO_MANY ) {
  123. $value = call_user_func(array($object, $property->getGetter()));
  124. $exporter = Exporter::lazy();
  125. } elseif( $property->getRelationId()===MetaRelation::MANY_TO_MANY ) {
  126. $value = call_user_func(array($object, $property->getGetter()));
  127. $exporter = Exporter::lazy();
  128. }
  129. $result[$property->getName()] = call_user_func($exporter, $value);
  130. }
  131. return $result;
  132. };
  133. }
  134. public static function prototypedByMap(array $map, $level = 0) {
  135. return function (Prototyped $object) use ($map, $level) {
  136. $result = array();
  137. foreach($map as $name=>$exporter) {
  138. $property = $object->proto()->getPropertyByName($name);
  139. $value = call_user_func(array($object, $property->getGetter()));
  140. $result[$name] = $exporter($value);
  141. }
  142. return $result;
  143. };
  144. }
  145. public static function lazy() {
  146. return function (UnifiedContainer $container) {
  147. return $container->getCount();
  148. };
  149. }
  150. public static function cascade($level) {
  151. return function (UnifiedContainer $container) use ($level) {
  152. return call_user_func(Exporter::set($level), $container->getList());
  153. };
  154. }
  155. public static function smart($level = 0) {
  156. return function ($value) use ($level) {
  157. $level++;
  158. if( is_null($value) ) {
  159. return null;
  160. } elseif( is_scalar($value) ) {
  161. return $value;
  162. } elseif( is_array($value) ) {
  163. return call_user_func(Exporter::set($level), $value);
  164. } elseif( is_object($value) ) {
  165. if( $value instanceof Date ) {
  166. return call_user_func(Exporter::date(), $value);
  167. } elseif( $value instanceof Hstore ) {
  168. return call_user_func(Exporter::hstore(), $value);
  169. } elseif( $value instanceof Prototyped ) {
  170. return call_user_func(Exporter::prototypedAuto($level), $value);
  171. } elseif( $value instanceof UnifiedContainer ) {
  172. return 'UnifiedContainer';
  173. // return call_user_func(Exporter::prototyped(null, $level), $value);
  174. } else {
  175. return call_user_func(Exporter::object($level), $value);
  176. }
  177. } else {
  178. return null;
  179. }
  180. };
  181. }
  182. public static function model(array $exportMap = null) {
  183. return function (Model $model) use ($exportMap) {
  184. // if exporters empty, try to build them smartly
  185. if( is_null($exportMap) ) {
  186. $exportMap = array();
  187. foreach($model->getList() as $key=>$value) {
  188. $exportMap[$key] = Exporter::smart();
  189. }
  190. }
  191. // execute exporters
  192. $result = array();
  193. foreach($exportMap as $key=>$exporter) {
  194. $value = null;
  195. if( $model->has($key) ) {
  196. $value = $exporter($model->get($key));
  197. }
  198. $result[$key] = $value;
  199. }
  200. return $result;
  201. };
  202. }
  203. protected static function getObjectProperties($object) {
  204. return Closure::bind(function ($object) {
  205. return get_object_vars($object);
  206. }, null, $object)->__invoke($object);
  207. }
  208. }