PageRenderTime 47ms CodeModel.GetById 15ms RepoModel.GetById 0ms app.codeStats 0ms

/ext/phalcon/di/service.zep.c

http://github.com/phalcon/cphalcon
C | 454 lines | 325 code | 63 blank | 66 comment | 50 complexity | 013d17a97c0a8e150e9b6d2e9d699191 MD5 | raw file
Possible License(s): BSD-3-Clause
  1. #ifdef HAVE_CONFIG_H
  2. #include "../../ext_config.h"
  3. #endif
  4. #include <php.h>
  5. #include "../../php_ext.h"
  6. #include "../../ext.h"
  7. #include <Zend/zend_operators.h>
  8. #include <Zend/zend_exceptions.h>
  9. #include <Zend/zend_interfaces.h>
  10. #include "kernel/main.h"
  11. #include "kernel/object.h"
  12. #include "kernel/operators.h"
  13. #include "kernel/memory.h"
  14. #include "kernel/exception.h"
  15. #include "kernel/array.h"
  16. #include "kernel/fcall.h"
  17. #include "Zend/zend_closures.h"
  18. #include "ext/spl/spl_exceptions.h"
  19. /**
  20. * This file is part of the Phalcon Framework.
  21. *
  22. * (c) Phalcon Team <team@phalcon.io>
  23. *
  24. * For the full copyright and license information, please view the LICENSE.txt
  25. * file that was distributed with this source code.
  26. */
  27. /**
  28. * Represents individually a service in the services container
  29. *
  30. *```php
  31. * $service = new \Phalcon\Di\Service(
  32. * "request",
  33. * \Phalcon\Http\Request::class
  34. * );
  35. *
  36. * $request = service->resolve();
  37. *```
  38. */
  39. ZEPHIR_INIT_CLASS(Phalcon_Di_Service)
  40. {
  41. ZEPHIR_REGISTER_CLASS(Phalcon\\Di, Service, phalcon, di_service, phalcon_di_service_method_entry, 0);
  42. /**
  43. * @var mixed
  44. */
  45. zend_declare_property_null(phalcon_di_service_ce, SL("definition"), ZEND_ACC_PROTECTED);
  46. /**
  47. * @var bool
  48. */
  49. zend_declare_property_bool(phalcon_di_service_ce, SL("resolved"), 0, ZEND_ACC_PROTECTED);
  50. /**
  51. * @var bool
  52. */
  53. zend_declare_property_bool(phalcon_di_service_ce, SL("shared"), 0, ZEND_ACC_PROTECTED);
  54. /**
  55. * @var mixed|null
  56. */
  57. zend_declare_property_null(phalcon_di_service_ce, SL("sharedInstance"), ZEND_ACC_PROTECTED);
  58. zend_class_implements(phalcon_di_service_ce, 1, phalcon_di_serviceinterface_ce);
  59. return SUCCESS;
  60. }
  61. /**
  62. * Phalcon\Di\Service
  63. */
  64. PHP_METHOD(Phalcon_Di_Service, __construct)
  65. {
  66. zend_bool shared;
  67. zval *definition, definition_sub, *shared_param = NULL, __$true, __$false;
  68. zval *this_ptr = getThis();
  69. ZVAL_UNDEF(&definition_sub);
  70. ZVAL_BOOL(&__$true, 1);
  71. ZVAL_BOOL(&__$false, 0);
  72. #if PHP_VERSION_ID >= 80000
  73. bool is_null_true = 1;
  74. ZEND_PARSE_PARAMETERS_START(1, 2)
  75. Z_PARAM_ZVAL(definition)
  76. Z_PARAM_OPTIONAL
  77. Z_PARAM_BOOL(shared)
  78. ZEND_PARSE_PARAMETERS_END();
  79. #endif
  80. zephir_fetch_params_without_memory_grow(1, 1, &definition, &shared_param);
  81. if (!shared_param) {
  82. shared = 0;
  83. } else {
  84. shared = zephir_get_boolval(shared_param);
  85. }
  86. zephir_update_property_zval(this_ptr, ZEND_STRL("definition"), definition);
  87. if (shared) {
  88. zephir_update_property_zval(this_ptr, ZEND_STRL("shared"), &__$true);
  89. } else {
  90. zephir_update_property_zval(this_ptr, ZEND_STRL("shared"), &__$false);
  91. }
  92. }
  93. /**
  94. * Returns the service definition
  95. */
  96. PHP_METHOD(Phalcon_Di_Service, getDefinition)
  97. {
  98. zval *this_ptr = getThis();
  99. RETURN_MEMBER(getThis(), "definition");
  100. }
  101. /**
  102. * Returns a parameter in a specific position
  103. *
  104. * @return array
  105. */
  106. PHP_METHOD(Phalcon_Di_Service, getParameter)
  107. {
  108. zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
  109. zval *position_param = NULL, definition, arguments, parameter, _0;
  110. zend_long position;
  111. zval *this_ptr = getThis();
  112. ZVAL_UNDEF(&definition);
  113. ZVAL_UNDEF(&arguments);
  114. ZVAL_UNDEF(&parameter);
  115. ZVAL_UNDEF(&_0);
  116. #if PHP_VERSION_ID >= 80000
  117. bool is_null_true = 1;
  118. ZEND_PARSE_PARAMETERS_START(1, 1)
  119. Z_PARAM_LONG(position)
  120. ZEND_PARSE_PARAMETERS_END();
  121. #endif
  122. ZEPHIR_MM_GROW();
  123. zephir_fetch_params(1, 1, 0, &position_param);
  124. position = zephir_get_intval(position_param);
  125. zephir_read_property(&_0, this_ptr, ZEND_STRL("definition"), PH_NOISY_CC | PH_READONLY);
  126. ZEPHIR_CPY_WRT(&definition, &_0);
  127. if (UNEXPECTED(Z_TYPE_P(&definition) != IS_ARRAY)) {
  128. ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_di_exception_ce, "Definition must be an array to obtain its parameters", "phalcon/Di/Service.zep", 82);
  129. return;
  130. }
  131. if (zephir_array_isset_string_fetch(&arguments, &definition, SL("arguments"), 1)) {
  132. if (zephir_array_isset_long_fetch(&parameter, &arguments, position, 1)) {
  133. RETURN_CTOR(&parameter);
  134. }
  135. }
  136. RETURN_MM_NULL();
  137. }
  138. /**
  139. * Returns true if the service was resolved
  140. */
  141. PHP_METHOD(Phalcon_Di_Service, isResolved)
  142. {
  143. zval *this_ptr = getThis();
  144. RETURN_MEMBER(getThis(), "resolved");
  145. }
  146. /**
  147. * Check whether the service is shared or not
  148. */
  149. PHP_METHOD(Phalcon_Di_Service, isShared)
  150. {
  151. zval *this_ptr = getThis();
  152. RETURN_MEMBER(getThis(), "shared");
  153. }
  154. /**
  155. * Resolves the service
  156. *
  157. * @param array parameters
  158. */
  159. PHP_METHOD(Phalcon_Di_Service, resolve)
  160. {
  161. zend_class_entry *_4$$14;
  162. zend_bool found = 0, _2$$7;
  163. zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
  164. zend_long ZEPHIR_LAST_CALL_STATUS;
  165. zval *parameters = NULL, parameters_sub, *container = NULL, container_sub, __$true, __$false, __$null, shared, definition, sharedInstance, instance, builder, _0, _1$$3, _3$$14, _5$$21;
  166. zval *this_ptr = getThis();
  167. ZVAL_UNDEF(&parameters_sub);
  168. ZVAL_UNDEF(&container_sub);
  169. ZVAL_BOOL(&__$true, 1);
  170. ZVAL_BOOL(&__$false, 0);
  171. ZVAL_NULL(&__$null);
  172. ZVAL_UNDEF(&shared);
  173. ZVAL_UNDEF(&definition);
  174. ZVAL_UNDEF(&sharedInstance);
  175. ZVAL_UNDEF(&instance);
  176. ZVAL_UNDEF(&builder);
  177. ZVAL_UNDEF(&_0);
  178. ZVAL_UNDEF(&_1$$3);
  179. ZVAL_UNDEF(&_3$$14);
  180. ZVAL_UNDEF(&_5$$21);
  181. #if PHP_VERSION_ID >= 80000
  182. bool is_null_true = 1;
  183. ZEND_PARSE_PARAMETERS_START(0, 2)
  184. Z_PARAM_OPTIONAL
  185. Z_PARAM_ZVAL_OR_NULL(parameters)
  186. Z_PARAM_OBJECT_OF_CLASS_OR_NULL(container, phalcon_di_diinterface_ce)
  187. ZEND_PARSE_PARAMETERS_END();
  188. #endif
  189. ZEPHIR_MM_GROW();
  190. zephir_fetch_params(1, 0, 2, &parameters, &container);
  191. if (!parameters) {
  192. parameters = &parameters_sub;
  193. parameters = &__$null;
  194. }
  195. if (!container) {
  196. container = &container_sub;
  197. container = &__$null;
  198. }
  199. zephir_read_property(&_0, this_ptr, ZEND_STRL("shared"), PH_NOISY_CC | PH_READONLY);
  200. ZEPHIR_CPY_WRT(&shared, &_0);
  201. if (zephir_is_true(&shared)) {
  202. zephir_read_property(&_1$$3, this_ptr, ZEND_STRL("sharedInstance"), PH_NOISY_CC | PH_READONLY);
  203. ZEPHIR_CPY_WRT(&sharedInstance, &_1$$3);
  204. if (Z_TYPE_P(&sharedInstance) != IS_NULL) {
  205. RETURN_CCTOR(&sharedInstance);
  206. }
  207. }
  208. found = 1;
  209. ZEPHIR_INIT_VAR(&instance);
  210. ZVAL_NULL(&instance);
  211. zephir_read_property(&_0, this_ptr, ZEND_STRL("definition"), PH_NOISY_CC | PH_READONLY);
  212. ZEPHIR_CPY_WRT(&definition, &_0);
  213. if (Z_TYPE_P(&definition) == IS_STRING) {
  214. if (Z_TYPE_P(container) != IS_NULL) {
  215. ZEPHIR_CALL_METHOD(&instance, container, "get", NULL, 0, &definition, parameters);
  216. zephir_check_call_status();
  217. } else if (zephir_class_exists(&definition, 1)) {
  218. _2$$7 = Z_TYPE_P(parameters) == IS_ARRAY;
  219. if (_2$$7) {
  220. _2$$7 = ((zephir_fast_count_int(parameters)) ? 1 : 0);
  221. }
  222. if (_2$$7) {
  223. ZEPHIR_INIT_NVAR(&instance);
  224. ZEPHIR_LAST_CALL_STATUS = zephir_create_instance_params(&instance, &definition, parameters);
  225. zephir_check_call_status();
  226. } else {
  227. ZEPHIR_INIT_NVAR(&instance);
  228. ZEPHIR_LAST_CALL_STATUS = zephir_create_instance(&instance, &definition);
  229. zephir_check_call_status();
  230. }
  231. } else {
  232. found = 0;
  233. }
  234. } else {
  235. if (Z_TYPE_P(&definition) == IS_OBJECT) {
  236. if (zephir_is_instance_of(&definition, SL("Closure"))) {
  237. if (Z_TYPE_P(container) == IS_OBJECT) {
  238. _4$$14 = zephir_fetch_class_str_ex(SL("Closure"), ZEND_FETCH_CLASS_AUTO);
  239. ZEPHIR_CALL_CE_STATIC(&_3$$14, _4$$14, "bind", NULL, 0, &definition, container);
  240. zephir_check_call_status();
  241. ZEPHIR_CPY_WRT(&definition, &_3$$14);
  242. }
  243. if (Z_TYPE_P(parameters) == IS_ARRAY) {
  244. ZEPHIR_INIT_NVAR(&instance);
  245. ZEPHIR_CALL_USER_FUNC_ARRAY(&instance, &definition, parameters);
  246. zephir_check_call_status();
  247. } else {
  248. ZEPHIR_INIT_NVAR(&instance);
  249. ZEPHIR_CALL_USER_FUNC(&instance, &definition);
  250. zephir_check_call_status();
  251. }
  252. } else {
  253. ZEPHIR_CPY_WRT(&instance, &definition);
  254. }
  255. } else {
  256. if (Z_TYPE_P(&definition) == IS_ARRAY) {
  257. ZEPHIR_INIT_VAR(&builder);
  258. object_init_ex(&builder, phalcon_di_service_builder_ce);
  259. if (zephir_has_constructor(&builder)) {
  260. ZEPHIR_CALL_METHOD(NULL, &builder, "__construct", NULL, 0);
  261. zephir_check_call_status();
  262. }
  263. ZEPHIR_CALL_METHOD(&instance, &builder, "build", NULL, 221, container, &definition, parameters);
  264. zephir_check_call_status();
  265. } else {
  266. found = 0;
  267. }
  268. }
  269. }
  270. if (UNEXPECTED(found == 0)) {
  271. ZEPHIR_INIT_VAR(&_5$$21);
  272. object_init_ex(&_5$$21, phalcon_di_exception_serviceresolutionexception_ce);
  273. ZEPHIR_CALL_METHOD(NULL, &_5$$21, "__construct", NULL, 8);
  274. zephir_check_call_status();
  275. zephir_throw_exception_debug(&_5$$21, "phalcon/Di/Service.zep", 205);
  276. ZEPHIR_MM_RESTORE();
  277. return;
  278. }
  279. if (zephir_is_true(&shared)) {
  280. zephir_update_property_zval(this_ptr, ZEND_STRL("sharedInstance"), &instance);
  281. }
  282. if (1) {
  283. zephir_update_property_zval(this_ptr, ZEND_STRL("resolved"), &__$true);
  284. } else {
  285. zephir_update_property_zval(this_ptr, ZEND_STRL("resolved"), &__$false);
  286. }
  287. RETURN_CCTOR(&instance);
  288. }
  289. /**
  290. * Set the service definition
  291. */
  292. PHP_METHOD(Phalcon_Di_Service, setDefinition)
  293. {
  294. zval *definition, definition_sub;
  295. zval *this_ptr = getThis();
  296. ZVAL_UNDEF(&definition_sub);
  297. #if PHP_VERSION_ID >= 80000
  298. bool is_null_true = 1;
  299. ZEND_PARSE_PARAMETERS_START(1, 1)
  300. Z_PARAM_ZVAL(definition)
  301. ZEND_PARSE_PARAMETERS_END();
  302. #endif
  303. zephir_fetch_params_without_memory_grow(1, 0, &definition);
  304. zephir_update_property_zval(this_ptr, ZEND_STRL("definition"), definition);
  305. }
  306. /**
  307. * Changes a parameter in the definition without resolve the service
  308. */
  309. PHP_METHOD(Phalcon_Di_Service, setParameter)
  310. {
  311. zephir_method_globals *ZEPHIR_METHOD_GLOBALS_PTR = NULL;
  312. zval parameter;
  313. zval *position_param = NULL, *parameter_param = NULL, definition, arguments, _0, _1$$5;
  314. zend_long position;
  315. zval *this_ptr = getThis();
  316. ZVAL_UNDEF(&definition);
  317. ZVAL_UNDEF(&arguments);
  318. ZVAL_UNDEF(&_0);
  319. ZVAL_UNDEF(&_1$$5);
  320. ZVAL_UNDEF(&parameter);
  321. #if PHP_VERSION_ID >= 80000
  322. bool is_null_true = 1;
  323. ZEND_PARSE_PARAMETERS_START(2, 2)
  324. Z_PARAM_LONG(position)
  325. Z_PARAM_ARRAY(parameter)
  326. ZEND_PARSE_PARAMETERS_END();
  327. #endif
  328. ZEPHIR_MM_GROW();
  329. zephir_fetch_params(1, 2, 0, &position_param, &parameter_param);
  330. position = zephir_get_intval(position_param);
  331. ZEPHIR_OBS_COPY_OR_DUP(&parameter, parameter_param);
  332. zephir_read_property(&_0, this_ptr, ZEND_STRL("definition"), PH_NOISY_CC | PH_READONLY);
  333. ZEPHIR_CPY_WRT(&definition, &_0);
  334. if (UNEXPECTED(Z_TYPE_P(&definition) != IS_ARRAY)) {
  335. ZEPHIR_THROW_EXCEPTION_DEBUG_STR(phalcon_di_exception_ce, "Definition must be an array to update its parameters", "phalcon/Di/Service.zep", 240);
  336. return;
  337. }
  338. ZEPHIR_OBS_VAR(&arguments);
  339. if (zephir_array_isset_string_fetch(&arguments, &definition, SL("arguments"), 0)) {
  340. zephir_array_update_long(&arguments, position, &parameter, PH_COPY | PH_SEPARATE ZEPHIR_DEBUG_PARAMS_DUMMY);
  341. } else {
  342. ZEPHIR_INIT_VAR(&_1$$5);
  343. zephir_create_array(&_1$$5, 1, 0);
  344. zephir_array_update_long(&_1$$5, position, &parameter, PH_COPY ZEPHIR_DEBUG_PARAMS_DUMMY);
  345. ZEPHIR_CPY_WRT(&arguments, &_1$$5);
  346. }
  347. zephir_array_update_string(&definition, SL("arguments"), &arguments, PH_COPY | PH_SEPARATE);
  348. zephir_update_property_zval(this_ptr, ZEND_STRL("definition"), &definition);
  349. RETURN_THIS();
  350. }
  351. /**
  352. * Sets if the service is shared or not
  353. */
  354. PHP_METHOD(Phalcon_Di_Service, setShared)
  355. {
  356. zval *shared_param = NULL, __$true, __$false;
  357. zend_bool shared;
  358. zval *this_ptr = getThis();
  359. ZVAL_BOOL(&__$true, 1);
  360. ZVAL_BOOL(&__$false, 0);
  361. #if PHP_VERSION_ID >= 80000
  362. bool is_null_true = 1;
  363. ZEND_PARSE_PARAMETERS_START(1, 1)
  364. Z_PARAM_BOOL(shared)
  365. ZEND_PARSE_PARAMETERS_END();
  366. #endif
  367. zephir_fetch_params_without_memory_grow(1, 0, &shared_param);
  368. shared = zephir_get_boolval(shared_param);
  369. if (shared) {
  370. zephir_update_property_zval(this_ptr, ZEND_STRL("shared"), &__$true);
  371. } else {
  372. zephir_update_property_zval(this_ptr, ZEND_STRL("shared"), &__$false);
  373. }
  374. }
  375. /**
  376. * Sets/Resets the shared instance related to the service
  377. */
  378. PHP_METHOD(Phalcon_Di_Service, setSharedInstance)
  379. {
  380. zval *sharedInstance, sharedInstance_sub;
  381. zval *this_ptr = getThis();
  382. ZVAL_UNDEF(&sharedInstance_sub);
  383. #if PHP_VERSION_ID >= 80000
  384. bool is_null_true = 1;
  385. ZEND_PARSE_PARAMETERS_START(1, 1)
  386. Z_PARAM_ZVAL(sharedInstance)
  387. ZEND_PARSE_PARAMETERS_END();
  388. #endif
  389. zephir_fetch_params_without_memory_grow(1, 0, &sharedInstance);
  390. zephir_update_property_zval(this_ptr, ZEND_STRL("sharedInstance"), sharedInstance);
  391. }