PageRenderTime 49ms CodeModel.GetById 20ms RepoModel.GetById 1ms app.codeStats 0ms

/ExtDirect/API.php

https://github.com/ktk070/Anopier
PHP | 335 lines | 273 code | 61 blank | 1 comment | 43 complexity | f33ab0774411abfe8b9b04dbbac71f02 MD5 | raw file
  1. <?php
  2. class ExtDirect_API {
  3. private $_routerUrl = 'router.php';
  4. private $_cacheProvider = null;
  5. private $_defaults = array();
  6. private $_classes = array();
  7. private $_remoteAttribute = '@remotable';
  8. private $_formAttribute = '@formHandler';
  9. private $_nameAttribute = '@remoteName';
  10. private $_namespace = false;
  11. private $_type = 'remoting';
  12. private $_parsedClasses = array();
  13. private $_parsedAPI = array();
  14. private $_descriptor = 'Ext.app.REMOTING_API';
  15. public function __construct() {
  16. }
  17. public function getState() {
  18. return array(
  19. 'routerUrl' => $this->getRouterUrl(),
  20. 'defaults' => $this->getDefaults(),
  21. 'classes' => $this->getClasses(),
  22. 'remoteAttribute' => $this->getRemoteAttribute(),
  23. 'formAttribute' => $this->getFormAttribute(),
  24. 'nameAttribute' => $this->getNameAttribute(),
  25. 'namespace' => $this->getNamespace(),
  26. 'parsedAPI' => $this->_parsedAPI,
  27. 'descriptor' => $this->_descriptor
  28. );
  29. }
  30. public function setState($state) {
  31. if(isset($state['routerUrl'])) {
  32. $this->setRouterUrl($state['routerUrl']);
  33. }
  34. if(isset($state['defaults'])) {
  35. $this->setDefaults($state['defaults']);
  36. }
  37. if(isset($state['classes'])) {
  38. $this->_classes = $state['classes'];
  39. }
  40. if(isset($state['remoteAttribute'])) {
  41. $this->setRemoteAttribute($state['remoteAttribute']);
  42. }
  43. if(isset($state['formAttribute'])) {
  44. $this->setFormAttribute($state['formAttribute']);
  45. }
  46. if(isset($state['nameAttribute'])) {
  47. $this->setFormAttribute($state['nameAttribute']);
  48. }
  49. if(isset($state['namespace'])) {
  50. $this->setNameSpace($state['namespace']);
  51. }
  52. if(isset($state['descriptor'])) {
  53. $this->setDescriptor($state['descriptor']);
  54. }
  55. if(isset($state['parsedAPI'])) {
  56. $this->_parsedAPI = $state['parsedAPI'];
  57. }
  58. }
  59. public function add($classes = array(), $settings = array()) {
  60. $settings = array_merge(
  61. array(
  62. 'autoInclude' => false,
  63. 'basePath' => '',
  64. 'seperator' => '_',
  65. 'prefix' => '',
  66. 'subPath' => ''
  67. ),
  68. $this->_defaults,
  69. $settings
  70. );
  71. if(is_string($classes)) {
  72. $classes = array($classes);
  73. }
  74. foreach($classes as $name => $cSettings) {
  75. if(is_int($name)) {
  76. $name = $cSettings;
  77. $cSettings = array();
  78. }
  79. $cSettings = array_merge($settings, $cSettings);
  80. $cSettings['fullPath'] = $this->getClassPath($name, $cSettings);
  81. $this->_classes[$name] = $cSettings;
  82. }
  83. }
  84. public function output($print = true) {
  85. $saveInCache = false;
  86. if(isset($this->_cacheProvider)) {
  87. if(!$this->_cacheProvider->isModified($this)) {
  88. $api = $this->_cacheProvider->getAPI();
  89. if($print === true) $this->_print($api);
  90. $this->_parsedClasses = $this->_classes;
  91. $this->_parsedAPI = $api;
  92. return $api;
  93. }
  94. $saveInCache = true;
  95. }
  96. $api = $this->getAPI();
  97. if($saveInCache) {
  98. $this->_cacheProvider->save($this);
  99. }
  100. if($print === true) $this->_print($api);
  101. return $api;
  102. }
  103. public function isEqual($old, $new) {
  104. return serialize($old) === serialize($new);
  105. }
  106. public function getAPI() {
  107. if($this->isEqual($this->_classes, $this->_parsedClasses)) {
  108. return $this->getParsedAPI();
  109. }
  110. $classes = array();
  111. foreach($this->_classes as $class => $settings) {
  112. $methods = array();
  113. if($settings['autoInclude'] === true) {
  114. $path = !$settings['fullPath']
  115. ? $this->getClassPath($class, $settings)
  116. : $settings['fullPath'];
  117. if(file_exists($path)) {
  118. require_once($path);
  119. }
  120. }
  121. // here the reflection magic begins
  122. $className = "\Anopier\Controller\\" . $settings['prefix'] . $class;
  123. if(class_exists($className)) {
  124. $rClass = new ReflectionClass($className);
  125. $rMethods = $rClass->getMethods();
  126. foreach($rMethods as $rMethod) {
  127. if(
  128. $rMethod->isPublic() &&
  129. strlen($rMethod->getDocComment()) > 0
  130. ) {
  131. $doc = $rMethod->getDocComment();
  132. $isRemote = !!preg_match('/' . $this->_remoteAttribute . '/', $doc);
  133. if($isRemote) {
  134. $method = array(
  135. 'name' => $rMethod->getName(),
  136. 'len' => $rMethod->getNumberOfParameters(),
  137. );
  138. if(!!preg_match('/' . $this->_nameAttribute . ' ([\w]+)/', $doc, $matches)) {
  139. $method['serverMethod'] = $method['name'];
  140. $method['name'] = $matches[1];
  141. }
  142. if(!!preg_match('/' . $this->_formAttribute . '/', $doc)) {
  143. $method['formHandler'] = true;
  144. }
  145. $methods[] = $method;
  146. }
  147. }
  148. }
  149. if(count($methods) > 0) {
  150. $classes[$class] = $methods;
  151. }
  152. }
  153. }
  154. $api = array(
  155. 'url' => $this->_routerUrl,
  156. 'type' => $this->_type,
  157. 'actions' => $classes
  158. );
  159. if($this->_namespace !== false) {
  160. $api['namespace'] = $this->_namespace;
  161. }
  162. $this->_parsedClasses = $this->_classes;
  163. $this->_parsedAPI = $api;
  164. return $api;
  165. }
  166. public function getParsedAPI() {
  167. return $this->_parsedAPI;
  168. }
  169. public function getClassPath($class, $settings = false) {
  170. if(!$settings) {
  171. $settings = $this->_settings;
  172. }
  173. if($settings['autoInclude'] === true) {
  174. $path = $settings['basePath'] . DIRECTORY_SEPARATOR .
  175. $settings['subPath'] . DIRECTORY_SEPARATOR .
  176. $class . '.php';
  177. $path = str_replace('\\\\', '\\', $path);
  178. } else {
  179. $rClass = new ReflectionClass($settings['prefix'] . $class);
  180. $path = $rClass->getFileName();
  181. }
  182. return $path;
  183. }
  184. public function getClassesPaths() {
  185. $classesPaths = array();
  186. foreach($this->getClasses() as $name => $settings) {
  187. $classesPaths[] = $this->getClassPath($name, $settings);
  188. }
  189. return $classesPaths;
  190. }
  191. public function getClasses() {
  192. return $this->_classes;
  193. }
  194. private function _print($api) {
  195. header('Content-Type: text/javascript');
  196. echo ($this->_namespace ?
  197. 'Ext.ns(\'' . substr($this->_descriptor, 0, strrpos($this->_descriptor, '.')) . '\'); ' . $this->_descriptor:
  198. 'Ext.ns(\'Ext.app\'); ' . 'Ext.app.REMOTING_API'
  199. );
  200. echo ' = ';
  201. echo json_encode($api);
  202. echo ';';
  203. }
  204. public function setRouterUrl($routerUrl = 'router.php') {
  205. if(isset($routerUrl)) {
  206. $this->_routerUrl = $routerUrl;
  207. }
  208. }
  209. public function getRouterUrl() {
  210. return $this->_routerUrl;
  211. }
  212. public function setCacheProvider($cacheProvider) {
  213. if($cacheProvider instanceof ExtDirect_CacheProvider) {
  214. $this->_cacheProvider = $cacheProvider;
  215. }
  216. }
  217. public function getCacheProvider() {
  218. return $this->_cacheProvider;
  219. }
  220. public function setRemoteAttribute($attribute) {
  221. if(is_string($attribute) && strlen($attribute) > 0) {
  222. $this->_remoteAttribute = $attribute;
  223. }
  224. }
  225. public function getRemoteAttribute() {
  226. return $this->_remoteAttribute;
  227. }
  228. public function setDescriptor($descriptor) {
  229. if(is_string($descriptor) && strlen($descriptor) > 0) {
  230. $this->_descriptor = $descriptor;
  231. }
  232. }
  233. public function getDescriptor() {
  234. return $this->_descriptor;
  235. }
  236. public function setFormAttribute($attribute) {
  237. if(is_string($attribute) && strlen($attribute) > 0) {
  238. $this->_formAttribute = $attribute;
  239. }
  240. }
  241. public function getFormAttribute() {
  242. return $this->_formAttribute;
  243. }
  244. public function setNameAttribute($attribute) {
  245. if(is_string($attribute) && strlen($attribute) > 0) {
  246. $this->_nameAttribute = $attribute;
  247. }
  248. }
  249. public function getNameAttribute() {
  250. return $this->_nameAttribute;
  251. }
  252. public function setNameSpace($namespace) {
  253. if(is_string($namespace) && strlen($namespace) > 0) {
  254. $this->_namespace = $namespace;
  255. }
  256. }
  257. public function getNamespace() {
  258. return $this->_namespace;
  259. }
  260. public function setDefaults($defaults, $clear = false) {
  261. if($clear === true) {
  262. $this->clearDefaults();
  263. }
  264. if(is_array($defaults)) {
  265. $this->_defaults = array_merge($this->_defaults, $defaults);
  266. }
  267. }
  268. public function getDefaults() {
  269. return $this->_defaults;
  270. }
  271. public function clearDefaults() {
  272. $this->_defaults = array();
  273. }
  274. }