WP RSS Aggregator - Version 4.11

Version Description

(2017-02-06) = * Fixed bug with lifetime licenses showing expiry notices. * Fixed bug with being able to submit form on Licenses page. * Fixed bug with empty saved license key causing PHP notice, and not triggering reminder notification. * Fixed bug with saved but inactive licenses not triggering reminder notification. * Fixed bug with minified assets not being served by default. * Fixed bug with cached admin assets being served even after update. * Fixed bug with admin notifications displayed on unrelated pages not being dismissable. * Enhanced Licenses page so as to make the [Enter] key toggle license activation. * Enhanced architecture by using a DI container. * Enhanced admin notifications by refactoring them to use the same mechanism. * Enhanced admin notifications by making all of them dismissable.

Download this release

Release Info

Developer markzahra
Plugin Icon 128x128 WP RSS Aggregator
Version 4.11
Comparing to
See all releases

Code changes from version 4.10 to 4.11

Files changed (148) hide show
  1. includes/Aventura/Wprss/Core/Block/AbstractBlock.php +14 -2
  2. includes/Aventura/Wprss/Core/Block/CallbackBlock.php +40 -0
  3. includes/Aventura/Wprss/Core/Component/AdminAjaxNotices.php +238 -0
  4. includes/Aventura/Wprss/Core/Component/AdminHelper.php +205 -0
  5. includes/Aventura/Wprss/Core/Component/BulkSourceImport.php +187 -0
  6. includes/Aventura/Wprss/Core/Component/EventManager.php +0 -13
  7. includes/Aventura/Wprss/Core/ComponentFactory.php +67 -17
  8. includes/Aventura/Wprss/Core/CompositeContainer.php +26 -0
  9. includes/Aventura/Wprss/Core/Container.php +64 -0
  10. includes/Aventura/Wprss/Core/EventManager.php +14 -0
  11. includes/Aventura/Wprss/Core/Factory.php +46 -7
  12. includes/Aventura/Wprss/Core/Licensing/License.php +13 -1
  13. includes/Aventura/Wprss/Core/Licensing/Manager.php +9 -1
  14. includes/Aventura/Wprss/Core/Licensing/Settings.php +35 -44
  15. includes/Aventura/Wprss/Core/Model/AbstractTranslatingModel.php +71 -0
  16. includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/AdminAjaxNotice.php +91 -0
  17. includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/AdminAjaxNoticeInterface.php +92 -0
  18. includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/NoticeAbstract.php +99 -0
  19. includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/NoticeInterface.php +214 -0
  20. includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/ServiceProvider.php +725 -0
  21. includes/Aventura/Wprss/Core/Model/BulkSourceImport/AbstractImporter.php +158 -0
  22. includes/Aventura/Wprss/Core/Model/BulkSourceImport/AbstractWpImporter.php +111 -0
  23. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/AbstractImportException.php +12 -0
  24. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/AbstractSourceValidationFailureException.php +84 -0
  25. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/ImportException.php +12 -0
  26. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/ImportExceptionInterface.php +12 -0
  27. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/SourceValidationFailureException.php +38 -0
  28. includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/SourceValidationFailureExceptionInterface.php +20 -0
  29. includes/Aventura/Wprss/Core/Model/BulkSourceImport/ImporterInterface.php +27 -0
  30. includes/Aventura/Wprss/Core/Model/BulkSourceImport/PlainTextImporter.php +68 -0
  31. includes/Aventura/Wprss/Core/Model/BulkSourceImport/ServiceProvider.php +85 -0
  32. includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php +1 -7
  33. includes/Aventura/Wprss/Core/Model/GenericServiceProvider.php +48 -0
  34. includes/Aventura/Wprss/Core/Plugin.php +6 -22
  35. includes/Aventura/Wprss/Core/Plugin/AddonAbstract.php +9 -0
  36. includes/Aventura/Wprss/Core/Plugin/Di/AbstractComponentServiceProvider.php +83 -0
  37. includes/Aventura/Wprss/Core/Plugin/Di/AbstractContainer.php +92 -0
  38. includes/Aventura/Wprss/Core/Plugin/Di/AbstractServiceProvider.php +132 -0
  39. includes/Aventura/Wprss/Core/Plugin/Di/AbstractWritableCompositeContainer.php +98 -0
  40. includes/Aventura/Wprss/Core/Plugin/Di/ContainerInterface.php +14 -0
  41. includes/Aventura/Wprss/Core/Plugin/Di/ServiceProviderInterface.php +22 -0
  42. includes/Aventura/Wprss/Core/Plugin/Di/WritableCompositeContainerInterface.php +14 -0
  43. includes/Aventura/Wprss/Core/Plugin/PluginAbstract.php +201 -42
  44. includes/Aventura/Wprss/Core/ServiceProvider.php +208 -0
  45. includes/admin-ajax-notice.php +78 -79
  46. includes/admin-debugging.php +37 -6
  47. includes/admin-display.php +2 -1
  48. includes/admin-import-export.php +30 -48
  49. includes/di.php +131 -0
  50. includes/feed-access.php +3 -1
  51. includes/feed-blacklist.php +2 -14
  52. includes/feed-states.php +6 -34
  53. includes/leave-review-notification.php +2 -2
  54. includes/licensing.php +1 -1
  55. includes/scripts.php +99 -107
  56. js/admin-licensing.js +25 -0
  57. js/aventura.js +45 -20
  58. js/aventura.min.js +1 -1
  59. readme.txt +90 -73
  60. test/diag/Aventura/Wprss/Core/DiagTest/DiTest.php +125 -0
  61. vendor/composer/autoload_psr4.php +2 -0
  62. vendor/composer/autoload_static.php +16 -0
  63. vendor/composer/installed.json +211 -0
  64. vendor/container-interop/container-interop/LICENSE +20 -0
  65. vendor/container-interop/container-interop/README.md +85 -0
  66. vendor/container-interop/container-interop/composer.json +11 -0
  67. vendor/container-interop/container-interop/docs/ContainerInterface-meta.md +114 -0
  68. vendor/container-interop/container-interop/docs/ContainerInterface.md +153 -0
  69. vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md +259 -0
  70. vendor/container-interop/container-interop/docs/Delegate-lookup.md +60 -0
  71. vendor/container-interop/container-interop/docs/images/interoperating_containers.png +0 -0
  72. vendor/container-interop/container-interop/docs/images/priority.png +0 -0
  73. vendor/container-interop/container-interop/docs/images/side_by_side_containers.png +0 -0
  74. vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php +37 -0
  75. vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php +13 -0
  76. vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php +13 -0
  77. vendor/container-interop/service-provider/README.md +279 -0
  78. vendor/container-interop/service-provider/composer.json +15 -0
  79. vendor/container-interop/service-provider/puli.json +6 -0
  80. vendor/container-interop/service-provider/src/ServiceProvider.php +27 -0
  81. vendor/dhii/di-abstract/.codeclimate.yml +19 -0
  82. vendor/dhii/di-abstract/.php_cs +23 -0
  83. vendor/dhii/di-abstract/.travis.yml +18 -0
  84. vendor/dhii/di-abstract/CHANGELOG.md +12 -0
  85. vendor/dhii/di-abstract/LICENSE +21 -0
  86. vendor/dhii/di-abstract/README.md +13 -0
  87. vendor/dhii/di-abstract/composer.json +35 -0
  88. vendor/dhii/di-abstract/composer.lock +1963 -0
  89. vendor/dhii/di-abstract/nbproject/private/private.xml +4 -0
  90. vendor/dhii/di-abstract/nbproject/project.properties +25 -0
  91. vendor/dhii/di-abstract/nbproject/project.xml +9 -0
  92. vendor/dhii/di-abstract/phpmd.xml +20 -0
  93. vendor/dhii/di-abstract/phpunit.xml +35 -0
  94. vendor/dhii/di-abstract/src/AbstractCompositeContainer.php +135 -0
  95. vendor/dhii/di-abstract/src/AbstractContainer.php +276 -0
  96. vendor/dhii/di-abstract/src/AbstractParentAwareContainer.php +102 -0
  97. vendor/dhii/di-abstract/src/AbstractServiceProvider.php +87 -0
  98. vendor/dhii/di-abstract/test/bootstrap.php +5 -0
  99. vendor/dhii/di-abstract/test/functional/AbstractCompositeContainerTest.php +337 -0
  100. vendor/dhii/di-abstract/test/functional/AbstractContainerTest.php +458 -0
  101. vendor/dhii/di-abstract/test/functional/AbstractParentAwareContainerTest.php +270 -0
  102. vendor/dhii/di-abstract/test/functional/AbstractServiceProviderTest.php +131 -0
  103. vendor/dhii/di-abstract/test/stub/AbstractCompositeContainerStub.php +25 -0
  104. vendor/dhii/di-abstract/test/stub/ContainerException.php +17 -0
  105. vendor/dhii/di-interface/.codeclimate.yml +17 -0
  106. vendor/dhii/di-interface/.php_cs +23 -0
  107. vendor/dhii/di-interface/.travis.yml +18 -0
  108. vendor/dhii/di-interface/CHANGELOG.md +12 -0
  109. vendor/dhii/di-interface/LICENSE +21 -0
  110. vendor/dhii/di-interface/README.md +29 -0
  111. vendor/dhii/di-interface/composer.json +29 -0
  112. vendor/dhii/di-interface/composer.lock +2075 -0
  113. vendor/dhii/di-interface/nbproject/private/private.xml +4 -0
  114. vendor/dhii/di-interface/nbproject/project.properties +31 -0
  115. vendor/dhii/di-interface/nbproject/project.xml +9 -0
  116. vendor/dhii/di-interface/phpunit.xml +35 -0
  117. vendor/dhii/di-interface/src/CompositeContainerInterface.php +17 -0
  118. vendor/dhii/di-interface/src/ContainerInterface.php +14 -0
  119. vendor/dhii/di-interface/src/ContainersAwareInterface.php +22 -0
  120. vendor/dhii/di-interface/src/ExceptionInterface.php +12 -0
  121. vendor/dhii/di-interface/src/FactoryInterface.php +26 -0
  122. vendor/dhii/di-interface/src/ParentAwareContainerInterface.php +22 -0
  123. vendor/dhii/di-interface/src/ServiceProviderInterface.php +14 -0
  124. vendor/dhii/di-interface/src/WritableCompositeContainerInterface.php +22 -0
  125. vendor/dhii/di-interface/src/WritableContainerInterface.php +35 -0
  126. vendor/dhii/di-interface/test/bootstrap.php +5 -0
  127. vendor/dhii/di-interface/test/functional/CompositeContainerInterfaceTest.php +51 -0
  128. vendor/dhii/di-interface/test/functional/ContainerInterfaceTest.php +49 -0
  129. vendor/dhii/di-interface/test/functional/ContainersAwareInterfaceTest.php +47 -0
  130. vendor/dhii/di-interface/test/functional/ExceptionInterfaceTest.php +46 -0
  131. vendor/dhii/di-interface/test/functional/FactoryInterface.php +47 -0
  132. vendor/dhii/di-interface/test/functional/ParentAwareContainerInterfaceTest.php +59 -0
  133. vendor/dhii/di-interface/test/functional/ServiceProviderInterfaceTest.php +48 -0
  134. vendor/dhii/di-interface/test/functional/WritableCompositeContainerInterfaceTest.php +53 -0
  135. vendor/dhii/di-interface/test/functional/WritableContainerInterfaceTest.php +53 -0
  136. vendor/dhii/di/CHANGELOG.md +22 -0
  137. vendor/dhii/di/LICENSE +21 -0
  138. vendor/dhii/di/README.md +21 -0
  139. vendor/dhii/di/composer.json +39 -0
  140. vendor/dhii/di/src/AbstractContainerBase.php +82 -0
  141. vendor/dhii/di/src/CompositeContainer.php +110 -0
  142. vendor/dhii/di/src/Container.php +54 -0
  143. vendor/dhii/di/src/ContainerWithImmutableParent.php +88 -0
  144. vendor/dhii/di/src/ContainerWithMutableParent.php +29 -0
  145. vendor/dhii/di/src/Exception/ContainerException.php +17 -0
  146. vendor/dhii/di/src/Exception/NotFoundException.php +17 -0
  147. vendor/dhii/di/src/ServiceProvider.php +49 -0
  148. wp-rss-aggregator.php +33 -42
includes/Aventura/Wprss/Core/Block/AbstractBlock.php CHANGED
@@ -13,16 +13,28 @@ abstract class AbstractBlock extends Core\Model\ModelAbstract implements BlockIn
13
  {
14
  /**
15
  * {@inheritdoc}
 
16
  * @since 4.9
17
  */
18
- public function __toString() {
19
- return $this->getOutput();
 
 
 
 
 
 
 
 
 
 
20
  }
21
 
22
  /**
23
  * A more structured way of retrieving this block's output.
24
  *
25
  * @since 4.9
 
26
  * @return string Output generated by this block.
27
  */
28
  abstract public function getOutput();
13
  {
14
  /**
15
  * {@inheritdoc}
16
+ *
17
  * @since 4.9
18
  */
19
+ public function __toString()
20
+ {
21
+ try {
22
+ $output = $this->getOutput();
23
+ } catch (\Exception $ex) {
24
+ $output = __(sprintf('Casting of block to string resulted in exception "%1$s" with message:' . "\n" . '%2$s', get_class($ex), $ex->getMessage()));
25
+ if (WPRSS_DEBUG) {
26
+ $output .= "\n" . $ex->getTraceAsString();
27
+ }
28
+ }
29
+
30
+ return $output;
31
  }
32
 
33
  /**
34
  * A more structured way of retrieving this block's output.
35
  *
36
  * @since 4.9
37
+ *
38
  * @return string Output generated by this block.
39
  */
40
  abstract public function getOutput();
includes/Aventura/Wprss/Core/Block/CallbackBlock.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Block;
4
+
5
+ /**
6
+ * A block that renders using a callback function.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class CallbackBlock extends AbstractBlock
11
+ {
12
+ /**
13
+ * {@inheritdoc}
14
+ *
15
+ * @since 4.11
16
+ *
17
+ * @param array $data
18
+ * @param \callable $callback
19
+ */
20
+ public function __construct(array $data = array(), $callback = null)
21
+ {
22
+ parent::__construct($data);
23
+
24
+ $this->setCallback($callback);
25
+ }
26
+
27
+ /**
28
+ * {@inheritdoc}
29
+ *
30
+ * @since 4.11
31
+ */
32
+ public function getOutput()
33
+ {
34
+ $callback = $this->getCallback();
35
+
36
+ return is_callable($callback)
37
+ ? call_user_func($callback)
38
+ : '';
39
+ }
40
+ }
includes/Aventura/Wprss/Core/Component/AdminAjaxNotices.php CHANGED
@@ -3,6 +3,8 @@
3
  namespace Aventura\Wprss\Core\Component;
4
 
5
  use Aventura\Wprss\Core;
 
 
6
 
7
  /**
8
  * Component responsible for notices in the backend.
@@ -11,6 +13,176 @@ use Aventura\Wprss\Core;
11
  */
12
  class AdminAjaxNotices extends Core\Plugin\ComponentAbstract
13
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
  /**
16
  * Retrieve the notice collection.
@@ -37,6 +209,72 @@ class AdminAjaxNotices extends Core\Plugin\ComponentAbstract
37
  */
38
  public function addNotice($notice)
39
  {
 
 
 
 
 
 
 
 
40
  return wprss_admin_notice_add($notice);
41
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
  }
3
  namespace Aventura\Wprss\Core\Component;
4
 
5
  use Aventura\Wprss\Core;
6
+ use Aventura\Wprss\Core\Model\AdminAjaxNotice\NoticeInterface;
7
+ use Interop\Container\ContainerInterface;
8
 
9
  /**
10
  * Component responsible for notices in the backend.
13
  */
14
  class AdminAjaxNotices extends Core\Plugin\ComponentAbstract
15
  {
16
+ /**
17
+ * @since 4.11
18
+ * @var ContainerInterface
19
+ */
20
+ protected $container;
21
+
22
+ public function __construct($data, ContainerInterface $container)
23
+ {
24
+ parent::__construct($data);
25
+
26
+ $this->_setContainer($container);
27
+ }
28
+
29
+ /**
30
+ * Sets the container that this component will use.
31
+ *
32
+ * @since 4.11
33
+ *
34
+ * @param ContainerInterface $container The container to set.
35
+ * @return AdminAjaxNotices This instance.
36
+ */
37
+ protected function _setContainer(ContainerInterface $container)
38
+ {
39
+ $this->container = $container;
40
+
41
+ return $this;
42
+ }
43
+
44
+ /**
45
+ * Retrieves the container used by this instance.
46
+ *
47
+ * @since 4.11
48
+ *
49
+ * @return ContainerInterface The container instance.
50
+ */
51
+ protected function _getContainer()
52
+ {
53
+ return $this->container;
54
+ }
55
+
56
+ /**
57
+ * {@inheritdoc}
58
+ *
59
+ * @since 4.11
60
+ */
61
+ public function hook()
62
+ {
63
+ parent::hook();
64
+ $this->_hookNotices();
65
+ $this->_hookAssets();
66
+ }
67
+
68
+ /**
69
+ * Hooks in a callback that adds existing notices to the controller.
70
+ *
71
+ * @see _addNotices()
72
+ *
73
+ * @since 4.11
74
+ */
75
+ protected function _hookNotices()
76
+ {
77
+ $this->on('!plugins_loaded', array($this, '_addNotices'));
78
+ }
79
+
80
+ /**
81
+ * Hooks in a callback that enqueues assets necessary for the notices.
82
+ *
83
+ * @since 4.11
84
+ */
85
+ protected function _hookAssets()
86
+ {
87
+ $me = $this;
88
+
89
+ $this->on('!init', function() use (&$me) {
90
+ if (is_admin()) {
91
+ $me->_registerAssets();
92
+ }
93
+ });
94
+
95
+ $this->on('admin_notice_add_after', function ($notice) use (&$me) {
96
+ /* @var $notice array Notice data */
97
+ /* @var $me AdminAjaxNotices */
98
+ $me->on('admin_scripts_styles', function () use (&$me) {
99
+ /* @var $me AdminAjaxNotices */
100
+ $me->enqueueAssets();
101
+ });
102
+ });
103
+ }
104
+
105
+ /**
106
+ * Enqueues assets of this component.
107
+ *
108
+ * @since 4.11
109
+ *
110
+ * @uses-filter wprss_admin_notice_collection_before_enqueue_scripts To modify list of script handles to enqueue.
111
+ * @uses-action wprss_admin_notice_collection_after_enqueue_scripts To access list of enqueued script handles.
112
+ */
113
+ public function enqueueAssets()
114
+ {
115
+ // Get singleton collection
116
+ $collection = $this->getNoticeCollection();
117
+
118
+ // Get script handles via filter
119
+ $script_handles = array('wprss-admin-notifications');
120
+ $this->event('admin_notice_collection_before_enqueue_scripts', array(&$script_handles, $collection));
121
+ // Iterate and enqueue scripts
122
+ foreach ($script_handles as $_idx => $_handle) {
123
+ wp_enqueue_script($_handle);
124
+ }
125
+ // Post-enqueueing action
126
+ $this->event('admin_notice_collection_after_enqueue_scripts', array(&$script_handles, $collection));
127
+ }
128
+
129
+ /**
130
+ * Registers assets of this component
131
+ *
132
+ * @since 4.11
133
+ */
134
+ public function _registerAssets()
135
+ {
136
+ $version = $this->getPlugin()->getVersion();
137
+ $collection = $this->getNoticeCollection();
138
+ // This handles the client side for WPRSS_Admin_Notices
139
+ wp_register_script( 'wprss-admin-notifications', wprss_get_script_url( 'admin-notifications' ), array('aventura'), $version, true );
140
+
141
+ // Frontend settings
142
+ $settings = array(
143
+ 'notice_class' => $collection->get_notice_base_class(),
144
+ 'nonce_class' => $collection->get_nonce_base_class(),
145
+ 'btn_close_class' => $collection->get_btn_close_base_class(),
146
+ 'action_code' => wprss_admin_notice_get_action_code(),
147
+ 'dismiss_mode_class_prefix' => $collection->get_dismiss_mode_class_prefix(),
148
+ );
149
+ $this->event( 'admin_notice_collection_before_localize_vars', array(&$settings, $collection) );
150
+ wp_localize_script( 'aventura', 'adminNoticeGlobalVars', $settings);
151
+
152
+ wp_enqueue_style( 'wprss-admin-styles' );
153
+ }
154
+
155
+ /**
156
+ * Adds notices to the notice controller.
157
+ *
158
+ * @see \WPRSS_Admin_Notices
159
+ *
160
+ * @since 4.11
161
+ *
162
+ * @return AdminAjaxNotices This instance.
163
+ */
164
+ public function _addNotices($eventData)
165
+ {
166
+ foreach ($this->_getNoticeNamesToAdd() as $_name) {
167
+ $this->addNotice($_name);
168
+ }
169
+
170
+ return $this;
171
+ }
172
+
173
+ /**
174
+ * Retrieves a list of notice names that should be added to the notice controller.
175
+ *
176
+ * @since 4.11
177
+ *
178
+ * @return array|\Traversable A list of notice names that should be added
179
+ */
180
+ protected function _getNoticeNamesToAdd()
181
+ {
182
+ return array(
183
+ 'more_features'
184
+ );
185
+ }
186
 
187
  /**
188
  * Retrieve the notice collection.
209
  */
210
  public function addNotice($notice)
211
  {
212
+ if (is_string($notice)) {
213
+ $notice = $this->_getNotice($notice);
214
+ }
215
+
216
+ if ($notice instanceof Core\DataObjectInterface) {
217
+ $notice = $notice->getData();
218
+ }
219
+
220
  return wprss_admin_notice_add($notice);
221
  }
222
+
223
+ /**
224
+ * Retrieves a notice instance for the given ID.
225
+ *
226
+ * @since 4.11
227
+ *
228
+ * @param string $name The unique notice name.
229
+ * @return NoticeInterface The notice for the name.
230
+ */
231
+ public function getNotice($name)
232
+ {
233
+ return $this->_getNotice($name);
234
+ }
235
+
236
+ /**
237
+ * Get a notice instance by its unique identifier.
238
+ *
239
+ * @since 4.11
240
+ *
241
+ * @param string $name Unique name of the notice.
242
+ * @return NoticeInterface The notice.
243
+ */
244
+ protected function _getNotice($name)
245
+ {
246
+ $serviceId = $this->_p($name);
247
+
248
+ return $this->_getContainer()->get($serviceId);
249
+ }
250
+
251
+ /**
252
+ * Determine whether or not a notice with the specified name exists.
253
+ *
254
+ * @since 4.11
255
+ *
256
+ * @param string $name The unique name of the notice.
257
+ * @return bool True if a notice with the specified name exists; false otherwise.
258
+ */
259
+ protected function _hasNotice($name)
260
+ {
261
+ $id = $this->_p($name);
262
+
263
+ return $this->_getContainer()->has($id);
264
+ }
265
+
266
+ /**
267
+ * Gets the service ID for a notice name.
268
+ *
269
+ * @since 4.11
270
+ *
271
+ * @param string $noticeName The unique notice name.
272
+ * @return string The service ID that corresponds to the given name.
273
+ */
274
+ protected function _p($noticeName)
275
+ {
276
+ return static::stringHadPrefix($noticeName)
277
+ ? $noticeName
278
+ : WPRSS_NOTICE_SERVICE_ID_PREFIX . $noticeName;
279
+ }
280
  }
includes/Aventura/Wprss/Core/Component/AdminHelper.php CHANGED
@@ -3,6 +3,7 @@
3
  namespace Aventura\Wprss\Core\Component;
4
 
5
  use Aventura\Wprss\Core;
 
6
 
7
  /**
8
  * Helper component for things related to the backend.
@@ -11,6 +12,20 @@ use Aventura\Wprss\Core;
11
  */
12
  class AdminHelper extends Core\Plugin\ComponentAbstract
13
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
  /**
15
  * Determine if currently showing page is related to WPRSS.
16
  *
@@ -65,4 +80,194 @@ class AdminHelper extends Core\Plugin\ComponentAbstract
65
 
66
  return $value;
67
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
  }
3
  namespace Aventura\Wprss\Core\Component;
4
 
5
  use Aventura\Wprss\Core;
6
+ use Dhii\Di\FactoryInterface;
7
 
8
  /**
9
  * Helper component for things related to the backend.
12
  */
13
  class AdminHelper extends Core\Plugin\ComponentAbstract
14
  {
15
+ /**
16
+ * The factory used by this instance to create services.
17
+ *
18
+ * @since 4.11
19
+ *
20
+ * @var FactoryInterface
21
+ */
22
+ protected $factory;
23
+
24
+ public function __construct($data, FactoryInterface $factory) {
25
+ parent::__construct($data);
26
+ $this->_setFactory($factory);
27
+ }
28
+
29
  /**
30
  * Determine if currently showing page is related to WPRSS.
31
  *
80
 
81
  return $value;
82
  }
83
+
84
+ /**
85
+ * Resolves a value accounting for case of it producing output.
86
+ *
87
+ * @since 4.11
88
+ *
89
+ * @param mixed $value The value to resolve.
90
+ *
91
+ * @return mixed|string The resolved value, if not null.
92
+ * Otherwise, output produced during resolution.
93
+ */
94
+ public function resolveValueOutput($value)
95
+ {
96
+ ob_start();
97
+ $value = $this->resolveValue($value);
98
+ $output = ob_get_clean();
99
+
100
+ return is_null($value)
101
+ ? $output
102
+ : $value;
103
+ }
104
+
105
+ /**
106
+ * Computes a hash of a given callable.
107
+ *
108
+ * @since 4.11
109
+ *
110
+ * @param callable $callable The callable to hash.
111
+ *
112
+ * @throws \InvalidArgumentException If not a valid callable.
113
+ *
114
+ * @return string A hash of the callable.
115
+ */
116
+ public function hashCallable($callable)
117
+ {
118
+ if (\is_object($callable) && \is_callable($callable)) {
119
+ return $this->hashObject($callable);
120
+ }
121
+
122
+ if (\is_array($callable) && \is_callable($callable)) {
123
+ if (\is_object($callable[0])) {
124
+ $callable[0] = \get_class($callable);
125
+ }
126
+
127
+ return $this->hashArray($callable);
128
+ }
129
+
130
+ if (\is_string($callable) && \is_callable($callable)) {
131
+ return $this->hashScalar($callable);
132
+ }
133
+
134
+ throw new \InvalidArgumentException('Could not hash: not a valid callback');
135
+ }
136
+
137
+ /**
138
+ * Computes a hash of the array.
139
+ *
140
+ * Accounts for nested arrays.
141
+ *
142
+ * @since 4.11
143
+ *
144
+ * @param array $array The array to hash.
145
+ *
146
+ * @return string A hash of the array.
147
+ */
148
+ public function hashArray(array $array)
149
+ {
150
+ $itemHashes = array();
151
+ foreach ($array as $_idx => $_item) {
152
+ if (\is_array($_item)) {
153
+ $itemHashes[$_idx] = $this->hashArray($_item);
154
+ } elseif (\is_object($_item)) {
155
+ $itemHashes[$_idx] = $this->hashObject($_item);
156
+ } elseif (\is_resource($_item)) {
157
+ $itemHashes[$_idx] = (string) $_item;
158
+ } else {
159
+ $itemHashes[$_idx] = $_item;
160
+ }
161
+ }
162
+
163
+ $itemHashes = \serialize($itemHashes);
164
+
165
+ return $this->hashScalar($itemHashes);
166
+ }
167
+
168
+ /**
169
+ * Computes a hash of an object.
170
+ *
171
+ * The same object will always have the same hash.
172
+ * Different identical objects will produce different results.
173
+ *
174
+ * @since 4.11
175
+ *
176
+ * @param object $object The object to hash.
177
+ *
178
+ * @return string A hash of the object.
179
+ */
180
+ public function hashObject($object)
181
+ {
182
+ return \spl_object_hash($object);
183
+ }
184
+
185
+ /**
186
+ * Computes a hash of a scalar value.
187
+ *
188
+ * @since 4.11
189
+ *
190
+ * @param string|int|float|bool $value The value to hash.
191
+ *
192
+ * @return string A hash of the scalar value.
193
+ */
194
+ public function hashScalar($value)
195
+ {
196
+ return \sha1($value);
197
+ }
198
+
199
+ /**
200
+ * Creates a new admin notificiation instance.
201
+ *
202
+ * @since 4.11
203
+ *
204
+ * @param array $data The data for the notice.
205
+ * @return NoticeInterface The new notice.
206
+ */
207
+ public function createNotice($data)
208
+ {
209
+ return $this->_getFactory()->make($this->_pn('generic_fallback'), $data);
210
+ }
211
+
212
+ /**
213
+ * Retrieves the factory used by this instance.
214
+ *
215
+ * @since 4.11
216
+ *
217
+ * @return FactoryInterface The factory instance.
218
+ */
219
+ protected function _getFactory()
220
+ {
221
+ return $this->factory;
222
+ }
223
+
224
+ /**
225
+ * Assigns the factory to be used by this instance.
226
+ *
227
+ * @since 4.11
228
+ *
229
+ * @param FactoryInterface $factory The factory instance..
230
+ *
231
+ * @return $this
232
+ */
233
+ protected function _setFactory(FactoryInterface $factory)
234
+ {
235
+ $this->factory = $factory;
236
+
237
+ return $this;
238
+ }
239
+
240
+ /**
241
+ * Retrieve the prefix used for notice services retrieved by this instance.
242
+ *
243
+ * @since 4.11
244
+ *
245
+ * @param string $name The service ID to prefix, if any.
246
+ *
247
+ * @return string The prefix, or prefixed ID.
248
+ */
249
+ protected function _pn($name = null)
250
+ {
251
+ $prefix = $this->getData('notice_service_id_prefix');
252
+ return static::stringHadPrefix($name)
253
+ ? $name
254
+ : "{$prefix}{$name}";
255
+ }
256
+
257
+ /**
258
+ * Retrieve the prefix used for services retrieved by this instance.
259
+ *
260
+ * @since 4.11
261
+ *
262
+ * @param string $name The service ID to prefix, if any.
263
+ *
264
+ * @return string The prefix, or prefixed ID.
265
+ */
266
+ protected function _p($name = null)
267
+ {
268
+ $prefix = $this->getData('service_id_prefix');
269
+ return static::stringHadPrefix($name)
270
+ ? $name
271
+ : "{$prefix}{$name}";
272
+ }
273
  }
includes/Aventura/Wprss/Core/Component/BulkSourceImport.php ADDED
@@ -0,0 +1,187 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Component;
4
+
5
+ use Aventura\Wprss\Core\Plugin\ComponentAbstract;
6
+ use Aventura\Wprss\Core\Model\BulkSourceImport\ImporterInterface;
7
+
8
+ /**
9
+ * A component that is responsible for importing feed sources in bulk.
10
+ *
11
+ * @since 4.11
12
+ */
13
+ class BulkSourceImport extends ComponentAbstract
14
+ {
15
+ const K_IMPORTED_SOURCES_COUNT = 'imported_sources_count';
16
+
17
+ /**
18
+ * @since 4.11
19
+ * @var ImporterInterface
20
+ */
21
+ protected $importer;
22
+
23
+ /**
24
+ * @since 4.11
25
+ *
26
+ * @param array $data The data members map.
27
+ * @param ImporterInterface $importer The importer that this instance should use to import sources.
28
+ */
29
+ public function __construct($data, ImporterInterface $importer)
30
+ {
31
+ parent::__construct($data);
32
+
33
+ $this->_setImporter($importer);
34
+ }
35
+
36
+ /**
37
+ * Resets data about the last import.
38
+ *
39
+ * @since 4.11
40
+ */
41
+ public function resetStats()
42
+ {
43
+ $this->unsetData(static::K_IMPORTED_SOURCES_COUNT);
44
+
45
+ return $this;
46
+ }
47
+
48
+ /**
49
+ * Imports a text representation of a feed source list.
50
+ *
51
+ * @since 4.11
52
+ *
53
+ * @param string $input The input string containing feed source representations.
54
+ * {@see \Aventura\Wprss\Core\Model\BulkSourceImport\PlainTextImporter::import()}
55
+ * @return array Array of results. See {@see ImporterInterface::import()}
56
+ */
57
+ public function import($input)
58
+ {
59
+ $this->resetStats();
60
+ $results = $this->_import($input);
61
+ $successCount = $this->_countSuccessfulResults($results);
62
+ $this->_setImportedSourcesCount($successCount);
63
+
64
+ return $results;
65
+ }
66
+
67
+ /**
68
+ *
69
+ * @param type $input
70
+ * @return array Array of results. See {@see ImporterInterface::import()}
71
+ */
72
+ protected function _import($input)
73
+ {
74
+ $importer = $this->_getImporter();
75
+ $results = $importer->import($input);
76
+
77
+ return $results;
78
+ }
79
+
80
+ /**
81
+ * Counts successful import results.
82
+ *
83
+ * @since 4.11
84
+ *
85
+ * @param array $results A list of import results.
86
+ * See {@see ImporterInterface::import()}.
87
+ * @return int The amount of successful results.
88
+ */
89
+ protected function _countSuccessfulResults($results)
90
+ {
91
+ $count = 0;
92
+ foreach ($results as $_idx => $_result) {
93
+ if (is_numeric($_result)) {
94
+ $count++;
95
+ }
96
+ }
97
+
98
+ return $count;
99
+ }
100
+
101
+ /**
102
+ * Retrieves errors that occurred during an import.
103
+ *
104
+ * @since 4.11
105
+ *
106
+ * @param array $results A list of import results.
107
+ * See {@see ImporterInterface::import()}.
108
+ * @return \Exception[] A list of exceptions that occurred during an import.
109
+ */
110
+ protected function _getImportFailures($results)
111
+ {
112
+ $failures = array();
113
+ foreach ($results as $_idx => $_result) {
114
+ if ($_result instanceof \Exception) {
115
+ $failures[$_idx] = $_result;
116
+ }
117
+ }
118
+
119
+ return $failures;
120
+ }
121
+
122
+ /**
123
+ * Retrieves the amount of feed sources successfully imported during the last import.
124
+ *
125
+ * @since 4.11
126
+ *
127
+ * @return int The amount of sources.
128
+ */
129
+ public function getImportedSourcesCount()
130
+ {
131
+ return $this->_getImportedSourcesCount();
132
+ }
133
+
134
+ /**
135
+ * Retrieves the imported sources count data member.
136
+ *
137
+ * @since 4.11
138
+ *
139
+ * @return int The amount of sources.
140
+ */
141
+ protected function _getImportedSourcesCount()
142
+ {
143
+ return (int) $this->_getData(self::K_IMPORTED_SOURCES_COUNT);
144
+ }
145
+
146
+ /**
147
+ * Sets the imported sources count data member.
148
+ *
149
+ * @since 4.11
150
+ *
151
+ * @param int $count The new count.
152
+ * @return BulkSourceImport This instance.
153
+ */
154
+ protected function _setImportedSourcesCount($count)
155
+ {
156
+ $this->setData(self::K_IMPORTED_SOURCES_COUNT, (int) $count);
157
+
158
+ return $this;
159
+ }
160
+
161
+ /**
162
+ * Assigns the importer that this instance should use.
163
+ *
164
+ * @since 4.11
165
+ *
166
+ * @param ImporterInterface $importer The importer.
167
+ * @return BulkSourceImport This instance.
168
+ */
169
+ protected function _setImporter(ImporterInterface $importer)
170
+ {
171
+ $this->importer = $importer;
172
+
173
+ return $this;
174
+ }
175
+
176
+ /**
177
+ * Retrieves the importer used by this instance.
178
+ *
179
+ * @since 4.11
180
+ *
181
+ * @return ImporterInterface
182
+ */
183
+ protected function _getImporter()
184
+ {
185
+ return $this->importer;
186
+ }
187
+ }
includes/Aventura/Wprss/Core/Component/EventManager.php DELETED
@@ -1,13 +0,0 @@
1
- <?php
2
-
3
- namespace Aventura\Wprss\Core\Component;
4
-
5
- use Aventura\Wprss\Core;
6
-
7
- /**
8
- * @since 4.8.1
9
- */
10
- class EventManager extends Core\Model\Event\EventManagerAbstract implements Core\Plugin\ComponentInterface
11
- {
12
- // All functionality is in most cases reusable from the ancestor
13
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
includes/Aventura/Wprss/Core/ComponentFactory.php CHANGED
@@ -3,13 +3,18 @@
3
  // This whole namespace is a temporary one, until there's a real Core add-on
4
  namespace Aventura\Wprss\Core;
5
 
 
 
 
 
 
6
  /**
7
  * A dummy factory of Core components.
8
  *
9
  * This is to be used with the Core plugin.
10
  *
11
- * @todo Create a real Core factory of Core components in the Core plugin.
12
  * @since 4.8.1
 
13
  */
14
  class ComponentFactory extends Plugin\ComponentFactoryAbstract
15
  {
@@ -22,29 +27,72 @@ class ComponentFactory extends Plugin\ComponentFactoryAbstract
22
  $this->setBaseNamespace(__NAMESPACE__ . '\\Component');
23
  }
24
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
25
  public function createLogger($data = array())
26
  {
27
- $logger = $this->createComponent('Logger', $this->getPlugin());
28
- if (!isset($data['log_file_path'])) {
29
- $data['log_file_path'] = WPRSS_LOG_FILE . '-' . get_current_blog_id() . WPRSS_LOG_FILE_EXT;
30
- }
31
- if (!isset($data['level_threshold'])) {
32
- $data['level_threshold'] = wprss_log_get_level();
33
- }
34
- $logger->addData($data);
35
 
36
- return $logger;
37
  }
38
 
39
  /**
 
 
40
  * @since 4.8.1
 
41
  * @param array $data
42
- * @return Model\Event\EventManagerInterface
43
  */
44
  public function createEventManager($data = array())
45
  {
46
- $events = $this->createComponent('EventManager', $this->getPlugin(), $data);
47
- return $events;
48
  }
49
 
50
  /**
@@ -53,11 +101,11 @@ class ComponentFactory extends Plugin\ComponentFactoryAbstract
53
  * @since 4.10
54
  *
55
  * @param array $data Additional data to use for component configuration.
56
- * @return Component\LeaveReviewNotification
57
  */
58
  public function createLeaveReviewNotification($data = array())
59
  {
60
- $component = $this->createComponent('LeaveReviewNotification', $this->getPlugin(), $data);
61
 
62
  return $component;
63
  }
@@ -65,13 +113,14 @@ class ComponentFactory extends Plugin\ComponentFactoryAbstract
65
  /**
66
  * Creates a component that is responsible for the admin notices.
67
  *
 
68
  * @since 4.10
69
  *
70
  * @return Component\AdminAjaxNotices
71
  */
72
  public function createAdminAjaxNotices($data = array())
73
  {
74
- $component = $this->createComponent('AdminAjaxNotices', $this->getPlugin(), $data);
75
 
76
  return $component;
77
  }
@@ -79,13 +128,14 @@ class ComponentFactory extends Plugin\ComponentFactoryAbstract
79
  /**
80
  * Creates a helper component related to the backend.
81
  *
 
82
  * @since 4.10
83
  *
84
  * @return Component\AdminHelper
85
  */
86
  public function createAdminHelper($data = array())
87
  {
88
- $component = $this->createComponent('AdminHelper', $this->getPlugin(), $data);
89
 
90
  return $component;
91
  }
3
  // This whole namespace is a temporary one, until there's a real Core add-on
4
  namespace Aventura\Wprss\Core;
5
 
6
+ use Dhii\Di\FactoryInterface;
7
+ use Interop\Container\ContainerInterface;
8
+ use Aventura\Wprss\Core\Model\LoggerInterface;
9
+ use Aventura\Wprss\Core\Model\Event\EventManagerInterface;
10
+
11
  /**
12
  * A dummy factory of Core components.
13
  *
14
  * This is to be used with the Core plugin.
15
  *
 
16
  * @since 4.8.1
17
+ * @deprecated 4.11 Here only for BC.
18
  */
19
  class ComponentFactory extends Plugin\ComponentFactoryAbstract
20
  {
27
  $this->setBaseNamespace(__NAMESPACE__ . '\\Component');
28
  }
29
 
30
+ /**
31
+ * Retrieve the DI container.
32
+ *
33
+ * @since 4.11
34
+ * @deprecated 4.11 This is just a temporary measure, until this class is removed.
35
+ *
36
+ * @return ContainerInterface The container instance.
37
+ */
38
+ protected function _getContainer()
39
+ {
40
+ return wprss_wp_container();
41
+ }
42
+
43
+ /**
44
+ * Prefixes a service name with the WPRA service ID prefix.
45
+ *
46
+ * @since 4.11
47
+ *
48
+ * @param string $name A service name.
49
+ * @return string The prefixed name.
50
+ */
51
+ protected function _p($name)
52
+ {
53
+ return \WPRSS_SERVICE_ID_PREFIX . $name;
54
+ }
55
+
56
+ /**
57
+ * Retrieve the factory used for component creation.
58
+ *
59
+ * @since 4.11
60
+ * @deprecated 4.11 This is just a temporary measure, until this class is removed.
61
+ *
62
+ * @return FactoryInterface The factory instance.
63
+ */
64
+ protected function _getFactory()
65
+ {
66
+ return $this->_getContainer()->get($this->_p('factory'));
67
+ }
68
+
69
+ /**
70
+ * Creates a logger.
71
+ *
72
+ * @since 4.8.1
73
+ *
74
+ * @param array $data Data for the logger.
75
+ * @return LoggerInterface The new logger instance.
76
+ */
77
  public function createLogger($data = array())
78
  {
79
+ $component = $this->_getFactory()->make($this->_p('logger'), $data);
 
 
 
 
 
 
 
80
 
81
+ return $component;
82
  }
83
 
84
  /**
85
+ * Creates an event manager.
86
+ *
87
  * @since 4.8.1
88
+ *
89
  * @param array $data
90
+ * @return EventManagerInterface The new event manager instance.
91
  */
92
  public function createEventManager($data = array())
93
  {
94
+ $component = $this->_getFactory()->make($this->_p('event_manager'), $data);
95
+ return $component;
96
  }
97
 
98
  /**
101
  * @since 4.10
102
  *
103
  * @param array $data Additional data to use for component configuration.
104
+ * @return Component\LeaveReviewNotification The new component instance.
105
  */
106
  public function createLeaveReviewNotification($data = array())
107
  {
108
+ $component = $this->_getFactory()->make($this->_p('leave_review'), $data);
109
 
110
  return $component;
111
  }
113
  /**
114
  * Creates a component that is responsible for the admin notices.
115
  *
116
+ * @deprecated 4.11
117
  * @since 4.10
118
  *
119
  * @return Component\AdminAjaxNotices
120
  */
121
  public function createAdminAjaxNotices($data = array())
122
  {
123
+ $component = $this->_getFactory()->make($this->_p('admin_ajax_notices'), $data);
124
 
125
  return $component;
126
  }
128
  /**
129
  * Creates a helper component related to the backend.
130
  *
131
+ * @deprecated 4.11
132
  * @since 4.10
133
  *
134
  * @return Component\AdminHelper
135
  */
136
  public function createAdminHelper($data = array())
137
  {
138
+ $component = $this->_getFactory()->make($this->_p('admin_helper'), $data);
139
 
140
  return $component;
141
  }
includes/Aventura/Wprss/Core/CompositeContainer.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core;
4
+
5
+ use Aventura\Wprss\Core\Plugin\Di\AbstractWritableCompositeContainer;
6
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
7
+
8
+ /**
9
+ * A container that delegates service lookup to child containers.
10
+ *
11
+ * @since 4.11
12
+ */
13
+ class CompositeContainer extends AbstractWritableCompositeContainer
14
+ {
15
+ /**
16
+ * @since 4.11
17
+ *
18
+ * @param BaseContainerInterface $parent The parent of this container, if any.
19
+ */
20
+ public function __construct(BaseContainerInterface $parent = null)
21
+ {
22
+ if (!is_null($parent)) {
23
+ $this->_setParentContainer($parent);
24
+ }
25
+ }
26
+ }
includes/Aventura/Wprss/Core/Container.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core;
4
+
5
+ use Aventura\Wprss\Core\Plugin\Di\AbstractContainer;
6
+ use Interop\Container\ServiceProvider as BaseServiceProvider;
7
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
8
+ use Dhii\Di\FactoryInterface;
9
+ use Dhii\Di\WritableContainerInterface;
10
+
11
+ /**
12
+ * The container that stores local, specific services.
13
+ *
14
+ * @since 4.11
15
+ */
16
+ class Container extends AbstractContainer implements FactoryInterface, WritableContainerInterface
17
+ {
18
+ /**
19
+ * @since 4.11
20
+ */
21
+ public function __construct(BaseServiceProvider $serviceProvider, BaseContainerInterface $parent = null)
22
+ {
23
+ $this->_register($serviceProvider);
24
+ if (!is_null($parent)) {
25
+ $this->_setParentContainer($parent);
26
+ }
27
+
28
+ $this->_construct();
29
+ }
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ *
34
+ * @since 4.11
35
+ */
36
+ public function make($id, array $config = array())
37
+ {
38
+ return $this->_make($id, $config);
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ *
44
+ * @since 4.11
45
+ */
46
+ public function register(\Interop\Container\ServiceProvider $serviceProvieder)
47
+ {
48
+ $this->_register($serviceProvieder);
49
+
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * {@inheritdoc}
55
+ *
56
+ * @since 4.11
57
+ */
58
+ public function set($id, $definition)
59
+ {
60
+ $this->_set($id, $definition);
61
+
62
+ return $this;
63
+ }
64
+ }
includes/Aventura/Wprss/Core/EventManager.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core;
4
+
5
+ use Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * Manages WPRA Core events.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ class EventManager extends Core\Model\Event\EventManagerAbstract
13
+ {
14
+ }
includes/Aventura/Wprss/Core/Factory.php CHANGED
@@ -2,22 +2,61 @@
2
 
3
  namespace Aventura\Wprss\Core;
4
 
 
 
5
  /**
 
6
  * @since 4.8.1
7
  */
8
  class Factory extends Plugin\FactoryAbstract
9
  {
 
 
 
 
 
 
 
10
  public function _create($data = array())
11
  {
12
- $plugin = new Plugin($data);
13
- $factory = new ComponentFactory($plugin);
14
- $plugin->setFactory($factory);
15
 
16
- $plugin->setLogger($factory->createLogger());
17
- $plugin->setEventManager($factory->createEventManager());
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
- $plugin->hook();
 
 
 
 
 
 
 
 
 
 
20
 
21
- return $plugin;
 
 
 
 
 
 
 
 
22
  }
23
  }
2
 
3
  namespace Aventura\Wprss\Core;
4
 
5
+ use Dhii\Di\FactoryInterface;
6
+
7
  /**
8
+ * @deprecated 4.11 Here only for BC.
9
  * @since 4.8.1
10
  */
11
  class Factory extends Plugin\FactoryAbstract
12
  {
13
+ /**
14
+ * Creates the plugin instance.
15
+ *
16
+ * @since 4.8.1
17
+ * @param array $data Data for the plugin.
18
+ * @return \Aventura\Wprss\Core\Plugin
19
+ */
20
  public function _create($data = array())
21
  {
22
+ $plugin = $this->_getFactory()->make($this->_p('plugin'), $data);
 
 
23
 
24
+ return $plugin;
25
+ }
26
+
27
+ /**
28
+ * Prefixes a service name with the WPRA service ID prefix.
29
+ *
30
+ * @since 4.11
31
+ *
32
+ * @param string $name A service name.
33
+ * @return string The prefixed name.
34
+ */
35
+ protected function _p($name)
36
+ {
37
+ return \WPRSS_SERVICE_ID_PREFIX . $name;
38
+ }
39
 
40
+ /**
41
+ * Gets service the factory.
42
+ *
43
+ * @since 4.11
44
+ *
45
+ * @return FactoryInterface The factory.
46
+ */
47
+ protected function _getFactory()
48
+ {
49
+ return $this->_getContainer()->get($this->_p('factory'));
50
+ }
51
 
52
+ /**
53
+ * Retrieve the DI container.
54
+ *
55
+ * @since 4.11
56
+ * @return ContainerInterface The container instance.
57
+ */
58
+ protected function _getContainer()
59
+ {
60
+ return wprss_wp_container();
61
  }
62
  }
includes/Aventura/Wprss/Core/Licensing/License.php CHANGED
@@ -94,10 +94,22 @@ class License {
94
  * @return self
95
  */
96
  public function setKey( $key ) {
97
- $this->_key = $key;
98
  return $this;
99
  }
100
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  /**
102
  * Gets the license status.
103
  *
94
  * @return self
95
  */
96
  public function setKey( $key ) {
97
+ $this->_key = $this->_sanitizeKey( $key );
98
  return $this;
99
  }
100
 
101
+ /**
102
+ * Sanitizes a license key string.
103
+ *
104
+ * @since 4.11
105
+ *
106
+ * @param string $key
107
+ * @return string
108
+ */
109
+ protected function _sanitizeKey($key) {
110
+ return trim( $key );
111
+ }
112
+
113
  /**
114
  * Gets the license status.
115
  *
includes/Aventura/Wprss/Core/Licensing/Manager.php CHANGED
@@ -27,6 +27,9 @@ class Manager {
27
  // Regex pattern for statuses in license option
28
  const DB_LICENSE_STATUSES_OPTION_PATTERN = '%s_license_%s';
29
 
 
 
 
30
  /**
31
  * License instance.
32
  *
@@ -353,6 +356,9 @@ class Manager {
353
  $license = $this->getLicense($addonId);
354
  // Get expiry
355
  $expires = $license->getExpiry();
 
 
 
356
  // Split using space and get first part only (date only)
357
  $parts = explode( ' ', $expires );
358
  $dateOnly = strtotime( $parts[0] );
@@ -463,7 +469,9 @@ class Manager {
463
 
464
  // Update the DB option
465
  $license->setStatus( $licenseData->license );
466
- $license->setExpiry( $licenseData->expires );
 
 
467
  $this->saveLicenseStatuses();
468
 
469
  // Return the data
27
  // Regex pattern for statuses in license option
28
  const DB_LICENSE_STATUSES_OPTION_PATTERN = '%s_license_%s';
29
 
30
+ // Lifetime expiration value
31
+ const EXPIRATION_LIFETIME = 'lifetime';
32
+
33
  /**
34
  * License instance.
35
  *
356
  $license = $this->getLicense($addonId);
357
  // Get expiry
358
  $expires = $license->getExpiry();
359
+ if ($expires === static::EXPIRATION_LIFETIME) {
360
+ return false;
361
+ }
362
  // Split using space and get first part only (date only)
363
  $parts = explode( ' ', $expires );
364
  $dateOnly = strtotime( $parts[0] );
469
 
470
  // Update the DB option
471
  $license->setStatus( $licenseData->license );
472
+ if (isset($licenseData->expires)) {
473
+ $license->setExpiry( $licenseData->expires );
474
+ }
475
  $this->saveLicenseStatuses();
476
 
477
  // Return the data
includes/Aventura/Wprss/Core/Licensing/Settings.php CHANGED
@@ -72,46 +72,32 @@ class Settings {
72
  * @return \Aventura\Wprss\Core\Licensing\Settings
73
  */
74
  protected function _initNotices() {
75
- $noticesCollection = wprss_admin_notice_get_collection();
 
 
76
  foreach ( $this->getManager()->getAddons() as $_addonId => $_addonName ) {
77
  $_year = date('Y');
78
- $noticesCollection->add_notice(
79
- array(
80
- 'id' => sprintf( 'empty_license_notice_%s', $_addonId ),
81
- 'addon' => $_addonId,
82
- 'notice_type' => 'error',
83
- 'condition' => array( array( $this, 'emptyLicenseKeyNoticeCondition' ) ),
84
- 'content' => sprintf(
85
- __( '<p>Remember to <a href="%1$s">enter your license key</a> for the <strong>WP RSS Aggregator - %2$s</strong> add-on to benefit from updates and support.</p>', WPRSS_TEXT_DOMAIN ),
86
- esc_attr( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings&tab=licenses_settings' ) ),
87
- $_addonName
88
- )
89
- )
90
- )->add_notice(
91
- array(
92
- 'id' => sprintf( 'saved_inactive_license_notice_%s', $_addonId ),
93
- 'addon' => $_addonId,
94
- 'notice_type' => 'error',
95
- 'condition' => array( array( $this, 'savedInactiveLicenseNoticeCondition' ) ),
96
- 'content' => sprintf(
97
- __( '<p>The license key for the <strong>WP RSS Aggregator - %2$s</strong> add-on is saved but not activated. In order to benefit from updates and support, it must be <a href="%1$s">activated</a>.</p>', WPRSS_TEXT_DOMAIN ),
98
- esc_attr( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings&tab=licenses_settings' ) ),
99
- $_addonName
100
- )
101
- )
102
- )->add_notice(
103
- array(
104
- 'id' => sprintf( 'soon_to_expire_license_notice_%s_%s', $_addonId, $_year ),
105
- 'addon' => $_addonId,
106
- 'notice_type' => 'error',
107
- 'condition' => array( array( $this, 'soonToExpireLicenseNoticeCondition' ) ),
108
- 'content' => sprintf(
109
- __( '<p>The license for the <strong>WP RSS Aggregator - %2$s</strong> add-on is about to expire. Make sure to renew it to keep receiving updates and benefit from support.</p>', WPRSS_TEXT_DOMAIN ),
110
- esc_attr( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings&tab=licenses_settings' ) ),
111
- $_addonName
112
- )
113
- )
114
- );
115
  }
116
 
117
  return $this;
@@ -123,9 +109,12 @@ class Settings {
123
  * @return boolean True if the notice is to be shown, false if not.
124
  */
125
  public function emptyLicenseKeyNoticeCondition( $args ) {
126
- if ( ! isset( $args['addon'] ) ) return false;
 
 
127
  $license = $this->getManager()->getLicense( $args['addon'] );
128
- return $license !== null && ! $license->isValid();
 
129
  }
130
 
131
 
@@ -135,9 +124,11 @@ class Settings {
135
  * @return boolean True if the notice is to be shown, false if not.
136
  */
137
  public function savedInactiveLicenseNoticeCondition( $args ) {
138
- if ( ! isset( $args['addon'] ) ) return false;
 
 
139
  $license = $this->getManager()->getLicense( $args['addon'] );
140
- return $license !== null && strlen( $license->getKey() ) > 0 && $license->isInactive();
141
  }
142
 
143
 
@@ -207,7 +198,7 @@ class Settings {
207
  $displayedKey = is_null( $license )? '' : self::obfuscateLicenseKey( $license->getKey() );
208
  // Render the markup ?>
209
  <input id="wprss-<?php echo $addonId ?>-license-key" name="wprss_settings_license_keys[<?php echo $addonId ?>_license_key]"
210
- type="text" value="<?php echo esc_attr( $displayedKey ) ?>" style="width: 300px;"
211
  />
212
  <label class="description" for="wprss-<?php echo $addonId ?>-license-key">
213
  <?php _e( 'Enter your license key', WPRSS_TEXT_DOMAIN ) ?>
@@ -312,7 +303,7 @@ class Settings {
312
  <p>
313
  <?php
314
  $license = $manager->getLicense( $addonId );
315
- if ( $license !== null && ($licenseKey = $license->getKey()) && !empty( $licenseKey ) ) :
316
  if ( is_object( $data ) ) :
317
  $currentActivations = $data->site_count;
318
  $activationsLeft = $data->activations_left;
72
  * @return \Aventura\Wprss\Core\Licensing\Settings
73
  */
74
  protected function _initNotices() {
75
+ $factory = wprss_core_container()->get(sprintf('%sfactory', WPRSS_SERVICE_ID_PREFIX));
76
+ $noticesComponent = wprss()->getAdminAjaxNotices();
77
+
78
  foreach ( $this->getManager()->getAddons() as $_addonId => $_addonName ) {
79
  $_year = date('Y');
80
+ $emptyLicenseNotice = $factory->make(sprintf('%saddon_empty_license', WPRSS_NOTICE_SERVICE_ID_PREFIX), array(
81
+ 'addon_id' => $_addonId,
82
+ 'addon_name' => $_addonName,
83
+ 'settings' => $this
84
+ ));
85
+ $noticesComponent->addNotice($emptyLicenseNotice);
86
+
87
+ $inactiveLicenseNotice = $factory->make(sprintf('%saddon_inactive_license', WPRSS_NOTICE_SERVICE_ID_PREFIX), array(
88
+ 'addon_id' => $_addonId,
89
+ 'addon_name' => $_addonName,
90
+ 'settings' => $this
91
+ ));
92
+ $noticesComponent->addNotice($inactiveLicenseNotice);
93
+
94
+ $expiringLicenseNotice = $factory->make(sprintf('%saddon_expiring_license', WPRSS_NOTICE_SERVICE_ID_PREFIX), array(
95
+ 'addon_id' => $_addonId,
96
+ 'addon_name' => $_addonName,
97
+ 'settings' => $this,
98
+ 'year' => $_year
99
+ ));
100
+ $noticesComponent->addNotice($expiringLicenseNotice);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
101
  }
102
 
103
  return $this;
109
  * @return boolean True if the notice is to be shown, false if not.
110
  */
111
  public function emptyLicenseKeyNoticeCondition( $args ) {
112
+ if ( ! isset( $args['addon'] ) ) {
113
+ return false;
114
+ }
115
  $license = $this->getManager()->getLicense( $args['addon'] );
116
+
117
+ return is_null($license) || strlen( $license->getKey() ) === 0;
118
  }
119
 
120
 
124
  * @return boolean True if the notice is to be shown, false if not.
125
  */
126
  public function savedInactiveLicenseNoticeCondition( $args ) {
127
+ if ( ! isset( $args['addon'] ) ) {
128
+ return false;
129
+ }
130
  $license = $this->getManager()->getLicense( $args['addon'] );
131
+ return $license !== null && strlen( $license->getKey() ) > 0 && ! $license->isValid();
132
  }
133
 
134
 
198
  $displayedKey = is_null( $license )? '' : self::obfuscateLicenseKey( $license->getKey() );
199
  // Render the markup ?>
200
  <input id="wprss-<?php echo $addonId ?>-license-key" name="wprss_settings_license_keys[<?php echo $addonId ?>_license_key]"
201
+ class="wprss-license-input" type="text" value="<?php echo esc_attr( $displayedKey ) ?>" style="width: 300px;"
202
  />
203
  <label class="description" for="wprss-<?php echo $addonId ?>-license-key">
204
  <?php _e( 'Enter your license key', WPRSS_TEXT_DOMAIN ) ?>
303
  <p>
304
  <?php
305
  $license = $manager->getLicense( $addonId );
306
+ if ( $license !== null && !$license->isInvalid() && ($licenseKey = $license->getKey()) && !empty( $licenseKey ) ) :
307
  if ( is_object( $data ) ) :
308
  $currentActivations = $data->site_count;
309
  $activationsLeft = $data->activations_left;
includes/Aventura/Wprss/Core/Model/AbstractTranslatingModel.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model;
4
+
5
+ /**
6
+ * A model that has translation capabilities via an external translator.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class AbstractTranslatingModel extends ModelAbstract
11
+ {
12
+ /**
13
+ * @since 4.11
14
+ * @var callable
15
+ */
16
+ protected $translator;
17
+
18
+ /**
19
+ * Sets the translator to be used by this instance.
20
+ *
21
+ * @since 4.11
22
+ *
23
+ * @param callable $translator The translator.
24
+ * @return $this This instance.
25
+ * @throws \Exception If translator not valid.
26
+ */
27
+ protected function _setTranslator($translator)
28
+ {
29
+ if (!is_callable($translator)) {
30
+ throw $this->exception('Could not set translator: translator must be callable');
31
+ }
32
+
33
+ $this->translator = $translator;
34
+
35
+ return $this;
36
+ }
37
+
38
+ /**
39
+ * Retrieves the translator used by this instance.
40
+ *
41
+ * @since 4.11
42
+ *
43
+ * @return callable The translator.
44
+ */
45
+ protected function _getTranslator()
46
+ {
47
+ return $this->translator;
48
+ }
49
+
50
+ /**
51
+ * {@inheritdoc}
52
+ *
53
+ * Translates text using
54
+ *
55
+ * If translator is not specified, and one is set for this instance,
56
+ * that translator will be used instead.
57
+ *
58
+ * @since 4.11
59
+ */
60
+ protected function _translate($text, $translator = null) {
61
+ if (is_null($translator)) {
62
+ $translator = $this->_getTranslator();
63
+ }
64
+
65
+ if (!is_callable($translator)) {
66
+ return parent::_translate($text);
67
+ }
68
+
69
+ return $translator($text);
70
+ }
71
+ }
includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/AdminAjaxNotice.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\AdminAjaxNotice;
4
+
5
+ /**
6
+ * Implementation of a notice that shows on the admin side and uses AJAX for dismissal.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class AdminAjaxNotice extends NoticeAbstract implements AdminAjaxNoticeInterface
11
+ {
12
+ /**
13
+ * {@inheritdoc}
14
+ *
15
+ * @since 4.11
16
+ */
17
+ public function getElementClass()
18
+ {
19
+ return $this->getData('element_class', '');
20
+ }
21
+
22
+ /**
23
+ * {@inheritdoc}
24
+ *
25
+ * @since 4.11
26
+ */
27
+ public function getCloseButtonId()
28
+ {
29
+ return $this->getData('btn_close_id', null);
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ *
35
+ * @since 4.11
36
+ */
37
+ public function getCloseButtonClass()
38
+ {
39
+ return $this->getData('btn_close_class', 'btn-close');
40
+ }
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ *
45
+ * @since 4.11
46
+ */
47
+ public function getCloseButtonContent()
48
+ {
49
+ return $this->getData('btn_close_content', '');
50
+ }
51
+
52
+ /**
53
+ * {@inheritdoc}
54
+ *
55
+ * @since 4.11
56
+ */
57
+ public function getNonce()
58
+ {
59
+ return $this->getData('nonce', null);
60
+ }
61
+
62
+ /**
63
+ * {@inheritdoc}
64
+ *
65
+ * @since 4.11
66
+ */
67
+ public function getNonceElementId()
68
+ {
69
+ return $this->getData('nonce_element_id', null);
70
+ }
71
+
72
+ /**
73
+ * {@inheritdoc}
74
+ *
75
+ * @since 4.11
76
+ */
77
+ public function getNonceElementClass()
78
+ {
79
+ return $this->getData('nonce_element_class', 'admin-notice-nonce');
80
+ }
81
+
82
+ /**
83
+ * {@inheritdoc}
84
+ *
85
+ * @since 4.11
86
+ */
87
+ public function getConditionOnError()
88
+ {
89
+ return $this->getData('condition_on_error', static::CONDITION_ON_ERROR_THROW_EXCEPTION);
90
+ }
91
+ }
includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/AdminAjaxNoticeInterface.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\AdminAjaxNotice;
4
+
5
+ use \Aventura\Wprss\Core\Block\BlockInterface;
6
+
7
+ /**
8
+ * Something that represents a WPRA admin AJAX notice.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ interface AdminAjaxNoticeInterface extends NoticeInterface
13
+ {
14
+ /**
15
+ * Throw an exception when an error is encountered during condition resolution.
16
+ *
17
+ * @since 4.11
18
+ */
19
+ const CONDITION_ON_ERROR_THROW_EXCEPTION = 'throw_exception';
20
+
21
+ /**
22
+ * Gets the notice HTML element class.
23
+ *
24
+ * @since 4.11
25
+ *
26
+ * @return string The HTML "class" attribute value.
27
+ */
28
+ public function getElementClass();
29
+
30
+ /**
31
+ * Gets the HTML ID of the close button.
32
+ *
33
+ * @since 4.11
34
+ *
35
+ * @return string The HTML ID attribute value string.
36
+ */
37
+ public function getCloseButtonId();
38
+
39
+ /**
40
+ * Gets the HTML class of the close button.
41
+ *
42
+ * @since 4.11
43
+ *
44
+ * @return string The HTML class attribute value string.
45
+ */
46
+ public function getCloseButtonClass();
47
+
48
+ /**
49
+ * Gets the content of the close button.
50
+ *
51
+ * @since 4.11
52
+ *
53
+ * @return BlockInterface|string The block or string for the close button content.
54
+ */
55
+ public function getCloseButtonContent();
56
+
57
+ /**
58
+ * Gets the AJAX nonce code.
59
+ *
60
+ * @since 4.11
61
+ *
62
+ * @return string The nonce code string.
63
+ */
64
+ public function getNonce();
65
+
66
+ /**
67
+ * Gets the AJAX nonce HTML element ID.
68
+ *
69
+ * @since 4.11
70
+ *
71
+ * @return string The HTML ID attribute value string.
72
+ */
73
+ public function getNonceElementId();
74
+
75
+ /**
76
+ * Gets the AJAX nonce HTML element class.
77
+ *
78
+ * @return string The HTML class attribute value string.
79
+ */
80
+ public function getNonceElementClass();
81
+
82
+ /**
83
+ * Gets the action to be taken when an error is encountered during condition resolution.
84
+ *
85
+ * @see CONDITION_ON_ERROR_THROW_EXCEPTION
86
+ *
87
+ * @since 4.11
88
+ *
89
+ * @return string A string identifying the action to be taken.
90
+ */
91
+ public function getConditionOnError();
92
+ }
includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/NoticeAbstract.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\AdminAjaxNotice;
4
+
5
+ use \Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * Basic functionality for a notice.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ abstract class NoticeAbstract extends Core\Model\ModelAbstract implements NoticeInterface
13
+ {
14
+ protected static $dismissModes = array(
15
+ NoticeInterface::DISMISS_MODE_NONE => NoticeInterface::DISMISS_MODE_NONE,
16
+ NoticeInterface::DISMISS_MODE_FRONTEND => NoticeInterface::DISMISS_MODE_FRONTEND,
17
+ NoticeInterface::DISMISS_MODE_AJAX => NoticeInterface::DISMISS_MODE_AJAX,
18
+ );
19
+
20
+ /**
21
+ * {@inheritdoc}
22
+ *
23
+ * @since 4.11
24
+ */
25
+ public function isActive()
26
+ {
27
+ return (bool) $this->getData('active', true);
28
+ }
29
+
30
+ /**
31
+ * {@inheritdoc}
32
+ *
33
+ * @since 4.11
34
+ */
35
+ public function getType()
36
+ {
37
+ return $this->getData('type', static::TYPE_UPDATED);
38
+ }
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ *
43
+ * @since 4.11
44
+ */
45
+ public function getStyle()
46
+ {
47
+ return $this->getData('style', static::STYLE_NORMAL);
48
+ }
49
+
50
+ /**
51
+ * {@inheritdoc}
52
+ *
53
+ * @since 4.11
54
+ */
55
+ public function getContent()
56
+ {
57
+ return $this->getData('content', '');
58
+ }
59
+
60
+ /**
61
+ * {@inheritdoc}
62
+ *
63
+ * @since 4.11
64
+ */
65
+ public function getConditions()
66
+ {
67
+ return $this->getData('condition', array());
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ *
73
+ * @since 4.11
74
+ */
75
+ public function getConditionType()
76
+ {
77
+ return $this->getData('condition_type', static::CONDITION_TYPE_ALL);
78
+ }
79
+
80
+ /**
81
+ * {@inheritdoc}
82
+ *
83
+ * @since 4.11
84
+ */
85
+ public function isDismissable()
86
+ {
87
+ return $this->getDismissMode() !== NoticeInterface::DISMISS_MODE_NONE;
88
+ }
89
+
90
+ /**
91
+ * {@inheritdoc}
92
+ *
93
+ * @since 4.11
94
+ */
95
+ public function getDismissMode()
96
+ {
97
+ return $this->getData('dismiss_mode', NoticeInterface::DISMISS_MODE_AJAX);
98
+ }
99
+ }
includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/NoticeInterface.php ADDED
@@ -0,0 +1,214 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\AdminAjaxNotice;
4
+
5
+ /**
6
+ * Something that represents a notice shown on the admin WordPress screens.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ interface NoticeInterface
11
+ {
12
+ /**
13
+ * Condition type that signifies that all conditions in a collection must evaluate to true.
14
+ *
15
+ * @since 4.11
16
+ */
17
+ const CONDITION_TYPE_ALL = 'all';
18
+
19
+ /**
20
+ * Condition type that signifies that at least one condition in a collection must be evaluate
21
+ * to true.
22
+ *
23
+ * @since 4.11
24
+ */
25
+ const CONDITION_TYPE_ANY = 'any';
26
+
27
+ /**
28
+ * Condition type that signifies that none of the conditions in a collection must evaluate
29
+ * to true.
30
+ *
31
+ * @since 4.11
32
+ */
33
+ const CONDITION_TYPE_NONE = 'none';
34
+
35
+ /**
36
+ * Condition type that signifies that at least on of the conditions in a collection must
37
+ * evaluate to false.
38
+ *
39
+ * @since 4.11
40
+ */
41
+ const CONDITION_TYPE_ALMOST = 'almost';
42
+
43
+ /**
44
+ * A notice type that represents a successful operation.
45
+ *
46
+ * @since 4.11
47
+ */
48
+ const TYPE_SUCCESS = 'success';
49
+
50
+ /**
51
+ * A notice type that signifies that something has been updated.
52
+ *
53
+ * @since 4.11
54
+ */
55
+ const TYPE_UPDATED = 'updated';
56
+
57
+ /**
58
+ * A notice type that represents an informational notice message.
59
+ *
60
+ * @since 4.11
61
+ */
62
+ const TYPE_INFO = 'info';
63
+
64
+ /**
65
+ * A notice type that represents a warning message.
66
+ *
67
+ * @since 4.11
68
+ */
69
+ const TYPE_WARNING = 'warning';
70
+
71
+ /**
72
+ * A notice type that represents an error message.
73
+ *
74
+ * @since 4.11
75
+ */
76
+ const TYPE_ERROR = 'error';
77
+
78
+ /**
79
+ * The normal styling mode for notices.
80
+ *
81
+ * @since 4.11
82
+ */
83
+ const STYLE_NORMAL = 'normal';
84
+
85
+ /**
86
+ * The alternative styling mode for notices.
87
+ *
88
+ * @since 4.11
89
+ */
90
+ const STYLE_ALT = 'alt';
91
+
92
+ /**
93
+ * Notice is dismissable by making an async request to the backend,
94
+ * where the decision to dismiss will persist.
95
+ *
96
+ * @since 4.11
97
+ */
98
+ const DISMISS_MODE_AJAX = 'ajax';
99
+
100
+ /**
101
+ * Notice is dismissable by simply and only removing the notice element from the DOM.
102
+ * Does not persist.
103
+ *
104
+ * @since 4.11
105
+ */
106
+ const DISMISS_MODE_FRONTEND = 'front';
107
+
108
+ /**
109
+ * Noice cannot be dismissed manually.
110
+ *
111
+ * @since 4.11
112
+ */
113
+ const DISMISS_MODE_NONE = 'none';
114
+
115
+ /**
116
+ * Gets the ID of the notice.
117
+ *
118
+ * @since 4.11
119
+ *
120
+ * @return string The notice ID string.
121
+ */
122
+ public function getId();
123
+
124
+ /**
125
+ * Checks if the notice is active or not.
126
+ *
127
+ * i.e. If it can be displayed or not.
128
+ *
129
+ * @since 4.11
130
+ *
131
+ * @return bool True if the notice is active, false if not.
132
+ */
133
+ public function isActive();
134
+
135
+ /**
136
+ * Gets the notice type.
137
+ *
138
+ * @see TYPE_SUCCESS
139
+ * @see TYPE_UPDATED
140
+ * @see TYPE_INFO
141
+ * @see TYPE_WARNING
142
+ * @see TYPE_ERROR
143
+ *
144
+ * @since 4.11
145
+ *
146
+ * @return string The notice type string.
147
+ */
148
+ public function getType();
149
+
150
+ /**
151
+ * Gets the notice style.
152
+ *
153
+ * @see STYLE_NORMAL
154
+ * @see STYLE_ALT
155
+ *
156
+ * @since 4.11
157
+ *
158
+ * @return string The notice style type string.
159
+ */
160
+ public function getStyle();
161
+
162
+ /**
163
+ * Gets the notice content.
164
+ *
165
+ * @since 4.11
166
+ *
167
+ * @return BlockInterface|string The notice content block or string.
168
+ */
169
+ public function getContent();
170
+
171
+ /**
172
+ * Gets the conditions which dictate when the notice is shown.
173
+ *
174
+ * @since 4.11
175
+ *
176
+ * @return array An array of callback function conditions.
177
+ */
178
+ public function getConditions();
179
+
180
+ /**
181
+ * Gets the condition resolution type.
182
+ *
183
+ * @see CONDITION_TYPE_ALL
184
+ * @see CONDITION_TYPE_ANY
185
+ * @see CONDITION_TYPE_NONE
186
+ * @see CONDITION_TYPE_ALMOST
187
+ *
188
+ * @since 4.11
189
+ *
190
+ * @return string The condition type string.
191
+ */
192
+ public function getConditionType();
193
+
194
+ /**
195
+ * Gets whether the notice is dismissable or persistent.
196
+ *
197
+ * @since 4.11
198
+ *
199
+ * @return bool True if the notice can be dismissed, false if it is persistent.
200
+ */
201
+ public function isDismissable();
202
+
203
+ /**
204
+ * Determines the way in which a notice can be dismissed, if any.
205
+ *
206
+ * @since 4.11
207
+ * @see DISMISS_MODE_NONE
208
+ * @see DISMISS_MODE_AJAX
209
+ * @see DISMISS_MODE_FRONTEND
210
+ *
211
+ * @return string|int One of the `DISMISS_MODE_*` class constants.
212
+ */
213
+ public function getDismissMode();
214
+ }
includes/Aventura/Wprss/Core/Model/AdminAjaxNotice/ServiceProvider.php ADDED
@@ -0,0 +1,725 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\AdminAjaxNotice;
4
+
5
+ use Aventura\Wprss\Core\Plugin\Di\AbstractComponentServiceProvider;
6
+ use Aventura\Wprss\Core\Plugin\Di\ServiceProviderInterface;
7
+ use Interop\Container\ContainerInterface;
8
+ use Aventura\Wprss\Core\Component\AdminAjaxNotices;
9
+ use Aventura\Wprss\Core\Block\CallbackBlock;
10
+ use Aventura\Wprss\Core\Component\AdminHelper;
11
+ use Aventura\Wprss\Core\Model\CommandInterface;
12
+
13
+ /**
14
+ * Provides services that represent admin notices.
15
+ *
16
+ * @since 4.11
17
+ */
18
+ class ServiceProvider extends AbstractComponentServiceProvider implements ServiceProviderInterface
19
+ {
20
+ /**
21
+ * {@inheritdoc}
22
+ *
23
+ * @since 4.11
24
+ */
25
+ protected function _getServiceDefinitions()
26
+ {
27
+ return array(
28
+ $this->_p('admin_ajax_notice_controller') => array($this, '_createAdminAjaxNoticeController'),
29
+ $this->_p('admin_ajax_notices') => array($this, '_createAdminAjaxNotices'),
30
+ $this->_p('command.is_wprss_page') => array($this, '_createCommandIsWprssPage'),
31
+
32
+ $this->_pn('more_features') => array($this, '_createMoreFeaturesNotice'),
33
+ $this->_pn('deleting_feed_items') => array($this, '_createDeletingFeedItemsNotice'),
34
+ $this->_pn('bulk_feed_import') => array($this, '_createBulkFeedImportNotice'),
35
+ $this->_pn('settings_import_success') => array($this, '_createSettingsImportSuccessNotice'),
36
+ $this->_pn('settings_import_failed') => array($this, '_createSettingsImportFailedNotice'),
37
+ $this->_pn('debug_feeds_updating') => array($this, '_createDebugFeedsUpdatingNotice'),
38
+ $this->_pn('debug_feeds_reimporting') => array($this, '_createDebugFeedsReimportingNotice'),
39
+ $this->_pn('debug_cleared_log') => array($this, '_createDebugClearedLogNotice'),
40
+ $this->_pn('debug_settings_reset') => array($this, '_createDebugSettingsResetNotice'),
41
+ $this->_pn('blacklist_item_success') => array($this, '_createBlacklistItemSuccessNotice'),
42
+ $this->_pn('bulk_feed_activated') => array($this, '_createBulkFeedActivatedNotice'),
43
+ $this->_pn('bulk_feed_paused') => array($this, '_createBulkFeedPausedNotice'),
44
+
45
+ $this->_pn('addon_empty_license') => array($this, '_createAddonEmptyLicenseNotice'),
46
+ $this->_pn('addon_inactive_license') => array($this, '_createAddonInactiveLicenseNotice'),
47
+ $this->_pn('addon_expiring_license') => array($this, '_createAddonExpiringLicenseNotice'),
48
+ $this->_pn('generic_fallback') => array($this, '_createGenericFallbackNotice'),
49
+ );
50
+ }
51
+
52
+ /**
53
+ * Creates an instance of the admin AJAX notice controller.
54
+ *
55
+ * @uses-filter wprss_admin_notice_collection_before_init To modify collection before initialization.
56
+ * @uses-filter wprss_admin_notice_collection_after_init To modify collection after initialization.
57
+ * @uses-action wprss_admin_exclusive_scripts_styles To enqueue the scripts for the collection.
58
+ *
59
+ * @since 4.11
60
+ *
61
+ * @param ContainerInterface $c
62
+ * @param null $p Deprecated.
63
+ * @param array $config
64
+ * @return \WPRSS_Admin_Notices
65
+ */
66
+ public function _createAdminAjaxNoticeController(ContainerInterface $c, $p = null, $config = null)
67
+ {
68
+ $config = $this->_normalizeConfig($config, array(
69
+ 'setting_code' => 'wprss_admin_notices',
70
+ 'id_prefix' => 'wprss_',
71
+ 'text_domain' => \WPRSS_TEXT_DOMAIN
72
+ ));
73
+ // Initialize collection
74
+ $controller = new \WPRSS_Admin_Notices($config);
75
+ $controller = apply_filters( \WPRSS_EVENT_PREFIX.'admin_notice_collection_before_init', $controller );
76
+ $controller->init();
77
+ $controller = apply_filters( \WPRSS_EVENT_PREFIX.'admin_notice_collection_after_init', $controller );
78
+
79
+ return $controller;
80
+ }
81
+
82
+ /**
83
+ * Creates an instance of the admin AJAX notices component.
84
+ *
85
+ * @since 4.11
86
+ *
87
+ * @param ContainerInterface $c
88
+ * @param null $p
89
+ * @param array $config
90
+ * @return Component\AdminAjaxNotices
91
+ */
92
+ public function _createAdminAjaxNotices(ContainerInterface $c, $p = null, $config = null)
93
+ {
94
+ $config = $this->_normalizeConfig($config, array(
95
+ 'plugin' => $c->get($this->_p('plugin'))
96
+ ));
97
+ $service = new AdminAjaxNotices($config, $c);
98
+ $this->_prepareComponent($service);
99
+
100
+ return $service;
101
+ }
102
+
103
+ /**
104
+ * Normalizes data of a notice.
105
+ *
106
+ * @since 4.11
107
+ *
108
+ * @param ContainerInterface $container DI container that will be used to retrieve notice controller.
109
+ * @param array $data Data to normalize.
110
+ * @return array Normalized data with defaults.
111
+ */
112
+ protected function _normalizeNoticeData(ContainerInterface $container, $data = array())
113
+ {
114
+ if (!isset($data['id']) && isset($data['content'])) {
115
+ $data['id'] = $this->_hashNoticeContent($container, $data['content']);
116
+ }
117
+
118
+ return $data;
119
+ }
120
+
121
+ /**
122
+ * Creates a notice that informs users about other features.
123
+ *
124
+ * @since 4.11
125
+ *
126
+ * @param ContainerInterface $c
127
+ * @param null $p
128
+ * @param array $config
129
+ * @return NoticeInterface
130
+ */
131
+ public function _createMoreFeaturesNotice(ContainerInterface $c, $p = null, $config = null)
132
+ {
133
+ $notice = $this->_createNotice(array(
134
+ 'id' => 'more_features',
135
+ 'notice_type' => NoticeInterface::TYPE_UPDATED,
136
+ 'condition' => $this->_getCommandIsWprssPage($c),
137
+ 'content' => $this->_autoParagraph($this->__('Did you know that you can get more RSS features? Excerpts, thumbnails, keyword filtering, importing into posts and more... ') .
138
+ $this->__(array('Check out the <a target="_blank" href="%1$s"><strong>extensions</strong></a> page.', 'http://www.wprssaggregator.com/extensions')))
139
+ ), $c);
140
+
141
+ return $notice;
142
+ }
143
+
144
+ /**
145
+ * Creates a notice that informs users that feed items are deleting in the background.
146
+ *
147
+ * @since 4.11
148
+ *
149
+ * @param ContainerInterface $c
150
+ * @param null $p
151
+ * @param array $config
152
+ * @return NoticeInterface
153
+ */
154
+ public function _createDeletingFeedItemsNotice(ContainerInterface $c, $p = null, $config = null)
155
+ {
156
+ $notice = $this->_createNotice(array(
157
+ 'id' => 'deleting_feed_items',
158
+ 'condition' => $this->_getCommandIsWprssPage($c),
159
+ 'content' => $this->_autoParagraph($this->__('The feed items for this feed source are being deleted in the background.')),
160
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
161
+ ), $c);
162
+
163
+ return $notice;
164
+ }
165
+
166
+ /**
167
+ * Creates a notice that tells the user how many feed sources where successfully imported
168
+ *
169
+ * @since 4.11
170
+ *
171
+ * @param ContainerInterface $c
172
+ * @param null $p
173
+ * @param array $config
174
+ * @return NoticeInterface
175
+ */
176
+ public function _createBulkFeedImportNotice(ContainerInterface $c, $p = null, $config)
177
+ {
178
+ $me = $this;
179
+ $import = $c->get($this->_p('bulk_source_import'));
180
+ $notice = $this->_createNotice(array(
181
+ 'id' => 'debug_reset_settings',
182
+ 'condition' => $this->_getCommandIsWprssPage($c),
183
+ 'content' => new CallbackBlock(array(), function() use ($me, $import) {
184
+ return $me->_autoParagraph(
185
+ sprintf($me->__('Successfully imported <code>%1$s</code> feed sources.'), $import->getImportedSourcesCount())
186
+ );
187
+ }),
188
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
189
+ ), $c);
190
+
191
+ return $notice;
192
+ }
193
+
194
+ /**
195
+ * Creates a notice that informs the user that the settings import was successful.
196
+ *
197
+ * @since 4.11
198
+ *
199
+ * @param ContainerInterface $c
200
+ * @param null $p
201
+ * @param array $config
202
+ * @return NoticeInterface
203
+ */
204
+ public function _createSettingsImportSuccessNotice(ContainerInterface $c, $p = null, $config)
205
+ {
206
+ $notice = $this->_createNotice(array(
207
+ 'id' => 'settings_import_success',
208
+ 'notice_type' => NoticeInterface::TYPE_UPDATED,
209
+ 'condition' => $this->_getCommandIsWprssPage($c),
210
+ 'content' => $this->_autoParagraph($this->__('All options are restored successfully.')),
211
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
212
+ ), $c);
213
+
214
+ return $notice;
215
+ }
216
+
217
+ /**
218
+ * Creates a notice that informs the user that the settings import failed.
219
+ *
220
+ * @since 4.11
221
+ *
222
+ * @param ContainerInterface $c
223
+ * @param null $p
224
+ * @param array $config
225
+ * @return NoticeInterface
226
+ */
227
+ public function _createSettingsImportFailedNotice(ContainerInterface $c, $p = null, $config)
228
+ {
229
+ $notice = $this->_createNotice(array(
230
+ 'id' => 'settings_import_failed',
231
+ 'notice_type' => NoticeInterface::TYPE_ERROR,
232
+ 'condition' => $this->_getCommandIsWprssPage($c),
233
+ 'content' => $this->_autoParagraph($this->__('Invalid file or file size too big.')),
234
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
235
+ ), $c);
236
+
237
+ return $notice;
238
+ }
239
+
240
+ /**
241
+ * Creates a notice that informs the user that all feed sources are updating.
242
+ *
243
+ * @since 4.11
244
+ *
245
+ * @param ContainerInterface $c
246
+ * @param null $p
247
+ * @param array $config
248
+ * @return NoticeInterface
249
+ */
250
+ public function _createDebugFeedsUpdatingNotice(ContainerInterface $c, $p = null, $config)
251
+ {
252
+ $notice = $this->_createNotice(array(
253
+ 'id' => 'debug_feeds_updating',
254
+ 'condition' => $this->_getCommandIsWprssPage($c),
255
+ 'content' => $this->_autoParagraph($this->__('Feeds are being updated in the background.')),
256
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
257
+ ), $c);
258
+
259
+ return $notice;
260
+ }
261
+
262
+ /**
263
+ * Creates a notice that informs the user that the feed items have been deleted and are being reimported.
264
+ *
265
+ * @since 4.11
266
+ *
267
+ * @param ContainerInterface $c
268
+ * @param null $p
269
+ * @param array $config
270
+ * @return NoticeInterface
271
+ */
272
+ public function _createDebugFeedsReimportingNotice(ContainerInterface $c, $p = null, $config)
273
+ {
274
+ $notice = $this->_createNotice(array(
275
+ 'id' => 'debug_feeds_reimporting',
276
+ 'condition' => $this->_getCommandIsWprssPage($c),
277
+ 'content' => $this->_autoParagraph($this->__('Feeds deleted and are being re-imported in the background.')),
278
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
279
+ ), $c);
280
+
281
+ return $notice;
282
+ }
283
+
284
+ /**
285
+ * Creates a notice that informs the user that the debug log has been cleared.
286
+ *
287
+ * @since 4.11
288
+ *
289
+ * @param ContainerInterface $c
290
+ * @param null $p
291
+ * @param array $config
292
+ * @return NoticeInterface
293
+ */
294
+ public function _createDebugClearedLogNotice(ContainerInterface $c, $p = null, $config)
295
+ {
296
+ $notice = $this->_createNotice(array(
297
+ 'id' => 'debug_cleared_log',
298
+ 'condition' => $this->_getCommandIsWprssPage($c),
299
+ 'content' => $this->_autoParagraph($this->__('The error log has been cleared.')),
300
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
301
+ ), $c);
302
+
303
+ return $notice;
304
+ }
305
+
306
+ /**
307
+ * Creates a notice that informs the user that the settings have been reset to default.
308
+ *
309
+ * @since 4.11
310
+ *
311
+ * @param ContainerInterface $c
312
+ * @param null $p
313
+ * @param array $config
314
+ * @return NoticeInterface
315
+ */
316
+ public function _createDebugSettingsResetNotice(ContainerInterface $c, $p = null, $config)
317
+ {
318
+ $notice = $this->_createNotice(array(
319
+ 'id' => 'debug_settings_reset',
320
+ 'condition' => $this->_getCommandIsWprssPage($c),
321
+ 'content' => $this->_autoParagraph($this->__('The plugin settings have been reset to default.')),
322
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
323
+ ), $c);
324
+
325
+ return $notice;
326
+ }
327
+
328
+ /**
329
+ * Creates a notice that informs the user that an item has been successfully blacklisted.
330
+ *
331
+ * @since 4.11
332
+ *
333
+ * @param ContainerInterface $c
334
+ * @param null $p
335
+ * @param array $config
336
+ * @return NoticeInterface
337
+ */
338
+ public function _createBlacklistItemSuccessNotice(ContainerInterface $c, $p = null, $config)
339
+ {
340
+ $notice = $this->_createNotice(array(
341
+ 'id' => 'blacklist_item_success',
342
+ 'content' => $this->_autoParagraph($this->__('The item was deleted successfully and added to the blacklist.')),
343
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
344
+ ), $c);
345
+
346
+ return $notice;
347
+ }
348
+
349
+ /**
350
+ * Creates a notice that informs the user that the selected feed sources have been activated.
351
+ *
352
+ * @since 4.11
353
+ *
354
+ * @param ContainerInterface $c
355
+ * @param null $p
356
+ * @param array $config
357
+ * @return NoticeInterface
358
+ */
359
+ public function _createBulkFeedActivatedNotice(ContainerInterface $c, $p = null, $config)
360
+ {
361
+ $helper = $c->get($this->_p('admin_helper'));
362
+ $notice = $this->_createNotice(array(
363
+ 'id' => 'bulk_feed_activated',
364
+ 'condition' => $helper->createCommand(array($helper, 'isWprssPage')),
365
+ 'content' => $this->_autoParagraph($this->__('The feed sources have been activated!')),
366
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
367
+ ), $c);
368
+
369
+ return $notice;
370
+ }
371
+
372
+ /**
373
+ * Creates a notice that informs the user that the selected feed sources have been paused.
374
+ *
375
+ * @since 4.11
376
+ *
377
+ * @param ContainerInterface $c
378
+ * @param null $p
379
+ * @param array $config
380
+ * @return NoticeInterface
381
+ */
382
+ public function _createBulkFeedPausedNotice(ContainerInterface $c, $p = null, $config)
383
+ {
384
+ $helper = $c->get($this->_p('admin_helper'));
385
+ $notice = $this->_createNotice(array(
386
+ 'id' => 'bulk_feed_paused',
387
+ 'condition' => $helper->createCommand(array($helper, 'isWprssPage')),
388
+ 'content' => $this->_autoParagraph($this->__('The feed sources have been paused!')),
389
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
390
+ ), $c);
391
+
392
+ return $notice;
393
+ }
394
+
395
+ /**
396
+ * Creates a notice that informs the user that an addon license has been saved empty.
397
+ *
398
+ * @since 4.11
399
+ *
400
+ * @param ContainerInterface $c
401
+ * @param null $p
402
+ * @param array $config
403
+ * @return NoticeInterface
404
+ */
405
+ public function _createAddonEmptyLicenseNotice(ContainerInterface $c, $p = null, $config)
406
+ {
407
+ $addonId = isset($config['addon_id'])
408
+ ? $config['addon_id']
409
+ : null;
410
+ $addonName = isset($config['addon_name'])
411
+ ? $config['addon_name']
412
+ : null;
413
+ $licenseSettings = isset($config['settings'])
414
+ ? $config['settings']
415
+ : wprss_licensing_get_settings_controller();
416
+
417
+ $helper = $c->get($this->_p('admin_helper'));
418
+ $me = $this;
419
+
420
+ $notice = $this->_createNotice(array(
421
+ 'id' => sprintf('addon_empty_license_%s', $addonId),
422
+ 'notice_type' => NoticeInterface::TYPE_ERROR,
423
+ 'condition' => $helper->createCommand(array($licenseSettings, 'emptyLicenseKeyNoticeCondition')),
424
+ 'content' => new CallbackBlock(array(), function() use ($addonName, &$me) {
425
+ return $me->_autoParagraph(
426
+ sprintf(
427
+ __( 'Remember to <a href="%1$s">enter your license key</a> for the <strong>WP RSS Aggregator - %2$s</strong> add-on to benefit from updates and support.', WPRSS_TEXT_DOMAIN ),
428
+ esc_attr( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings&tab=licenses_settings' ) ),
429
+ $addonName
430
+ )
431
+ );
432
+ }),
433
+ 'addon' => $addonId
434
+ ), $c);
435
+
436
+ return $notice;
437
+ }
438
+
439
+ /**
440
+ * Creates a notice that informs the user that an addon license is inactive.
441
+ *
442
+ * @since 4.11
443
+ *
444
+ * @param ContainerInterface $c
445
+ * @param null $p
446
+ * @param array $config
447
+ * @return NoticeInterface
448
+ */
449
+ public function _createAddonInactiveLicenseNotice(ContainerInterface $c, $p = null, $config)
450
+ {
451
+ $addonId = isset($config['addon_id'])
452
+ ? $config['addon_id']
453
+ : null;
454
+ $addonName = isset($config['addon_name'])
455
+ ? $config['addon_name']
456
+ : null;
457
+ $licenseSettings = isset($config['settings'])
458
+ ? $config['settings']
459
+ : wprss_licensing_get_settings_controller();
460
+
461
+ $helper = $c->get($this->_p('admin_helper'));
462
+ $me = $this;
463
+
464
+ $notice = $this->_createNotice(array(
465
+ 'id' => sprintf('addon_saved_inactive_license_%s', $addonId),
466
+ 'notice_type' => NoticeInterface::TYPE_ERROR,
467
+ 'condition' => $helper->createCommand(array($licenseSettings, 'savedInactiveLicenseNoticeCondition')),
468
+ 'content' => new CallbackBlock(array(), function() use ($addonName, &$me) {
469
+ return $me->_autoParagraph(
470
+ sprintf(
471
+ __( 'The license key for the <strong>WP RSS Aggregator - %2$s</strong> add-on is saved but not activated. In order to benefit from updates and support, it must be <a href="%1$s">activated</a>.', WPRSS_TEXT_DOMAIN ),
472
+ esc_attr( admin_url( 'edit.php?post_type=wprss_feed&page=wprss-aggregator-settings&tab=licenses_settings' ) ),
473
+ $addonName
474
+ )
475
+ );
476
+ }),
477
+ 'addon' => $addonId
478
+ ), $c);
479
+
480
+ return $notice;
481
+ }
482
+
483
+ /**
484
+ * Creates a notice that informs the user that an addon license will soon expire.
485
+ *
486
+ * @since 4.11
487
+ *
488
+ * @param ContainerInterface $c
489
+ * @param null $p
490
+ * @param array $config
491
+ * @return NoticeInterface
492
+ */
493
+ public function _createAddonExpiringLicenseNotice(ContainerInterface $c, $p = null, $config)
494
+ {
495
+ $addonId = isset($config['addon_id'])
496
+ ? $config['addon_id']
497
+ : null;
498
+ $addonName = isset($config['addon_name'])
499
+ ? $config['addon_name']
500
+ : null;
501
+ $licenseSettings = isset($config['settings'])
502
+ ? $config['settings']
503
+ : wprss_licensing_get_settings_controller();
504
+ $year = isset($config['year'])
505
+ ? $config['year']
506
+ : date('Y');
507
+
508
+ $helper = $c->get($this->_p('admin_helper'));
509
+ $me = $this;
510
+
511
+ $notice = $this->_createNotice(array(
512
+ 'id' => sprintf('addon_empty_license_%1$s_%2$s', $addonId, $year),
513
+ 'notice_type' => NoticeInterface::TYPE_ERROR,
514
+ 'condition' => $helper->createCommand(array($licenseSettings, 'soonToExpireLicenseNoticeCondition')),
515
+ 'content' => new CallbackBlock(array(), function() use ($addonName, &$me) {
516
+ return $me->_autoParagraph(
517
+ sprintf(
518
+ __( 'The license for the <strong>WP RSS Aggregator - %2$s</strong> add-on is about to expire. <a href="%1$s">Please renew it</a> to keep receiving updates and benefit from support.', WPRSS_TEXT_DOMAIN ),
519
+ esc_attr( 'https://docs.wprssaggregator.com/renewing-your-license/' ),
520
+ $addonName
521
+ )
522
+ );
523
+ }),
524
+ 'addon' => $addonId
525
+ ), $c);
526
+
527
+ return $notice;
528
+ }
529
+
530
+ /**
531
+ * Creates a notice that can be used to wrap non-DI compliant notices.
532
+ *
533
+ * @since 4.11
534
+ *
535
+ * @param ContainerInterface $c
536
+ * @param null $p Deprecated
537
+ * @param array $config Configuration for this service.
538
+ * @return NoticeInterface The new notice.
539
+ */
540
+ public function _createGenericFallbackNotice(ContainerInterface $c, $p = null, $config)
541
+ {
542
+ $notice = $this->_createNotice($this->_normalizeConfig($config, array(
543
+ 'notice_type' => NoticeInterface::TYPE_UPDATED,
544
+ 'content' => '',
545
+ 'addon' => '',
546
+ )), $c);
547
+
548
+ return $notice;
549
+ }
550
+
551
+ /**
552
+ * Crates a new admin notice instance.
553
+ *
554
+ * @since 4.11
555
+ *
556
+ * @return NoticeInterface
557
+ */
558
+ protected function _createNotice($data, ContainerInterface $container)
559
+ {
560
+ $data = $this->_normalizeNoticeData($container, $data);
561
+ $notice = new AdminAjaxNotice($data);
562
+
563
+ return $notice;
564
+ }
565
+
566
+ /**
567
+ * {@inheritdoc}
568
+ *
569
+ * @since 4.11
570
+ */
571
+ public function getServices()
572
+ {
573
+ return $this->_getServices();
574
+ }
575
+
576
+ /**
577
+ * {@inheritdoc}
578
+ *
579
+ * @since 4.11
580
+ */
581
+ public function getServiceIdPrefix($id = null)
582
+ {
583
+ return $this->_p($id);
584
+ }
585
+
586
+ /**
587
+ * Retrieve the prefix that is used by services that represent notices.
588
+ *
589
+ * @param string|null $id The ID to prefix, if not null.
590
+ *
591
+ * @since 4.11
592
+ */
593
+ protected function _pn($id = null)
594
+ {
595
+ $prefix = $this->_getNoticeServiceIdPrefix();
596
+ return static::stringHadPrefix($id)
597
+ ? $id
598
+ : "{$prefix}{$id}";
599
+ }
600
+
601
+ /**
602
+ * Retrieves the prefix applied to IDs of services that represent notices.
603
+ *
604
+ * @since 4.11
605
+ *
606
+ * @return string The prefix.
607
+ */
608
+ protected function _getNoticeServiceIdPrefix()
609
+ {
610
+ return $this->_getDataOrConst('notice_service_id_prefix');
611
+ }
612
+
613
+ /**
614
+ * Creates a notice that informs the user that all feed sources are updating.
615
+ *
616
+ * @since 4.11
617
+ *
618
+ * @param ContainerInterface $c
619
+ * @param null $p
620
+ * @return CommandInterface
621
+ */
622
+ public function _createCommandIsWprssPage(ContainerInterface $c)
623
+ {
624
+ $helper = $this->_getAdminHelper($c);
625
+ $command = $this->_createCommand($c, array($helper, 'isWprssPage'));
626
+
627
+ return $command;
628
+ }
629
+
630
+ /**
631
+ * Creates a command that can be invoked like a function.
632
+ *
633
+ * @since 4.11
634
+ *
635
+ * @param ContainerInterface $c The container which to use while creating the command.
636
+ * @param array $config Data for the command.
637
+ * @return CommandInterface The new command.
638
+ */
639
+ protected function _createCommand(ContainerInterface $c, $config = array())
640
+ {
641
+ $helper = $this->_getAdminHelper($c);
642
+ $config = $this->_normalizeConfig($config, array());
643
+ $command = $helper->createCommand($config);
644
+
645
+ return $command;
646
+ }
647
+
648
+ /**
649
+ * Retrieves the admin helper from the container.
650
+ *
651
+ * @since 4.11
652
+ *
653
+ * @param ContainerInterface $c The container which has the admin helper.
654
+ * @return AdminHelper The helper.
655
+ */
656
+ protected function _getAdminHelper(ContainerInterface $c)
657
+ {
658
+ return $c->get($this->_p('admin_helper'));
659
+ }
660
+
661
+ /**
662
+ * Retrieves the command which can determine whether currently on WPRA page.
663
+ *
664
+ * @since 4.11
665
+ *
666
+ * @param ContainerInterface $c The container which has the command.
667
+ * @return AdminHelper The command.
668
+ */
669
+ protected function _getCommandIsWprssPage(ContainerInterface $c)
670
+ {
671
+ return $c->get($this->_p('command.is_wprss_page'));
672
+ }
673
+
674
+ /**
675
+ * {@inheritdoc}
676
+ *
677
+ * Uses the translator retrieved from global container as default.
678
+ *
679
+ * This is because it's not possible to inject a translator created
680
+ * in another service provider into this one, due to the way containers
681
+ * are registered.
682
+ *
683
+ * @since 4.11
684
+ */
685
+ protected function _translate($text, $translator = null)
686
+ {
687
+ if (is_null($translator) && !$this->_getTranslator()) {
688
+ $translator = wprss_wp_container()->get($this->_p('translator'));
689
+ }
690
+
691
+ return parent::_translate($text, $translator);
692
+ }
693
+
694
+ /**
695
+ * Converts plain text paragraphs to HTML ones.
696
+ *
697
+ * @since 4.11
698
+ *
699
+ * @param string $text The text to add paragraphs to.
700
+ * @return string The text with HTML paragraphs.
701
+ */
702
+ public function _autoParagraph($text)
703
+ {
704
+ return \wpautop($text);
705
+ }
706
+
707
+ /**
708
+ * Computes a unique hash of the notice content.
709
+ *
710
+ * @since 4.11
711
+ *
712
+ * @param ContainerInterface $c A container instance.
713
+ * @param string|callable $content The content to hash.
714
+ *
715
+ * @return string The content hash.
716
+ */
717
+ public function _hashNoticeContent(ContainerInterface $c, $content) {
718
+ $helper = $this->_getAdminHelper($c);
719
+ $hash = \is_callable($content)
720
+ ? $helper->hashCallable($content)
721
+ : $helper->hashScalar((string) $content);
722
+
723
+ return $hash;
724
+ }
725
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/AbstractImporter.php ADDED
@@ -0,0 +1,158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport;
4
+
5
+ use Aventura\Wprss\Core\Model\AbstractTranslatingModel;
6
+
7
+ /**
8
+ * Common functionality for feed source importers.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ abstract class AbstractImporter extends AbstractTranslatingModel
13
+ {
14
+ /**
15
+ * Transforms import input into feed source data.
16
+ *
17
+ * @since 4.11
18
+ *
19
+ * @return array[] A list of data maps.
20
+ */
21
+ abstract protected function _inputToSourcesList($input);
22
+
23
+ /**
24
+ * Imports feed sources from a list.
25
+ *
26
+ * @since 4.11
27
+ *
28
+ * @param array|\Traversable $list
29
+ *
30
+ * @return array|\Traversable A list of results.
31
+ * For each item in order, the value will be either an integer representing the created resource ID,
32
+ * or an instance of {@see \Exception} if something went wrong.
33
+ */
34
+ protected function _importFromSourcesList($list)
35
+ {
36
+ $results = array();
37
+ foreach ($list as $_idx => $_source) {
38
+ try {
39
+ $results[$_idx] = $this->_importSource($_source);
40
+ } catch (\Exception $e) {
41
+ $results[$_idx] = new Exception\ImportException($this->__(array('Could not import item #%1$s', $_idx)), 0, $e);
42
+ continue;
43
+ }
44
+ }
45
+
46
+ return $results;
47
+ }
48
+
49
+ /**
50
+ * Imports a feed source.
51
+ *
52
+ * @since 4.11
53
+ *
54
+ * @param array|\ArrayAccess $source The source to import.
55
+ * @return int The ID of the imported resource. See {@see _createLocalResource()}.
56
+ */
57
+ protected function _importSource($source)
58
+ {
59
+ $this->_assertSourceValid($source);
60
+ $data = $this->_prepareInsertionData($source);
61
+ $id = $this->_createLocalResource($data);
62
+
63
+ return $id;
64
+ }
65
+
66
+ /**
67
+ * Prepares data using a feed source representation, ready to be converted into a local resource.
68
+ *
69
+ * @since 4.11
70
+ *
71
+ * @param array|\ArrayAccess $source The feed source representation.
72
+ * @return array Data ready for insertion that can represent a feed source.
73
+ */
74
+ protected function _prepareInsertionData($source)
75
+ {
76
+ return $this->_getPostDataDefaults($source);
77
+ }
78
+
79
+ /**
80
+ * Creates a local representation of a feed source locally.
81
+ *
82
+ * @since [*next-version]
83
+ *
84
+ * @param mixed $data The data ready to be converted to a local resoure.
85
+ *
86
+ * @return int The ID of the new resource.
87
+ */
88
+ abstract protected function _createLocalResource($data);
89
+
90
+ /**
91
+ * Merges two arrays recursively.
92
+ *
93
+ * @since 4.11
94
+ *
95
+ * @param array $default
96
+ * @param array $additional
97
+ * @return array The product of two arrays.
98
+ */
99
+ protected function _mergeArrays($default, $additional = array())
100
+ {
101
+ return \array_merge_recursive_distinct($default, $additional);
102
+ }
103
+
104
+ /**
105
+ * Determines whether a source representation is valid for import.
106
+ *
107
+ * If resulting list is empty, the source is valid.
108
+ *
109
+ * @since 4.11
110
+ *
111
+ * @param array|\ArrayAccess $source The feed source representation.
112
+ *
113
+ * @return string[]|\Exception[]|\Traversable A list of validation errors.
114
+ */
115
+ protected function _validateSource($source)
116
+ {
117
+ $errors = array();
118
+ if (\count($source) < 2) {
119
+ $errors[] = $this->__('A source must have at least two data members');
120
+ }
121
+
122
+ if (!isset($source[ImporterInterface::SK_TITLE])) {
123
+ $errors[] = $this->__('Source title is missing');
124
+ }
125
+
126
+ if (isset($source[ImporterInterface::SK_TITLE]) && !strlen($source[ImporterInterface::SK_TITLE])) {
127
+ $errors[] = $this->__('Source title must not be empty');
128
+ }
129
+
130
+ if (!isset($source[ImporterInterface::SK_URL])) {
131
+ $errors[] = $this->__('Source URL is missing');
132
+ }
133
+
134
+ if (isset($source[ImporterInterface::SK_URL]) && !strlen($source[ImporterInterface::SK_URL])) {
135
+ $errors[] = $this->__('Source URL must not be empty');
136
+ }
137
+
138
+ return $errors;
139
+ }
140
+
141
+ /**
142
+ * Throws an exception if specified source is not valid.
143
+ *
144
+ * @since 4.11
145
+ *
146
+ * @param array|\ArrayAccess $source The source that must be valid.
147
+ * @return AbstractImporter This instance.
148
+ * @throws Exception\SourceValidationFailureExceptionInterface If feed source is not valid.
149
+ */
150
+ protected function _assertSourceValid($source)
151
+ {
152
+ if (\count($errors = $this->_validateSource($source))) {
153
+ throw new Exception\SourceValidationFailureException($this->__('Feed source representation is invalid'), 0, null, $errors);
154
+ }
155
+
156
+ return $this;
157
+ }
158
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/AbstractWpImporter.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport;
4
+
5
+ /**
6
+ * An importer that can import feed sources into WordPress.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ abstract class AbstractWpImporter extends AbstractImporter
11
+ {
12
+
13
+ /**
14
+ * Prepares data using a feed source representation, ready to be converted into a local resource.
15
+ *
16
+ * @since 4.11
17
+ *
18
+ * @param array|\ArrayAccess $source The feed source representation.
19
+ * @return array Data ready for insertion that can represent a feed source.
20
+ */
21
+ protected function _prepareInsertionData($source)
22
+ {
23
+ $data = $this->_getPostDataDefaults($source);
24
+ $post = array(
25
+ 'post_title' => $data['title'],
26
+ 'post_status' => $data['status'],
27
+ 'post_type' => $data['type'],
28
+ 'post_site' => $data['site'],
29
+ 'url' => $data['url'],
30
+ );
31
+
32
+ return $post;
33
+ }
34
+
35
+ /**
36
+ * {@inheritdoc}
37
+ *
38
+ * @since 4.11
39
+ */
40
+ protected function _createLocalResource($data)
41
+ {
42
+ // The URL does not go into the post, but is meta data
43
+ $url = $data[ImporterInterface::SK_URL];
44
+ unset($data[ImporterInterface::SK_URL]);
45
+
46
+ $id = $this->_insertWpPost($data);
47
+ $this->_updateWpPostMeta($id, 'wprss_url', $url);
48
+
49
+ return $id;
50
+ }
51
+
52
+ /**
53
+ * Inserts a post with the specified data into WordPress.
54
+ *
55
+ * @since 4.11
56
+ *
57
+ * @param type $data
58
+ * @return int The ID of the inserted post.
59
+ *
60
+ * @throws Exception\ImportExceptionInterface If post could not be inserted.
61
+ */
62
+ protected function _insertWpPost($data)
63
+ {
64
+ $id = \wp_insert_post($data, true);
65
+ if (\is_wp_error($id)) {
66
+ throw new Exception\ImportException($id->get_error_message());
67
+ }
68
+
69
+ return $id;
70
+ }
71
+
72
+ /**
73
+ * Updates a meta value for a WordPress post.
74
+ *
75
+ * @since 4.11
76
+ *
77
+ * @param int $postId The ID of the post.
78
+ * @param string $metaName Name of the meta to update.
79
+ * @param string|int $metaValue Value of the meta to set.
80
+ * @return int|true True if meta value existed, and updated successfully.
81
+ * If meta value created in the process, the meta ID for it.
82
+ * @throws \RuntimeException If meta value could not be updated.
83
+ */
84
+ protected function _updateWpPostMeta($postId, $metaName, $metaValue)
85
+ {
86
+ if ($result = \update_post_meta($postId, $metaName, $metaValue) === false) {
87
+ throw new \RuntimeException(sprintf('Could not update meta "%2$s" for post #%1$s', $postId, $metaName));
88
+ }
89
+
90
+ return $result;
91
+ }
92
+
93
+ /**
94
+ * Retrieves default values for posts which represent imported feed sources.
95
+ *
96
+ * @since 4.11
97
+ *
98
+ * @param array $data Additional data to merge into defaults.
99
+ * @return array The defaults, merged with additional data.
100
+ */
101
+ protected function _getPostDataDefaults($data = array())
102
+ {
103
+ $defaults = array(
104
+ 'status' => $this->_getData('default_status'),
105
+ 'type' => $this->_getData('default_type'),
106
+ 'site' => $this->_getData('default_site')
107
+ );
108
+
109
+ return $this->_mergeArrays($defaults, $data);
110
+ }
111
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/AbstractImportException.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * Common functionality for feed source import exceptions.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class AbstractImportException extends \RuntimeException
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/AbstractSourceValidationFailureException.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * Common functionality for exeptions that occur if a source representation is invalid.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class AbstractSourceValidationFailureException extends AbstractImportException
11
+ {
12
+ /**
13
+ * @since 4.11
14
+ * @var array|\Traversable
15
+ */
16
+ protected $validationErrors;
17
+
18
+ /**
19
+ * Retrieve the list of validation errors that this instance represents.
20
+ *
21
+ * @since 4.11
22
+ *
23
+ * @return array|\Traversable The error list.
24
+ */
25
+ protected function _getValidationErrors()
26
+ {
27
+ if (!$this->_isValidList($this->validationErrors)) {
28
+ $this->validationErrors = array();
29
+ }
30
+
31
+ return $this->validationErrors;
32
+ }
33
+
34
+ /**
35
+ * Sets the list of validation errors that this intance should represent.
36
+ *
37
+ * @since 4.11
38
+ *
39
+ * @param array|\Traversable $errorList The list of errors.
40
+ * @return AbstractSourceValidationFailureException This instance.
41
+ */
42
+ protected function _setValidationErrors($errorList)
43
+ {
44
+ $this->_assertList($errorList);
45
+ $this->validationErrors = $errorList;
46
+
47
+ return $this;
48
+ }
49
+
50
+ /**
51
+ * Throws an exception if the given list is invalid.
52
+ *
53
+ * @since 4.11
54
+ *
55
+ * @param \Traversable $list
56
+ * @return AbstractSourceValidationFailureException This instance.
57
+ * @throws ImportException If list is invalid.
58
+ */
59
+ protected function _assertList($list)
60
+ {
61
+ if (!$this->_isValidList($list)) {
62
+ throw new ImportException('The list is invalid');
63
+ }
64
+
65
+ return $this;
66
+ }
67
+
68
+ /**
69
+ * Determines if the given list is valid.
70
+ *
71
+ * @since 4.11
72
+ *
73
+ * @param array|\Traversable $list The list to validate.
74
+ * @return boolean True if the given list is valid; false otherwise.
75
+ */
76
+ protected function _isValidList($list)
77
+ {
78
+ if (!is_array($list) && !($list instanceof \Traversable)) {
79
+ return false;
80
+ }
81
+
82
+ return true;
83
+ }
84
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/ImportException.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * An exception that occurs if a feed source representation is invalid.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class ImportException extends AbstractImportException implements ImportExceptionInterface
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/ImportExceptionInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * Something that can represent an error that occurs during import of feed sources.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ interface ImportExceptionInterface
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/SourceValidationFailureException.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * An exception that occurs if a feed source representation is invalid.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class SourceValidationFailureException extends AbstractSourceValidationFailureException implements SourceValidationFailureExceptionInterface
11
+ {
12
+ /**
13
+ * {@inheritdoc}
14
+ *
15
+ * @since 4.11
16
+ *
17
+ * @param string $message {@inheritdoc}
18
+ * @param int $code {@inheritdoc}
19
+ * @param \Exception $previous {@inheritdoc}
20
+ * @param array|\Traversable $validationErrors The list of validation errors.
21
+ */
22
+ public function __construct($message = "", $code = 0, \Exception $previous = null, $validationErrors = array())
23
+ {
24
+ parent::__construct($message, $code, $previous);
25
+
26
+ $this->_setValidationErrors($validationErrors);
27
+ }
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ *
32
+ * @since 4.11
33
+ */
34
+ public function getValidationErrors()
35
+ {
36
+ return $this->_getValidationErrors();
37
+ }
38
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/Exception/SourceValidationFailureExceptionInterface.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport\Exception;
4
+
5
+ /**
6
+ * Something that can represent an exception that occurs if a feed source is invalid.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ interface SourceValidationFailureExceptionInterface extends ImportExceptionInterface
11
+ {
12
+ /**
13
+ * Retrieves a list of problems with a feed source.
14
+ *
15
+ * @since 4.11
16
+ *
17
+ * @return array|\Traversable
18
+ */
19
+ public function getValidationErrors();
20
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/ImporterInterface.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport;
4
+
5
+ /**
6
+ * Something that can create multiple feed sources from input.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ interface ImporterInterface
11
+ {
12
+ const SK_TITLE = 'title';
13
+ const SK_URL = 'url';
14
+
15
+ /**
16
+ * Creates feed sources from input.
17
+ *
18
+ * @since 4.11
19
+ *
20
+ * @param mixed $input Some kind of input that can be used to retrieve information about a feed source.
21
+ *
22
+ * @return array The import results. For each source representation (in order), the result will be one of:
23
+ * - Integer, representing the ID of the created resource;
24
+ * - An {@see \Exception} if something went wrong during import.
25
+ */
26
+ public function import($input);
27
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/PlainTextImporter.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport;
4
+
5
+
6
+ /**
7
+ * Something that can create multiple feed sources from plain text.
8
+ *
9
+ * @since 4.11
10
+ */
11
+ class PlainTextImporter extends AbstractWpImporter implements ImporterInterface
12
+ {
13
+ /**
14
+ * @since 4.11
15
+ *
16
+ * @param array $data Data members map.
17
+ * @param callable $translator A translator.
18
+ */
19
+ public function __construct($data, $translator = null)
20
+ {
21
+ parent::__construct($data);
22
+
23
+ if (!is_null($translator)) {
24
+ $this->_setTranslator($translator);
25
+ }
26
+ }
27
+
28
+ /**
29
+ * {@inheritdoc}
30
+ *
31
+ * @since 4.11
32
+ *
33
+ * @param string $input The plain text to import from.
34
+ * The current format is as follows:
35
+ * - Feed sources are separated by new lines;
36
+ * - Every line represents one feed source's fields;
37
+ * - Fields are separated with a coma, and can optionally be surrounded by whitespace which will be trimmed;
38
+ * - The first fields will be interpreted as the feed source's title;
39
+ * - The second field will be interpreted as the feed source's URL.
40
+ */
41
+ public function import($input)
42
+ {
43
+ $list = $this->_inputToSourcesList($input);
44
+ $results = $this->_importFromSourcesList($list);
45
+
46
+ return $results;
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ *
52
+ * @since 4.11
53
+ */
54
+ protected function _inputToSourcesList($input)
55
+ {
56
+ $lines = explode("\n", $input);
57
+ $sources = array();
58
+ foreach ($lines as $_line) {
59
+ $parts = array_map('trim', explode(',', $_line) );
60
+ $sources[] = array(
61
+ ImporterInterface::SK_TITLE => isset($parts[0]) ? $parts[0] : null,
62
+ ImporterInterface::SK_URL => isset($parts[1]) ? $parts[1] : null,
63
+ );
64
+ }
65
+
66
+ return $sources;
67
+ }
68
+ }
includes/Aventura/Wprss/Core/Model/BulkSourceImport/ServiceProvider.php ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\BulkSourceImport;
4
+
5
+ use Interop\Container\ContainerInterface;
6
+ use Aventura\Wprss\Core\Plugin\Di\AbstractComponentServiceProvider;
7
+ use Aventura\Wprss\Core\Plugin\Di\ServiceProviderInterface;
8
+ use Aventura\Wprss\Core\Component\BulkSourceImport;
9
+
10
+ /**
11
+ * Provides services that represent admin notices.
12
+ *
13
+ * @since 4.11
14
+ */
15
+ class ServiceProvider extends AbstractComponentServiceProvider implements ServiceProviderInterface
16
+ {
17
+ /**
18
+ * {@inheritdoc}
19
+ *
20
+ * @since 4.11
21
+ */
22
+ protected function _getServiceDefinitions()
23
+ {
24
+ return array(
25
+ $this->_p('bulk_source_import') => array($this, '_createBulkSourceImport'),
26
+ $this->_p('source_importer') => array($this, '_createPlainTextImporter')
27
+ );
28
+ }
29
+
30
+ /**
31
+ * Creates a bulk source import component.
32
+ *
33
+ * @since 4.11
34
+ *
35
+ * @param ContainerInterface $c
36
+ * @param null $p
37
+ * @param array $config
38
+ * @return Component\AdminAjaxNotices
39
+ */
40
+ public function _createBulkSourceImport(ContainerInterface $c, $p = null, $config = null)
41
+ {
42
+ $config = $this->_normalizeConfig($config, array(
43
+ 'plugin' => $c->get($this->_p('plugin')),
44
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
45
+ ));
46
+ $importer = $c->get($this->_p('source_importer'));
47
+ $service = new BulkSourceImport($config, $importer);
48
+ $this->_prepareComponent($service);
49
+
50
+ return $service;
51
+ }
52
+
53
+ public function _createPlainTextImporter(ContainerInterface $c, $p = null, $config = null)
54
+ {
55
+ $config = $this->_normalizeConfig($config, array(
56
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
57
+ 'default_status' => 'publish',
58
+ 'default_type' => \WPRSS_POST_TYPE_FEED_SOURCE,
59
+ 'default_site' => \is_multisite() ? \get_current_blog_id() : '',
60
+ ));
61
+ $service = new PlainTextImporter($config, $c->get($this->_p('translator')));
62
+
63
+ return $service;
64
+ }
65
+
66
+ /**
67
+ * {@inheritdoc}
68
+ *
69
+ * @since 4.11
70
+ */
71
+ public function getServices()
72
+ {
73
+ return $this->_getServices();
74
+ }
75
+
76
+ /**
77
+ * {@inheritdoc}
78
+ *
79
+ * @since 4.11
80
+ */
81
+ public function getServiceIdPrefix($id = null)
82
+ {
83
+ return $this->_p($id);
84
+ }
85
+ }
includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php CHANGED
@@ -7,7 +7,7 @@ use Aventura\Wprss\Core;
7
  /**
8
  * @since 4.8.1
9
  */
10
- class EventManagerAbstract extends Core\Plugin\ComponentAbstract implements EventManagerInterface
11
  {
12
  /** @since 4.8.1 */
13
  const DEFAULT_PRIORITY = 10;
@@ -24,12 +24,6 @@ class EventManagerAbstract extends Core\Plugin\ComponentAbstract implements Even
24
  protected $_events = array();
25
  protected $_isRan;
26
 
27
- protected function _construct()
28
- {
29
- parent::_construct();
30
- $this->setIsKeepRecords(true);
31
- }
32
-
33
  /**
34
  * Registers an event listener.
35
  *
7
  /**
8
  * @since 4.8.1
9
  */
10
+ class EventManagerAbstract extends Core\Model\ModelAbstract implements EventManagerInterface
11
  {
12
  /** @since 4.8.1 */
13
  const DEFAULT_PRIORITY = 10;
24
  protected $_events = array();
25
  protected $_isRan;
26
 
 
 
 
 
 
 
27
  /**
28
  * Registers an event listener.
29
  *
includes/Aventura/Wprss/Core/Model/GenericServiceProvider.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model;
4
+ use Aventura\Wprss\Core\Plugin\Di\AbstractServiceProvider;
5
+ use Aventura\Wprss\Core\Plugin\Di\ServiceProviderInterface;
6
+
7
+ /**
8
+ * A generic service provider.
9
+ *
10
+ * Many instances can be created, as needed, to group service definitions,
11
+ * which can be injected in the constructor.
12
+ *
13
+ * @since 4.11
14
+ */
15
+ class GenericServiceProvider extends AbstractServiceProvider implements ServiceProviderInterface
16
+ {
17
+ /**
18
+ * @since 4.11
19
+ *
20
+ * @param array $services The services to set for this instance, if any.
21
+ */
22
+ public function __construct($data = null, array $services = null)
23
+ {
24
+ parent::__construct($data);
25
+
26
+ $this->_setServices($services);
27
+ }
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ *
32
+ * @since 4.11
33
+ */
34
+ public function getServices()
35
+ {
36
+ return $this->_getServices();
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ *
42
+ * @since 4.11
43
+ */
44
+ public function getServiceIdPrefix($id = null)
45
+ {
46
+ return $this->_p($id);
47
+ }
48
+ }
includes/Aventura/Wprss/Core/Plugin.php CHANGED
@@ -11,14 +11,10 @@ use Aventura\Wprss\Core\Component;
11
  */
12
  class Plugin extends Plugin\PluginAbstract
13
  {
14
- const CODE = 'wprss';
15
- const VERSION = WPRSS_VERSION;
16
 
17
- const POST_TYPE_FEED_SOURCE = WPRSS_POST_TYPE_FEED_SOURCE;
18
-
19
- protected $adminAjaxNotices;
20
- protected $leaveReviewNotification;
21
- protected $adminHelper;
22
 
23
  /**
24
  * Hooks the rest of the functionality of this class.
@@ -166,11 +162,7 @@ class Plugin extends Plugin\PluginAbstract
166
  */
167
  public function getAdminAjaxNotices()
168
  {
169
- if (is_null($this->adminAjaxNotices)) {
170
- $this->adminAjaxNotices = $this->getFactory()->createAdminAjaxNotices();
171
- }
172
-
173
- return $this->adminAjaxNotices;
174
  }
175
 
176
  /**
@@ -182,11 +174,7 @@ class Plugin extends Plugin\PluginAbstract
182
  */
183
  public function getLeaveReviewNotification()
184
  {
185
- if (is_null($this->leaveReviewNotification)) {
186
- $this->leaveReviewNotification = $this->getFactory()->createLeaveReviewNotification();
187
- }
188
-
189
- return $this->leaveReviewNotification;
190
  }
191
 
192
  /**
@@ -198,10 +186,6 @@ class Plugin extends Plugin\PluginAbstract
198
  */
199
  public function getAdminHelper()
200
  {
201
- if (is_null($this->adminHelper)) {
202
- $this->adminHelper = $this->getFactory()->createAdminHelper();
203
- }
204
-
205
- return $this->adminHelper;
206
  }
207
  }
11
  */
12
  class Plugin extends Plugin\PluginAbstract
13
  {
14
+ const CODE = \WPRSS_PLUGIN_CODE;
15
+ const VERSION = \WPRSS_VERSION;
16
 
17
+ const POST_TYPE_FEED_SOURCE = \WPRSS_POST_TYPE_FEED_SOURCE;
 
 
 
 
18
 
19
  /**
20
  * Hooks the rest of the functionality of this class.
162
  */
163
  public function getAdminAjaxNotices()
164
  {
165
+ return $this->_getContainer()->get($this->_getServiceIdPrefix('admin_ajax_notices'));
 
 
 
 
166
  }
167
 
168
  /**
174
  */
175
  public function getLeaveReviewNotification()
176
  {
177
+ return $this->_getContainer()->get($this->_getServiceIdPrefix('leave_review'));
 
 
 
 
178
  }
179
 
180
  /**
186
  */
187
  public function getAdminHelper()
188
  {
189
+ return $this->_getContainer()->get($this->_getServiceIdPrefix('admin_helper'));
 
 
 
 
190
  }
191
  }
includes/Aventura/Wprss/Core/Plugin/AddonAbstract.php CHANGED
@@ -21,6 +21,15 @@ abstract class AddonAbstract extends PluginAbstract implements AddonInterface, C
21
  {
22
  parent::__construct($data, $factory);
23
  $this->_setParent($parent);
 
 
 
 
 
 
 
 
 
24
  }
25
 
26
  /**
21
  {
22
  parent::__construct($data, $factory);
23
  $this->_setParent($parent);
24
+
25
+ /**
26
+ * This is necessary because extensions still don't know about the new
27
+ * DI container mechanics, and no container is being passed in those
28
+ * extensions to the constructor of this class.
29
+ *
30
+ * @todo Remove when add-ons re-factored.
31
+ */
32
+ $this->tmpParent = wprss_wp_container()->get($this->_getServiceIdPrefix('plugin'));
33
  }
34
 
35
  /**
includes/Aventura/Wprss/Core/Plugin/Di/AbstractComponentServiceProvider.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ /**
6
+ * A service provider that can create components.
7
+ *
8
+ * @since 4.11
9
+ */
10
+ class AbstractComponentServiceProvider extends AbstractServiceProvider
11
+ {
12
+ const PREFIX_OVERRIDE = '!';
13
+ const COMPONENT_INTERFACE = 'Aventura\\Wprss\\Core\\Plugin\\ComponentInterface';
14
+
15
+ /**
16
+ * Throws an exception if given instance or class name is not a valid component or component class name.
17
+ *
18
+ * @since 4.11
19
+ *
20
+ * @param string|ComponentInterface|mixed $component
21
+ * @throws Exception If the argument is not a valid component instance or class name.
22
+ */
23
+ protected function _assertComponent($component)
24
+ {
25
+ if (!is_a($component, static::COMPONENT_INTERFACE)) {
26
+ $componentType = is_string($component)
27
+ ? $component
28
+ : (is_object($component)
29
+ ? get_class($component)
30
+ : get_type($component));
31
+ throw $this->exception(array('"%1$s" is not a component', $componentType));
32
+ }
33
+ }
34
+
35
+ /**
36
+ * Prepares a component instance.
37
+ *
38
+ * @since 4.11
39
+ *
40
+ * @param ComponentInterface $component The component to prepare.
41
+ * @return ComponentInterface The prepared component.
42
+ */
43
+ protected function _prepareComponent($component)
44
+ {
45
+ $this->_assertComponent($component);
46
+ $component->hook();
47
+
48
+ return $component;
49
+ }
50
+
51
+ /**
52
+ * Normalizes a factory config, optionally by using defaults.
53
+ *
54
+ * @since 4.11
55
+ *
56
+ * @param array|null $config The config to normalize.
57
+ * @param array $defaults Defaults, if any, which will be extended by the normalized config.
58
+ * @return array The normalized config, optionally applied on top of defaults.
59
+ */
60
+ protected function _normalizeConfig($config, $defaults = array())
61
+ {
62
+ if (is_null($config)) {
63
+ $config = array();
64
+ }
65
+
66
+ return $this->_arrayMergeRecursive($defaults, $config);
67
+ }
68
+
69
+ /**
70
+ * Merges two arrays recursively, preserving element types.
71
+ *
72
+ * @since 4.11
73
+ *
74
+ * @see \array_merge_recursive_distinct()
75
+ * @param array $array1
76
+ * @param array $array2
77
+ * @return array
78
+ */
79
+ protected function _arrayMergeRecursive(&$array1, &$array2)
80
+ {
81
+ return \array_merge_recursive_distinct($array1, $array2);
82
+ }
83
+ }
includes/Aventura/Wprss/Core/Plugin/Di/AbstractContainer.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Exception as BaseException;
6
+ use Dhii\Di\AbstractParentAwareContainer as BaseParentAwareContainer;
7
+ use Dhii\Di\ParentAwareContainerInterface;
8
+ use Dhii\Di\Exception\NotFoundException;
9
+ use Dhii\Di\Exception\ContainerException;
10
+
11
+ /**
12
+ * Common functionality for containers.
13
+ *
14
+ * @since 4.11
15
+ */
16
+ abstract class AbstractContainer extends BaseParentAwareContainer implements
17
+ ContainerInterface,
18
+ ParentAwareContainerInterface
19
+ {
20
+ /**
21
+ * Parameter-less constructor.
22
+ *
23
+ * @since 4.11
24
+ */
25
+ protected function _construct()
26
+ {
27
+ }
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ *
32
+ * @since 4.11
33
+ *
34
+ * @param string $id The ID of the service to check for.
35
+ *
36
+ * @return bool True if a service exists with the given ID; false otherwise.
37
+ */
38
+ public function has($id)
39
+ {
40
+ return $this->_has($id);
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ *
46
+ * @since 4.11
47
+ *
48
+ * @param string $id The ID of the service to retrieve.
49
+ *
50
+ * @throws NotFoundException If no service with the given ID exists in the container.
51
+ *
52
+ * @return mixed The service with the matching ID.
53
+ */
54
+ public function get($id)
55
+ {
56
+ return $this->_get($id);
57
+ }
58
+
59
+ /**
60
+ * {@inheritdoc}
61
+ *
62
+ * @since 4.11
63
+ */
64
+ public function getParentContainer()
65
+ {
66
+ return $this->_getParentContainer();
67
+ }
68
+
69
+ /**
70
+ * {@inheritdoc}
71
+ *
72
+ * @since 4.11
73
+ *
74
+ * @return NotFoundException The new exception instance.
75
+ */
76
+ protected function _createNotFoundException($message, $code = 0, BaseException $innerException = null)
77
+ {
78
+ return new NotFoundException($message, $code, $innerException);
79
+ }
80
+
81
+ /**
82
+ * {@inheritdoc}
83
+ *
84
+ * @since 4.11
85
+ *
86
+ * @return ContainerException The new exception instance.
87
+ */
88
+ protected function _createContainerException($message, $code = 0, BaseException $innerException = null)
89
+ {
90
+ return new ContainerException($message, $code, $innerException);
91
+ }
92
+ }
includes/Aventura/Wprss/Core/Plugin/Di/AbstractServiceProvider.php ADDED
@@ -0,0 +1,132 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Aventura\Wprss\Core\Model\AbstractTranslatingModel;
6
+
7
+ /**
8
+ * Common functionality for WPRA service providers.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ abstract class AbstractServiceProvider extends AbstractTranslatingModel
13
+ {
14
+ /**
15
+ * @since 4.11
16
+ * @var array
17
+ */
18
+ protected $services;
19
+
20
+ /**
21
+ * Retrieves the definitions that this service provides.
22
+ *
23
+ * Definitions are get exposed to the `services` event as 'definitions'.
24
+ * The definition list is normalized to an array.
25
+ * The eventual definitions list is cached.
26
+ *
27
+ * @since 4.11
28
+ *
29
+ * @return array The definitions provided by this instance.
30
+ */
31
+ protected function _getServices()
32
+ {
33
+ if (is_null($this->services)) {
34
+ $definitions = $this->_getServiceDefinitions();
35
+ $this->_trigger('services', array('definitions' => &$definitions));
36
+
37
+ if (empty($definitions)) {
38
+ $definitions = array();
39
+ }
40
+
41
+ if (!is_array($definitions)) {
42
+ $definitions = (array) $definitions;
43
+ }
44
+
45
+ $this->services = $definitions;
46
+ }
47
+
48
+ return $this->services;
49
+ }
50
+
51
+ /**
52
+ * Retrieves the internal services list.
53
+ *
54
+ * @since 4.11
55
+ *
56
+ * @param array $services An array of service definitions.
57
+ * @return AbstractServiceProvider This instance.
58
+ */
59
+ protected function _setServices(array $services)
60
+ {
61
+ $this->services = $services;
62
+
63
+ return $this;
64
+ }
65
+
66
+ /**
67
+ * The definitions provided by this instance.
68
+ *
69
+ * Not cached, not normalized. Override this in descendants class.
70
+ *
71
+ * @since 4.11
72
+ *
73
+ * @return array The definition list.
74
+ */
75
+ protected function _getServiceDefinitions()
76
+ {
77
+ return array();
78
+ }
79
+
80
+ /**
81
+ * Retrieves the prefix used by IDs of services that this instance provides.
82
+ *
83
+ * @since 4.11
84
+ *
85
+ * @return string The prefix used for IDs of services.
86
+ */
87
+ protected function _getServiceIdPrefix()
88
+ {
89
+ return $this->_getDataOrConst('service_id_prefix', $this->_getEventPrefix());
90
+ }
91
+
92
+ /**
93
+ * Alias of `getServiceIdPrefix()`.
94
+ *
95
+ * @see getServiceIdPrefix().
96
+ *
97
+ * @since 4.11
98
+ */
99
+ protected function _p($name = null)
100
+ {
101
+ $prefix = $this->_getServiceIdPrefix();
102
+ return static::stringHadPrefix($name)
103
+ ? $name
104
+ : "{$prefix}{$name}";
105
+ }
106
+
107
+ /**
108
+ * Triggers and returns an event.
109
+ *
110
+ * Due to nature of the WP native function used by this method,
111
+ * the single argument accepted by handlers is an array, and
112
+ * must be accepted by reference.
113
+ *
114
+ * @since 4.11
115
+ *
116
+ * @param string $name Name of the event.
117
+ * Will be automatically prefixed, unless prefix overridden.
118
+ * @param array $args Data for the event.
119
+ * @return array The args list, after all handlers have been applied to it.
120
+ */
121
+ protected function _trigger($name, $args = array())
122
+ {
123
+ if (!isset($args['caller'])) {
124
+ $args['caller'] = $this;
125
+ }
126
+
127
+ $realName = $this->getEventPrefix($name);
128
+ do_action_ref_array($realName, array(&$args));
129
+
130
+ return $args;
131
+ }
132
+ }
includes/Aventura/Wprss/Core/Plugin/Di/AbstractWritableCompositeContainer.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Exception as BaseException;
6
+ use Dhii\Di\AbstractCompositeContainer;
7
+ use Dhii\Di\ParentAwareContainerInterface;
8
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
9
+
10
+ /**
11
+ * Common functionality for composite containers that can have children added.
12
+ *
13
+ * @since 4.11
14
+ */
15
+ class AbstractWritableCompositeContainer extends AbstractCompositeContainer implements
16
+ ParentAwareContainerInterface,
17
+ WritableCompositeContainerInterface
18
+ {
19
+ /**
20
+ * {@inheritdoc}
21
+ *
22
+ * @since 4.11
23
+ */
24
+ public function get($id)
25
+ {
26
+ return $this->_getDelegated($id);
27
+ }
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ *
32
+ * @since 4.11
33
+ */
34
+ public function has($id)
35
+ {
36
+ return $this->_hasDelegated($id);
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ *
42
+ * @since 4.11
43
+ */
44
+ public function getParentContainer()
45
+ {
46
+ return $this->_getParentContainer();
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ *
52
+ * @since 4.11
53
+ */
54
+ public function getContainers()
55
+ {
56
+ return $this->_getContainers();
57
+ }
58
+
59
+ /**
60
+ * Adds a child container.
61
+ *
62
+ * @since 4.11
63
+ *
64
+ * @param BaseContainerInterface $container The container to add.
65
+ *
66
+ * @return $this This instance.
67
+ */
68
+ public function add(BaseContainerInterface $container)
69
+ {
70
+ $this->_add($container);
71
+
72
+ return $this;
73
+ }
74
+
75
+ /**
76
+ * {@inheritdoc}
77
+ *
78
+ * @since 4.11
79
+ *
80
+ * @return NotFoundException The new exception instance.
81
+ */
82
+ protected function _createNotFoundException($message, $code = 0, BaseException $innerException = null)
83
+ {
84
+ return new NotFoundException($message, $code, $innerException);
85
+ }
86
+
87
+ /**
88
+ * {@inheritdoc}
89
+ *
90
+ * @since 4.11
91
+ *
92
+ * @return ContainerException The new exception instance.
93
+ */
94
+ protected function _createContainerException($message, $code = 0, BaseException $innerException = null)
95
+ {
96
+ return new ContainerException($message, $code, $innerException);
97
+ }
98
+ }
includes/Aventura/Wprss/Core/Plugin/Di/ContainerInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+
7
+ /**
8
+ * Represents a generic WPRA container.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ interface ContainerInterface extends BaseContainerInterface
13
+ {
14
+ }
includes/Aventura/Wprss/Core/Plugin/Di/ServiceProviderInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Interop\Container\ServiceProvider as BaseServiceProviderInterface;
6
+
7
+ /**
8
+ * Represents a WPRA-specific service provider.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ interface ServiceProviderInterface extends BaseServiceProviderInterface
13
+ {
14
+ /**
15
+ * Retrieve the prefix that is used by services provided by this instance.
16
+ *
17
+ * @param string|null $id The ID to prefix, if not null.
18
+ *
19
+ * @since 4.11
20
+ */
21
+ public function getServiceIdPrefix($id = null);
22
+ }
includes/Aventura/Wprss/Core/Plugin/Di/WritableCompositeContainerInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Plugin\Di;
4
+
5
+ use Dhii\Di\WritableCompositeContainerInterface as BaseWritableCompositeContainerInterface;
6
+
7
+ /**
8
+ * Represents a WPRA-specific composite container.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ interface WritableCompositeContainerInterface extends BaseWritableCompositeContainerInterface
13
+ {
14
+ }
includes/Aventura/Wprss/Core/Plugin/PluginAbstract.php CHANGED
@@ -3,6 +3,8 @@
3
  namespace Aventura\Wprss\Core\Plugin;
4
 
5
  use Aventura\Wprss\Core;
 
 
6
 
7
  /**
8
  * The base class for all WP plugins.
@@ -14,12 +16,19 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
14
  const CODE = '';
15
  const VERSION = '';
16
 
17
- /** @since 4.8.1 */
 
 
 
18
  protected $_factory;
19
  /** @since 4.8.1 */
20
  protected $_logger;
21
  /** @since 4.8.1 */
22
  protected $_eventManager;
 
 
 
 
23
 
24
  /**
25
  *
@@ -31,12 +40,18 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
31
  * * `text_domain` - The text domain used for translation by this plugin. See {@see getTextDomain}.
32
  * * `name` - The human-readable name of the plugin. See {@see getName()}.
33
  * Any other data will just be added to this instances internal data.
34
- * @param ComponentFactoryInterface A factory that will create components for this plugin.
 
 
35
  *
36
  * @throws Exception If required fields are not specified.
37
  */
38
- public function __construct($data, ComponentFactoryInterface $factory = null)
39
- {
 
 
 
 
40
  if (!is_array($data)) {
41
  $data = array('basename' => $data);
42
  }
@@ -48,43 +63,178 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
48
  $data['basename'] = static::standardizeBasename($data['basename']);
49
 
50
  // Normalizing and setting component factory
51
- if (is_null($factory) && isset($data['component_factory'])) {
52
- $factory = $data['component_factory'];
 
 
 
 
53
  }
54
 
55
  if ($factory) {
56
- $this->setFactory($factory);
 
 
 
 
57
  }
58
 
59
  parent::__construct($data);
60
  }
61
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
62
  public function getBasename()
63
  {
64
  return $this->getData('basename');
65
  }
66
 
 
 
 
 
 
67
  public function getTextDomain()
68
  {
69
  return $this->getData('text_domain');
70
  }
71
 
 
 
 
 
 
72
  public function getName()
73
  {
74
  return $this->getData('name');
75
  }
76
 
 
 
 
 
 
77
  public function getCode()
78
  {
79
  return $this->_getDataOrConst('code');
80
  }
81
 
 
 
 
 
 
82
  public function getVersion()
83
  {
84
  return $this->_getDataOrConst('version');
85
  }
86
 
87
  /**
 
88
  * @since 4.8.1
89
  * @return ComponentFactoryInterface
90
  */
@@ -93,17 +243,33 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
93
  return $this->_factory;
94
  }
95
 
 
 
 
 
 
 
96
  public function setFactory(ComponentFactoryInterface $factory)
97
  {
98
- $this->_setFactory($factory);
99
  return $this;
100
  }
101
 
 
 
 
 
 
102
  public function isActive()
103
  {
104
  return static::isPluginActive($this);
105
  }
106
 
 
 
 
 
 
107
  public function deactivate()
108
  {
109
  static::deactivatePlugin($this);
@@ -128,6 +294,11 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
128
  return is_plugin_active($plugin);
129
  }
130
 
 
 
 
 
 
131
  static public function deactivatePlugin($plugin)
132
  {
133
  static::_ensurePluginFunctionsExist();
@@ -139,6 +310,11 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
139
  deactivate_plugins($plugin);
140
  }
141
 
 
 
 
 
 
142
  static protected function _ensurePluginFunctionsExist()
143
  {
144
  // Making sure there are the functions we need
@@ -147,37 +323,6 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
147
  }
148
  }
149
 
150
- /**
151
- * Sets the component factory instance.
152
- *
153
- * If class name given instead, it will be instantiated.
154
- *
155
- * @since 4.8.1
156
- * @param ComponentFactoryInterface|string $factory The component factory instance or class name.
157
- * @return PluginInterface This instance.
158
- * @throws Exception If factory class specified as classname string does not exist, or is not a factory.
159
- */
160
- protected function _setFactory(ComponentFactoryInterface $factory) {
161
- // Factory could be a classname
162
- if (is_string($factory)) {
163
- // Making sure it exists
164
- $factory = trim($factory);
165
- if (!class_exists($factory)) {
166
- throw $this->exception(array('Could not set component factory: Factory class "%1$s" does not exist', $factory), array(__NAMESPACE__, 'Exception'));
167
- }
168
- // Making sure it's a factory
169
- if (!is_a($factory, __NAMESPACE__ . '\ComponentFactoryInterface')) {
170
- throw $this->exception(array('Could not set component factory: Factory class "%1$s" is not a factory', $factory), array(__NAMESPACE__, 'Exception'));
171
- }
172
-
173
- $factory = new $factory();
174
- /* @var $factory Aventura\Wprss\Core\Plugin\ComponentFactoryInterface */
175
- }
176
-
177
- $this->_factory = $factory;
178
- return $this;
179
- }
180
-
181
  /**
182
  * Translates some text.
183
  *
@@ -215,12 +360,13 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
215
  */
216
  public function getLogger()
217
  {
218
- return $this->_logger;
219
  }
220
 
221
  /**
222
  * Sets the logger instance to be used by this plugin.
223
  *
 
224
  * @since 4.8.1
225
  * @param Core\Model\LoggerInterface $logger
226
  * @return Core\Plugin\PluginAbstract
@@ -231,6 +377,11 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
231
  return $this;
232
  }
233
 
 
 
 
 
 
234
  public function log($level, $message, array $context = array())
235
  {
236
  $isFormattable = is_array($message) && isset($message[0]) && is_string($message[0]);
@@ -250,6 +401,11 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
250
  return false;
251
  }
252
 
 
 
 
 
 
253
  public function logObject($level, $object, array $context = array())
254
  {
255
  if (empty($object)) {
@@ -281,7 +437,9 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
281
  {
282
  $prefix = $this->hasData('event_prefix')
283
  ? $this->getData('event_prefix')
284
- : ($code = $this->getCode()) ? sprintf('%1$s_', $code) : '';
 
 
285
 
286
  return string_had_prefix($name, $this->getPrefixOverride())
287
  ? $name
@@ -291,6 +449,7 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
291
  /**
292
  * Sets the event manager for this instance.
293
  *
 
294
  * @since 4.8.1
295
  * @param Core\Model\Event\EventManagerInterface $manager An event manager.
296
  * @return PluginAbstract This instance.
@@ -309,7 +468,7 @@ class PluginAbstract extends Core\Model\ModelAbstract implements PluginInterface
309
  */
310
  public function getEventManager()
311
  {
312
- return $this->_eventManager;
313
  }
314
 
315
  /**
3
  namespace Aventura\Wprss\Core\Plugin;
4
 
5
  use Aventura\Wprss\Core;
6
+ use Dhii\Di\FactoryInterface;
7
+ use Interop\Container\ContainerInterface;
8
 
9
  /**
10
  * The base class for all WP plugins.
16
  const CODE = '';
17
  const VERSION = '';
18
 
19
+ /**
20
+ * @deprecated 4.11
21
+ * @since 4.8.1
22
+ */
23
  protected $_factory;
24
  /** @since 4.8.1 */
25
  protected $_logger;
26
  /** @since 4.8.1 */
27
  protected $_eventManager;
28
+ /** @since 4.11 */
29
+ protected $container;
30
+ /** @since 4.11 */
31
+ protected $factory;
32
 
33
  /**
34
  *
40
  * * `text_domain` - The text domain used for translation by this plugin. See {@see getTextDomain}.
41
  * * `name` - The human-readable name of the plugin. See {@see getName()}.
42
  * Any other data will just be added to this instances internal data.
43
+ * @param mixed Deprecated since 4.11.
44
+ * @param ContainerInterface $container The DI container that will be used by this plugin to resolve dependencies.
45
+ * @param FactoryInterface $factory The factory that will be used by this plugin to create generate new instances.
46
  *
47
  * @throws Exception If required fields are not specified.
48
  */
49
+ public function __construct(
50
+ $data,
51
+ $_factory = null, // Deprecated; kept for BC
52
+ ContainerInterface $container = null,
53
+ FactoryInterface $factory = null
54
+ ){
55
  if (!is_array($data)) {
56
  $data = array('basename' => $data);
57
  }
63
  $data['basename'] = static::standardizeBasename($data['basename']);
64
 
65
  // Normalizing and setting component factory
66
+ if (is_null($_factory) && isset($data['component_factory'])) {
67
+ $_factory = $data['component_factory'];
68
+ }
69
+
70
+ if ($_factory) {
71
+ $this->setFactory($_factory);
72
  }
73
 
74
  if ($factory) {
75
+ $this->_setFactory($factory);
76
+ }
77
+
78
+ if ($container) {
79
+ $this->_setContainer($container);
80
  }
81
 
82
  parent::__construct($data);
83
  }
84
 
85
+ /**
86
+ * Sets the service factory.
87
+ *
88
+ * @since 4.8.1
89
+ * @param FactoryInterface $factory The factory.
90
+ * @return $this This instance.
91
+ */
92
+ protected function _setFactory(FactoryInterface $factory)
93
+ {
94
+ $this->factory = $factory;
95
+
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * Gets the service factory.
101
+ *
102
+ * @since 4.11
103
+ *
104
+ * @return FactoryInterface
105
+ */
106
+ protected function _getFactory()
107
+ {
108
+ return $this->factory;
109
+ }
110
+
111
+ /**
112
+ * Sets the DI container.
113
+ *
114
+ * @since 4.11
115
+ *
116
+ * @param ContainerInterface $container The container.
117
+ * @return $this This instance.
118
+ */
119
+ protected function _setContainer(ContainerInterface $container)
120
+ {
121
+ $this->container = $container;
122
+
123
+ return $this;
124
+ }
125
+
126
+ /**
127
+ * Gets the DI container.
128
+ *
129
+ * @since 4.11
130
+ *
131
+ * @return ContainerInterface
132
+ */
133
+ protected function _getContainer()
134
+ {
135
+ /**
136
+ * This is necessary because extensions still don't know about the new
137
+ * DI container mechanics, and no container is being passed in those
138
+ * extensions to the constructor of this class.
139
+ *
140
+ * @todo Remove when add-ons refactored (4.11).
141
+ */
142
+ if (is_null($this->container)) {
143
+ return wprss_wp_container();
144
+ }
145
+
146
+ return $this->container;
147
+ }
148
+
149
+ /**
150
+ * Gets the service ID prefix, or prefixes the given ID with it.
151
+ *
152
+ * @since 4.11
153
+ *
154
+ * @param string|null $id The service ID to prefix, if not null.
155
+ * @return string The prefix, or potentially prefixed ID.
156
+ */
157
+ protected function _getServiceIdPrefix($id = null)
158
+ {
159
+ $prefix = $this->_getServiceIdPrefixRaw();
160
+ return static::stringHadPrefix($id)
161
+ ? $id
162
+ : "{$prefix}{$id}";
163
+ }
164
+
165
+ /**
166
+ * Gets the prefix for service IDs.
167
+ *
168
+ * @since 4.11
169
+ *
170
+ * @return type
171
+ */
172
+ protected function _getServiceIdPrefixRaw()
173
+ {
174
+ /**
175
+ * This is necessary because extensions still don't know about the new
176
+ * DI container mechanics, and no container is being passed in those
177
+ * extensions to the constructor of this class.
178
+ *
179
+ * @todo Remove when add-ons refactored (4.11).
180
+ */
181
+ $default = \WPRSS_SERVICE_ID_PREFIX;
182
+
183
+ return $this->_getDataOrConst('service_id_prefix', $default);
184
+ }
185
+
186
+ /**
187
+ * @since 4.8.1
188
+ *
189
+ * @return string
190
+ */
191
  public function getBasename()
192
  {
193
  return $this->getData('basename');
194
  }
195
 
196
+ /**
197
+ * @since 4.8.1
198
+ *
199
+ * @return string
200
+ */
201
  public function getTextDomain()
202
  {
203
  return $this->getData('text_domain');
204
  }
205
 
206
+ /**
207
+ * @since 4.8.1
208
+ *
209
+ * @return string
210
+ */
211
  public function getName()
212
  {
213
  return $this->getData('name');
214
  }
215
 
216
+ /**
217
+ * @since 4.8.1
218
+ *
219
+ * @return string
220
+ */
221
  public function getCode()
222
  {
223
  return $this->_getDataOrConst('code');
224
  }
225
 
226
+ /**
227
+ * @since 4.8.1
228
+ *
229
+ * @return string
230
+ */
231
  public function getVersion()
232
  {
233
  return $this->_getDataOrConst('version');
234
  }
235
 
236
  /**
237
+ * @todo Change to return the interop factory once extensions are refactored (4.11).
238
  * @since 4.8.1
239
  * @return ComponentFactoryInterface
240
  */
243
  return $this->_factory;
244
  }
245
 
246
+ /**
247
+ * @deprecated 4.11 Factory can no longer be set after construction.
248
+ * @since 4.8.1
249
+ *
250
+ * @return string
251
+ */
252
  public function setFactory(ComponentFactoryInterface $factory)
253
  {
254
+ $this->_factory = $factory;
255
  return $this;
256
  }
257
 
258
+ /**
259
+ * @since 4.8.1
260
+ *
261
+ * @return string
262
+ */
263
  public function isActive()
264
  {
265
  return static::isPluginActive($this);
266
  }
267
 
268
+ /**
269
+ * @since 4.8.1
270
+ *
271
+ * @return string
272
+ */
273
  public function deactivate()
274
  {
275
  static::deactivatePlugin($this);
294
  return is_plugin_active($plugin);
295
  }
296
 
297
+ /**
298
+ * @since 4.8.1
299
+ *
300
+ * @return string
301
+ */
302
  static public function deactivatePlugin($plugin)
303
  {
304
  static::_ensurePluginFunctionsExist();
310
  deactivate_plugins($plugin);
311
  }
312
 
313
+ /**
314
+ * @since 4.8.1
315
+ *
316
+ * @return string
317
+ */
318
  static protected function _ensurePluginFunctionsExist()
319
  {
320
  // Making sure there are the functions we need
323
  }
324
  }
325
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
326
  /**
327
  * Translates some text.
328
  *
360
  */
361
  public function getLogger()
362
  {
363
+ return $this->_getContainer()->get($this->_getServiceIdPrefix('logger'));
364
  }
365
 
366
  /**
367
  * Sets the logger instance to be used by this plugin.
368
  *
369
+ * @deprecated 4.11 Logger can no longer be set, but is retrieved from container.
370
  * @since 4.8.1
371
  * @param Core\Model\LoggerInterface $logger
372
  * @return Core\Plugin\PluginAbstract
377
  return $this;
378
  }
379
 
380
+ /**
381
+ * @since 4.8.1
382
+ *
383
+ * @return string
384
+ */
385
  public function log($level, $message, array $context = array())
386
  {
387
  $isFormattable = is_array($message) && isset($message[0]) && is_string($message[0]);
401
  return false;
402
  }
403
 
404
+ /**
405
+ * @since 4.8.1
406
+ *
407
+ * @return string
408
+ */
409
  public function logObject($level, $object, array $context = array())
410
  {
411
  if (empty($object)) {
437
  {
438
  $prefix = $this->hasData('event_prefix')
439
  ? $this->getData('event_prefix')
440
+ : (($code = $this->getCode())
441
+ ? sprintf('%1$s_', $code)
442
+ : '');
443
 
444
  return string_had_prefix($name, $this->getPrefixOverride())
445
  ? $name
449
  /**
450
  * Sets the event manager for this instance.
451
  *
452
+ * @deprecated 4.11
453
  * @since 4.8.1
454
  * @param Core\Model\Event\EventManagerInterface $manager An event manager.
455
  * @return PluginAbstract This instance.
468
  */
469
  public function getEventManager()
470
  {
471
+ return $this->_getContainer()->get($this->_getServiceIdPrefix('event_manager'));
472
  }
473
 
474
  /**
includes/Aventura/Wprss/Core/ServiceProvider.php ADDED
@@ -0,0 +1,208 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core;
4
+
5
+ use Aventura\Wprss\Core\Plugin\Di\AbstractComponentServiceProvider;
6
+ use Aventura\Wprss\Core\Plugin\Di\ServiceProviderInterface;
7
+ use Interop\Container\ContainerInterface;
8
+ use Dhii\Di\FactoryInterface;
9
+ use Aventura\Wprss\Core\Plugin\ComponentInterface;
10
+ use Aventura\Wprss\Core\Model\Event\EventManagerInterface;
11
+ use Aventura\Wprss\Core\Component\AdminHelper;
12
+
13
+ /**
14
+ * Providers service definitions.
15
+ *
16
+ * @since 4.11
17
+ */
18
+ class ServiceProvider extends AbstractComponentServiceProvider implements ServiceProviderInterface
19
+ {
20
+ /**
21
+ * {@inheritdoc}
22
+ *
23
+ * @since 4.11
24
+ */
25
+ protected function _getServiceDefinitions()
26
+ {
27
+ return array(
28
+ $this->_p('plugin') => array($this, '_createPlugin'),
29
+ $this->_p('factory') => array($this, '_createFactory'),
30
+ $this->_p('event_manager') => array($this, '_createEventManager'),
31
+ $this->_p('logger') => array($this, '_createLogger'),
32
+ $this->_p('admin_helper') => array($this, '_createAdminHelper'),
33
+ $this->_p('leave_review') => array($this, '_createLeaveReview'),
34
+ $this->_p('translator') => array($this, '_createTranslator'),
35
+ );
36
+ }
37
+
38
+ /**
39
+ * {@inheritdoc}
40
+ *
41
+ * @since 4.11
42
+ */
43
+ public function getServices()
44
+ {
45
+ return $this->_getServices();
46
+ }
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ *
51
+ * @since 4.11
52
+ */
53
+ public function getServiceIdPrefix($name = null)
54
+ {
55
+ return $this->_p($name);
56
+ }
57
+
58
+ /**
59
+ * Creates the main plugin instance.
60
+ *
61
+ * @since 4.11
62
+ *
63
+ * @return Plugin
64
+ */
65
+ public function _createPlugin(ContainerInterface $c, $p = null, $config = null)
66
+ {
67
+ $factory = $c->get($this->_p('factory'));
68
+ $config = $this->_normalizeConfig($config, array(
69
+ 'basename' => \WPRSS_FILE_CONSTANT,
70
+ 'name' => \WPRSS_CORE_PLUGIN_NAME,
71
+ 'service_id_prefix' => \WPRSS_SERVICE_ID_PREFIX,
72
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
73
+ ), $config);
74
+ $plugin = new Plugin($config, null, $c, $factory);
75
+
76
+ $plugin->hook();
77
+
78
+ return $plugin;
79
+ }
80
+
81
+ /**
82
+ * Gets the reference to the factory.
83
+ *
84
+ * @since 4.11
85
+ *
86
+ * @param ContainerInterface $c
87
+ * @param null $p Previous definition.
88
+ * @param array|null $config
89
+ * @return FactoryInterface
90
+ */
91
+ public function _createFactory(ContainerInterface $c, $p = null, $config = null)
92
+ {
93
+ return wprss_core_container();
94
+ }
95
+
96
+ /**
97
+ * Creates an event manager instance.
98
+ *
99
+ * @since 4.11
100
+ *
101
+ * @param ContainerInterface $c
102
+ * @param null $p
103
+ * @param array $config
104
+ * @return EventManagerInterface
105
+ */
106
+ public function _createEventManager(ContainerInterface $c, $p = null, $config = null)
107
+ {
108
+ $config = $this->_normalizeConfig($config, array(
109
+ 'is_keep_records' => \WPRSS_DEBUG
110
+ ));
111
+ $service = new EventManager($config);
112
+
113
+ return $service;
114
+ }
115
+
116
+ /**
117
+ * Creates an instance of the admin helper component.
118
+ *
119
+ * @since 4.11
120
+ *
121
+ * @param ContainerInterface $c
122
+ * @param null $p
123
+ * @param array $config
124
+ * @return Component\AdminHelper
125
+ */
126
+ public function _createAdminHelper(ContainerInterface $c, $p = null, $config = null)
127
+ {
128
+ $config = $this->_normalizeConfig($config, array(
129
+ 'plugin' => $c->get($this->_p('plugin')),
130
+ 'service_id_prefix' => \WPRSS_SERVICE_ID_PREFIX,
131
+ 'notice_service_id_prefix' => \WPRSS_NOTICE_SERVICE_ID_PREFIX,
132
+ ));
133
+ $service = new Component\AdminHelper($config, $c->get($this->_p('factory')));
134
+ $this->_prepareComponent($service);
135
+
136
+ return $service;
137
+ }
138
+
139
+ /**
140
+ * Creates an instance of the leave-a-review component.
141
+ *
142
+ * @since 4.11
143
+ *
144
+ * @param ContainerInterface $c
145
+ * @param null $p
146
+ * @param array $config
147
+ * @return Component\LeaveReviewNotification
148
+ */
149
+ public function _createLeaveReview(ContainerInterface $c, $p = null, $config = null)
150
+ {
151
+ $config = $this->_normalizeConfig($config, array(
152
+ 'plugin' => $c->get($this->_p('plugin'))
153
+ ));
154
+ $service = new Component\LeaveReviewNotification($config);
155
+ $this->_prepareComponent($service);
156
+
157
+ return $service;
158
+ }
159
+
160
+ /**
161
+ * Creates an instance of the leave-a-review component.
162
+ *
163
+ * @since 4.11
164
+ *
165
+ * @param ContainerInterface $c
166
+ * @param null $p
167
+ * @param array $config
168
+ * @return Component\LeaveReviewNotification
169
+ */
170
+ public function _createLogger(ContainerInterface $c, $p = null, $config = null)
171
+ {
172
+ $config = $this->_normalizeConfig($config, array(
173
+ 'plugin' => $c->get($this->_p('plugin')),
174
+ 'log_file_path' => WPRSS_LOG_FILE . '-' . get_current_blog_id() . WPRSS_LOG_FILE_EXT,
175
+ 'level_threshold' => wprss_log_get_level()
176
+ ));
177
+ $service = new Component\Logger($config);
178
+ $this->_prepareComponent($service);
179
+
180
+ return $service;
181
+ }
182
+
183
+ /**
184
+ * Creates a translator.
185
+ *
186
+ * @since 4.11
187
+ *
188
+ * @param ContainerInterface $c
189
+ * @param null $p
190
+ * @param array $config
191
+ * @return callable
192
+ */
193
+ public function _createTranslator(ContainerInterface $c, $p = null, $config = null)
194
+ {
195
+ $textDomain = \WPRSS_TEXT_DOMAIN;
196
+ $helper = $c->get($this->_p('admin_helper'));
197
+ /* @var $helper \Aventura\Wprss\Core\Component\AdminHelper */
198
+ $command = $helper->createCommand(array(
199
+ 'function' => function($text, $context = null) use ($textDomain) {
200
+ return is_null($context)
201
+ ? __($text, $textDomain)
202
+ : _x($text, $context, $textDomain);
203
+ }
204
+ ));
205
+
206
+ return $command;
207
+ }
208
+ }
includes/admin-ajax-notice.php CHANGED
@@ -1,46 +1,10 @@
1
  <?php
2
 
3
- /**
4
- * Serves up a notice to leave a review for this plugin
5
- *
6
- * @link http://wp.tutsplus.com/tutorials/creative-coding/a-primer-on-ajax-in-the-wordpress-dashboard-requesting-and-responding/
7
- * @link http://wptheming.com/2011/08/admin-notices-in-wordpress/
8
- *
9
- * @since 3.0
10
- *
11
- */
12
 
13
- add_action( 'admin_notices', 'wprss_display_admin_notice' );
14
- /**
15
- * Renders the administration notice. Also renders a hidden nonce used for security when processing the Ajax request.
16
- *
17
- * @since 3.0
18
- */
19
- function wprss_display_admin_notice() {
20
- // If not an admin, do not show the notification
21
- if ( ! current_user_can( 'manage_options' ) ) return;
22
-
23
- global $pagenow, $typenow;
24
- if ( empty( $typenow ) && !empty( $_GET['post'] ) ) {
25
- $post = get_post( $_GET['post'] );
26
- if ( $post !== NULL && !is_wp_error( $post ) )
27
- $typenow = $post->post_type;
28
- }
29
- $notices_settings = get_option( 'wprss_settings_notices' );
30
-
31
- if ( ( false == $notices_settings ) && ( ( $typenow == 'wprss_feed' ) || ( $typenow == 'wprss_feed_item' ) ) ) {
32
- $html = '<div id="ajax-notification" class="updated">';
33
- $html .= '<p>';
34
- $html .= __( 'Did you know that you can get more RSS features? Excerpts, thumbnails, keyword filtering, importing into posts and more... ', WPRSS_TEXT_DOMAIN );
35
- $html .= __( 'Check out the', WPRSS_TEXT_DOMAIN ) . ' <a target="_blank" href="http://www.wprssaggregator.com/extensions"><strong>' . __( 'extensions', 'WPRSS_TEXT_DOMAIN' ) . '</strong></a> ' . __( 'page.', WPRSS_TEXT_DOMAIN );
36
- $html .= '<a href="javascript:;" id="dismiss-ajax-notification" style="float:right;">' . __( 'Dismiss this notification', WPRSS_TEXT_DOMAIN ) . '</a>';
37
- $html .= '</p>';
38
- $html .= '<span id="ajax-notification-nonce" class="hidden">' . wp_create_nonce( 'ajax-notification-nonce' ) . '</span>';
39
- $html .= '</div>';
40
-
41
- echo $html;
42
- }
43
- }
44
 
45
 
46
  add_action( 'wp_ajax_wprss_hide_admin_notification', 'wprss_hide_admin_notification' );
@@ -175,6 +139,7 @@ class WPRSS_Admin_Notices {
175
  protected $_notice_base_class;
176
  protected $_nonce_base_class;
177
  protected $_btn_close_base_class;
 
178
 
179
 
180
  /**
@@ -222,6 +187,11 @@ class WPRSS_Admin_Notices {
222
  $data['btn_close_base_class'] = $this->prefix( 'admin-notice-btn-close' );
223
  $this->set_btn_close_base_class( $data['btn_close_base_class'] );
224
 
 
 
 
 
 
225
  $this->_construct();
226
  }
227
 
@@ -255,6 +225,31 @@ class WPRSS_Admin_Notices {
255
  }
256
 
257
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
258
  /**
259
  * Get the ID prefix, or a prefixed string.
260
  *
@@ -495,6 +490,7 @@ class WPRSS_Admin_Notices {
495
  'btn_close_id' => null, // The HTML ID for the close button
496
  'btn_close_class' => 'btn-close', // The HTML class for the close button, in addition to default
497
  'btn_close_content' => __( 'Dismiss this notification', $this->get_text_domain() ), // The content of the close button. HTML allowed.
 
498
  )));
499
 
500
  // Auto-generate ID
@@ -1074,7 +1070,7 @@ class WPRSS_Admin_Notices {
1074
  : $this->get_notices( $id );
1075
 
1076
  if ( !$notice )
1077
- throw new Exception( sprintf( 'Could not render notice: no notice found for ID "%1$s"' ), $id );
1078
 
1079
  $helper = wprss()->getAdminHelper();
1080
 
@@ -1082,11 +1078,13 @@ class WPRSS_Admin_Notices {
1082
  $notice = apply_filters( $this->prefix( 'admin_notice_render_before' ), $notice, $this );
1083
  ?>
1084
 
1085
- <div id="<?php echo $notice['id'] ?>" class="<?php echo $notice['notice_type'] ?> <?php echo $notice['notice_element_class'] ?> <?php echo $this->get_notice_base_class() ?>">
1086
  <div class="notice-content">
1087
  <?php echo $notice['content'] ?>
1088
  </div>
 
1089
  <a href="javascript:;" id="<?php echo $notice['btn_close_id'] ?>" style="float:right;" class="<?php echo $this->get_btn_close_base_class() ?> <?php echo $notice['btn_close_class'] ?>"><?php echo $notice['btn_close_content'] ?></a>
 
1090
  <span id="<?php echo $notice['nonce_element_id'] ?>" class="hidden <?php echo $notice['nonce_element_class'] ?> <?php echo $this->get_nonce_base_class() ?>"><?php echo $helper->resolveValue($notice['nonce']) ?></span>
1091
  </div>
1092
  <?php
@@ -1138,17 +1136,17 @@ class WPRSS_Admin_Notices {
1138
  // This should initialize the notice collection before anything can use it
1139
  add_action( 'init', 'wprss_admin_notice_get_collection', 9 );
1140
 
 
 
 
 
 
1141
 
1142
  /**
1143
  * Returns the singleton, plugin-wide instane of the admin notices controller.
1144
  * Initializes it if necessary.
1145
  *
1146
  * @since 4.7.4
1147
- * @uses-filter wprss_admin_notice_collection_before_init To modify collection before initialization.
1148
- * @uses-filter wprss_admin_notice_collection_after_init To modify collection after initialization.
1149
- * @uses-action admin_enqueue_scripts To enqueue the scripts for the collection.
1150
- * @uses-filter wprss_admin_notice_collection_before_localize_vars To modify list of vars to expose to the frontend.
1151
- * @uses-action wprss_admin_notice_collection_after_localize_vars To access list of vars exposed to the frontend.
1152
  * @staticvar WPRSS_Admin_Notices $collection The singleton instance.
1153
  * @return \WPRSS_Admin_Notices|null The singleton instance of notice collection, or null if it is unavailable.
1154
  */
@@ -1156,17 +1154,8 @@ function wprss_admin_notice_get_collection() {
1156
  static $collection = null;
1157
 
1158
  if ( is_null( $collection ) && is_admin() ) {
1159
- // Initialize collection
1160
- $collection = new WPRSS_Admin_Notices(array(
1161
- 'setting_code' => 'wprss_admin_notices',
1162
- 'id_prefix' => 'wprss_',
1163
- 'text_domain' => WPRSS_TEXT_DOMAIN
1164
- ));
1165
- $collection = apply_filters( 'wprss_admin_notice_collection_before_init', $collection );
1166
- $collection->init();
1167
- $collection = apply_filters( 'wprss_admin_notice_collection_after_init', $collection );
1168
-
1169
- add_action( 'wprss_admin_exclusive_scripts_styles', 'wprss_admin_notices_collection_enqueue_scripts' );
1170
  }
1171
 
1172
  return $collection;
@@ -1176,29 +1165,11 @@ function wprss_admin_notice_get_collection() {
1176
  * Enqueues the scripts for a notice collection.
1177
  *
1178
  * @since 4.7.8
1179
- * @uses-filter wprss_admin_notice_collection_before_enqueue_scripts To modify list of script handles to enqueue.
1180
- * @uses-action wprss_admin_notice_collection_after_enqueue_scripts To access list of enqueued script handles.
1181
  */
1182
  function wprss_admin_notices_collection_enqueue_scripts() {
1183
- // Get singleton collection
1184
- $collection = wprss_admin_notice_get_collection();
1185
-
1186
- // Get script handles via filter
1187
- $script_handles = apply_filters( 'wprss_admin_notice_collection_before_enqueue_scripts', array( 'wprss-admin-notifications' ), $collection );
1188
- // Iterate and enqueue scripts
1189
- foreach ( $script_handles as $_idx => $_handle ) wp_enqueue_script( $_handle );
1190
- // Post-enqueueing action
1191
- do_action( 'wprss_admin_notice_collection_after_enqueue_scripts', $script_handles, $collection );
1192
-
1193
- // Frontend settings
1194
- $settings = apply_filters( 'wprss_admin_notice_collection_before_localize_vars', array(
1195
- 'notice_class' => $collection->get_notice_base_class(),
1196
- 'nonce_class' => $collection->get_nonce_base_class(),
1197
- 'btn_close_class' => $collection->get_btn_close_base_class(),
1198
- 'action_code' => wprss_admin_notice_get_action_code()
1199
- ), $collection );
1200
- wp_localize_script( 'aventura', 'adminNoticeGlobalVars', $settings);
1201
- do_action( 'wprss_admin_notice_collection_after_localize_vars', $settings, $collection );
1202
  }
1203
 
1204
  /**
@@ -1318,3 +1289,31 @@ function wprss_user_can_manage_options() {
1318
  return apply_filters( 'wprss_user_can_manage_options', current_user_can( 'manage_options' ) );
1319
  }
1320
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
 
3
+ use Aventura\Wprss\Core\Model\AdminAjaxNotice\ServiceProvider;
4
+ use Dhii\Di\WritableContainerInterface;
5
+ use Aventura\Wprss\Core\Model\AdminAjaxNotice\NoticeInterface;
 
 
 
 
 
 
6
 
7
+ define ('WPRSS_NOTICE_SERVICE_ID_PREFIX', WPRSS_SERVICE_ID_PREFIX . 'notice.');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
 
9
 
10
  add_action( 'wp_ajax_wprss_hide_admin_notification', 'wprss_hide_admin_notification' );
139
  protected $_notice_base_class;
140
  protected $_nonce_base_class;
141
  protected $_btn_close_base_class;
142
+ protected $_dismiss_mode_class_prefix;
143
 
144
 
145
  /**
187
  $data['btn_close_base_class'] = $this->prefix( 'admin-notice-btn-close' );
188
  $this->set_btn_close_base_class( $data['btn_close_base_class'] );
189
 
190
+ // Class prefix for dismiss mode
191
+ if ( !isset( $data['dismiss_mode_class_prefix'] ) )
192
+ $data['dismiss_mode_class_prefix'] = 'dismiss-mode-';
193
+ $this->set_dismiss_mode_class_prefix($data['dismiss_mode_class_prefix']);
194
+
195
  $this->_construct();
196
  }
197
 
225
  }
226
 
227
 
228
+ /**
229
+ * Sets the prefix for dismiss mode class name.
230
+ *
231
+ * @since 4.11
232
+ *
233
+ * @param string $prefix The prefix.
234
+ * @return $this This instance.
235
+ */
236
+ public function set_dismiss_mode_class_prefix($prefix) {
237
+ $this->_dismiss_mode_class_prefix = trim($prefix);
238
+ return $this;
239
+ }
240
+
241
+
242
+ /**
243
+ * Sets the prefix for dismiss mode class name.
244
+ *
245
+ * @since 4.11
246
+ *
247
+ * @return string The prefix.
248
+ */
249
+ public function get_dismiss_mode_class_prefix() {
250
+ return $this->_dismiss_mode_class_prefix;
251
+ }
252
+
253
  /**
254
  * Get the ID prefix, or a prefixed string.
255
  *
490
  'btn_close_id' => null, // The HTML ID for the close button
491
  'btn_close_class' => 'btn-close', // The HTML class for the close button, in addition to default
492
  'btn_close_content' => __( 'Dismiss this notification', $this->get_text_domain() ), // The content of the close button. HTML allowed.
493
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_AJAX
494
  )));
495
 
496
  // Auto-generate ID
1070
  : $this->get_notices( $id );
1071
 
1072
  if ( !$notice )
1073
+ throw new Exception( sprintf( 'Could not render notice: no notice found for ID "%1$s"', $id ) );
1074
 
1075
  $helper = wprss()->getAdminHelper();
1076
 
1078
  $notice = apply_filters( $this->prefix( 'admin_notice_render_before' ), $notice, $this );
1079
  ?>
1080
 
1081
+ <div id="<?php echo $notice['id'] ?>" class="<?php echo $notice['notice_type'] ?> <?php echo $notice['notice_element_class'] ?> <?php echo $this->get_notice_base_class() ?> dismiss-mode-<?php echo $notice['dismiss_mode'] ?>">
1082
  <div class="notice-content">
1083
  <?php echo $notice['content'] ?>
1084
  </div>
1085
+ <?php if ($notice['dismiss_mode'] !== NoticeInterface::DISMISS_MODE_NONE): ?>
1086
  <a href="javascript:;" id="<?php echo $notice['btn_close_id'] ?>" style="float:right;" class="<?php echo $this->get_btn_close_base_class() ?> <?php echo $notice['btn_close_class'] ?>"><?php echo $notice['btn_close_content'] ?></a>
1087
+ <?php endif ?>
1088
  <span id="<?php echo $notice['nonce_element_id'] ?>" class="hidden <?php echo $notice['nonce_element_class'] ?> <?php echo $this->get_nonce_base_class() ?>"><?php echo $helper->resolveValue($notice['nonce']) ?></span>
1089
  </div>
1090
  <?php
1136
  // This should initialize the notice collection before anything can use it
1137
  add_action( 'init', 'wprss_admin_notice_get_collection', 9 );
1138
 
1139
+ // Trigger the component to initialize
1140
+ add_action('wprss_pre_init', function() {
1141
+ wprss_wp_container()->get(\WPRSS_SERVICE_ID_PREFIX.'admin_ajax_notices');
1142
+ });
1143
+
1144
 
1145
  /**
1146
  * Returns the singleton, plugin-wide instane of the admin notices controller.
1147
  * Initializes it if necessary.
1148
  *
1149
  * @since 4.7.4
 
 
 
 
 
1150
  * @staticvar WPRSS_Admin_Notices $collection The singleton instance.
1151
  * @return \WPRSS_Admin_Notices|null The singleton instance of notice collection, or null if it is unavailable.
1152
  */
1154
  static $collection = null;
1155
 
1156
  if ( is_null( $collection ) && is_admin() ) {
1157
+ $collection = wprss_wp_container()->get(\WPRSS_SERVICE_ID_PREFIX.'admin_ajax_notice_controller');
1158
+ add_action( \WPRSS_EVENT_PREFIX.'admin_exclusive_scripts_styles', 'wprss_admin_notices_collection_enqueue_scripts' );
 
 
 
 
 
 
 
 
 
1159
  }
1160
 
1161
  return $collection;
1165
  * Enqueues the scripts for a notice collection.
1166
  *
1167
  * @since 4.7.8
 
 
1168
  */
1169
  function wprss_admin_notices_collection_enqueue_scripts() {
1170
+ $notices = wprss()->getAdminAjaxNotices();
1171
+ $notices->_registerAssets();
1172
+ $notices->enqueueAssets();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1173
  }
1174
 
1175
  /**
1289
  return apply_filters( 'wprss_user_can_manage_options', current_user_can( 'manage_options' ) );
1290
  }
1291
 
1292
+ // Adds the AJAX notice service provider to the core container
1293
+ add_filter(WPRSS_EVENT_PREFIX .'core_container_init', function(WritableContainerInterface $container) {
1294
+ $noticeProvider = wprss_core_admin_ajax_notices_service_provider();
1295
+ $container->register($noticeProvider);
1296
+ });
1297
+
1298
+ /**
1299
+ * Retrieves the service provider that provides notice service definitions.
1300
+ *
1301
+ * @since 4.11
1302
+ *
1303
+ * @staticvar ServiceProvider $provider
1304
+ * @return ServiceProvider
1305
+ */
1306
+ function wprss_core_admin_ajax_notices_service_provider()
1307
+ {
1308
+ static $provider = null;
1309
+
1310
+ if(is_null($provider)) {
1311
+ $provider = new ServiceProvider(array(
1312
+ 'notice_service_id_prefix' => \WPRSS_NOTICE_SERVICE_ID_PREFIX,
1313
+ 'service_id_prefix' => \WPRSS_SERVICE_ID_PREFIX,
1314
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
1315
+ ));
1316
+ }
1317
+
1318
+ return $provider;
1319
+ }
includes/admin-debugging.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php
 
 
 
 
2
  /**
3
  * Plugin debugging
4
  *
@@ -232,10 +236,10 @@
232
  $debug_messages = apply_filters(
233
  'wprss_debug_messages',
234
  array(
235
- '1' => 'wprss_debugging_admin_notice_update_feeds',
236
- '2' => 'wprss_debugging_admin_notice_reimport_feeds',
237
- '3' => 'wprss_debugging_admin_notice_clear_log',
238
- '4' => 'wprss_debugging_admin_notice_reset_settings'
239
  )
240
  );
241
 
@@ -249,9 +253,36 @@
249
  if ( isset( $_GET['debug_message'] )) {//&& ( check_admin_referer( 'wprss-delete-import-feed-items' ) || check_admin_referer( 'wprss-update-feed-items' ) ) ) {
250
  $message = $_GET['debug_message'];
251
 
252
- foreach ( $debug_messages as $id => $callback) {
 
253
  if ( $message == $id ) {
254
- call_user_func( $callback );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
255
  break;
256
  }
257
  }
1
  <?php
2
+
3
+ use Interop\Container\Exception\NotFoundException as ServiceNotFoundException;
4
+ use Aventura\Wprss\Core\Model\AdminAjaxNotice\NoticeInterface;
5
+
6
  /**
7
  * Plugin debugging
8
  *
236
  $debug_messages = apply_filters(
237
  'wprss_debug_messages',
238
  array(
239
+ '1' => 'debug_feeds_updating',
240
+ '2' => 'debug_feeds_reimporting',
241
+ '3' => 'debug_cleared_log',
242
+ '4' => 'debug_settings_reset',
243
  )
244
  );
245
 
253
  if ( isset( $_GET['debug_message'] )) {//&& ( check_admin_referer( 'wprss-delete-import-feed-items' ) || check_admin_referer( 'wprss-update-feed-items' ) ) ) {
254
  $message = $_GET['debug_message'];
255
 
256
+ $helper = wprss()->getAdminHelper();
257
+ foreach ( $debug_messages as $id => $noticeId) {
258
  if ( $message == $id ) {
259
+ $noticeId = $helper->resolveValueOutput($noticeId);
260
+
261
+ $component = wprss()->getAdminAjaxNotices();
262
+ $collection = $component->getNoticeCollection();
263
+
264
+ try {
265
+ $noticeObj = $component->getNotice($noticeId);
266
+
267
+ if (!$noticeObj instanceof Aventura\Wprss\Core\DataObject) {
268
+ throw new Exception(
269
+ sprintf(
270
+ __('Expected notice to be a DataObject instance: %s given.', WPRSS_TEXT_DOMAIN),
271
+ is_object($noticeObj)? get_class($noticeObj) : gettype($noticeObj)
272
+ )
273
+ );
274
+ }
275
+ } catch (ServiceNotFoundException $ex) {
276
+ $content = trim(strip_tags($noticeId, '<strong><em><br><p>'));
277
+ $noticeObj = $helper->createNotice(array(
278
+ 'content' => $content,
279
+ 'dismiss_mode' => NoticeInterface::DISMISS_MODE_FRONTEND,
280
+ ));
281
+ }
282
+
283
+ $noticeData = $noticeObj->getData();
284
+ echo $collection->render_notice($collection->normalize_notice_data($noticeData));
285
+
286
  break;
287
  }
288
  }
includes/admin-display.php CHANGED
@@ -396,7 +396,8 @@
396
  // delete it
397
  delete_transient( 'wprss_delete_posts_by_source_notif' );
398
  // Add an action to show the notification
399
- add_action( 'all_admin_notices', 'wprss_notify_about_deleting_source_feed_items' );
 
400
  }
401
  }
402
  }
396
  // delete it
397
  delete_transient( 'wprss_delete_posts_by_source_notif' );
398
  // Add an action to show the notification
399
+ wprss()->getAdminAjaxNotices()->addNotice('deleting_feed_items');
400
+ // add_action( 'all_admin_notices', 'wprss_notify_about_deleting_source_feed_items' );
401
  }
402
  }
403
  }
includes/admin-import-export.php CHANGED
@@ -1,4 +1,8 @@
1
  <?php
 
 
 
 
2
  /**
3
  * Build the import/export settings page, used to import and export the plugin's settings
4
  * Based on http://wp.tutsplus.com/tutorials/creative-coding/creating-a-simple-backuprestore-settings-feature/
@@ -10,59 +14,25 @@
10
  /**
11
  * Checks for the submission of a bulk import.
12
  * If a bulk submission is made, creates the feed sources.
13
- *
14
  * @since 4.5
15
  */
16
- function wp_rss_aggregator_bulk_import() {
17
  // Check if recieving
18
  if ( !empty( $_POST['bulk-feeds'] ) ) {
19
  // Check nonce
20
- check_admin_referer('wprss-bulk-import', 'wprss-bulk-import');
21
  // Get the site which we should post to
22
- $post_site = is_multisite() ? get_current_blog_id() : '';
23
  // Get the text
24
  $bulk_feeds = $_POST['bulk-feeds'];
25
- // Split by lines
26
- $lines = explode("\n", $bulk_feeds);
27
- // Keep a counter
28
- global $wprss_bulk_count;
29
- $wprss_bulk_count = 0;
30
- // Iterate each line
31
- foreach( $lines as $line ) {
32
- // Split by comma
33
- $parts = array_map('trim', explode(",", $line) );
34
- // Check if split was successful
35
- if ( count($parts) < 2 ) continue;
36
- // Prepare the feed data
37
- $name = $parts[0];
38
- $url = $parts[1];
39
- // Check if both name and url are set
40
- if ( empty($name) || empty($url) ) continue;
41
- $feed = array(
42
- 'post_title' => $name,
43
- 'post_status' => 'publish',
44
- 'post_type' => 'wprss_feed',
45
- 'post_site' => $post_site
46
- );
47
- // Insert the feed into the DB
48
- $inserted_id = wp_insert_post( $feed );
49
- // Check if an error occurred
50
- if ( is_wp_error($inserted_id) ) continue;
51
- // Set the URL
52
- update_post_meta($inserted_id, 'wprss_url', $url);
53
- // Increment the counter
54
- $wprss_bulk_count++;
55
- }
56
- add_action('admin_notices', 'wprss_notify_bulk_add');
57
- }
58
- }
59
 
60
- function wprss_notify_bulk_add() {
61
- global $wprss_bulk_count; ?>
62
- <div class="updated">
63
- <p><?php echo sprintf( __( 'Successfully imported <code>%1$s</code> feed sources.', WPRSS_TEXT_DOMAIN ), $wprss_bulk_count )?></p>
64
- </div>
65
- <?php
66
  }
67
 
68
 
@@ -161,7 +131,8 @@
161
  wp_die( "Error during import" );
162
  } else {
163
  $file_name = $_FILES['import']['name'];
164
- $file_ext = strtolower( end( explode( ".", $file_name ) ) );
 
165
  $file_size = $_FILES['import']['size'];
166
  if ( ( $file_ext == "json" ) && ( $file_size < 500000 ) ) {
167
  $encode_options = file_get_contents( $_FILES['import']['tmp_name'] );
@@ -169,11 +140,11 @@
169
  foreach ( $options as $key => $value ) {
170
  update_option( $key, $value );
171
  }
172
- add_action( 'admin_notices', 'wp_rss_aggregator_import_notice1' );
173
  do_action( 'wprss_settings_imported' );
174
  }
175
  else {
176
- add_action( 'admin_notices', 'wp_rss_aggregator_import_notice2' );
177
  }
178
  }
179
  }
@@ -239,4 +210,15 @@
239
  </div>
240
  <?php
241
  }
242
- }
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+
3
+ use Dhii\Di\WritableContainerInterface;
4
+ use Aventura\Wprss\Core\Model\BulkSourceImport\ServiceProvider;
5
+
6
  /**
7
  * Build the import/export settings page, used to import and export the plugin's settings
8
  * Based on http://wp.tutsplus.com/tutorials/creative-coding/creating-a-simple-backuprestore-settings-feature/
14
  /**
15
  * Checks for the submission of a bulk import.
16
  * If a bulk submission is made, creates the feed sources.
17
+ *
18
  * @since 4.5
19
  */
20
+ function wp_rss_aggregator_bulk_import() {
21
  // Check if recieving
22
  if ( !empty( $_POST['bulk-feeds'] ) ) {
23
  // Check nonce
24
+ \check_admin_referer('wprss-bulk-import', 'wprss-bulk-import');
25
  // Get the site which we should post to
26
+ $post_site = \is_multisite() ? \get_current_blog_id() : '';
27
  // Get the text
28
  $bulk_feeds = $_POST['bulk-feeds'];
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
29
 
30
+ $importer = \wprss_wp_container()->get(\WPRSS_SERVICE_ID_PREFIX.'bulk_source_import');
31
+ /* @var $importer Aventura\Wprss\Core\Component\BulkSourceImport */
32
+ $results = $importer->import($bulk_feeds);
33
+
34
+ \wprss()->getAdminAjaxNotices()->addNotice('bulk_feed_import');
35
+ }
36
  }
37
 
38
 
131
  wp_die( "Error during import" );
132
  } else {
133
  $file_name = $_FILES['import']['name'];
134
+ $file_name_parts = explode( ".", $file_name );
135
+ $file_ext = strtolower( end( $file_name_parts ) );
136
  $file_size = $_FILES['import']['size'];
137
  if ( ( $file_ext == "json" ) && ( $file_size < 500000 ) ) {
138
  $encode_options = file_get_contents( $_FILES['import']['tmp_name'] );
140
  foreach ( $options as $key => $value ) {
141
  update_option( $key, $value );
142
  }
143
+ wprss()->getAdminAjaxNotices()->addNotice('settings_import_success');
144
  do_action( 'wprss_settings_imported' );
145
  }
146
  else {
147
+ wprss()->getAdminAjaxNotices()->addNotice('settings_import_failed');
148
  }
149
  }
150
  }
210
  </div>
211
  <?php
212
  }
213
+ }
214
+
215
+
216
+ // Adds the bulk import service provider to the core container
217
+ add_filter(\WPRSS_EVENT_PREFIX .'core_container_init', function(WritableContainerInterface $container) {
218
+ $serviceProvider = new ServiceProvider(array(
219
+ 'notice_service_id_prefix' => \WPRSS_NOTICE_SERVICE_ID_PREFIX,
220
+ 'service_id_prefix' => \WPRSS_SERVICE_ID_PREFIX,
221
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
222
+ ));
223
+ $container->register($serviceProvider);
224
+ });
includes/di.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /*
3
+ * The DI module
4
+ */
5
+
6
+ use Dhii\Di\CompositeContainer;
7
+ use Dhii\Di\CompositeContainerInterface;
8
+ use Dhii\Di\WritableCompositeContainerInterface;
9
+ use Aventura\Wprss\Core\CompositeContainer as WpraCompositeContainer;
10
+ use Aventura\Wprss\Core\ServiceProvider;
11
+ use Aventura\Wprss\Core\Container;
12
+ use Dhii\Di\FactoryInterface;
13
+
14
+ define('WPRSS_SERVICE_ID_PREFIX', \WPRSS_PLUGIN_CODE . '.');
15
+
16
+
17
+ if (!function_exists('wprss_wp_container')) {
18
+
19
+ /**
20
+ * Gets the global WP container.
21
+ *
22
+ * This is intended to be used everywhere in WP, by all plugins.
23
+ *
24
+ * @since 4.11
25
+ *
26
+ * @staticvar CompositeContainer $container
27
+ * @return CompositeContainerInterface The global composite container.
28
+ */
29
+ function wprss_wp_container()
30
+ {
31
+ static $container = null;
32
+
33
+ if (is_null($container)) {
34
+ $container = new CompositeContainer();
35
+
36
+ /**
37
+ * Exposes the global container at the moment of its initialization.
38
+ *
39
+ * This allows registration of child containers specific to plugins.
40
+ *
41
+ * @since 4.11
42
+ *
43
+ * @param WritableCompositeContainerInterface The global DI container.
44
+ */
45
+ do_action('wp_container_init', $container);
46
+ }
47
+
48
+ return $container;
49
+ }
50
+ }
51
+
52
+ /**
53
+ * Retrieves the container that has access to all services of all WPRA plugins.
54
+ *
55
+ * @since 4.11
56
+ * @staticvar WpraCompositeContainer $container
57
+ * @return CompositeContainerInterface The WPRA hub container.
58
+ */
59
+ function wprss_hub_container()
60
+ {
61
+ static $container = null;
62
+
63
+ if (is_null($container)) {
64
+ $container = new WpraCompositeContainer(wprss_wp_container());
65
+
66
+
67
+ /**
68
+ * Exposes the WPRA-wide container at the moment of its initialization.
69
+ *
70
+ * This allows registration of child containers specific to WPRA extensions.
71
+ *
72
+ * @since 4.11
73
+ *
74
+ * @param WritableCompositeContainerInterface The WPRA container DI container.
75
+ */
76
+ do_action('wprss_container_init', $container);
77
+ }
78
+
79
+ return $container;
80
+ }
81
+
82
+ /**
83
+ * Retrieves the WPRA Core container instance.
84
+ *
85
+ * @since 4.11
86
+ *
87
+ * @staticvar Container $container
88
+ * @return Container The container instance.
89
+ */
90
+ function wprss_core_container()
91
+ {
92
+ static $container = null;
93
+
94
+ if (is_null($container)) {
95
+ $serviceProvider = new ServiceProvider(array(
96
+ 'service_id_prefix' => \WPRSS_SERVICE_ID_PREFIX,
97
+ 'event_prefix' => \WPRSS_EVENT_PREFIX,
98
+ ));
99
+ $container = new Container($serviceProvider, wprss_hub_container());
100
+
101
+ /**
102
+ * Exposes the WPRA Core container at the moment of its initialization.
103
+ *
104
+ * @since 4.11
105
+ *
106
+ * @param WritableCompositeContainerInterface The container which has all WPRA Core services.
107
+ */
108
+ do_action('wprss_core_container_init', $container);
109
+ }
110
+
111
+ return $container;
112
+ }
113
+
114
+ // Making sure the global container is initialized - 1st tier
115
+ add_action('wprss_pre_init', function() {
116
+ wprss_wp_container();
117
+ });
118
+
119
+ // Adding WPRA-wide container - 2nd tier
120
+ add_action('wp_container_init', function(WritableCompositeContainerInterface $parent) {
121
+ $container = wprss_hub_container();
122
+
123
+ $parent->add($container);
124
+ });
125
+
126
+ // Creating and attaching the WPRA Core container, and feeding service definitions to it
127
+ add_action('wprss_container_init', function(WritableCompositeContainerInterface $parent) {
128
+ $container = wprss_core_container();
129
+
130
+ $parent->add($container);
131
+ });
includes/feed-access.php CHANGED
@@ -352,7 +352,9 @@ class WPRSS_Feed_Access
352
  }
353
 
354
  // Initialize
355
- WPRSS_Feed_Access::instance();
 
 
356
 
357
 
358
  /**
352
  }
353
 
354
  // Initialize
355
+ add_action('wprss_init', function() {
356
+ WPRSS_Feed_Access::instance();
357
+ });
358
 
359
 
360
  /**
includes/feed-blacklist.php CHANGED
@@ -160,23 +160,11 @@ function wprss_check_notice_transient() {
160
  // Remove the transient
161
  delete_transient( 'wprss_item_blacklist_notice' );
162
  // Show the notice
163
- add_action( 'admin_notices', 'wprss_blacklist_item_notice' );
 
164
  }
165
  }
166
 
167
- /**
168
- * The admin notice shown when an item is blacklisted.
169
- */
170
- function wprss_blacklist_item_notice() {
171
- ?>
172
- <div class="updated">
173
- <p>
174
- The item was deleted successfully and added to the blacklist.
175
- </p>
176
- </div>
177
- <?php
178
- }
179
-
180
 
181
  /**
182
  * Registers the Blacklist Custom Post Type.
160
  // Remove the transient
161
  delete_transient( 'wprss_item_blacklist_notice' );
162
  // Show the notice
163
+ // add_action( 'admin_notices', 'wprss_blacklist_item_notice' );
164
+ wprss()->getAdminAjaxNotices()->addNotice('blacklist_item_success');
165
  }
166
  }
167
 
 
 
 
 
 
 
 
 
 
 
 
 
 
168
 
169
  /**
170
  * Registers the Blacklist Custom Post Type.
includes/feed-states.php CHANGED
@@ -90,46 +90,18 @@
90
  $transient = get_transient( 'wprss_notify_bulk_change_state' );
91
  if ( $transient !== FALSE ) {
92
  switch ( $transient ) {
93
- case 'activated': add_action( 'all_admin_notices', 'wprss_notify_feed_sources_activated' ); break;
94
- case 'paused': add_action( 'all_admin_notices', 'wprss_notify_feed_sources_paused' ); break;
 
 
 
 
95
  }
96
  delete_transient( 'wprss_notify_bulk_change_state' );
97
  }
98
  }
99
 
100
 
101
-
102
- /**
103
- * Shows an admin notice to notify that feed sources have been activated.
104
- *
105
- * @since 4.1
106
- */
107
- function wprss_notify_feed_sources_activated() {
108
- ?>
109
- <div class="updated">
110
- <?php echo wpautop( __( 'The feed sources have been activated!', WPRSS_TEXT_DOMAIN ) ) ?>
111
- </div>
112
- <?php
113
- }
114
-
115
-
116
- /**
117
- * Shows an admin notice to notify that feed sources have been activated.
118
- *
119
- * @since 4.1
120
- */
121
- function wprss_notify_feed_sources_paused() {
122
- ?>
123
- <div class="updated">
124
- <?php echo wpautop( __( 'The feed sources have been paused!!', WPRSS_TEXT_DOMAIN ) ) ?>
125
- </div>
126
- <?php
127
- }
128
-
129
-
130
-
131
-
132
-
133
 
134
  /**
135
  * Activates the feed source. Runs on a schedule.
90
  $transient = get_transient( 'wprss_notify_bulk_change_state' );
91
  if ( $transient !== FALSE ) {
92
  switch ( $transient ) {
93
+ case 'activated':
94
+ wprss()->getAdminAjaxNotices()->addNotice('bulk_feed_activated');
95
+ break;
96
+ case 'paused':
97
+ wprss()->getAdminAjaxNotices()->addNotice('bulk_feed_paused');
98
+ break;
99
  }
100
  delete_transient( 'wprss_notify_bulk_change_state' );
101
  }
102
  }
103
 
104
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
 
106
  /**
107
  * Activates the feed source. Runs on a schedule.
includes/leave-review-notification.php CHANGED
@@ -21,6 +21,6 @@ if (!defined('WPRSS_LEAVE_REVIEW_NOTIFICATION_MIN_ACTIVE_FEED_SOURCES')) {
21
  define('WPRSS_LEAVE_REVIEW_NOTIFICATION_MIN_ACTIVE_FEED_SOURCES', 1);
22
  }
23
 
24
- //add_action('wprss_init', function() {
25
  wprss()->getLeaveReviewNotification();
26
- //});
21
  define('WPRSS_LEAVE_REVIEW_NOTIFICATION_MIN_ACTIVE_FEED_SOURCES', 1);
22
  }
23
 
24
+ add_action('wprss_init', function() {
25
  wprss()->getLeaveReviewNotification();
26
+ });
includes/licensing.php CHANGED
@@ -82,7 +82,7 @@ function wprss_licensing() {
82
  // Licensing Settings Controller hooks
83
  add_action( 'wprss_admin_init', array( $settingsController, 'registerSettings' ), 100 );
84
  add_action( 'admin_init', array( $settingsController, 'handleLicenseStatusChange' ), 10 );
85
- add_action( 'wprss_settings_license_key_is_valid', array( $settingsController, 'validateLicenseKeyForSave' ) );
86
 
87
  $licensing = (object) compact( 'manager', 'settingsController', 'ajaxController' );
88
 
82
  // Licensing Settings Controller hooks
83
  add_action( 'wprss_admin_init', array( $settingsController, 'registerSettings' ), 100 );
84
  add_action( 'admin_init', array( $settingsController, 'handleLicenseStatusChange' ), 10 );
85
+ add_action( 'wprss_settings_license_key_is_valid', array( $settingsController, 'validateLicenseKeyForSave' ), 10, 2 );
86
 
87
  $licensing = (object) compact( 'manager', 'settingsController', 'ajaxController' );
88
 
includes/scripts.php CHANGED
@@ -5,16 +5,73 @@
5
  * @package WPRSSAggregator
6
  */
7
 
8
- add_action( 'init', 'wprss_register_scripts', 9 );
9
- function wprss_register_scripts() {
10
- // Add the Class library, the Xdn library, and the Aventura namespace and classes
11
- wp_register_script( 'wprss-xdn-class', wprss_get_script_url( 'class' ), array('jquery') );
12
- wp_register_script( 'wprss-xdn-lib', wprss_get_script_url( 'xdn' ), array('wprss-xdn-class') );
13
- wp_register_script( 'aventura', wprss_get_script_url( 'aventura' ), array('wprss-xdn-lib') );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
15
- // This handles the client side for WPRSS_Admin_Notices
16
- wp_register_script( 'wprss-admin-notifications', wprss_get_script_url( 'admin-notifications' ), array('aventura'), false, true );
17
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
18
 
19
 
20
  add_action( 'admin_enqueue_scripts', 'wprss_admin_scripts_styles' );
@@ -30,10 +87,11 @@
30
  $pageBase = $screen->base;
31
  $postType = $screen->post_type;
32
  $page = isset( $_GET['page'] )? $_GET['page'] : '';
 
33
 
34
  // On all admin screens
35
- wp_enqueue_style( 'wprss-admin-editor-styles', WPRSS_CSS . 'admin-editor.css' );
36
- wp_enqueue_style( 'wprss-admin-tracking-styles', WPRSS_CSS . 'admin-tracking-styles.css' );
37
 
38
  // Only on WPRA-related admin screens
39
  if ($isWpraScreen) {
@@ -54,92 +112,47 @@
54
  $pageBase = $screen->base;
55
  $postType = $screen->post_type;
56
  $page = isset( $_GET['page'] )? $_GET['page'] : '';
 
57
 
58
- wp_enqueue_style( 'wprss-styles', WPRSS_CSS . 'admin-styles.css' );
59
- wp_enqueue_style( 'wprss-admin-styles', WPRSS_CSS . 'admin-styles.css' );
60
- wp_enqueue_style( 'wprss-fa', WPRSS_CSS . 'font-awesome.min.css' );
61
- wp_enqueue_style( 'wprss-admin-3.8-styles', WPRSS_CSS . 'admin-3.8.css' );
62
 
63
  wp_enqueue_script( 'wprss-xdn-class' );
64
  wp_enqueue_script( 'wprss-xdn-lib' );
65
  wp_enqueue_script( 'aventura' );
66
 
67
- wp_enqueue_script( 'wprss-admin-addon-ajax', WPRSS_JS .'admin-addon-ajax.js', array('jquery') );
68
- wp_localize_script( 'wprss-admin-addon-ajax', 'wprss_admin_addon_ajax', array(
69
- 'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN )
70
- ));
71
 
72
- // Prepare the URL for removing bulk from blacklist, with a nonce
73
- $blacklist_remove_url = admin_url( 'edit.php?wprss-bulk=1' );
74
- $blacklist_remove_url = wp_nonce_url( $blacklist_remove_url, 'blacklist-remove-selected', 'wprss_blacklist_trash' );
75
- $blacklist_remove_url .= '&wprss-blacklist-remove=';
76
-
77
- wp_enqueue_script( 'wprss-admin-custom', WPRSS_JS .'admin-custom.js', array('jquery','jquery-ui-datepicker','jquery-ui-slider') );
78
- wp_localize_script( 'wprss-admin-custom', 'wprss_admin_custom', array(
79
- 'failed_to_import' => __( 'Failed to import', WPRSS_TEXT_DOMAIN ),
80
- 'items_are_importing' => __( 'Items are importing', WPRSS_TEXT_DOMAIN ),
81
- 'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN ),
82
- 'bulk_add' => __( 'Bulk Add', WPRSS_TEXT_DOMAIN ),
83
- 'ok' => __( 'OK', WPRSS_TEXT_DOMAIN ),
84
- 'cancel' => __( 'Cancel', WPRSS_TEXT_DOMAIN ),
85
- 'blacklist_desc' => __( 'The feed items listed here will be disregarded when importing new items from your feed sources.', WPRSS_TEXT_DOMAIN ),
86
- 'blacklist_remove' => __( 'Remove selected from Blacklist', WPRSS_TEXT_DOMAIN ),
87
- 'blacklist_remove_url' => $blacklist_remove_url
88
- ) );
89
 
90
- wp_enqueue_script( 'jquery-ui-timepicker-addon', WPRSS_JS .'jquery-ui-timepicker-addon.js', array('jquery','jquery-ui-datepicker') );
91
- wp_enqueue_style( 'jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css' );
92
 
93
  if ($pageBase === 'post' && $postType = 'wprss_feed') {
94
  // Change text on post screen from 'Enter title here' to 'Enter feed name here'
95
  add_filter( 'enter_title_here', 'wprss_change_title_text' );
96
  }
97
  if ('wprss_feed' === $postType) {
98
- wp_enqueue_script( 'wprss-custom-bulk-actions', WPRSS_JS . 'admin-custom-bulk-actions.js', array( 'jquery' ) );
99
- wp_localize_script( 'wprss-custom-bulk-actions', 'wprss_admin_bulk', array(
100
- 'activate' => __( 'Activate', WPRSS_TEXT_DOMAIN ),
101
- 'pause' => __( 'Pause', WPRSS_TEXT_DOMAIN )
102
- ) );
103
  }
104
  if ('wprss_feed_item' === $postType) {
105
- wp_enqueue_script( 'wprss-custom-bulk-actions-feed-item', WPRSS_JS . 'admin-custom-bulk-actions-feed-item.js', array( 'jquery' ) );
106
- wp_localize_script( 'wprss-custom-bulk-actions-feed-item', 'wprss_admin_bulk_feed_item', array(
107
- 'trash' => __( 'Move to Trash', WPRSS_TEXT_DOMAIN )
108
- ) );
109
  }
110
 
111
  // Load Heartbeat script and set dependancy for Heartbeat to ensure Heartbeat is loaded
112
  if ($pageBase === 'edit' && $postType === 'wprss_feed' && apply_filters('wprss_ajax_polling', TRUE) === TRUE ) {
113
- wp_enqueue_script( 'wprss-feed-source-table-heartbeat', WPRSS_JS .'heartbeat.js' );
114
- wp_localize_script( 'wprss-feed-source-table-heartbeat', 'wprss_admin_heartbeat', array(
115
- 'ago' => __( 'ago', WPRSS_TEXT_DOMAIN )
116
- ) );
117
  }
118
 
119
- // Creates the wprss_urls object in JS
120
- wp_localize_script( 'wprss-admin-custom', 'wprss_urls',
121
- array(
122
- 'import_export' => admin_url('edit.php?post_type=wprss_feed&page=wprss-import-export-settings')
123
- )
124
- );
125
-
126
  if ($pageBase === 'wprss_feed_page_wprss-aggregator-settings') {
127
- wp_enqueue_script( 'wprss-admin-license-manager', WPRSS_JS . 'admin-license-manager.js' );
128
-
129
- wp_enqueue_script( 'wprss-admin-licensing', WPRSS_JS . 'admin-licensing.js' );
130
- wp_localize_script( 'wprss-admin-licensing', 'wprss_admin_licensing', array(
131
- 'activating' => __('Activating...', WPRSS_TEXT_DOMAIN),
132
- 'deactivating' => __('Deactivating...', WPRSS_TEXT_DOMAIN)
133
- ) );
134
  }
135
 
136
  if ($pageBase === 'wprss_feed_page_wprss-help') {
137
- wp_enqueue_script( 'wprss-admin-help', WPRSS_JS . 'admin-help.js' );
138
- wp_localize_script( 'wprss-admin-help', 'wprss_admin_help', array(
139
- 'sending' => __('Sending...', WPRSS_TEXT_DOMAIN),
140
- 'sent-error' => sprintf(__('There was an error sending the form. Please use the <a href="%s">contact form on our site.</a>'), esc_attr('http://www.wprssaggregator.com/contact/')),
141
- 'sent-ok' => __("Your message has been sent and we'll send you a confirmation e-mail when we receive it.")
142
- ) );
143
  }
144
 
145
  do_action('wprss_admin_exclusive_scripts_styles');
@@ -181,44 +194,23 @@
181
  }
182
 
183
 
184
- add_action( 'wp_enqueue_scripts', 'wprss_register_styles' );
185
  /**
186
- * Register front end CSS styling files
187
- * Inspiration from Easy Digital Downloads
 
188
  *
189
  * @since 3.0
190
  */
191
- function wprss_register_styles() {
192
-
193
- /* $general_settings = get_option( 'wprss_settings_general' );
194
-
195
- if( $general_settings['styles_disable'] == 1 )
196
- return;
197
- wp_enqueue_style( 'colorbox', WPRSS_CSS . 'colorbox.css', array(), '1.4.1' );
198
- wp_enqueue_style( 'styles', WPRSS_CSS . 'styles.css', array(), '' );
199
-
200
- /* If using DISABLE CSS option:
201
- global $edd_options;
202
-
203
- if( isset( $edd_options['disable_styles'] ) )
204
- return;
205
-
206
- */
207
-
208
- /* $file = 'wprss.css';
209
-
210
- // Check child theme first
211
- if ( file_exists( trailingslashit( get_stylesheet_directory() ) . 'wprss_templates/' . $file ) ) {
212
- $url = trailingslashit( get_stylesheet_directory_uri() ) . 'wprss_templates/' . $file;
213
-
214
- // Check parent theme next
215
- } elseif ( file_exists( trailingslashit( get_template_directory() ) . 'wprss_templates/' . $file ) ) {
216
- $url = trailingslashit( get_template_directory_uri() ) . 'wprss_templates/' . $file;
217
-
218
- // Check theme compatibility last
219
- } elseif ( file_exists( trailingslashit( wprss_get_templates_dir() ) . $file ) ) {
220
- $url = trailingslashit( wprss_get_templates_uri() ) . $file;
221
- }
222
-
223
- wp_enqueue_style( 'wprss-styles', $url, WPRSS_VERSION );*/
224
  }
5
  * @package WPRSSAggregator
6
  */
7
 
8
+ add_action( 'init', 'wprss_register_scripts', 9 );
9
+ function wprss_register_scripts()
10
+ {
11
+ $version = wprss()->getVersion();
12
+
13
+ // Add the Class library, the Xdn library, and the Aventura namespace and classes
14
+ wp_register_script( 'wprss-xdn-class', wprss_get_script_url( 'class' ), array('jquery'), $version );
15
+ wp_register_script( 'wprss-xdn-lib', wprss_get_script_url( 'xdn' ), array('wprss-xdn-class'), $version );
16
+ wp_register_script( 'aventura', wprss_get_script_url( 'aventura' ), array('wprss-xdn-lib'), $version );
17
+
18
+ wp_register_script( 'wprss-admin-addon-ajax', WPRSS_JS .'admin-addon-ajax.js', array('jquery'), $version );
19
+ wp_localize_script( 'wprss-admin-addon-ajax', 'wprss_admin_addon_ajax', array(
20
+ 'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN )
21
+ ));
22
+
23
+ // Prepare the URL for removing bulk from blacklist, with a nonce
24
+ $blacklist_remove_url = admin_url( 'edit.php?wprss-bulk=1' );
25
+ $blacklist_remove_url = wp_nonce_url( $blacklist_remove_url, 'blacklist-remove-selected', 'wprss_blacklist_trash' );
26
+ $blacklist_remove_url .= '&wprss-blacklist-remove=';
27
+ wp_register_script( 'wprss-admin-custom', WPRSS_JS .'admin-custom.js', array('jquery','jquery-ui-datepicker','jquery-ui-slider'), $version );
28
+ wp_localize_script( 'wprss-admin-custom', 'wprss_admin_custom', array(
29
+ 'failed_to_import' => __( 'Failed to import', WPRSS_TEXT_DOMAIN ),
30
+ 'items_are_importing' => __( 'Items are importing', WPRSS_TEXT_DOMAIN ),
31
+ 'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN ),
32
+ 'bulk_add' => __( 'Bulk Add', WPRSS_TEXT_DOMAIN ),
33
+ 'ok' => __( 'OK', WPRSS_TEXT_DOMAIN ),
34
+ 'cancel' => __( 'Cancel', WPRSS_TEXT_DOMAIN ),
35
+ 'blacklist_desc' => __( 'The feed items listed here will be disregarded when importing new items from your feed sources.', WPRSS_TEXT_DOMAIN ),
36
+ 'blacklist_remove' => __( 'Remove selected from Blacklist', WPRSS_TEXT_DOMAIN ),
37
+ 'blacklist_remove_url' => $blacklist_remove_url
38
+ ));
39
+ // Creates the wprss_urls object in JS
40
+ wp_localize_script( 'wprss-admin-custom', 'wprss_urls', array(
41
+ 'import_export' => admin_url('edit.php?post_type=wprss_feed&page=wprss-import-export-settings')
42
+ ));
43
+
44
+ wp_register_script( 'jquery-ui-timepicker-addon', WPRSS_JS .'jquery-ui-timepicker-addon.js', array('jquery','jquery-ui-datepicker'), $version );
45
+ wp_register_script( 'wprss-custom-bulk-actions', WPRSS_JS . 'admin-custom-bulk-actions.js', array( 'jquery' ), $version );
46
+ wp_localize_script( 'wprss-custom-bulk-actions', 'wprss_admin_bulk', array(
47
+ 'activate' => __( 'Activate', WPRSS_TEXT_DOMAIN ),
48
+ 'pause' => __( 'Pause', WPRSS_TEXT_DOMAIN )
49
+ ));
50
 
51
+ wp_register_script( 'wprss-custom-bulk-actions-feed-item', WPRSS_JS . 'admin-custom-bulk-actions-feed-item.js', array( 'jquery' ), $version );
52
+ wp_localize_script( 'wprss-custom-bulk-actions-feed-item', 'wprss_admin_bulk_feed_item', array(
53
+ 'trash' => __( 'Move to Trash', WPRSS_TEXT_DOMAIN )
54
+ ));
55
+
56
+ wp_register_script( 'wprss-feed-source-table-heartbeat', WPRSS_JS .'heartbeat.js', array(), $version );
57
+ wp_localize_script( 'wprss-feed-source-table-heartbeat', 'wprss_admin_heartbeat', array(
58
+ 'ago' => __( 'ago', WPRSS_TEXT_DOMAIN )
59
+ ));
60
+ wp_register_script( 'wprss-admin-license-manager', WPRSS_JS . 'admin-license-manager.js', array(), $version );
61
+
62
+ wp_register_script( 'wprss-admin-licensing', WPRSS_JS . 'admin-licensing.js', array(), $version );
63
+ wp_localize_script( 'wprss-admin-licensing', 'wprss_admin_licensing', array(
64
+ 'activating' => __('Activating...', WPRSS_TEXT_DOMAIN),
65
+ 'deactivating' => __('Deactivating...', WPRSS_TEXT_DOMAIN)
66
+ ));
67
+
68
+ wp_register_script( 'wprss-admin-help', WPRSS_JS . 'admin-help.js', array(), $version );
69
+ wp_localize_script( 'wprss-admin-help', 'wprss_admin_help', array(
70
+ 'sending' => __('Sending...', WPRSS_TEXT_DOMAIN),
71
+ 'sent-error' => sprintf(__('There was an error sending the form. Please use the <a href="%s">contact form on our site.</a>', WPRSS_TEXT_DOMAIN), esc_attr('http://www.wprssaggregator.com/contact/')),
72
+ 'sent-ok' => __("Your message has been sent and we'll send you a confirmation e-mail when we receive it.", WPRSS_TEXT_DOMAIN)
73
+ ));
74
+ }
75
 
76
 
77
  add_action( 'admin_enqueue_scripts', 'wprss_admin_scripts_styles' );
87
  $pageBase = $screen->base;
88
  $postType = $screen->post_type;
89
  $page = isset( $_GET['page'] )? $_GET['page'] : '';
90
+ $version = wprss()->getVersion();
91
 
92
  // On all admin screens
93
+ wp_enqueue_style( 'wprss-admin-editor-styles' );
94
+ wp_enqueue_style( 'wprss-admin-tracking-styles' );
95
 
96
  // Only on WPRA-related admin screens
97
  if ($isWpraScreen) {
112
  $pageBase = $screen->base;
113
  $postType = $screen->post_type;
114
  $page = isset( $_GET['page'] )? $_GET['page'] : '';
115
+ $version = wprss()->getVersion();
116
 
117
+ wp_enqueue_style( 'wprss-styles' );
118
+ wp_enqueue_style( 'wprss-admin-styles' );
119
+ wp_enqueue_style( 'wprss-fa' );
120
+ wp_enqueue_style( 'wprss-admin-3.8-styles' );
121
 
122
  wp_enqueue_script( 'wprss-xdn-class' );
123
  wp_enqueue_script( 'wprss-xdn-lib' );
124
  wp_enqueue_script( 'aventura' );
125
 
126
+ wp_enqueue_script( 'wprss-admin-addon-ajax' );
 
 
 
127
 
128
+ wp_enqueue_script( 'wprss-admin-custom' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
129
 
130
+ wp_enqueue_script( 'jquery-ui-timepicker-addon' );
131
+ wp_enqueue_style( 'jquery-style' );
132
 
133
  if ($pageBase === 'post' && $postType = 'wprss_feed') {
134
  // Change text on post screen from 'Enter title here' to 'Enter feed name here'
135
  add_filter( 'enter_title_here', 'wprss_change_title_text' );
136
  }
137
  if ('wprss_feed' === $postType) {
138
+ wp_enqueue_script( 'wprss-custom-bulk-actions' );
 
 
 
 
139
  }
140
  if ('wprss_feed_item' === $postType) {
141
+ wp_enqueue_script( 'wprss-custom-bulk-actions-feed-item' );
 
 
 
142
  }
143
 
144
  // Load Heartbeat script and set dependancy for Heartbeat to ensure Heartbeat is loaded
145
  if ($pageBase === 'edit' && $postType === 'wprss_feed' && apply_filters('wprss_ajax_polling', TRUE) === TRUE ) {
146
+ wp_enqueue_script( 'wprss-feed-source-table-heartbeat' );
 
 
 
147
  }
148
 
 
 
 
 
 
 
 
149
  if ($pageBase === 'wprss_feed_page_wprss-aggregator-settings') {
150
+ wp_enqueue_script( 'wprss-admin-license-manager' );
151
+ wp_enqueue_script( 'wprss-admin-licensing' );
 
 
 
 
 
152
  }
153
 
154
  if ($pageBase === 'wprss_feed_page_wprss-help') {
155
+ wp_enqueue_script( 'wprss-admin-help' );
 
 
 
 
 
156
  }
157
 
158
  do_action('wprss_admin_exclusive_scripts_styles');
194
  }
195
 
196
 
197
+ add_action( 'init', 'wprss_register_styles' );
198
  /**
199
+ * Registers all WPRA styles.
200
+ *
201
+ * Does not enqueue anything.
202
  *
203
  * @since 3.0
204
  */
205
+ function wprss_register_styles()
206
+ {
207
+ $version = wprss()->getVersion();
208
+
209
+ wp_register_style( 'wprss-styles', WPRSS_CSS . 'admin-styles.css', array(), $version );
210
+ wp_register_style( 'wprss-admin-styles', WPRSS_CSS . 'admin-styles.css', array(), $version );
211
+ wp_register_style( 'wprss-fa', WPRSS_CSS . 'font-awesome.min.css', array(), $version );
212
+ wp_register_style( 'wprss-admin-3.8-styles', WPRSS_CSS . 'admin-3.8.css', array(), $version );
213
+ wp_register_style( 'wprss-admin-editor-styles', WPRSS_CSS . 'admin-editor.css', array(), $version );
214
+ wp_register_style( 'wprss-admin-tracking-styles', WPRSS_CSS . 'admin-tracking-styles.css', array(), $version );
215
+ wp_register_style( 'jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css', array(), $version );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
216
  }
js/admin-licensing.js CHANGED
@@ -51,11 +51,36 @@ jQuery( document ).ready( function($) {
51
 
52
  };
53
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
54
  // This .js is only enqueued on our settings page, so just check the tab we're on.
55
  if ( document.location.href.search('tab=licenses_settings') > 0 ) {
56
  $('.button-activate-license').click(manage_license);
57
  $('.button-deactivate-license').click(manage_license);
58
  $('.submit').remove();
 
 
 
 
59
  }
60
 
61
  });
51
 
52
  };
53
 
54
+ handle_license_keypress = function(event) {
55
+ if (event.keyCode !== 13) {
56
+ return;
57
+ }
58
+ var row = $(this).closest('tr'),
59
+ nextRow = row.next(),
60
+ btn = nextRow.find('.button-process-license');
61
+
62
+ btn.click();
63
+
64
+ event.preventDefault();
65
+ event.stopPropagation();
66
+
67
+ return false;
68
+ };
69
+
70
+ on_form_submit = function() {
71
+ // Disable submission
72
+ return false;
73
+ };
74
+
75
  // This .js is only enqueued on our settings page, so just check the tab we're on.
76
  if ( document.location.href.search('tab=licenses_settings') > 0 ) {
77
  $('.button-activate-license').click(manage_license);
78
  $('.button-deactivate-license').click(manage_license);
79
  $('.submit').remove();
80
+ // Handle form submission
81
+ $('form').submit(on_form_submit);
82
+ // Handle keypress on license fields
83
+ $('.wprss-license-input').bind('keypress', handle_license_keypress);
84
  }
85
 
86
  });
js/aventura.js CHANGED
@@ -16,7 +16,8 @@
16
  var Aventura_Wp_Admin_Notices = Xdn.Object.Configurable.extend({
17
 
18
  attach: function() {
19
- var noticeClass, btnCloseClass, nonceElementClass, ajaxUrl, actionCode;
 
20
 
21
  if ( !( noticeClass = this.getOptions( 'notice_class' ) ) )
22
  console.error( 'Could not initialize admin notices: "notice_class" option must be specified' );
@@ -29,35 +30,59 @@
29
 
30
  if ( !( ajaxUrl = this.getOptions( 'ajax_url' ) ) )
31
  console.error( 'Could not initialize admin notices: "ajax_url" must be specified' );
32
-
33
  if ( !( actionCode = this.getOptions( 'action_code' ) ) )
34
  console.error( 'Could not initialize admin notices: "action_code" must be specified' );
 
 
 
35
 
36
  // Look through each notice
37
  $( '.'+noticeClass ).each(function(i, el) {
 
 
 
 
 
 
 
 
38
  $(el).find('.'+btnCloseClass).on( 'click', function(e) {
39
  e.preventDefault();
40
  e.stopPropagation();
41
-
42
- $.post(ajaxUrl, {
43
- // The name of the function to fire on the server
44
- action: actionCode,
45
- // The nonce value to send for the security check
46
- nonce: $.trim( $(el).find('.'+nonceElementClass).text() ),
47
- // The ID of the notice itself
48
- notice_id: $(el).attr('id')
49
- }, function (response) {
50
- // Unsuccessful
51
- if ( response !== '1' ) {
52
- $(el).removeClass('updated').addClass('error');
53
- console.error( response );
54
- return;
55
- }
56
-
57
- $(el).remove();
58
- });
 
 
 
 
 
 
 
 
 
59
  });
60
  });
 
 
 
 
61
  }
62
  });
63
  Xdn.assignNamespace(Aventura_Wp_Admin_Notices, 'Aventura.Wp.Admin.Notices');
16
  var Aventura_Wp_Admin_Notices = Xdn.Object.Configurable.extend({
17
 
18
  attach: function() {
19
+ var noticeClass, btnCloseClass, nonceElementClass, ajaxUrl, actionCode, dismissModeClassPrefix;
20
+ var me = this;
21
 
22
  if ( !( noticeClass = this.getOptions( 'notice_class' ) ) )
23
  console.error( 'Could not initialize admin notices: "notice_class" option must be specified' );
30
 
31
  if ( !( ajaxUrl = this.getOptions( 'ajax_url' ) ) )
32
  console.error( 'Could not initialize admin notices: "ajax_url" must be specified' );
33
+
34
  if ( !( actionCode = this.getOptions( 'action_code' ) ) )
35
  console.error( 'Could not initialize admin notices: "action_code" must be specified' );
36
+
37
+ if ( !( dismissModeClassPrefix = this.getOptions( 'dismiss_mode_class_prefix' ) ) )
38
+ console.error( 'Could not initialize admin notices: "dismiss_mode_class_prefix" must be specified' );
39
 
40
  // Look through each notice
41
  $( '.'+noticeClass ).each(function(i, el) {
42
+ var isDismissableAjax;
43
+ var isDismissableFrontend;
44
+ var isDismissable = !$(el).hasClass(dismissModeClassPrefix+'none');
45
+ if (!isDismissable) return;
46
+
47
+ isDismissableAjax = $(el).hasClass(dismissModeClassPrefix+'ajax');
48
+ isDismissableFrontend = $(el).hasClass(dismissModeClassPrefix+'front');
49
+
50
  $(el).find('.'+btnCloseClass).on( 'click', function(e) {
51
  e.preventDefault();
52
  e.stopPropagation();
53
+
54
+ if (isDismissableFrontend) {
55
+ me.hideNotice(el);
56
+ return;
57
+ }
58
+
59
+ if (isDismissableAjax) {
60
+ $.post(ajaxUrl, {
61
+ // The name of the function to fire on the server
62
+ action: actionCode,
63
+ // The nonce value to send for the security check
64
+ nonce: $.trim( $(el).find('.'+nonceElementClass).text() ),
65
+ // The ID of the notice itself
66
+ notice_id: $(el).attr('id')
67
+ }, function (response) {
68
+ // Unsuccessful
69
+ if ( response !== '1' ) {
70
+ $(el).removeClass('updated').addClass('error');
71
+ console.error( response );
72
+ return;
73
+ }
74
+
75
+ me.hideNotice(el);
76
+ });
77
+
78
+ return;
79
+ }
80
  });
81
  });
82
+ },
83
+
84
+ hideNotice: function(el) {
85
+ $(el).remove();
86
  }
87
  });
88
  Xdn.assignNamespace(Aventura_Wp_Admin_Notices, 'Aventura.Wp.Admin.Notices');
js/aventura.min.js CHANGED
@@ -1,2 +1,2 @@
1
  /* Automatically minified by JS CSS Minify Compress, a NetBeans plugin */;
2
- (function($,window,document,undefined){window.Aventura=window.Aventura||{}})(jQuery,top,document);(function($,window,document,undefined){var Aventura_Wp_Admin_Notices=Xdn.Object.Configurable.extend({attach:function(){var noticeClass,btnCloseClass,nonceElementClass,ajaxUrl,actionCode;if(!(noticeClass=this.getOptions("notice_class"))){console.error('Could not initialize admin notices: "notice_class" option must be specified')}if(!(btnCloseClass=this.getOptions("btn_close_class"))){console.error('Could not initialize admin notices: "btn_close_class" must be specified')}if(!(nonceElementClass=this.getOptions("nonce_class"))){console.error('Could not initialize admin notices: "nonce_class" must be specified')}if(!(ajaxUrl=this.getOptions("ajax_url"))){console.error('Could not initialize admin notices: "ajax_url" must be specified')}if(!(actionCode=this.getOptions("action_code"))){console.error('Could not initialize admin notices: "action_code" must be specified')}$("."+noticeClass).each(function(i,el){$(el).find("."+btnCloseClass).on("click",function(e){e.preventDefault();e.stopPropagation();$.post(ajaxUrl,{action:actionCode,nonce:$.trim($(el).find("."+nonceElementClass).text()),notice_id:$(el).attr("id")},function(response){if(response!=="1"){$(el).removeClass("updated").addClass("error");console.error(response);return}$(el).remove()})})})}});Xdn.assignNamespace(Aventura_Wp_Admin_Notices,"Aventura.Wp.Admin.Notices");var globalNotices;Aventura.Wp.Admin.Notices.getGlobal=function(){globalNotices=globalNotices||(function(){return new Aventura.Wp.Admin.Notices()})();return globalNotices}})(jQuery,top,document);
1
  /* Automatically minified by JS CSS Minify Compress, a NetBeans plugin */;
2
+ (function($,window,document,undefined){window.Aventura=window.Aventura||{}})(jQuery,top,document);(function($,window,document,undefined){var Aventura_Wp_Admin_Notices=Xdn.Object.Configurable.extend({attach:function(){var noticeClass,btnCloseClass,nonceElementClass,ajaxUrl,actionCode,dismissModeClassPrefix;var me=this;if(!(noticeClass=this.getOptions("notice_class"))){console.error('Could not initialize admin notices: "notice_class" option must be specified')}if(!(btnCloseClass=this.getOptions("btn_close_class"))){console.error('Could not initialize admin notices: "btn_close_class" must be specified')}if(!(nonceElementClass=this.getOptions("nonce_class"))){console.error('Could not initialize admin notices: "nonce_class" must be specified')}if(!(ajaxUrl=this.getOptions("ajax_url"))){console.error('Could not initialize admin notices: "ajax_url" must be specified')}if(!(actionCode=this.getOptions("action_code"))){console.error('Could not initialize admin notices: "action_code" must be specified')}if(!(dismissModeClassPrefix=this.getOptions("dismiss_mode_class_prefix"))){console.error('Could not initialize admin notices: "dismiss_mode_class_prefix" must be specified')}$("."+noticeClass).each(function(i,el){var isDismissableAjax;var isDismissableFrontend;var isDismissable=!$(el).hasClass(dismissModeClassPrefix+"none");if(!isDismissable){return}isDismissableAjax=$(el).hasClass(dismissModeClassPrefix+"ajax");isDismissableFrontend=$(el).hasClass(dismissModeClassPrefix+"front");$(el).find("."+btnCloseClass).on("click",function(e){e.preventDefault();e.stopPropagation();if(isDismissableFrontend){me.hideNotice(el);return}if(isDismissableAjax){$.post(ajaxUrl,{action:actionCode,nonce:$.trim($(el).find("."+nonceElementClass).text()),notice_id:$(el).attr("id")},function(response){if(response!=="1"){$(el).removeClass("updated").addClass("error");console.error(response);return}me.hideNotice(el)});return}})})},hideNotice:function(el){$(el).remove()}});Xdn.assignNamespace(Aventura_Wp_Admin_Notices,"Aventura.Wp.Admin.Notices");var globalNotices;Aventura.Wp.Admin.Notices.getGlobal=function(){globalNotices=globalNotices||(function(){return new Aventura.Wp.Admin.Notices()})();return globalNotices}})(jQuery,top,document);
readme.txt CHANGED
@@ -3,8 +3,8 @@ Contributors: RebelCode, jeangalea, Mekku, xedin.unknown, markzahra
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS, RSS feeds, aggregation, autoblog, content curation, feed reader, feed to post, RSS aggregator, RSS feeder, RSS import, RSS to post, syndication, multiple feed import
5
  Requires at least: 4.0
6
- Tested up to: 4.7
7
- Stable tag: 4.10
8
  License: GPLv3
9
  WP RSS Aggregator is the most comprehensive RSS feed importer and autoblogging plugin for WordPress with premium add-ons for additional functionality.
10
 
@@ -12,99 +12,100 @@ WP RSS Aggregator is the most comprehensive RSS feed importer and autoblogging p
12
 
13
  WP RSS Aggregator is the original and best plugin for easily importing, merging and displaying RSS and Atom feeds on your WordPress site. It’s the most comprehensive and elegant RSS feed solution for WordPress.
14
 
15
- [youtube https://www.youtube.com/watch?v=xXefoQHOfno]
16
-
17
- With the free core version of WP RSS Aggregator you will be able to aggregate as many RSS feeds from as many sources as you'd like, with the ability to stagger them for better performance.
18
- Using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) you can then display the imported feed items from one or more sources anywhere on your WordPress site.
19
 
20
  [youtube https://www.youtube.com/watch?v=OgB3veegtz4]
21
 
22
- Go [here](http://docs.wprssaggregator.com/introductory-videos/) to watch all our other video tutorials for our premium add-ons.
23
-
24
- ### Feature Highlights ###
25
  These are the main [features](https://www.wprssaggregator.com/features/) offered with the free core version of WP RSS Aggregator.
26
 
27
- > * Set a name for each feed source.
28
- > * Import any number of feed items from multiple RSS Feeds.
29
- > * Display feed items using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) or by
30
- > [calling the display function from within your theme](http://docs.wprssaggregator.com/shortcodes/#using-shortcodes-directly-in-templates).
31
- > * Limit the age of, or number of, feed items stored in the database (general or per feed source).
32
- > * Set a general or per feed source feed import time interval.
33
- > * Set the links as no-follow or not, or add no-follow to the meta tag.
34
- > * Customise the output using various [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters) and [styling changes](http://docs.wprssaggregator.com/styling-the-feeds/).
35
- > * Choose the Open Link Behaviour (lightbox, new window or current window).
36
- > * Opens YouTube, DailyMotion and Vimeo videos directly.
37
- > * Create a [custom RSS feed](https://docs.wprssaggregator.com/custom-feed-url/).
38
- > * Extendable via [action and filter hooks](https://docs.wprssaggregator.com/category/filters/).
39
- > * Incorporates feed auto-discovery, which lets you add feed sources without knowing the exact URL (not guaranteed to work for all sources).
40
- > * Integrated with the Simplepie library that comes with WordPress.
41
- > * Import/Export functionality.
42
- > * [View all features](https://www.wprssaggregator.com/features/).
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
 
44
  ### Minimal System Requirements ###
45
  * PHP 5.3.9 or higher
46
  * WordPress 4.0 or higher
47
 
48
  ### Premium Add-Ons ###
49
- WP RSS Aggregator has a number of [premium add-ons](https://www.wprssaggregator.com/extensions/) that add more functionality to the core plugin.
50
- They provide the means to create auto-blogging websites, display job listings, import YouTube videos and lots more.
51
- Take a look at our [Use Cases](https://www.wprssaggregator.com/use-cases/) and [Showcase](https://www.wprssaggregator.com/showcase/) for more ideas.
52
- These are the add-ons currently available:
53
-
54
- > * [Excerpts & Thumbnails](https://www.wprssaggregator.com/extension/excerpts-thumbnails/) displays an excerpt and thumbnail image
55
- > (taken from within the RSS feed) together with the title, date and source of each feed item.It uses the shortcode to display the feed items.
56
- > * [Categories](https://www.wprssaggregator.com/extension/categories/) categorises your feed sources and allows you to display
57
- > feed items from a particular category within your site using the
58
- > [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#categories-parameters). (It does not use WordPress Post Categories)
59
- > * [Keyword Filtering](https://www.wprssaggregator.com/extension/keyword-filtering/) filters the feed items to be imported based on your own keywords,
60
- > key phrases, or tags; you only get the items you're interested in. It is compatible with all other add-ons.
61
- > * [Feed to Post](https://www.wprssaggregator.com/extension/feed-to-post/) is an advanced importer that lets you import
62
- > RSS feed items as WordPress posts or any other custom post type. You can use it to populate a website in minutes (auto-blog).
63
- > This is the most popular and feature-filled extension. (It does not use shortcodes)
64
- > * [Full Text RSS Feeds](https://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our premium full text service,
65
- > which allows you to import the full post content for an unlimited number of feed items per feed source,
66
- > even when the feed itself doesn’t provide it. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/))
67
- > * [WordAi](https://www.wprssaggregator.com/extension/wordai/) allows you to take an RSS feed and turn it into
68
- > new content that is both completely unique and completely readable.
69
- > (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [WordAi account](https://wordai.com/))
70
- > * [SpinnerChief](https://www.wprssaggregator.com/extension/spinnerchief/) is an extension for
71
- > [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) that allows you to integrate the SpinnerChief article spinner
72
- > so that the imported content is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and
73
- > a [SpinnerChief account](http://www.spinnerchief.com/))
74
- > * [Widget](https://www.wprssaggregator.com/extension/widget/) adds a widget to your website
75
- > that displays all the imported feed items. It can also display excerpts and thumbnail images when used in conjunction
76
- > with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) add-on.
77
-
78
- View a comparison of our three most popular add-ons [here](http://www.wprssaggregator.com/product-comparison/).
79
- If you're unsure as to which add-ons you need, we put together [this comprehensive post](https://www.wprssaggregator.com/add-ons-purchase/)
80
- to help you out, or simply [contact our support team](https://www.wprssaggregator.com/contact/).
81
 
82
- There are also two premium bundles available, the [Simple Feeds Bundle](https://www.wprssaggregator.com/extension/simple-feeds-bundle/)
83
- and the [Advanced Feeds Bundle](https://www.wprssaggregator.com/extension/advanced-feeds-bundle/).
84
- View a quick comparison of these bundles [here](http://www.wprssaggregator.com/bundle-comparison/) or follow the guides below for more information:
85
 
86
- * [Enhance Your Feed Display](https://www.wprssaggregator.com/enhance-feed-display/)
87
- * [Automatic Content Aggregation and Curation](https://www.wprssaggregator.com/content-aggregation-curation/)
88
 
89
  We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed.
90
 
91
- ### Demos ###
92
- To try out some of the premium add-ons for yourself you can use our free demo sites:
93
 
94
  * [Simple Feeds Bundle Demo](http://simple.wprssaggregator.com/)
95
  * [Advanced Feeds Bundle Demo](http://demo.wprssaggregator.com/)
96
 
97
- We also have a number of live demo sites built by our team to showcase the power of WP RSS Aggregator and its add-ons. You can check them out [here](https://www.wprssaggregator.com/live-demos/).
 
 
 
 
98
 
99
  ### Documentation ###
100
- Our comprehensive [documentation](http://docs.wprssaggregator.com/) provides you with everything you need
101
- to install, set up and customise the plugin to your needs. You can also browse through a large number of
102
- [FAQs](http://docs.wprssaggregator.com/category/faqs/) that cover almost everything there is to ask.
103
 
104
  ### Support ###
105
- Support for the free version of WP RSS Aggregator is provided via the plugin directory support forum
106
- [here](https://wordpress.org/support/plugin/wp-rss-aggregator). It’s important to read and follow the
107
- [Support Guidelines](https://wordpress.org/support/topic/support-guidelines-1/) before opening a new ticket.
108
 
109
  For premium support (owners of premium add-on licenses) and pre-sales questions please contact us via our [premium support channel](https://www.wprssaggregator.com/contact/).
110
 
@@ -115,6 +116,7 @@ Would you like to praise any member of our team for our plugins or support servi
115
  * [Elegant Themes](https://www.elegantthemes.com/blog/tips-tricks/how-to-get-the-most-from-your-wordpress-rss-feed)
116
  * [LatestWP](http://www.latestwp.com/2015/03/15/wp-rss-aggregator-plugin-review/)
117
  * [WPBeginner](http://www.wpbeginner.com/plugins/how-to-fetch-feeds-in-wordpress-using-wp-rss-aggregator/)
 
118
  * [WPExplorer](http://www.wpexplorer.com/custom-rss-aggregator-plugin/)
119
  * [WPKube](http://www.wpkube.com/wp-rss-aggregator-wordpress-review/)
120
  * [Torque](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
@@ -128,14 +130,16 @@ Would you like to praise any member of our team for our plugins or support servi
128
  * [Magazine3](http://magazine3.com/blog/news-aggregator-website/)
129
 
130
  ### Translations ###
 
 
131
  * Italian - Davide De Maestri
132
  * Spanish - Andrew Kurtis
133
  * Brazilian Portugese - Bruno Calheira
134
  * Dutch - Erick Suiker
135
 
 
136
  ### NOTES ###
137
- The core WP RSS Aggregator plugin is free to download from the WordPress.org plugin repository.
138
- The plugin works on self-hosted versions of WordPress only (WordPress.org). It is not compatible with the hosted version
139
  of WordPress (WordPress.com). [Click here](https://www.wpmayor.com/differences-between-wordpressorg-and-wordpresscom/) if you're not sure about the difference between the two.
140
 
141
  Terms & conditions can be found [here](https://www.wprssaggregator.com/terms-conditions/).
@@ -282,6 +286,19 @@ Our complete documentation with FAQs included can be found on our dedicated [doc
282
 
283
  == Changelog ==
284
 
 
 
 
 
 
 
 
 
 
 
 
 
 
285
  = 4.10 (2016-12-29) =
286
  * Fixed bug with feed error output breaking tooltips on "Feed Sources" page.
287
  * Fixed bug with nonces on the "Feed Sources" page that broke some source actions.
3
  Plugin URI: https://www.wprssaggregator.com
4
  Tags: RSS, RSS feeds, aggregation, autoblog, content curation, feed reader, feed to post, RSS aggregator, RSS feeder, RSS import, RSS to post, syndication, multiple feed import
5
  Requires at least: 4.0
6
+ Tested up to: 4.7.2
7
+ Stable tag: 4.11
8
  License: GPLv3
9
  WP RSS Aggregator is the most comprehensive RSS feed importer and autoblogging plugin for WordPress with premium add-ons for additional functionality.
10
 
12
 
13
  WP RSS Aggregator is the original and best plugin for easily importing, merging and displaying RSS and Atom feeds on your WordPress site. It’s the most comprehensive and elegant RSS feed solution for WordPress.
14
 
15
+ With the free core version of WP RSS Aggregator you can aggregate as many RSS feeds from as many sources as you need, with the ability to [stagger them](https://docs.wprssaggregator.com/staggering-updates/) for better performance.
16
+ Using our [shortcode](http://docs.wprssaggregator.com/shortcodes/) and its parameters you can then display the imported feed items from one or more sources anywhere on your WordPress site.
 
 
17
 
18
  [youtube https://www.youtube.com/watch?v=OgB3veegtz4]
19
 
20
+ ### Core Features ###
 
 
21
  These are the main [features](https://www.wprssaggregator.com/features/) offered with the free core version of WP RSS Aggregator.
22
 
23
+ **Import & Display**
24
+
25
+ * Import any number of feed items from multiple RSS Feeds.
26
+ * Incorporates feed auto-discovery to add feed sources without knowing the exact URL (not guaranteed to work for all sources).
27
+ * Display feed items via our [shortcode](https://docs.wprssaggregator.com/shortcodes/) and its parameters.
28
+ * Display feed items by [calling the display function from within your theme](http://docs.wprssaggregator.com/shortcodes/#using-shortcodes-directly-in-templates).
29
+
30
+ **General Settings**
31
+
32
+ * Import feed items with [unique titles only](http://docs.wprssaggregator.com/general-plugin-settings/#unique-titles-only).
33
+ * Limit the number of feed items stored [per feed source](http://docs.wprssaggregator.com/general-plugin-settings/#limit-feed-items-per-feed).
34
+ * Limit the number of feed items stored [by their age](http://docs.wprssaggregator.com/general-plugin-settings/#limit-feed-items-by-age).
35
+ * Link to the [enclosure tag URL](https://docs.wprssaggregator.com/adding-a-feed-source-importing-as-feed-items/#step-5-other-options) for each feed item.
36
+ * Set all feed item links as nofollow.
37
+ * Easily manage your feed sources and imported feed items.
38
+ * [Stagger the update interval](https://docs.wprssaggregator.com/staggering-updates/) of each source to improve site performance.
39
+
40
+ **General Display Settings**
41
+
42
+ * Link the title and source name to the original source.
43
+ * Choose to hide or show the date and source of each feed item.
44
+ * Choose to display the original author’s name with each feed item.
45
+ * Change the date display format based on your needs.
46
+ * Style the shortcode’s feed item display with some CSS.
47
+ * Change the open link behaviour (lightbox, new window or current window).
48
+ * Change the feed item list pagination type.
49
+
50
+ **Other Features**
51
+
52
+ * Opens YouTube, DailyMotion and Vimeo videos directly.
53
+ * Create a [custom RSS feed](https://docs.wprssaggregator.com/custom-feed-url/) from imported feed items.
54
+ * Blacklist selected feed items so they’re never imported again.
55
+ * Import/export your feed sources using the WordPress or OPML Importer.
56
+ * Extendable via [action and filter hooks](https://docs.wprssaggregator.com/category/filters/).
57
+ * Integrated with the Simplepie library that comes with WordPress.
58
+ * Multilingual ready.
59
 
60
  ### Minimal System Requirements ###
61
  * PHP 5.3.9 or higher
62
  * WordPress 4.0 or higher
63
 
64
  ### Premium Add-Ons ###
65
+ With our premium add-ons you can do such things as creating auto-blogging websites, displaying job listings, importing YouTube videos, building news websites, and lots more. Take a look at our [Use Cases](https://www.wprssaggregator.com/use-cases/) and [Showcase](https://www.wprssaggregator.com/showcase/) for more ideas. Go [here](http://docs.wprssaggregator.com/introductory-videos/) to watch the video tutorials for our premium add-ons.
66
+
67
+ The add-ons currently available are:
68
+
69
+ * [Feed to Post](https://www.wprssaggregator.com/extension/feed-to-post/) is an advanced importer that lets you import RSS feed items as WordPress posts or any other custom post type. You can use it to populate a website in minutes (auto-blog). This is the most popular and feature-filled extension. (It does not use shortcodes)
70
+
71
+ * [Full Text RSS Feeds](https://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our premium full text service, which allows you to import the full post content for an unlimited number of feed items per feed source, even when the feed itself doesn’t provide it. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/))
72
+
73
+ * [WordAi](https://www.wprssaggregator.com/extension/wordai/) allows you to take an RSS feed and turn it into new content that is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [WordAi account](https://wordai.com/))
74
+
75
+ * [SpinnerChief](https://www.wprssaggregator.com/extension/spinnerchief/) is an extension for [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) that allows you to integrate the SpinnerChief article spinner so that the imported content is both completely unique and completely readable. (Requires [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) and a [SpinnerChief account](http://www.spinnerchief.com/))
76
+
77
+ * [Excerpts & Thumbnails](https://www.wprssaggregator.com/extension/excerpts-thumbnails/) displays an excerpt and thumbnail image (taken from within the RSS feed) together with the title, date and source of each feed item.It uses the shortcode to display the feed items.
78
+
79
+ * [Categories](https://www.wprssaggregator.com/extension/categories/) categorises your feed sources and allows you to display feed items from a particular category within your site using the [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#categories-parameters). (It does not use WordPress Post Categories)
80
+
81
+ * [Keyword Filtering](https://www.wprssaggregator.com/extension/keyword-filtering/) filters the feed items to be imported based on your own keywords, key phrases, or tags; you only get the items you're interested in. It is compatible with all other add-ons.
82
+
83
+ * [Widget](https://www.wprssaggregator.com/extension/widget/) adds a widget to your website that displays all the imported feed items. It can also display excerpts and thumbnail images when used in conjunction with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extension/excerpts-thumbnails/) add-on.
 
 
 
 
 
 
 
 
 
 
 
 
 
84
 
85
+ There are also two premium bundles available, the [Simple Feeds Bundle](https://www.wprssaggregator.com/extension/simple-feeds-bundle/) and the [Advanced Feeds Bundle](https://www.wprssaggregator.com/extension/advanced-feeds-bundle/). View a comparison of these bundles [here](http://www.wprssaggregator.com/bundle-comparison/) or follow the guides below for more information:
 
 
86
 
87
+ * [Enhance Your Feed Display](https://www.wprssaggregator.com/enhance-feed-display/) with the Simple Feeds Bundle
88
+ * [Content Aggregation and Curation](https://www.wprssaggregator.com/content-aggregation-curation/) with the Advanced Feeds Bundle
89
 
90
  We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service that allows you to generate RSS feeds from any webpage, even if it doesn't have its own RSS feed.
91
 
92
+ ### Free Demos ###
93
+ We offer two free demo sites, each including a different set of add-ons:
94
 
95
  * [Simple Feeds Bundle Demo](http://simple.wprssaggregator.com/)
96
  * [Advanced Feeds Bundle Demo](http://demo.wprssaggregator.com/)
97
 
98
+ We also have a number of live demo sites built by our team to showcase the power of our add-ons:
99
+
100
+ * [WP News Desk](http://wpnewsdesk.com/)
101
+ * [Travel Blogger Community](http://travelbloggercommunity.com/)
102
+ * [Dribbble Me](http://dribbble.wprssaggregator.com/)
103
 
104
  ### Documentation ###
105
+ Our comprehensive [documentation](http://docs.wprssaggregator.com/) provides you with everything you need to install, set up and customise the plugin to your needs. You can also browse through a large number of [FAQs](http://docs.wprssaggregator.com/category/faqs/) that cover almost everything there is to ask.
 
 
106
 
107
  ### Support ###
108
+ Support for the free version of WP RSS Aggregator is provided via the plugin directory support forum [here](https://wordpress.org/support/plugin/wp-rss-aggregator). It’s important to read and follow the [Support Guidelines](https://wordpress.org/support/topic/support-guidelines-1/) before opening a new ticket.
 
 
109
 
110
  For premium support (owners of premium add-on licenses) and pre-sales questions please contact us via our [premium support channel](https://www.wprssaggregator.com/contact/).
111
 
116
  * [Elegant Themes](https://www.elegantthemes.com/blog/tips-tricks/how-to-get-the-most-from-your-wordpress-rss-feed)
117
  * [LatestWP](http://www.latestwp.com/2015/03/15/wp-rss-aggregator-plugin-review/)
118
  * [WPBeginner](http://www.wpbeginner.com/plugins/how-to-fetch-feeds-in-wordpress-using-wp-rss-aggregator/)
119
+ * [Cloudways](https://www.cloudways.com/blog/wp-rss-aggregator-plugin-rss-feed-importer-autoblogging-plugin/)
120
  * [WPExplorer](http://www.wpexplorer.com/custom-rss-aggregator-plugin/)
121
  * [WPKube](http://www.wpkube.com/wp-rss-aggregator-wordpress-review/)
122
  * [Torque](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
130
  * [Magazine3](http://magazine3.com/blog/news-aggregator-website/)
131
 
132
  ### Translations ###
133
+ Would you like to contribute to a translation for WP RSS Aggregator and its add-ons? [Get in touch](https://www.wprssaggregator.com/contact/).
134
+
135
  * Italian - Davide De Maestri
136
  * Spanish - Andrew Kurtis
137
  * Brazilian Portugese - Bruno Calheira
138
  * Dutch - Erick Suiker
139
 
140
+
141
  ### NOTES ###
142
+ The core WP RSS Aggregator plugin is free to download from the WordPress.org plugin repository. The plugin works on self-hosted versions of WordPress only (WordPress.org). It is not compatible with the hosted version
 
143
  of WordPress (WordPress.com). [Click here](https://www.wpmayor.com/differences-between-wordpressorg-and-wordpresscom/) if you're not sure about the difference between the two.
144
 
145
  Terms & conditions can be found [here](https://www.wprssaggregator.com/terms-conditions/).
286
 
287
  == Changelog ==
288
 
289
+ = 4.11 (2017-02-06) =
290
+ * Fixed bug with lifetime licenses showing expiry notices.
291
+ * Fixed bug with being able to submit form on Licenses page.
292
+ * Fixed bug with empty saved license key causing PHP notice, and not triggering reminder notification.
293
+ * Fixed bug with saved but inactive licenses not triggering reminder notification.
294
+ * Fixed bug with minified assets not being served by default.
295
+ * Fixed bug with cached admin assets being served even after update.
296
+ * Fixed bug with admin notifications displayed on unrelated pages not being dismissable.
297
+ * Enhanced Licenses page so as to make the [Enter] key toggle license activation.
298
+ * Enhanced architecture by using a DI container.
299
+ * Enhanced admin notifications by refactoring them to use the same mechanism.
300
+ * Enhanced admin notifications by making all of them dismissable.
301
+
302
  = 4.10 (2016-12-29) =
303
  * Fixed bug with feed error output breaking tooltips on "Feed Sources" page.
304
  * Fixed bug with nonces on the "Feed Sources" page that broke some source actions.
test/diag/Aventura/Wprss/Core/DiagTest/DiTest.php ADDED
@@ -0,0 +1,125 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest;
4
+
5
+ use RebelCode\Wprss\Debug\DiagTest\Model\TestCase;
6
+
7
+ /**
8
+ * Tests dependency injection mechanism.
9
+ *
10
+ * @since 4.11
11
+ */
12
+ class DiTest extends TestCase
13
+ {
14
+ /**
15
+ * Tests whether the global container is returned correctly.
16
+ *
17
+ * @since 4.11
18
+ */
19
+ public function testGlobalContainer()
20
+ {
21
+ $container = wprss_wp_container();
22
+ $this->assertTrue($container instanceof \Interop\Container\ContainerInterface, 'Global container is not a valid container');
23
+ }
24
+
25
+ /**
26
+ * Tests whether the WPRA Core container is returned correctly.
27
+ *
28
+ * @since 4.11
29
+ */
30
+ public function testWpraCoreContainer()
31
+ {
32
+ $container = wprss_core_container();
33
+ $this->assertTrue($container instanceof \Interop\Container\ContainerInterface, 'WPRA Core container is not a valid container');
34
+ }
35
+
36
+ /**
37
+ * Tests whether the essential `event_manager` service is returned correctly.
38
+ *
39
+ * @since 4.11
40
+ */
41
+ public function testEventManagerService()
42
+ {
43
+ $container = wprss_wp_container();
44
+ $subject = $container->get(sprintf('%1$sevent_manager', \WPRSS_SERVICE_ID_PREFIX));
45
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Model\Event\EventManagerInterface, 'Not a valid event manager');
46
+ }
47
+
48
+ /**
49
+ * Tests whether the essential `logger` service is returned correctly.
50
+ *
51
+ * @since 4.11
52
+ */
53
+ public function testLoggerService()
54
+ {
55
+ $container = wprss_wp_container();
56
+ $subject = $container->get(sprintf('%1$slogger', \WPRSS_SERVICE_ID_PREFIX));
57
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Plugin\ComponentInterface, 'Not a valid component');
58
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Model\LoggerInterface, 'Not a valid logger');
59
+ }
60
+
61
+ /**
62
+ * Tests whether the essential `factory` service is returned correctly.
63
+ *
64
+ * @since 4.11
65
+ */
66
+ public function testFactoryService()
67
+ {
68
+ $container = wprss_wp_container();
69
+ $subject = $container->get(sprintf('%1$sfactory', \WPRSS_SERVICE_ID_PREFIX));
70
+ $this->assertTrue($subject instanceof \Dhii\Di\FactoryInterface, 'Not a valid factory');
71
+ }
72
+
73
+ /**
74
+ * Tests whether the essential `plugin` service is returned correctly.
75
+ *
76
+ * @since 4.11
77
+ */
78
+ public function testPluginService()
79
+ {
80
+ $container = wprss_wp_container();
81
+ $subject = $container->get(sprintf('%1$splugin', \WPRSS_SERVICE_ID_PREFIX));
82
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Plugin\PluginInterface, 'Not a valid plugin');
83
+ }
84
+
85
+ /**
86
+ * Tests whether the essential `admin_helper` service is returned correctly.
87
+ *
88
+ * @since 4.11
89
+ */
90
+ public function testAdminHelperService()
91
+ {
92
+ $container = wprss_wp_container();
93
+ $subject = $container->get(sprintf('%1$sadmin_helper', \WPRSS_SERVICE_ID_PREFIX));
94
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Plugin\ComponentInterface, 'Not a valid component');
95
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Component\AdminHelper, 'Not the right admin helper');
96
+ }
97
+
98
+ /**
99
+ * Tests whether the essential `leave_review` service is returned correctly.
100
+ *
101
+ * @since 4.11
102
+ */
103
+ public function testLeaveReviewService()
104
+ {
105
+ $container = wprss_wp_container();
106
+ $subject = $container->get(sprintf('%1$sleave_review', \WPRSS_SERVICE_ID_PREFIX));
107
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Plugin\ComponentInterface, 'Not a valid component');
108
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Component\LeaveReviewNotification, 'Not the right component');
109
+ }
110
+
111
+ /**
112
+ * Tests whether the structure of container relationships is correct.
113
+ *
114
+ * @since 4.11
115
+ */
116
+ public function testContainerStructure()
117
+ {
118
+ $globalContainer = wprss_wp_container();
119
+ $wpraContainer = wprss_hub_container();
120
+ $coreContainer = wprss_core_container();
121
+
122
+ $this->assertTrue(in_array($wpraContainer, $globalContainer->getContainers(), true), 'Global container does not container the WPRA container');
123
+ $this->assertTrue(in_array($coreContainer, $wpraContainer->getContainers(), true), 'WPRA container does not contain the Core container');
124
+ }
125
+ }
vendor/composer/autoload_psr4.php CHANGED
@@ -6,6 +6,8 @@ $vendorDir = dirname(dirname(__FILE__));
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
 
9
  'Dhii\\Stats\\' => array($vendorDir . '/dhii/stats-interface/src', $vendorDir . '/dhii/stats-abstract/src'),
 
10
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src', $vendorDir . '/dhii/collections-abstract-base/src', $vendorDir . '/dhii/collections-abstract/src'),
11
  );
6
  $baseDir = dirname($vendorDir);
7
 
8
  return array(
9
+ 'Interop\\Container\\' => array($vendorDir . '/container-interop/service-provider/src', $vendorDir . '/container-interop/container-interop/src/Interop/Container'),
10
  'Dhii\\Stats\\' => array($vendorDir . '/dhii/stats-interface/src', $vendorDir . '/dhii/stats-abstract/src'),
11
+ 'Dhii\\Di\\' => array($vendorDir . '/dhii/di-interface/src', $vendorDir . '/dhii/di-abstract/src', $vendorDir . '/dhii/di/src'),
12
  'Dhii\\Collection\\' => array($vendorDir . '/dhii/collections-interface/src', $vendorDir . '/dhii/collections-abstract-base/src', $vendorDir . '/dhii/collections-abstract/src'),
13
  );
vendor/composer/autoload_static.php CHANGED
@@ -7,19 +7,35 @@ namespace Composer\Autoload;
7
  class ComposerStaticInit5b1214f1b4db5e953417a3c5488d163a
8
  {
9
  public static $prefixLengthsPsr4 = array (
 
 
 
 
10
  'D' =>
11
  array (
12
  'Dhii\\Stats\\' => 11,
 
13
  'Dhii\\Collection\\' => 16,
14
  ),
15
  );
16
 
17
  public static $prefixDirsPsr4 = array (
 
 
 
 
 
18
  'Dhii\\Stats\\' =>
19
  array (
20
  0 => __DIR__ . '/..' . '/dhii/stats-interface/src',
21
  1 => __DIR__ . '/..' . '/dhii/stats-abstract/src',
22
  ),
 
 
 
 
 
 
23
  'Dhii\\Collection\\' =>
24
  array (
25
  0 => __DIR__ . '/..' . '/dhii/collections-interface/src',
7
  class ComposerStaticInit5b1214f1b4db5e953417a3c5488d163a
8
  {
9
  public static $prefixLengthsPsr4 = array (
10
+ 'I' =>
11
+ array (
12
+ 'Interop\\Container\\' => 18,
13
+ ),
14
  'D' =>
15
  array (
16
  'Dhii\\Stats\\' => 11,
17
+ 'Dhii\\Di\\' => 8,
18
  'Dhii\\Collection\\' => 16,
19
  ),
20
  );
21
 
22
  public static $prefixDirsPsr4 = array (
23
+ 'Interop\\Container\\' =>
24
+ array (
25
+ 0 => __DIR__ . '/..' . '/container-interop/service-provider/src',
26
+ 1 => __DIR__ . '/..' . '/container-interop/container-interop/src/Interop/Container',
27
+ ),
28
  'Dhii\\Stats\\' =>
29
  array (
30
  0 => __DIR__ . '/..' . '/dhii/stats-interface/src',
31
  1 => __DIR__ . '/..' . '/dhii/stats-abstract/src',
32
  ),
33
+ 'Dhii\\Di\\' =>
34
+ array (
35
+ 0 => __DIR__ . '/..' . '/dhii/di-interface/src',
36
+ 1 => __DIR__ . '/..' . '/dhii/di-abstract/src',
37
+ 2 => __DIR__ . '/..' . '/dhii/di/src',
38
+ ),
39
  'Dhii\\Collection\\' =>
40
  array (
41
  0 => __DIR__ . '/..' . '/dhii/collections-interface/src',
vendor/composer/installed.json CHANGED
@@ -215,5 +215,216 @@
215
  }
216
  ],
217
  "description": "A collections library"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
218
  }
219
  ]
215
  }
216
  ],
217
  "description": "A collections library"
218
+ },
219
+ {
220
+ "name": "container-interop/service-provider",
221
+ "version": "v0.3.0",
222
+ "version_normalized": "0.3.0.0",
223
+ "source": {
224
+ "type": "git",
225
+ "url": "https://github.com/container-interop/service-provider.git",
226
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf"
227
+ },
228
+ "dist": {
229
+ "type": "zip",
230
+ "url": "https://api.github.com/repos/container-interop/service-provider/zipball/5cb38893b836edb00d3e1ace26c20ee1d29957cf",
231
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf",
232
+ "shasum": ""
233
+ },
234
+ "require": {
235
+ "container-interop/container-interop": "^1.1"
236
+ },
237
+ "time": "2016-05-16 07:42:22",
238
+ "type": "library",
239
+ "installation-source": "dist",
240
+ "autoload": {
241
+ "psr-4": {
242
+ "Interop\\Container\\": "src/"
243
+ }
244
+ },
245
+ "notification-url": "https://packagist.org/downloads/",
246
+ "license": [
247
+ "MIT"
248
+ ],
249
+ "description": "Promoting container interoperability through standard service providers",
250
+ "homepage": "https://github.com/container-interop/service-provider"
251
+ },
252
+ {
253
+ "name": "dhii/di-interface",
254
+ "version": "v0.1",
255
+ "version_normalized": "0.1.0.0",
256
+ "source": {
257
+ "type": "git",
258
+ "url": "https://github.com/Dhii/di-interface.git",
259
+ "reference": "0320846a577d68b761e29acd5d4db40d88cc4f98"
260
+ },
261
+ "dist": {
262
+ "type": "zip",
263
+ "url": "https://api.github.com/repos/Dhii/di-interface/zipball/0320846a577d68b761e29acd5d4db40d88cc4f98",
264
+ "reference": "0320846a577d68b761e29acd5d4db40d88cc4f98",
265
+ "shasum": ""
266
+ },
267
+ "require": {
268
+ "container-interop/container-interop": "^1.1",
269
+ "container-interop/service-provider": "^0.3",
270
+ "php": "^5.3 | ^7.0"
271
+ },
272
+ "require-dev": {
273
+ "codeclimate/php-test-reporter": "<=0.3.2",
274
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
275
+ "phpunit/phpunit": "^4.8",
276
+ "ptrofimov/xpmock": "^1.1"
277
+ },
278
+ "time": "2017-02-02 13:12:09",
279
+ "type": "library",
280
+ "installation-source": "dist",
281
+ "autoload": {
282
+ "psr-4": {
283
+ "Dhii\\Di\\": "src/"
284
+ }
285
+ },
286
+ "notification-url": "https://packagist.org/downloads/",
287
+ "license": [
288
+ "MIT"
289
+ ],
290
+ "authors": [
291
+ {
292
+ "name": "Dhii Team",
293
+ "email": "development@dhii.co"
294
+ }
295
+ ],
296
+ "description": "Interfaces for DI container implementations"
297
+ },
298
+ {
299
+ "name": "dhii/di-abstract",
300
+ "version": "v0.1",
301
+ "version_normalized": "0.1.0.0",
302
+ "source": {
303
+ "type": "git",
304
+ "url": "https://github.com/Dhii/di-abstract.git",
305
+ "reference": "e87ee3782d5f4c44724e79c4b2e1a55103e5cd11"
306
+ },
307
+ "dist": {
308
+ "type": "zip",
309
+ "url": "https://api.github.com/repos/Dhii/di-abstract/zipball/e87ee3782d5f4c44724e79c4b2e1a55103e5cd11",
310
+ "reference": "e87ee3782d5f4c44724e79c4b2e1a55103e5cd11",
311
+ "shasum": ""
312
+ },
313
+ "require": {
314
+ "container-interop/container-interop": "^1.1",
315
+ "container-interop/service-provider": "^0.3",
316
+ "dhii/di-interface": "^0.1",
317
+ "php": "^5.3 | ^7.0"
318
+ },
319
+ "require-dev": {
320
+ "codeclimate/php-test-reporter": "<=0.3.2",
321
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
322
+ "phpunit/phpunit": "^4.8",
323
+ "ptrofimov/xpmock": "^1.1"
324
+ },
325
+ "time": "2017-02-02 18:30:06",
326
+ "type": "library",
327
+ "installation-source": "dist",
328
+ "autoload": {
329
+ "psr-4": {
330
+ "Dhii\\Di\\": "src/"
331
+ }
332
+ },
333
+ "notification-url": "https://packagist.org/downloads/",
334
+ "license": [
335
+ "MIT"
336
+ ],
337
+ "authors": [
338
+ {
339
+ "name": "Dhii Team",
340
+ "email": "development@dhii.co"
341
+ }
342
+ ],
343
+ "description": "Base abstract classes for DI container implementations"
344
+ },
345
+ {
346
+ "name": "dhii/di",
347
+ "version": "v0.1.1",
348
+ "version_normalized": "0.1.1.0",
349
+ "source": {
350
+ "type": "git",
351
+ "url": "https://github.com/Dhii/di.git",
352
+ "reference": "52efd50f1b11fcdd2f789bae483bdb858772c306"
353
+ },
354
+ "dist": {
355
+ "type": "zip",
356
+ "url": "https://api.github.com/repos/Dhii/di/zipball/52efd50f1b11fcdd2f789bae483bdb858772c306",
357
+ "reference": "52efd50f1b11fcdd2f789bae483bdb858772c306",
358
+ "shasum": ""
359
+ },
360
+ "require": {
361
+ "container-interop/container-interop": "^1.1",
362
+ "container-interop/service-provider": "^0.3",
363
+ "dhii/di-abstract": "^0.1",
364
+ "dhii/di-interface": "^0.1",
365
+ "php": "^5.3 | ^7.0"
366
+ },
367
+ "provide": {
368
+ "container-interop/container-interop-implementation": "^1.0"
369
+ },
370
+ "require-dev": {
371
+ "codeclimate/php-test-reporter": "<=0.3.2",
372
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
373
+ "phpunit/phpunit": "^4.8",
374
+ "ptrofimov/xpmock": "^1.1"
375
+ },
376
+ "time": "2017-02-03 13:33:48",
377
+ "type": "library",
378
+ "installation-source": "dist",
379
+ "autoload": {
380
+ "psr-4": {
381
+ "Dhii\\Di\\": "src/"
382
+ }
383
+ },
384
+ "notification-url": "https://packagist.org/downloads/",
385
+ "license": [
386
+ "MIT"
387
+ ],
388
+ "authors": [
389
+ {
390
+ "name": "Dhii Team",
391
+ "email": "development@dhii.co"
392
+ }
393
+ ],
394
+ "description": "A DI container implementation",
395
+ "keywords": [
396
+ "container",
397
+ "dependency injection",
398
+ "di"
399
+ ]
400
+ },
401
+ {
402
+ "name": "container-interop/container-interop",
403
+ "version": "1.1.0",
404
+ "version_normalized": "1.1.0.0",
405
+ "source": {
406
+ "type": "git",
407
+ "url": "https://github.com/container-interop/container-interop.git",
408
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
409
+ },
410
+ "dist": {
411
+ "type": "zip",
412
+ "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
413
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
414
+ "shasum": ""
415
+ },
416
+ "time": "2014-12-30 15:22:37",
417
+ "type": "library",
418
+ "installation-source": "dist",
419
+ "autoload": {
420
+ "psr-4": {
421
+ "Interop\\Container\\": "src/Interop/Container/"
422
+ }
423
+ },
424
+ "notification-url": "https://packagist.org/downloads/",
425
+ "license": [
426
+ "MIT"
427
+ ],
428
+ "description": "Promoting the interoperability of container objects (DIC, SL, etc.)"
429
  }
430
  ]
vendor/container-interop/container-interop/LICENSE ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ The MIT License (MIT)
2
+
3
+ Copyright (c) 2013 container-interop
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy of
6
+ this software and associated documentation files (the "Software"), to deal in
7
+ the Software without restriction, including without limitation the rights to
8
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
9
+ the Software, and to permit persons to whom the Software is furnished to do so,
10
+ subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
17
+ FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
18
+ COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
19
+ IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
20
+ CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
vendor/container-interop/container-interop/README.md ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Container Interoperability
2
+
3
+ [![Latest Stable Version](https://poser.pugx.org/container-interop/container-interop/v/stable.png)](https://packagist.org/packages/container-interop/container-interop)
4
+
5
+ *container-interop* tries to identify and standardize features in *container* objects (service locators,
6
+ dependency injection containers, etc.) to achieve interopererability.
7
+
8
+ Through discussions and trials, we try to create a standard, made of common interfaces but also recommendations.
9
+
10
+ If PHP projects that provide container implementations begin to adopt these common standards, then PHP
11
+ applications and projects that use containers can depend on the common interfaces instead of specific
12
+ implementations. This facilitates a high-level of interoperability and flexibility that allows users to consume
13
+ *any* container implementation that can be adapted to these interfaces.
14
+
15
+ The work done in this project is not officially endorsed by the [PHP-FIG](http://www.php-fig.org/), but it is being
16
+ worked on by members of PHP-FIG and other good developers. We adhere to the spirit and ideals of PHP-FIG, and hope
17
+ this project will pave the way for one or more future PSRs.
18
+
19
+
20
+ ## Installation
21
+
22
+ You can install this package through Composer:
23
+
24
+ ```json
25
+ {
26
+ "require": {
27
+ "container-interop/container-interop": "~1.0"
28
+ }
29
+ }
30
+ ```
31
+
32
+ The packages adheres to the [SemVer](http://semver.org/) specification, and there will be full backward compatibility
33
+ between minor versions.
34
+
35
+ ## Standards
36
+
37
+ ### Available
38
+
39
+ - [`ContainerInterface`](src/Interop/Container/ContainerInterface.php).
40
+ [Description](docs/ContainerInterface.md) [Meta Document](docs/ContainerInterface-meta.md).
41
+ Describes the interface of a container that exposes methods to read its entries.
42
+ - [*Delegate lookup feature*](docs/Delegate-lookup.md).
43
+ [Meta Document](docs/Delegate-lookup-meta.md).
44
+ Describes the ability for a container to delegate the lookup of its dependencies to a third-party container. This
45
+ feature lets several containers work together in a single application.
46
+
47
+ ### Proposed
48
+
49
+ View open [request for comments](https://github.com/container-interop/container-interop/labels/RFC)
50
+
51
+ ## Compatible projects
52
+
53
+ ### Projects implementing `ContainerInterface`
54
+
55
+ - [Acclimate](https://github.com/jeremeamia/acclimate-container)
56
+ - [dcp-di](https://github.com/estelsmith/dcp-di)
57
+ - [Mouf](http://mouf-php.com)
58
+ - [Njasm Container](https://github.com/njasm/container)
59
+ - [PHP-DI](http://php-di.org)
60
+ - [PimpleInterop](https://github.com/moufmouf/pimple-interop)
61
+ - [XStatic](https://github.com/jeremeamia/xstatic)
62
+
63
+ ### Projects implementing the *delegate lookup* feature
64
+
65
+ - [Mouf](http://mouf-php.com)
66
+ - [PHP-DI](http://php-di.org)
67
+ - [PimpleInterop](https://github.com/moufmouf/pimple-interop)
68
+
69
+ ## Workflow
70
+
71
+ Everyone is welcome to join and contribute.
72
+
73
+ The general workflow looks like this:
74
+
75
+ 1. Someone opens a discussion (GitHub issue) to suggest an interface
76
+ 1. Feedback is gathered
77
+ 1. The interface is added to a development branch
78
+ 1. We release alpha versions so that the interface can be experimented with
79
+ 1. Discussions and edits ensue until the interface is deemed stable by a general consensus
80
+ 1. A new minor version of the package is released
81
+
82
+ We try to not break BC by creating new interfaces instead of editing existing ones.
83
+
84
+ While we currently work on interfaces, we are open to anything that might help towards interoperability, may that
85
+ be code, best practices, etc.
vendor/container-interop/container-interop/composer.json ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "container-interop/container-interop",
3
+ "type": "library",
4
+ "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
5
+ "license": "MIT",
6
+ "autoload": {
7
+ "psr-4": {
8
+ "Interop\\Container\\": "src/Interop/Container/"
9
+ }
10
+ }
11
+ }
vendor/container-interop/container-interop/docs/ContainerInterface-meta.md ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # ContainerInterface Meta Document
2
+
3
+ ## Introduction
4
+
5
+ This document describes the process and discussions that lead to the `ContainerInterface`.
6
+ Its goal is to explain the reasons behind each decision.
7
+
8
+ ## Goal
9
+
10
+ The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
11
+ container to obtain objects and parameters.
12
+
13
+ By standardizing such a behavior, frameworks and libraries using the `ContainerInterface`
14
+ could work with any compatible container.
15
+ That would allow end users to choose their own container based on their own preferences.
16
+
17
+ It is important to distinguish the two usages of a container:
18
+
19
+ - configuring entries
20
+ - fetching entries
21
+
22
+ Most of the time, those two sides are not used by the same party.
23
+ While it is often end users who tend to configure entries, it is generally the framework that fetch
24
+ entries to build the application.
25
+
26
+ This is why this interface focuses only on how entries can be fetched from a container.
27
+
28
+ ## Interface name
29
+
30
+ The interface name has been thoroughly discussed and was decided by a vote.
31
+
32
+ The list of options considered with their respective votes are:
33
+
34
+ - `ContainerInterface`: +8
35
+ - `ProviderInterface`: +2
36
+ - `LocatorInterface`: 0
37
+ - `ReadableContainerInterface`: -5
38
+ - `ServiceLocatorInterface`: -6
39
+ - `ObjectFactory`: -6
40
+ - `ObjectStore`: -8
41
+ - `ConsumerInterface`: -9
42
+
43
+ [Full results of the vote](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)
44
+
45
+ The complete discussion can be read in [the issue #1](https://github.com/container-interop/container-interop/issues/1).
46
+
47
+ ## Interface methods
48
+
49
+ The choice of which methods the interface would contain was made after a statistical analysis of existing containers.
50
+ The results of this analysis are available [in this document](https://gist.github.com/mnapoli/6159681).
51
+
52
+ The summary of the analysis showed that:
53
+
54
+ - all containers offer a method to get an entry by its id
55
+ - a large majority name such method `get()`
56
+ - for all containers, the `get()` method has 1 mandatory parameter of type string
57
+ - some containers have an optional additional argument for `get()`, but it doesn't same the same purpose between containers
58
+ - a large majority of the containers offer a method to test if it can return an entry by its id
59
+ - a majority name such method `has()`
60
+ - for all containers offering `has()`, the method has exactly 1 parameter of type string
61
+ - a large majority of the containers throw an exception rather than returning null when an entry is not found in `get()`
62
+ - a large majority of the containers don't implement `ArrayAccess`
63
+
64
+ The question of whether to include methods to define entries has been discussed in
65
+ [issue #1](https://github.com/container-interop/container-interop/issues/1).
66
+ It has been judged that such methods do not belong in the interface described here because it is out of its scope
67
+ (see the "Goal" section).
68
+
69
+ As a result, the `ContainerInterface` contains two methods:
70
+
71
+ - `get()`, returning anything, with one mandatory string parameter. Should throw an exception if the entry is not found.
72
+ - `has()`, returning a boolean, with one mandatory string parameter.
73
+
74
+ ### Number of parameters in `get()` method
75
+
76
+ While `ContainerInterface` only defines one mandatory parameter in `get()`, it is not incompatible with
77
+ existing containers that have additional optional parameters. PHP allows an implementation to offer more parameters
78
+ as long as they are optional, because the implementation *does* satisfy the interface.
79
+
80
+ This issue has been discussed in [issue #6](https://github.com/container-interop/container-interop/issues/6).
81
+
82
+ ### Type of the `$id` parameter
83
+
84
+ The type of the `$id` parameter in `get()` and `has()` has been discussed in
85
+ [issue #6](https://github.com/container-interop/container-interop/issues/6).
86
+ While `string` is used in all the containers that were analyzed, it was suggested that allowing
87
+ anything (such as objects) could allow containers to offer a more advanced query API.
88
+
89
+ An example given was to use the container as an object builder. The `$id` parameter would then be an
90
+ object that would describe how to create an instance.
91
+
92
+ The conclusion of the discussion was that this was beyond the scope of getting entries from a container without
93
+ knowing how the container provided them, and it was more fit for a factory.
94
+
95
+ ## Contributors
96
+
97
+ Are listed here all people that contributed in the discussions or votes, by alphabetical order:
98
+
99
+ - [Amy Stephen](https://github.com/AmyStephen)
100
+ - [David Négrier](https://github.com/moufmouf)
101
+ - [Don Gilbert](https://github.com/dongilbert)
102
+ - [Jason Judge](https://github.com/judgej)
103
+ - [Jeremy Lindblom](https://github.com/jeremeamia)
104
+ - [Marco Pivetta](https://github.com/Ocramius)
105
+ - [Matthieu Napoli](https://github.com/mnapoli)
106
+ - [Paul M. Jones](https://github.com/pmjones)
107
+ - [Stephan Hochdörfer](https://github.com/shochdoerfer)
108
+ - [Taylor Otwell](https://github.com/taylorotwell)
109
+
110
+ ## Relevant links
111
+
112
+ - [`ContainerInterface.php`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php)
113
+ - [List of all issues](https://github.com/container-interop/container-interop/issues?labels=ContainerInterface&milestone=&page=1&state=closed)
114
+ - [Vote for the interface name](https://github.com/container-interop/container-interop/wiki/%231-interface-name:-Vote)
vendor/container-interop/container-interop/docs/ContainerInterface.md ADDED
@@ -0,0 +1,153 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Container interface
2
+ ===================
3
+
4
+ This document describes a common interface for dependency injection containers.
5
+
6
+ The goal set by `ContainerInterface` is to standardize how frameworks and libraries make use of a
7
+ container to obtain objects and parameters (called *entries* in the rest of this document).
8
+
9
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
10
+ "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
11
+ interpreted as described in [RFC 2119][].
12
+
13
+ The word `implementor` in this document is to be interpreted as someone
14
+ implementing the `ContainerInterface` in a depency injection-related library or framework.
15
+ Users of dependency injections containers (DIC) are refered to as `user`.
16
+
17
+ [RFC 2119]: http://tools.ietf.org/html/rfc2119
18
+
19
+ 1. Specification
20
+ -----------------
21
+
22
+ ### 1.1 Basics
23
+
24
+ - The `Interop\Container\ContainerInterface` exposes two methods : `get` and `has`.
25
+
26
+ - `get` takes one mandatory parameter: an entry identifier. It MUST be a string.
27
+ A call to `get` can return anything (a *mixed* value), or throws an exception if the identifier
28
+ is not known to the container. Two successive calls to `get` with the same
29
+ identifier SHOULD return the same value. However, depending on the `implementor`
30
+ design and/or `user` configuration, different values might be returned, so
31
+ `user` SHOULD NOT rely on getting the same value on 2 successive calls.
32
+ While `ContainerInterface` only defines one mandatory parameter in `get()`, implementations
33
+ MAY accept additional optional parameters.
34
+
35
+ - `has` takes one unique parameter: an entry identifier. It MUST return `true`
36
+ if an entry identifier is known to the container and `false` if it is not.
37
+
38
+ ### 1.2 Exceptions
39
+
40
+ Exceptions directly thrown by the container MUST implement the
41
+ [`Interop\Container\Exception\ContainerException`](../src/Interop/Container/Exception/ContainerException.php).
42
+
43
+ A call to the `get` method with a non-existing id should throw a
44
+ [`Interop\Container\Exception\NotFoundException`](../src/Interop/Container/Exception/NotFoundException.php).
45
+
46
+ ### 1.3 Additional features
47
+
48
+ This section describes additional features that MAY be added to a container. Containers are not
49
+ required to implement these features to respect the ContainerInterface.
50
+
51
+ #### 1.3.1 Delegate lookup feature
52
+
53
+ The goal of the *delegate lookup* feature is to allow several containers to share entries.
54
+ Containers implementing this feature can perform dependency lookups in other containers.
55
+
56
+ Containers implementing this feature will offer a greater lever of interoperability
57
+ with other containers. Implementation of this feature is therefore RECOMMENDED.
58
+
59
+ A container implementing this feature:
60
+
61
+ - MUST implement the `ContainerInterface`
62
+ - MUST provide a way to register a delegate container (using a constructor parameter, or a setter,
63
+ or any possible way). The delegate container MUST implement the `ContainerInterface`.
64
+
65
+ When a container is configured to use a delegate container for dependencies:
66
+
67
+ - Calls to the `get` method should only return an entry if the entry is part of the container.
68
+ If the entry is not part of the container, an exception should be thrown
69
+ (as requested by the `ContainerInterface`).
70
+ - Calls to the `has` method should only return `true` if the entry is part of the container.
71
+ If the entry is not part of the container, `false` should be returned.
72
+ - If the fetched entry has dependencies, **instead** of performing
73
+ the dependency lookup in the container, the lookup is performed on the *delegate container*.
74
+
75
+ Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself.
76
+
77
+ It is however allowed for containers to provide exception cases for special entries, and a way to lookup
78
+ into the same container (or another container) instead of the delegate container.
79
+
80
+ 2. Package
81
+ ----------
82
+
83
+ The interfaces and classes described as well as relevant exception are provided as part of the
84
+ [container-interop/container-interop](https://packagist.org/packages/container-interop/container-interop) package.
85
+
86
+ 3. `Interop\Container\ContainerInterface`
87
+ -----------------------------------------
88
+
89
+ ```php
90
+ <?php
91
+ namespace Interop\Container;
92
+
93
+ use Interop\Container\Exception\ContainerException;
94
+ use Interop\Container\Exception\NotFoundException;
95
+
96
+ /**
97
+ * Describes the interface of a container that exposes methods to read its entries.
98
+ */
99
+ interface ContainerInterface
100
+ {
101
+ /**
102
+ * Finds an entry of the container by its identifier and returns it.
103
+ *
104
+ * @param string $id Identifier of the entry to look for.
105
+ *
106
+ * @throws NotFoundException No entry was found for this identifier.
107
+ * @throws ContainerException Error while retrieving the entry.
108
+ *
109
+ * @return mixed Entry.
110
+ */
111
+ public function get($id);
112
+
113
+ /**
114
+ * Returns true if the container can return an entry for the given identifier.
115
+ * Returns false otherwise.
116
+ *
117
+ * @param string $id Identifier of the entry to look for.
118
+ *
119
+ * @return boolean
120
+ */
121
+ public function has($id);
122
+ }
123
+ ```
124
+
125
+ 4. `Interop\Container\Exception\ContainerException`
126
+ ---------------------------------------------------
127
+
128
+ ```php
129
+ <?php
130
+ namespace Interop\Container\Exception;
131
+
132
+ /**
133
+ * Base interface representing a generic exception in a container.
134
+ */
135
+ interface ContainerException
136
+ {
137
+ }
138
+ ```
139
+
140
+ 5. `Interop\Container\Exception\NotFoundException`
141
+ ---------------------------------------------------
142
+
143
+ ```php
144
+ <?php
145
+ namespace Interop\Container\Exception;
146
+
147
+ /**
148
+ * No entry was found in the container.
149
+ */
150
+ interface NotFoundException extends ContainerException
151
+ {
152
+ }
153
+ ```
vendor/container-interop/container-interop/docs/Delegate-lookup-meta.md ADDED
@@ -0,0 +1,259 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Delegate lookup feature Meta Document
2
+ =====================================
3
+
4
+ 1. Summary
5
+ ----------
6
+
7
+ This document describes the *delegate lookup feature*.
8
+ Containers are not required to implement this feature to respect the `ContainerInterface`.
9
+ However, containers implementing this feature will offer a greater lever of interoperability
10
+ with other containers, allowing multiple containers to share entries in the same application.
11
+ Implementation of this feature is therefore recommanded.
12
+
13
+ 2. Why Bother?
14
+ --------------
15
+
16
+ The [`ContainerInterface`](../src/Interop/Container/ContainerInterface.php) ([meta doc](ContainerInterface.md))
17
+ standardizes how frameworks and libraries make use of a container to obtain objects and parameters.
18
+
19
+ By standardizing such a behavior, frameworks and libraries relying on the `ContainerInterface`
20
+ could work with any compatible container.
21
+ That would allow end users to choose their own container based on their own preferences.
22
+
23
+ The `ContainerInterface` is also enough if we want to have several containers side-by-side in the same
24
+ application. For instance, this is what the [CompositeContainer](https://github.com/jeremeamia/acclimate-container/blob/master/src/CompositeContainer.php)
25
+ class of [Acclimate](https://github.com/jeremeamia/acclimate-container) is designed for:
26
+
27
+ ![Side by side containers](images/side_by_side_containers.png)
28
+
29
+ However, an instance in container 1 cannot reference an instance in container 2.
30
+
31
+ It would be better if an instance of container 1 could reference an instance in container 2,
32
+ and the opposite should be true.
33
+
34
+ ![Interoperating containers](images/interoperating_containers.png)
35
+
36
+ In the sample above, entry 1 in container 1 is referencing entry 3 in container 2.
37
+
38
+ 3. Scope
39
+ --------
40
+
41
+ ### 3.1 Goals
42
+
43
+ The goal of the *delegate lookup* feature is to allow several containers to share entries.
44
+
45
+ 4. Approaches
46
+ -------------
47
+
48
+ ### 4.1 Chosen Approach
49
+
50
+ Containers implementing this feature can perform dependency lookups in other containers.
51
+
52
+ A container implementing this feature:
53
+
54
+ - must implement the `ContainerInterface`
55
+ - must provide a way to register a *delegate container* (using a constructor parameter, or a setter, or any
56
+ possible way). The *delegate container* must implement the `ContainerInterface`.
57
+
58
+ When a *delegate container* is configured on a container:
59
+
60
+ - Calls to the `get` method should only return an entry if the entry is part of the container.
61
+ If the entry is not part of the container, an exception should be thrown (as required in the `ContainerInterface`).
62
+ - Calls to the `has` method should only return *true* if the entry is part of the container.
63
+ If the entry is not part of the container, *false* should be returned.
64
+ - Finally, the important part: if the entry we are fetching has dependencies,
65
+ **instead** of perfoming the dependency lookup in the container, the lookup is performed on the *delegate container*.
66
+
67
+ Important! By default, the lookup should be performed on the delegate container **only**, not on the container itself.
68
+
69
+ It is however allowed for containers to provide exception cases for special entries, and a way to lookup into
70
+ the same container (or another container) instead of the delegate container.
71
+
72
+ ### 4.2 Typical usage
73
+
74
+ The *delegate container* will usually be a composite container. A composite container is a container that
75
+ contains several other containers. When performing a lookup on a composite container, the inner containers are
76
+ queried until one container returns an entry.
77
+ An inner container implementing the *delegate lookup feature* will return entries it contains, but if these
78
+ entries have dependencies, the dependencies lookup calls will be performed on the composite container, giving
79
+ a chance to all containers to answer.
80
+
81
+ Interestingly enough, the order in which containers are added in the composite container matters. Indeed,
82
+ the first containers to be added in the composite container can "override" the entries of containers with
83
+ lower priority.
84
+
85
+ ![Containers priority](images/priority.png)
86
+
87
+ In the example above, "container 2" contains a controller "myController" and the controller is referencing an
88
+ "entityManager" entry. "Container 1" contains also an entry named "entityManager".
89
+ Without the *delegate lookup* feature, when requesting the "myController" instance to container 2, it would take
90
+ in charge the instanciation of both entries.
91
+
92
+ However, using the *delegate lookup* feature, here is what happens when we ask the composite controller for the
93
+ "myController" instance:
94
+
95
+ - The composite controller asks container 1 if if contains the "myController" instance. The answer is no.
96
+ - The composite controller asks container 2 if if contains the "myController" instance. The answer is yes.
97
+ - The composite controller performs a `get` call on container 2 for the "myController" instance.
98
+ - Container 2 sees that "myController" has a dependency on "entityManager".
99
+ - Container 2 delegates the lookup of "entityManager" to the composite controller.
100
+ - The composite controller asks container 1 if if contains the "entityManager" instance. The answer is yes.
101
+ - The composite controller performs a `get` call on container 1 for the "entityManager" instance.
102
+
103
+ In the end, we get a controller instanciated by container 2 that references an entityManager instanciated
104
+ by container 1.
105
+
106
+ ### 4.3 Alternative: the fallback strategy
107
+
108
+ The first proposed approach we tried was to perform all the lookups in the "local" container,
109
+ and if a lookup fails in the container, to use the delegate container. In this scenario, the
110
+ delegate container is used in "fallback" mode.
111
+
112
+ This strategy has been described in @moufmouf blog post: http://mouf-php.com/container-interop-whats-next (solution 1).
113
+ It was also discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-33570697) and
114
+ [here](https://github.com/container-interop/container-interop/pull/20#issuecomment-56599631).
115
+
116
+ Problems with this strategy:
117
+
118
+ - Heavy problem regarding infinite loops
119
+ - Unable to overload a container entry with the delegate container entry
120
+
121
+ ### 4.4 Alternative: force implementing an interface
122
+
123
+ The first proposed approach was to develop a `ParentAwareContainerInterface` interface.
124
+ It was proposed here: https://github.com/container-interop/container-interop/pull/8
125
+
126
+ The interface would have had the behaviour of the delegate lookup feature but would have forced the addition of
127
+ a `setParentContainter` method:
128
+
129
+ ```php
130
+ interface ParentAwareContainerInterface extends ReadableContainerInterface {
131
+ /**
132
+ * Sets the parent container associated to that container. This container will call
133
+ * the parent container to fetch dependencies.
134
+ *
135
+ * @param ContainerInterface $container
136
+ */
137
+ public function setParentContainer(ContainerInterface $container);
138
+ }
139
+ ```
140
+
141
+ The interface idea was first questioned by @Ocramius [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777).
142
+ @Ocramius expressed the idea that an interface should not contain setters, otherwise, it is forcing implementation
143
+ details on the class implementing the interface.
144
+ Then @mnapoli made a proposal for a "convention" [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51841079),
145
+ this idea was further discussed until all participants in the discussion agreed to remove the interface idea
146
+ and replace it with a "standard" feature.
147
+
148
+ **Pros:**
149
+
150
+ If we had had an interface, we could have delegated the registration of the delegate/composite container to the
151
+ the delegate/composite container itself.
152
+ For instance:
153
+
154
+ ```php
155
+ $containerA = new ContainerA();
156
+ $containerB = new ContainerB();
157
+
158
+ $compositeContainer = new CompositeContainer([$containerA, $containerB]);
159
+
160
+ // The call to 'setParentContainer' is delegated to the CompositeContainer
161
+ // It is not the responsibility of the user anymore.
162
+ class CompositeContainer {
163
+ ...
164
+
165
+ public function __construct($containers) {
166
+ foreach ($containers as $container) {
167
+ if ($container instanceof ParentAwareContainerInterface) {
168
+ $container->setParentContainer($this);
169
+ }
170
+ }
171
+ ...
172
+ }
173
+ }
174
+
175
+ ```
176
+
177
+ **Cons:**
178
+
179
+ Cons have been extensively discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-51721777).
180
+ Basically, forcing a setter into an interface is a bad idea. Setters are similar to constructor arguments,
181
+ and it's a bad idea to standardize a constructor: how the delegate container is configured into a container is an implementation detail. This outweights the benefits of the interface.
182
+
183
+ ### 4.4 Alternative: no exception case for delegate lookups
184
+
185
+ Originally, the proposed wording for delegate lookup calls was:
186
+
187
+ > Important! The lookup MUST be performed on the delegate container **only**, not on the container itself.
188
+
189
+ This was later replaced by:
190
+
191
+ > Important! By default, the lookup SHOULD be performed on the delegate container **only**, not on the container itself.
192
+ >
193
+ > It is however allowed for containers to provide exception cases for special entries, and a way to lookup
194
+ > into the same container (or another container) instead of the delegate container.
195
+
196
+ Exception cases have been allowed to avoid breaking dependencies with some services that must be provided
197
+ by the container (on @njasm proposal). This was proposed here: https://github.com/container-interop/container-interop/pull/20#issuecomment-56597235
198
+
199
+ ### 4.5 Alternative: having one of the containers act as the composite container
200
+
201
+ In real-life scenarios, we usually have a big framework (Symfony 2, Zend Framework 2, etc...) and we want to
202
+ add another DI container to this container. Most of the time, the "big" framework will be responsible for
203
+ creating the controller's instances, using it's own DI container. Until *container-interop* is fully adopted,
204
+ the "big" framework will not be aware of the existence of a composite container that it should use instead
205
+ of its own container.
206
+
207
+ For this real-life use cases, @mnapoli and @moufmouf proposed to extend the "big" framework's DI container
208
+ to make it act as a composite container.
209
+
210
+ This has been discussed [here](https://github.com/container-interop/container-interop/pull/8#issuecomment-40367194)
211
+ and [here](http://mouf-php.com/container-interop-whats-next#solution4).
212
+
213
+ This was implemented in Symfony 2 using:
214
+
215
+ - [interop.symfony.di](https://github.com/thecodingmachine/interop.symfony.di/tree/v0.1.0)
216
+ - [framework interop](https://github.com/mnapoli/framework-interop/)
217
+
218
+ This was implemented in Silex using:
219
+
220
+ - [interop.silex.di](https://github.com/thecodingmachine/interop.silex.di)
221
+
222
+ Having a container act as the composite container is not part of the delegate lookup standard because it is
223
+ simply a temporary design pattern used to make existing frameworks that do not support yet ContainerInterop
224
+ play nice with other DI containers.
225
+
226
+
227
+ 5. Implementations
228
+ ------------------
229
+
230
+ The following projects already implement the delegate lookup feature:
231
+
232
+ - [Mouf](http://mouf-php.com), through the [`setDelegateLookupContainer` method](https://github.com/thecodingmachine/mouf/blob/2.0/src/Mouf/MoufManager.php#L2120)
233
+ - [PHP-DI](http://php-di.org/), through the [`$wrapperContainer` parameter of the constructor](https://github.com/mnapoli/PHP-DI/blob/master/src/DI/Container.php#L72)
234
+ - [pimple-interop](https://github.com/moufmouf/pimple-interop), through the [`$container` parameter of the constructor](https://github.com/moufmouf/pimple-interop/blob/master/src/Interop/Container/Pimple/PimpleInterop.php#L62)
235
+
236
+ 6. People
237
+ ---------
238
+
239
+ Are listed here all people that contributed in the discussions, by alphabetical order:
240
+
241
+ - [Alexandru Pătrănescu](https://github.com/drealecs)
242
+ - [Ben Peachey](https://github.com/potherca)
243
+ - [David Négrier](https://github.com/moufmouf)
244
+ - [Jeremy Lindblom](https://github.com/jeremeamia)
245
+ - [Marco Pivetta](https://github.com/Ocramius)
246
+ - [Matthieu Napoli](https://github.com/mnapoli)
247
+ - [Nelson J Morais](https://github.com/njasm)
248
+ - [Phil Sturgeon](https://github.com/philsturgeon)
249
+ - [Stephan Hochdörfer](https://github.com/shochdoerfer)
250
+
251
+ 7. Relevant Links
252
+ -----------------
253
+
254
+ _**Note:** Order descending chronologically._
255
+
256
+ - [Pull request on the delegate lookup feature](https://github.com/container-interop/container-interop/pull/20)
257
+ - [Pull request on the interface idea](https://github.com/container-interop/container-interop/pull/8)
258
+ - [Original article exposing the delegate lookup idea along many others](http://mouf-php.com/container-interop-whats-next)
259
+
vendor/container-interop/container-interop/docs/Delegate-lookup.md ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Delegate lookup feature
2
+ =======================
3
+
4
+ This document describes a standard for dependency injection containers.
5
+
6
+ The goal set by the *delegate lookup* feature is to allow several containers to share entries.
7
+ Containers implementing this feature can perform dependency lookups in other containers.
8
+
9
+ Containers implementing this feature will offer a greater lever of interoperability
10
+ with other containers. Implementation of this feature is therefore RECOMMENDED.
11
+
12
+ The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD",
13
+ "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be
14
+ interpreted as described in [RFC 2119][].
15
+
16
+ The word `implementor` in this document is to be interpreted as someone
17
+ implementing the delegate lookup feature in a dependency injection-related library or framework.
18
+ Users of dependency injections containers (DIC) are refered to as `user`.
19
+
20
+ [RFC 2119]: http://tools.ietf.org/html/rfc2119
21
+
22
+ 1. Vocabulary
23
+ -------------
24
+
25
+ In a dependency injection container, the container is used to fetch entries.
26
+ Entries can have dependencies on other entries. Usually, these other entries are fetched by the container.
27
+
28
+ The *delegate lookup* feature is the ability for a container to fetch dependencies in
29
+ another container. In the rest of the document, the word "container" will reference the container
30
+ implemented by the implementor. The word "delegate container" will reference the container we are
31
+ fetching the dependencies from.
32
+
33
+ 2. Specification
34
+ ----------------
35
+
36
+ A container implementing the *delegate lookup* feature:
37
+
38
+ - MUST implement the [`ContainerInterface`](ContainerInterface.md)
39
+ - MUST provide a way to register a delegate container (using a constructor parameter, or a setter,
40
+ or any possible way). The delegate container MUST implement the [`ContainerInterface`](ContainerInterface.md).
41
+
42
+ When a container is configured to use a delegate container for dependencies:
43
+
44
+ - Calls to the `get` method should only return an entry if the entry is part of the container.
45
+ If the entry is not part of the container, an exception should be thrown
46
+ (as requested by the [`ContainerInterface`](ContainerInterface.md)).
47
+ - Calls to the `has` method should only return `true` if the entry is part of the container.
48
+ If the entry is not part of the container, `false` should be returned.
49
+ - If the fetched entry has dependencies, **instead** of performing
50
+ the dependency lookup in the container, the lookup is performed on the *delegate container*.
51
+
52
+ Important: By default, the dependency lookups SHOULD be performed on the delegate container **only**, not on the container itself.
53
+
54
+ It is however allowed for containers to provide exception cases for special entries, and a way to lookup
55
+ into the same container (or another container) instead of the delegate container.
56
+
57
+ 3. Package / Interface
58
+ ----------------------
59
+
60
+ This feature is not tied to any code, interface or package.
vendor/container-interop/container-interop/docs/images/interoperating_containers.png ADDED
Binary file
vendor/container-interop/container-interop/docs/images/priority.png ADDED
Binary file
vendor/container-interop/container-interop/docs/images/side_by_side_containers.png ADDED
Binary file
vendor/container-interop/container-interop/src/Interop/Container/ContainerInterface.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Interop\Container;
7
+
8
+ use Interop\Container\Exception\ContainerException;
9
+ use Interop\Container\Exception\NotFoundException;
10
+
11
+ /**
12
+ * Describes the interface of a container that exposes methods to read its entries.
13
+ */
14
+ interface ContainerInterface
15
+ {
16
+ /**
17
+ * Finds an entry of the container by its identifier and returns it.
18
+ *
19
+ * @param string $id Identifier of the entry to look for.
20
+ *
21
+ * @throws NotFoundException No entry was found for this identifier.
22
+ * @throws ContainerException Error while retrieving the entry.
23
+ *
24
+ * @return mixed Entry.
25
+ */
26
+ public function get($id);
27
+
28
+ /**
29
+ * Returns true if the container can return an entry for the given identifier.
30
+ * Returns false otherwise.
31
+ *
32
+ * @param string $id Identifier of the entry to look for.
33
+ *
34
+ * @return boolean
35
+ */
36
+ public function has($id);
37
+ }
vendor/container-interop/container-interop/src/Interop/Container/Exception/ContainerException.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Interop\Container\Exception;
7
+
8
+ /**
9
+ * Base interface representing a generic exception in a container.
10
+ */
11
+ interface ContainerException
12
+ {
13
+ }
vendor/container-interop/container-interop/src/Interop/Container/Exception/NotFoundException.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * @license http://www.opensource.org/licenses/mit-license.php MIT (see the LICENSE file)
4
+ */
5
+
6
+ namespace Interop\Container\Exception;
7
+
8
+ /**
9
+ * No entry was found in the container.
10
+ */
11
+ interface NotFoundException extends ContainerException
12
+ {
13
+ }
vendor/container-interop/service-provider/README.md ADDED
@@ -0,0 +1,279 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Standard service providers
2
+
3
+ This project tries to find a solution for cross-framework modules (aka bundles) through **standard container configuration**. It is part of the [container-interop](https://github.com/container-interop/container-interop) group.
4
+
5
+ **Work in progress:** the project is currently experimental and is being tried in frameworks, containers and modules until considered viable. Until a 1.0.0 release the code in this repository is not stable. Expect changes breaking backward compatibility between minor versions (0.1.x -> 0.2.x).
6
+
7
+ [![Gitter chat](https://badges.gitter.im/container-interop/definition-interop.png)](https://gitter.im/container-interop/definition-interop)
8
+
9
+ ## Background
10
+
11
+ Three main alternatives were identified to standardize container configuration:
12
+
13
+ - standard PHP objects/interfaces representing container definitions
14
+ - standard container configuration format (e.g. XML, …)
15
+ - standard service providers
16
+
17
+ The first solution that container-interop members tried to implement was [a set of standard PHP interfaces for container definitions](https://github.com/container-interop/definition-interop). While this solution is working, it has a few limitations and it is complicated to explain, understand and use.
18
+
19
+ There were then discussions about a standard configuration format (for example in XML), which has the advantage of being slightly easier to understand and use for module developers. This work has not be formalized yet because of the amount of work needed. This approach would also suffers from a few of the limitations identified in the first approach. It would also requires the inclusion in the standard of many specific features: the standard must define many different ways for how objects can be created and dependencies injected. That makes the standard complex to define, and would force all containers (even simple ones) to support all the features.
20
+
21
+ This repository contains a proposition for **standard service providers** (service providers are PHP components that provide container entries). This approach has turned out to be simpler on many level:
22
+
23
+ - the standard is much simpler, which means it is easier to explain and understand
24
+ - it is easier to use as it relies on plain old PHP code
25
+ - it is easier to implement support in containers
26
+
27
+ ## Usage
28
+
29
+ To declare a service provider, simply implement the `ServiceProvider` interface.
30
+
31
+ ```php
32
+ use Interop\Container\ServiceProvider;
33
+
34
+ class MyServiceProvider implements ServiceProvider
35
+ {
36
+ public function getServices()
37
+ {
38
+ return [
39
+ 'my_service' => function(ContainerInterface $container, callable $getPrevious = null) {
40
+ $dependency = $container->get('my_other_service');
41
+ return new MyService($dependency);
42
+ }
43
+ ];
44
+ }
45
+ }
46
+ ```
47
+
48
+ The `getServices()` method must return a list of all container entries the service provider wishes to register:
49
+
50
+ - the key is the entry name
51
+ - the value is a callable that will return the entry, aka the **factory**
52
+
53
+ Factories have the following signature:
54
+
55
+ ```php
56
+ function(ContainerInterface $container, callable $getPrevious = null)
57
+ ```
58
+
59
+ Factories accept the following parameters:
60
+
61
+ - the container (instance of `Interop\Container\ContainerInterface`)
62
+ - a callable that returns the previous entry if overriding a previous entry, or `null` if not
63
+
64
+ The only difference between defining an entry from scratch or overriding/extending a previous entry is that the `$getPrevious` parameter will be either a `callable` or `null`. Factories are free to *use it or ignore it* if it's not `null`.
65
+
66
+ If you know you will not be using the `$container` parameter or the `$getPrevious` parameter, you can omit them:
67
+
68
+ ```php
69
+ function() {
70
+ return new MyService();
71
+ }
72
+ ```
73
+
74
+ Each factory is responsible for returning a given entry of the container. Nothing should be cached by service providers, this is the responsibility of the container.
75
+
76
+ ### Values (aka parameters)
77
+
78
+ A service provider can provide PHP objects (services) as well as any value. Simply return the value you wish from factory methods.
79
+
80
+ ### Aliases
81
+
82
+ To alias a container entry to another, you can get the aliased entry from the container and return it:
83
+
84
+ ```php
85
+ class MyServiceProvider implements ServiceProvider
86
+ {
87
+ public function getServices()
88
+ {
89
+ return [
90
+ 'my_service' => [ MyServiceProvider::class, 'createMyService' ],
91
+ 'alias' => [ MyServiceProvider::class, 'resolveAlias' ],
92
+ ];
93
+ }
94
+
95
+ // ...
96
+
97
+ public static function resolveAlias(ContainerInterface $container)
98
+ {
99
+ return $container->get('my_service');
100
+ }
101
+ }
102
+ ```
103
+
104
+ ### Entry overriding
105
+
106
+ Overriding an entry defined in another service provider is as easy as defining it again.
107
+
108
+ Module A:
109
+
110
+ ```php
111
+ class A implements ServiceProvider
112
+ {
113
+ public function getServices()
114
+ {
115
+ return [
116
+ 'foo' => [ A::class, 'getFoo' ],
117
+ ];
118
+ }
119
+
120
+ public static function getFoo()
121
+ {
122
+ return 'abc';
123
+ }
124
+ }
125
+ ```
126
+
127
+ Module B:
128
+
129
+ ```php
130
+ class B implements ServiceProvider
131
+ {
132
+ public function getServices()
133
+ {
134
+ return [
135
+ 'foo' => [ B::class, 'getFoo' ],
136
+ ];
137
+ }
138
+
139
+ public static function getFoo()
140
+ {
141
+ return 'def';
142
+ }
143
+ }
144
+ ```
145
+
146
+ If you register the service providers in the correct order in your container (A first, then B), then the entry `foo` will be `'def'` because B's definition will override A's.
147
+
148
+ ### Entry extension
149
+
150
+ Extending an entry before it is returned by the container is very similar to overriding it.
151
+
152
+ Module A:
153
+
154
+ ```php
155
+ class A implements ServiceProvider
156
+ {
157
+ public function getServices()
158
+ {
159
+ return [
160
+ 'logger' => [ A::class, 'getLogger' ],
161
+ ];
162
+ }
163
+
164
+ public static function getLogger()
165
+ {
166
+ return new Logger;
167
+ }
168
+ }
169
+ ```
170
+
171
+ Module B:
172
+
173
+ ```php
174
+ class B implements ServiceProvider
175
+ {
176
+ public function getServices()
177
+ {
178
+ return [
179
+ 'logger' => [ B::class, 'getLogger' ],
180
+ ];
181
+ }
182
+
183
+ public static function getLogger(ContainerInterface $container, callable $getPrevious = null)
184
+ {
185
+ // Get the previous entry
186
+ $previous = $getPrevious();
187
+
188
+ // Register a new log handler
189
+ $previous->addHandler(new SyslogHandler());
190
+
191
+ // Return the object that we modified
192
+ return $previous;
193
+ }
194
+ }
195
+ ```
196
+
197
+ If you register the service providers in the correct order in your container (A first, then B), the logger will be first created by `A` then a new handler will be registered on it by `B`.
198
+
199
+ ## Compatible projects
200
+ ### Projects consuming *service providers*
201
+
202
+ - [Laravel service provider bridge](https://github.com/thecodingmachine/laravel-universal-service-provider/): Use container-interop's service-providers into any [Laravel](http://laravel.com/) application.
203
+ - [Simplex](https://github.com/mnapoli/simplex): A [Pimple 3](https://github.com/silexphp/Pimple) fork with full [container-interop](https://github.com/container-interop/container-interop) compliance and cross-framework service-provider support.
204
+ - [Service provider bridge bundle](https://github.com/thecodingmachine/service-provider-bridge-bundle): Use container-interop's service-providers into a Symfony container.
205
+ - [Yaco](https://github.com/thecodingmachine/yaco): A compiler that generates container-interop compliant containers. Yaco can consume service-providers.
206
+
207
+ ### Packages providing *service providers*
208
+
209
+ - [DBAL Module](https://github.com/thecodingmachine/dbal-universal-module): A module integrating [Doctrine DBAL](http://www.doctrine-project.org/projects/dbal.html) in an application using a service provider.
210
+ - [Glide Module](https://github.com/mnapoli/glide-module): A module integrating Glide in an application using a service provider.
211
+ - [Stratigility Module](https://github.com/thecodingmachine/stratigility-harmony): A service provider for the Stratigility PSR-7 middleware.
212
+ - [Whoops PSR-7 Middleware Module](https://github.com/thecodingmachine/whoops-middleware-universal-module): a service provider for the [Whoops](https://filp.github.io/whoops/) [PSR-7 middleware](https://github.com/franzliedke/whoops-middleware).
213
+
214
+ ## Best practices
215
+
216
+ ### Managing configuration
217
+
218
+ The service created by a factory should only depend on the input parameters of the factory (`$container` and `$getPrevious`).
219
+ If the factory needs to fetch parameters, those should be fetched from the container directly.
220
+
221
+ ```php
222
+ class MyServiceProvider implements ServiceProvider
223
+ {
224
+ public function getServices()
225
+ {
226
+ return [
227
+ 'logger' => [ MyServiceProvider::class, 'createLogger' ],
228
+ ];
229
+ }
230
+
231
+ public static function createLogger(ContainerInterface $container)
232
+ {
233
+ // The path to the log file is fetched from the container, not from the service provider state.
234
+ return new FileLogger($this->container->get('logFilePath'));
235
+ }
236
+ }
237
+ ```
238
+
239
+ ## FAQ
240
+
241
+ ### Why inject a callable instead of the previous entry directly in factories?
242
+
243
+ In a first version, service provider factories received the previous entry directly as a second parameter:
244
+
245
+ ```php
246
+ public static function getMyService(ContainerInterface $container, $previous = null)
247
+ {
248
+ // ...
249
+ }
250
+ ```
251
+
252
+ That caused 2 problems:
253
+
254
+ - it was inefficient since it caused the container to resolve all the previous entries that might exist, even when they were overridden by another service provider
255
+ - when the entry name was a class name, autowiring containers would try to resolve the previous entry using autowiring: when some parameters could not be resolved by the container, there would be exceptions
256
+
257
+ By injecting a callable that returns the previous entry, that makes it *lazily loaded*. That is both more efficient and avoids most problems with autowiring containers.
258
+
259
+ For a more detailed explanation you can read the full discussion in the [issue #9](https://github.com/container-interop/service-provider/issues/9).
260
+
261
+ ### Why does the service provider not configure the container instead of returning entries?
262
+
263
+ Service providers usually take a container and configure it (e.g. in Pimple). The problem is that it requires the container to expose methods for configuration. That's an impossible requirement in a standard because all containers have a different API for configuration and they could never be made to implement the same.
264
+
265
+ These service providers provide factories for each container entry it provides. They do not require configuration methods on containers, so they can be made compatible with all/most of them. Each container entry is, in the end, just a callable to invoke, which most containers can do.
266
+
267
+ ## Puli integration
268
+
269
+ The Puli integration is completely optional and not required to use this standard. It is only here to facilitate usage with Puli.
270
+
271
+ This package provides a [Puli *binding type*](http://docs.puli.io/en/latest/discovery/getting-started.html): `container-interop/service-provider`. Modules using Puli and implementing this standard can register service providers (fully qualified class names) through this binding type.
272
+
273
+ This way, frameworks or applications based on Puli can discover service providers automatically.
274
+
275
+ To register your service provider, simply use Puli's `bind` command:
276
+
277
+ ```sh
278
+ puli bind --class Acme\\Foo\\MyServiceProvider container-interop/service-provider
279
+ ```
vendor/container-interop/service-provider/composer.json ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "container-interop/service-provider",
3
+ "type": "library",
4
+ "description": "Promoting container interoperability through standard service providers",
5
+ "homepage": "https://github.com/container-interop/service-provider",
6
+ "license": "MIT",
7
+ "autoload": {
8
+ "psr-4": {
9
+ "Interop\\Container\\": "src/"
10
+ }
11
+ },
12
+ "require": {
13
+ "container-interop/container-interop": "^1.1"
14
+ }
15
+ }
vendor/container-interop/service-provider/puli.json ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
1
+ {
2
+ "version": "1.0",
3
+ "binding-types": {
4
+ "container-interop/service-provider": {}
5
+ }
6
+ }
vendor/container-interop/service-provider/src/ServiceProvider.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Interop\Container;
4
+
5
+ /**
6
+ * A service provider provides entries to a container.
7
+ */
8
+ interface ServiceProvider
9
+ {
10
+ /**
11
+ * Returns a list of all container entries registered by this service provider.
12
+ *
13
+ * - the key is the entry name
14
+ * - the value is a callable that will return the entry, aka the **factory**
15
+ *
16
+ * Factories have the following signature:
17
+ * function(ContainerInterface $container, callable $getPrevious = null)
18
+ *
19
+ * About factories parameters:
20
+ *
21
+ * - the container (instance of `Interop\Container\ContainerInterface`)
22
+ * - a callable that returns the previous entry if overriding a previous entry, or `null` if not
23
+ *
24
+ * @return callable[]
25
+ */
26
+ public function getServices();
27
+ }
vendor/dhii/di-abstract/.codeclimate.yml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - php
8
+ fixme:
9
+ enabled: true
10
+ phpmd:
11
+ enabled: true
12
+ config:
13
+ rulesets: "phpmd.xml"
14
+ ratings:
15
+ paths:
16
+ - "**.inc"
17
+ - "**.php"
18
+ exclude_paths:
19
+ - test/
vendor/dhii/di-abstract/.php_cs ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
3
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
4
+ $fixers = $config->getFixers();
5
+ $toRemove = array();
6
+ foreach ($toRemove as $_fixer) {
7
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
8
+ continue;
9
+ }
10
+
11
+ unset($fixers[$removeIndex]);
12
+ }
13
+ $toAdd = array();
14
+ foreach ($toAdd as $_fixer) {
15
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
16
+ continue;
17
+ }
18
+
19
+ $fixers[] = $_fixer;
20
+ }
21
+ $config->fixers($fixers);
22
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
23
+ return $config;
vendor/dhii/di-abstract/.travis.yml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+ php:
3
+ - '5.3'
4
+ - '5.4'
5
+ - '5.5'
6
+ - '5.6'
7
+ - '7.0'
8
+ - '7.1'
9
+ - nightly
10
+
11
+ before_script:
12
+ - composer update
13
+
14
+ script:
15
+ - vendor/bin/phpunit
16
+
17
+ after_script:
18
+ - vendor/bin/test-reporter --coverage-report="test/coverage/clover.xml"
vendor/dhii/di-abstract/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Change log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [0.1] - 2017-02-02
8
+ Initial release, containing the abstract implementations.
9
+
10
+ ### Added
11
+ - Abstract implementations;
12
+ - Functional tests.
vendor/dhii/di-abstract/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2016-2017 Dhii
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/dhii/di-abstract/README.md ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Dhii - DI Abstract ##
2
+ [![Build Status](https://travis-ci.org/Dhii/di-abstract.svg?branch=master)](https://travis-ci.org/Dhii/di-abstract)
3
+ [![Code Climate](https://codeclimate.com/github/Dhii/di-abstract/badges/gpa.svg)](https://codeclimate.com/github/Dhii/di-abstract)
4
+ [![Test Coverage](https://codeclimate.com/github/Dhii/di-abstract/badges/coverage.svg)](https://codeclimate.com/github/Dhii/di-abstract/coverage)
5
+
6
+ Abstract, standards-compliant, re-usable, tested implementation agnostic of concrete cases.
7
+ Use functionality in this package to create DI container implementations.
8
+
9
+ The packages adheres to the [SemVer][] specification, and there will be full backward compatibility between minor versions.
10
+ Additionally, it follows the rule of the [caret operator][], i.e. there will be full backward compatibility between patch pre-release versions.
11
+
12
+ [SemVer]: http://semver.org/
13
+ [caret operator]: https://getcomposer.org/doc/articles/versions.md#caret
vendor/dhii/di-abstract/composer.json ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/di-abstract",
3
+ "description": "Base abstract classes for DI container implementations",
4
+ "type": "library",
5
+ "license": "MIT",
6
+ "authors": [
7
+ {
8
+ "name": "Dhii Team",
9
+ "email": "development@dhii.co"
10
+ }
11
+ ],
12
+ "minimum-stability": "dev",
13
+ "require": {
14
+ "php": "^5.3 | ^7.0",
15
+ "dhii/di-interface": "^0.1",
16
+ "container-interop/container-interop": "^1.1",
17
+ "container-interop/service-provider": "^0.3"
18
+ },
19
+ "require-dev": {
20
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
21
+ "phpunit/phpunit": "^4.8",
22
+ "ptrofimov/xpmock": "^1.1",
23
+ "codeclimate/php-test-reporter": "<=0.3.2"
24
+ },
25
+ "autoload": {
26
+ "psr-4": {
27
+ "Dhii\\Di\\": "src/"
28
+ }
29
+ },
30
+ "autoload-dev": {
31
+ "psr-4": {
32
+ "Dhii\\Di\\Stub\\": "test/stub/"
33
+ }
34
+ }
35
+ }
vendor/dhii/di-abstract/composer.lock ADDED
@@ -0,0 +1,1963 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "hash": "86ce9fb180a039b55bf36eea5ce93fb0",
8
+ "content-hash": "697579d6a2c04b47639316c1716fcd2f",
9
+ "packages": [
10
+ {
11
+ "name": "container-interop/container-interop",
12
+ "version": "1.1.0",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/container-interop/container-interop.git",
16
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
21
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
22
+ "shasum": ""
23
+ },
24
+ "type": "library",
25
+ "autoload": {
26
+ "psr-4": {
27
+ "Interop\\Container\\": "src/Interop/Container/"
28
+ }
29
+ },
30
+ "notification-url": "https://packagist.org/downloads/",
31
+ "license": [
32
+ "MIT"
33
+ ],
34
+ "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
35
+ "time": "2014-12-30 15:22:37"
36
+ },
37
+ {
38
+ "name": "container-interop/service-provider",
39
+ "version": "v0.3.0",
40
+ "source": {
41
+ "type": "git",
42
+ "url": "https://github.com/container-interop/service-provider.git",
43
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf"
44
+ },
45
+ "dist": {
46
+ "type": "zip",
47
+ "url": "https://api.github.com/repos/container-interop/service-provider/zipball/5cb38893b836edb00d3e1ace26c20ee1d29957cf",
48
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf",
49
+ "shasum": ""
50
+ },
51
+ "require": {
52
+ "container-interop/container-interop": "^1.1"
53
+ },
54
+ "type": "library",
55
+ "autoload": {
56
+ "psr-4": {
57
+ "Interop\\Container\\": "src/"
58
+ }
59
+ },
60
+ "notification-url": "https://packagist.org/downloads/",
61
+ "license": [
62
+ "MIT"
63
+ ],
64
+ "description": "Promoting container interoperability through standard service providers",
65
+ "homepage": "https://github.com/container-interop/service-provider",
66
+ "time": "2016-05-16 07:42:22"
67
+ },
68
+ {
69
+ "name": "dhii/di-interface",
70
+ "version": "v0.1",
71
+ "source": {
72
+ "type": "git",
73
+ "url": "https://github.com/Dhii/di-interface.git",
74
+ "reference": "0320846a577d68b761e29acd5d4db40d88cc4f98"
75
+ },
76
+ "dist": {
77
+ "type": "zip",
78
+ "url": "https://api.github.com/repos/Dhii/di-interface/zipball/0320846a577d68b761e29acd5d4db40d88cc4f98",
79
+ "reference": "0320846a577d68b761e29acd5d4db40d88cc4f98",
80
+ "shasum": ""
81
+ },
82
+ "require": {
83
+ "container-interop/container-interop": "^1.1",
84
+ "container-interop/service-provider": "^0.3",
85
+ "php": "^5.3 | ^7.0"
86
+ },
87
+ "require-dev": {
88
+ "codeclimate/php-test-reporter": "<=0.3.2",
89
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
90
+ "phpunit/phpunit": "^4.8",
91
+ "ptrofimov/xpmock": "^1.1"
92
+ },
93
+ "type": "library",
94
+ "autoload": {
95
+ "psr-4": {
96
+ "Dhii\\Di\\": "src/"
97
+ }
98
+ },
99
+ "notification-url": "https://packagist.org/downloads/",
100
+ "license": [
101
+ "MIT"
102
+ ],
103
+ "authors": [
104
+ {
105
+ "name": "Dhii Team",
106
+ "email": "development@dhii.co"
107
+ }
108
+ ],
109
+ "description": "Interfaces for DI container implementations",
110
+ "time": "2017-02-02 13:12:09"
111
+ }
112
+ ],
113
+ "packages-dev": [
114
+ {
115
+ "name": "codeclimate/php-test-reporter",
116
+ "version": "v0.3.2",
117
+ "source": {
118
+ "type": "git",
119
+ "url": "https://github.com/codeclimate/php-test-reporter.git",
120
+ "reference": "3a2d3ebdc1df5acf372458c15041af240a6fc016"
121
+ },
122
+ "dist": {
123
+ "type": "zip",
124
+ "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/3a2d3ebdc1df5acf372458c15041af240a6fc016",
125
+ "reference": "3a2d3ebdc1df5acf372458c15041af240a6fc016",
126
+ "shasum": ""
127
+ },
128
+ "require": {
129
+ "ext-curl": "*",
130
+ "php": ">=5.3",
131
+ "satooshi/php-coveralls": "1.0.*",
132
+ "symfony/console": ">=2.0"
133
+ },
134
+ "require-dev": {
135
+ "ext-xdebug": "*",
136
+ "phpunit/phpunit": "3.7.*@stable"
137
+ },
138
+ "bin": [
139
+ "composer/bin/test-reporter"
140
+ ],
141
+ "type": "library",
142
+ "extra": {
143
+ "branch-alias": {
144
+ "dev-master": "0.3.x-dev"
145
+ }
146
+ },
147
+ "autoload": {
148
+ "psr-0": {
149
+ "CodeClimate\\Component": "src/",
150
+ "CodeClimate\\Bundle": "src/"
151
+ }
152
+ },
153
+ "notification-url": "https://packagist.org/downloads/",
154
+ "license": [
155
+ "MIT"
156
+ ],
157
+ "authors": [
158
+ {
159
+ "name": "Code Climate",
160
+ "email": "hello@codeclimate.com",
161
+ "homepage": "https://codeclimate.com"
162
+ }
163
+ ],
164
+ "description": "PHP client for reporting test coverage to Code Climate",
165
+ "homepage": "https://github.com/codeclimate/php-test-reporter",
166
+ "keywords": [
167
+ "codeclimate",
168
+ "coverage"
169
+ ],
170
+ "time": "2016-04-19 16:54:33"
171
+ },
172
+ {
173
+ "name": "dhii/php-cs-fixer-config",
174
+ "version": "dev-php-5.3",
175
+ "source": {
176
+ "type": "git",
177
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
178
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
179
+ },
180
+ "dist": {
181
+ "type": "zip",
182
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
183
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
184
+ "shasum": ""
185
+ },
186
+ "require": {
187
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
188
+ "php": "^5.3 | ^7.0"
189
+ },
190
+ "require-dev": {
191
+ "phpunit/phpunit": "^4.8"
192
+ },
193
+ "type": "library",
194
+ "autoload": {
195
+ "psr-4": {
196
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
197
+ }
198
+ },
199
+ "notification-url": "https://packagist.org/downloads/",
200
+ "license": [
201
+ "MIT"
202
+ ],
203
+ "authors": [
204
+ {
205
+ "name": "Dhii Team",
206
+ "email": "development@dhii.co"
207
+ }
208
+ ],
209
+ "description": "A default PHP CS Fixer config implementation",
210
+ "time": "2016-09-03 14:45:03"
211
+ },
212
+ {
213
+ "name": "doctrine/instantiator",
214
+ "version": "dev-master",
215
+ "source": {
216
+ "type": "git",
217
+ "url": "https://github.com/doctrine/instantiator.git",
218
+ "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac"
219
+ },
220
+ "dist": {
221
+ "type": "zip",
222
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/68099b02b60bbf3b088ff5cb67bf506770ef9cac",
223
+ "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac",
224
+ "shasum": ""
225
+ },
226
+ "require": {
227
+ "php": ">=5.3,<8.0-DEV"
228
+ },
229
+ "require-dev": {
230
+ "athletic/athletic": "~0.1.8",
231
+ "ext-pdo": "*",
232
+ "ext-phar": "*",
233
+ "phpunit/phpunit": "~4.0",
234
+ "squizlabs/php_codesniffer": "~2.0"
235
+ },
236
+ "type": "library",
237
+ "extra": {
238
+ "branch-alias": {
239
+ "dev-master": "1.0.x-dev"
240
+ }
241
+ },
242
+ "autoload": {
243
+ "psr-4": {
244
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
245
+ }
246
+ },
247
+ "notification-url": "https://packagist.org/downloads/",
248
+ "license": [
249
+ "MIT"
250
+ ],
251
+ "authors": [
252
+ {
253
+ "name": "Marco Pivetta",
254
+ "email": "ocramius@gmail.com",
255
+ "homepage": "http://ocramius.github.com/"
256
+ }
257
+ ],
258
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
259
+ "homepage": "https://github.com/doctrine/instantiator",
260
+ "keywords": [
261
+ "constructor",
262
+ "instantiate"
263
+ ],
264
+ "time": "2017-01-23 09:23:06"
265
+ },
266
+ {
267
+ "name": "friendsofphp/php-cs-fixer",
268
+ "version": "v1.11.8",
269
+ "source": {
270
+ "type": "git",
271
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
272
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
273
+ },
274
+ "dist": {
275
+ "type": "zip",
276
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
277
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
278
+ "shasum": ""
279
+ },
280
+ "require": {
281
+ "ext-tokenizer": "*",
282
+ "php": ">=5.3.6",
283
+ "sebastian/diff": "~1.1",
284
+ "symfony/console": "~2.3|~3.0",
285
+ "symfony/event-dispatcher": "~2.1|~3.0",
286
+ "symfony/filesystem": "~2.1|~3.0",
287
+ "symfony/finder": "~2.1|~3.0",
288
+ "symfony/process": "~2.3|~3.0",
289
+ "symfony/stopwatch": "~2.5|~3.0"
290
+ },
291
+ "conflict": {
292
+ "hhvm": "<3.9"
293
+ },
294
+ "require-dev": {
295
+ "phpunit/phpunit": "^4.5|^5",
296
+ "satooshi/php-coveralls": "^0.7.1"
297
+ },
298
+ "bin": [
299
+ "php-cs-fixer"
300
+ ],
301
+ "type": "application",
302
+ "autoload": {
303
+ "psr-4": {
304
+ "Symfony\\CS\\": "Symfony/CS/"
305
+ }
306
+ },
307
+ "notification-url": "https://packagist.org/downloads/",
308
+ "license": [
309
+ "MIT"
310
+ ],
311
+ "authors": [
312
+ {
313
+ "name": "Dariusz Rumiński",
314
+ "email": "dariusz.ruminski@gmail.com"
315
+ },
316
+ {
317
+ "name": "Fabien Potencier",
318
+ "email": "fabien@symfony.com"
319
+ }
320
+ ],
321
+ "description": "A tool to automatically fix PHP code style",
322
+ "time": "2016-08-16 23:31:05"
323
+ },
324
+ {
325
+ "name": "guzzle/guzzle",
326
+ "version": "dev-master",
327
+ "source": {
328
+ "type": "git",
329
+ "url": "https://github.com/guzzle/guzzle3.git",
330
+ "reference": "f7778ed85e3db90009d79725afd6c3a82dab32fe"
331
+ },
332
+ "dist": {
333
+ "type": "zip",
334
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/f7778ed85e3db90009d79725afd6c3a82dab32fe",
335
+ "reference": "f7778ed85e3db90009d79725afd6c3a82dab32fe",
336
+ "shasum": ""
337
+ },
338
+ "require": {
339
+ "ext-curl": "*",
340
+ "php": ">=5.3.3",
341
+ "symfony/event-dispatcher": "~2.1"
342
+ },
343
+ "replace": {
344
+ "guzzle/batch": "self.version",
345
+ "guzzle/cache": "self.version",
346
+ "guzzle/common": "self.version",
347
+ "guzzle/http": "self.version",
348
+ "guzzle/inflection": "self.version",
349
+ "guzzle/iterator": "self.version",
350
+ "guzzle/log": "self.version",
351
+ "guzzle/parser": "self.version",
352
+ "guzzle/plugin": "self.version",
353
+ "guzzle/plugin-async": "self.version",
354
+ "guzzle/plugin-backoff": "self.version",
355
+ "guzzle/plugin-cache": "self.version",
356
+ "guzzle/plugin-cookie": "self.version",
357
+ "guzzle/plugin-curlauth": "self.version",
358
+ "guzzle/plugin-error-response": "self.version",
359
+ "guzzle/plugin-history": "self.version",
360
+ "guzzle/plugin-log": "self.version",
361
+ "guzzle/plugin-md5": "self.version",
362
+ "guzzle/plugin-mock": "self.version",
363
+ "guzzle/plugin-oauth": "self.version",
364
+ "guzzle/service": "self.version",
365
+ "guzzle/stream": "self.version"
366
+ },
367
+ "require-dev": {
368
+ "doctrine/cache": "~1.3",
369
+ "monolog/monolog": "~1.0",
370
+ "phpunit/phpunit": "3.7.*",
371
+ "psr/log": "~1.0",
372
+ "symfony/class-loader": "~2.1",
373
+ "zendframework/zend-cache": "2.*,<2.3",
374
+ "zendframework/zend-log": "2.*,<2.3"
375
+ },
376
+ "suggest": {
377
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
378
+ },
379
+ "type": "library",
380
+ "extra": {
381
+ "branch-alias": {
382
+ "dev-master": "3.9-dev"
383
+ }
384
+ },
385
+ "autoload": {
386
+ "psr-0": {
387
+ "Guzzle": "src/",
388
+ "Guzzle\\Tests": "tests/"
389
+ }
390
+ },
391
+ "notification-url": "https://packagist.org/downloads/",
392
+ "license": [
393
+ "MIT"
394
+ ],
395
+ "authors": [
396
+ {
397
+ "name": "Michael Dowling",
398
+ "email": "mtdowling@gmail.com",
399
+ "homepage": "https://github.com/mtdowling"
400
+ },
401
+ {
402
+ "name": "Guzzle Community",
403
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
404
+ }
405
+ ],
406
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
407
+ "homepage": "http://guzzlephp.org/",
408
+ "keywords": [
409
+ "client",
410
+ "curl",
411
+ "framework",
412
+ "http",
413
+ "http client",
414
+ "rest",
415
+ "web service"
416
+ ],
417
+ "abandoned": "guzzlehttp/guzzle",
418
+ "time": "2016-10-26 18:22:07"
419
+ },
420
+ {
421
+ "name": "phpdocumentor/reflection-docblock",
422
+ "version": "2.0.4",
423
+ "source": {
424
+ "type": "git",
425
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
426
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
427
+ },
428
+ "dist": {
429
+ "type": "zip",
430
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
431
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
432
+ "shasum": ""
433
+ },
434
+ "require": {
435
+ "php": ">=5.3.3"
436
+ },
437
+ "require-dev": {
438
+ "phpunit/phpunit": "~4.0"
439
+ },
440
+ "suggest": {
441
+ "dflydev/markdown": "~1.0",
442
+ "erusev/parsedown": "~1.0"
443
+ },
444
+ "type": "library",
445
+ "extra": {
446
+ "branch-alias": {
447
+ "dev-master": "2.0.x-dev"
448
+ }
449
+ },
450
+ "autoload": {
451
+ "psr-0": {
452
+ "phpDocumentor": [
453
+ "src/"
454
+ ]
455
+ }
456
+ },
457
+ "notification-url": "https://packagist.org/downloads/",
458
+ "license": [
459
+ "MIT"
460
+ ],
461
+ "authors": [
462
+ {
463
+ "name": "Mike van Riel",
464
+ "email": "mike.vanriel@naenius.com"
465
+ }
466
+ ],
467
+ "time": "2015-02-03 12:10:50"
468
+ },
469
+ {
470
+ "name": "phpspec/prophecy",
471
+ "version": "dev-master",
472
+ "source": {
473
+ "type": "git",
474
+ "url": "https://github.com/phpspec/prophecy.git",
475
+ "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
476
+ },
477
+ "dist": {
478
+ "type": "zip",
479
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
480
+ "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
481
+ "shasum": ""
482
+ },
483
+ "require": {
484
+ "doctrine/instantiator": "^1.0.2",
485
+ "php": "^5.3|^7.0",
486
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
487
+ "sebastian/comparator": "^1.1",
488
+ "sebastian/recursion-context": "^1.0|^2.0"
489
+ },
490
+ "require-dev": {
491
+ "phpspec/phpspec": "^2.0",
492
+ "phpunit/phpunit": "^4.8 || ^5.6.5"
493
+ },
494
+ "type": "library",
495
+ "extra": {
496
+ "branch-alias": {
497
+ "dev-master": "1.6.x-dev"
498
+ }
499
+ },
500
+ "autoload": {
501
+ "psr-0": {
502
+ "Prophecy\\": "src/"
503
+ }
504
+ },
505
+ "notification-url": "https://packagist.org/downloads/",
506
+ "license": [
507
+ "MIT"
508
+ ],
509
+ "authors": [
510
+ {
511
+ "name": "Konstantin Kudryashov",
512
+ "email": "ever.zet@gmail.com",
513
+ "homepage": "http://everzet.com"
514
+ },
515
+ {
516
+ "name": "Marcello Duarte",
517
+ "email": "marcello.duarte@gmail.com"
518
+ }
519
+ ],
520
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
521
+ "homepage": "https://github.com/phpspec/prophecy",
522
+ "keywords": [
523
+ "Double",
524
+ "Dummy",
525
+ "fake",
526
+ "mock",
527
+ "spy",
528
+ "stub"
529
+ ],
530
+ "time": "2016-11-21 14:58:47"
531
+ },
532
+ {
533
+ "name": "phpunit/php-code-coverage",
534
+ "version": "2.2.x-dev",
535
+ "source": {
536
+ "type": "git",
537
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
538
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
539
+ },
540
+ "dist": {
541
+ "type": "zip",
542
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
543
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
544
+ "shasum": ""
545
+ },
546
+ "require": {
547
+ "php": ">=5.3.3",
548
+ "phpunit/php-file-iterator": "~1.3",
549
+ "phpunit/php-text-template": "~1.2",
550
+ "phpunit/php-token-stream": "~1.3",
551
+ "sebastian/environment": "^1.3.2",
552
+ "sebastian/version": "~1.0"
553
+ },
554
+ "require-dev": {
555
+ "ext-xdebug": ">=2.1.4",
556
+ "phpunit/phpunit": "~4"
557
+ },
558
+ "suggest": {
559
+ "ext-dom": "*",
560
+ "ext-xdebug": ">=2.2.1",
561
+ "ext-xmlwriter": "*"
562
+ },
563
+ "type": "library",
564
+ "extra": {
565
+ "branch-alias": {
566
+ "dev-master": "2.2.x-dev"
567
+ }
568
+ },
569
+ "autoload": {
570
+ "classmap": [
571
+ "src/"
572
+ ]
573
+ },
574
+ "notification-url": "https://packagist.org/downloads/",
575
+ "license": [
576
+ "BSD-3-Clause"
577
+ ],
578
+ "authors": [
579
+ {
580
+ "name": "Sebastian Bergmann",
581
+ "email": "sb@sebastian-bergmann.de",
582
+ "role": "lead"
583
+ }
584
+ ],
585
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
586
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
587
+ "keywords": [
588
+ "coverage",
589
+ "testing",
590
+ "xunit"
591
+ ],
592
+ "time": "2015-10-06 15:47:00"
593
+ },
594
+ {
595
+ "name": "phpunit/php-file-iterator",
596
+ "version": "dev-master",
597
+ "source": {
598
+ "type": "git",
599
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
600
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
601
+ },
602
+ "dist": {
603
+ "type": "zip",
604
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
605
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
606
+ "shasum": ""
607
+ },
608
+ "require": {
609
+ "php": ">=5.3.3"
610
+ },
611
+ "type": "library",
612
+ "extra": {
613
+ "branch-alias": {
614
+ "dev-master": "1.4.x-dev"
615
+ }
616
+ },
617
+ "autoload": {
618
+ "classmap": [
619
+ "src/"
620
+ ]
621
+ },
622
+ "notification-url": "https://packagist.org/downloads/",
623
+ "license": [
624
+ "BSD-3-Clause"
625
+ ],
626
+ "authors": [
627
+ {
628
+ "name": "Sebastian Bergmann",
629
+ "email": "sb@sebastian-bergmann.de",
630
+ "role": "lead"
631
+ }
632
+ ],
633
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
634
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
635
+ "keywords": [
636
+ "filesystem",
637
+ "iterator"
638
+ ],
639
+ "time": "2016-10-03 07:40:28"
640
+ },
641
+ {
642
+ "name": "phpunit/php-text-template",
643
+ "version": "1.2.1",
644
+ "source": {
645
+ "type": "git",
646
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
647
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
648
+ },
649
+ "dist": {
650
+ "type": "zip",
651
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
652
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
653
+ "shasum": ""
654
+ },
655
+ "require": {
656
+ "php": ">=5.3.3"
657
+ },
658
+ "type": "library",
659
+ "autoload": {
660
+ "classmap": [
661
+ "src/"
662
+ ]
663
+ },
664
+ "notification-url": "https://packagist.org/downloads/",
665
+ "license": [
666
+ "BSD-3-Clause"
667
+ ],
668
+ "authors": [
669
+ {
670
+ "name": "Sebastian Bergmann",
671
+ "email": "sebastian@phpunit.de",
672
+ "role": "lead"
673
+ }
674
+ ],
675
+ "description": "Simple template engine.",
676
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
677
+ "keywords": [
678
+ "template"
679
+ ],
680
+ "time": "2015-06-21 13:50:34"
681
+ },
682
+ {
683
+ "name": "phpunit/php-timer",
684
+ "version": "1.0.8",
685
+ "source": {
686
+ "type": "git",
687
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
688
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
689
+ },
690
+ "dist": {
691
+ "type": "zip",
692
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
693
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
694
+ "shasum": ""
695
+ },
696
+ "require": {
697
+ "php": ">=5.3.3"
698
+ },
699
+ "require-dev": {
700
+ "phpunit/phpunit": "~4|~5"
701
+ },
702
+ "type": "library",
703
+ "autoload": {
704
+ "classmap": [
705
+ "src/"
706
+ ]
707
+ },
708
+ "notification-url": "https://packagist.org/downloads/",
709
+ "license": [
710
+ "BSD-3-Clause"
711
+ ],
712
+ "authors": [
713
+ {
714
+ "name": "Sebastian Bergmann",
715
+ "email": "sb@sebastian-bergmann.de",
716
+ "role": "lead"
717
+ }
718
+ ],
719
+ "description": "Utility class for timing",
720
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
721
+ "keywords": [
722
+ "timer"
723
+ ],
724
+ "time": "2016-05-12 18:03:57"
725
+ },
726
+ {
727
+ "name": "phpunit/php-token-stream",
728
+ "version": "dev-master",
729
+ "source": {
730
+ "type": "git",
731
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
732
+ "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
733
+ },
734
+ "dist": {
735
+ "type": "zip",
736
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
737
+ "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
738
+ "shasum": ""
739
+ },
740
+ "require": {
741
+ "ext-tokenizer": "*",
742
+ "php": ">=5.3.3"
743
+ },
744
+ "require-dev": {
745
+ "phpunit/phpunit": "~4.2"
746
+ },
747
+ "type": "library",
748
+ "extra": {
749
+ "branch-alias": {
750
+ "dev-master": "1.4-dev"
751
+ }
752
+ },
753
+ "autoload": {
754
+ "classmap": [
755
+ "src/"
756
+ ]
757
+ },
758
+ "notification-url": "https://packagist.org/downloads/",
759
+ "license": [
760
+ "BSD-3-Clause"
761
+ ],
762
+ "authors": [
763
+ {
764
+ "name": "Sebastian Bergmann",
765
+ "email": "sebastian@phpunit.de"
766
+ }
767
+ ],
768
+ "description": "Wrapper around PHP's tokenizer extension.",
769
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
770
+ "keywords": [
771
+ "tokenizer"
772
+ ],
773
+ "time": "2016-11-15 14:06:22"
774
+ },
775
+ {
776
+ "name": "phpunit/phpunit",
777
+ "version": "4.8.x-dev",
778
+ "source": {
779
+ "type": "git",
780
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
781
+ "reference": "95f30cd26abebb91ea4e762f040fc4bf711b81e2"
782
+ },
783
+ "dist": {
784
+ "type": "zip",
785
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/95f30cd26abebb91ea4e762f040fc4bf711b81e2",
786
+ "reference": "95f30cd26abebb91ea4e762f040fc4bf711b81e2",
787
+ "shasum": ""
788
+ },
789
+ "require": {
790
+ "ext-dom": "*",
791
+ "ext-json": "*",
792
+ "ext-pcre": "*",
793
+ "ext-reflection": "*",
794
+ "ext-spl": "*",
795
+ "php": ">=5.3.3",
796
+ "phpspec/prophecy": "^1.3.1",
797
+ "phpunit/php-code-coverage": "~2.1",
798
+ "phpunit/php-file-iterator": "~1.4",
799
+ "phpunit/php-text-template": "~1.2",
800
+ "phpunit/php-timer": "^1.0.6",
801
+ "phpunit/phpunit-mock-objects": "~2.3",
802
+ "sebastian/comparator": "~1.2.2",
803
+ "sebastian/diff": "~1.2",
804
+ "sebastian/environment": "~1.3",
805
+ "sebastian/exporter": "~1.2",
806
+ "sebastian/global-state": "~1.0",
807
+ "sebastian/version": "~1.0",
808
+ "symfony/yaml": "~2.1|~3.0"
809
+ },
810
+ "suggest": {
811
+ "phpunit/php-invoker": "~1.1"
812
+ },
813
+ "bin": [
814
+ "phpunit"
815
+ ],
816
+ "type": "library",
817
+ "extra": {
818
+ "branch-alias": {
819
+ "dev-master": "4.8.x-dev"
820
+ }
821
+ },
822
+ "autoload": {
823
+ "classmap": [
824
+ "src/"
825
+ ]
826
+ },
827
+ "notification-url": "https://packagist.org/downloads/",
828
+ "license": [
829
+ "BSD-3-Clause"
830
+ ],
831
+ "authors": [
832
+ {
833
+ "name": "Sebastian Bergmann",
834
+ "email": "sebastian@phpunit.de",
835
+ "role": "lead"
836
+ }
837
+ ],
838
+ "description": "The PHP Unit Testing framework.",
839
+ "homepage": "https://phpunit.de/",
840
+ "keywords": [
841
+ "phpunit",
842
+ "testing",
843
+ "xunit"
844
+ ],
845
+ "time": "2017-02-02 11:33:20"
846
+ },
847
+ {
848
+ "name": "phpunit/phpunit-mock-objects",
849
+ "version": "2.3.x-dev",
850
+ "source": {
851
+ "type": "git",
852
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
853
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
854
+ },
855
+ "dist": {
856
+ "type": "zip",
857
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
858
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
859
+ "shasum": ""
860
+ },
861
+ "require": {
862
+ "doctrine/instantiator": "^1.0.2",
863
+ "php": ">=5.3.3",
864
+ "phpunit/php-text-template": "~1.2",
865
+ "sebastian/exporter": "~1.2"
866
+ },
867
+ "require-dev": {
868
+ "phpunit/phpunit": "~4.4"
869
+ },
870
+ "suggest": {
871
+ "ext-soap": "*"
872
+ },
873
+ "type": "library",
874
+ "extra": {
875
+ "branch-alias": {
876
+ "dev-master": "2.3.x-dev"
877
+ }
878
+ },
879
+ "autoload": {
880
+ "classmap": [
881
+ "src/"
882
+ ]
883
+ },
884
+ "notification-url": "https://packagist.org/downloads/",
885
+ "license": [
886
+ "BSD-3-Clause"
887
+ ],
888
+ "authors": [
889
+ {
890
+ "name": "Sebastian Bergmann",
891
+ "email": "sb@sebastian-bergmann.de",
892
+ "role": "lead"
893
+ }
894
+ ],
895
+ "description": "Mock Object library for PHPUnit",
896
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
897
+ "keywords": [
898
+ "mock",
899
+ "xunit"
900
+ ],
901
+ "time": "2015-10-02 06:51:40"
902
+ },
903
+ {
904
+ "name": "psr/log",
905
+ "version": "dev-master",
906
+ "source": {
907
+ "type": "git",
908
+ "url": "https://github.com/php-fig/log.git",
909
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
910
+ },
911
+ "dist": {
912
+ "type": "zip",
913
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
914
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
915
+ "shasum": ""
916
+ },
917
+ "require": {
918
+ "php": ">=5.3.0"
919
+ },
920
+ "type": "library",
921
+ "extra": {
922
+ "branch-alias": {
923
+ "dev-master": "1.0.x-dev"
924
+ }
925
+ },
926
+ "autoload": {
927
+ "psr-4": {
928
+ "Psr\\Log\\": "Psr/Log/"
929
+ }
930
+ },
931
+ "notification-url": "https://packagist.org/downloads/",
932
+ "license": [
933
+ "MIT"
934
+ ],
935
+ "authors": [
936
+ {
937
+ "name": "PHP-FIG",
938
+ "homepage": "http://www.php-fig.org/"
939
+ }
940
+ ],
941
+ "description": "Common interface for logging libraries",
942
+ "homepage": "https://github.com/php-fig/log",
943
+ "keywords": [
944
+ "log",
945
+ "psr",
946
+ "psr-3"
947
+ ],
948
+ "time": "2016-10-10 12:19:37"
949
+ },
950
+ {
951
+ "name": "ptrofimov/xpmock",
952
+ "version": "1.1.5",
953
+ "source": {
954
+ "type": "git",
955
+ "url": "https://github.com/ptrofimov/xpmock.git",
956
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
957
+ },
958
+ "dist": {
959
+ "type": "zip",
960
+ "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
961
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
962
+ "shasum": ""
963
+ },
964
+ "require": {
965
+ "php": ">=5.3.0"
966
+ },
967
+ "require-dev": {
968
+ "phpunit/phpunit": "3.7.*"
969
+ },
970
+ "type": "library",
971
+ "autoload": {
972
+ "psr-0": {
973
+ "Xpmock": "src"
974
+ }
975
+ },
976
+ "notification-url": "https://packagist.org/downloads/",
977
+ "license": [
978
+ "MIT"
979
+ ],
980
+ "description": "PHPUnit: simple syntax to create mock-objects",
981
+ "time": "2014-01-02 16:42:27"
982
+ },
983
+ {
984
+ "name": "satooshi/php-coveralls",
985
+ "version": "1.0.x-dev",
986
+ "source": {
987
+ "type": "git",
988
+ "url": "https://github.com/satooshi/php-coveralls.git",
989
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
990
+ },
991
+ "dist": {
992
+ "type": "zip",
993
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
994
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
995
+ "shasum": ""
996
+ },
997
+ "require": {
998
+ "ext-json": "*",
999
+ "ext-simplexml": "*",
1000
+ "guzzle/guzzle": "^2.8|^3.0",
1001
+ "php": ">=5.3.3",
1002
+ "psr/log": "^1.0",
1003
+ "symfony/config": "^2.1|^3.0",
1004
+ "symfony/console": "^2.1|^3.0",
1005
+ "symfony/stopwatch": "^2.0|^3.0",
1006
+ "symfony/yaml": "^2.0|^3.0"
1007
+ },
1008
+ "suggest": {
1009
+ "symfony/http-kernel": "Allows Symfony integration"
1010
+ },
1011
+ "bin": [
1012
+ "bin/coveralls"
1013
+ ],
1014
+ "type": "library",
1015
+ "autoload": {
1016
+ "psr-4": {
1017
+ "Satooshi\\": "src/Satooshi/"
1018
+ }
1019
+ },
1020
+ "notification-url": "https://packagist.org/downloads/",
1021
+ "license": [
1022
+ "MIT"
1023
+ ],
1024
+ "authors": [
1025
+ {
1026
+ "name": "Kitamura Satoshi",
1027
+ "email": "with.no.parachute@gmail.com",
1028
+ "homepage": "https://www.facebook.com/satooshi.jp"
1029
+ }
1030
+ ],
1031
+ "description": "PHP client library for Coveralls API",
1032
+ "homepage": "https://github.com/satooshi/php-coveralls",
1033
+ "keywords": [
1034
+ "ci",
1035
+ "coverage",
1036
+ "github",
1037
+ "test"
1038
+ ],
1039
+ "time": "2016-01-20 17:35:46"
1040
+ },
1041
+ {
1042
+ "name": "sebastian/comparator",
1043
+ "version": "1.2.x-dev",
1044
+ "source": {
1045
+ "type": "git",
1046
+ "url": "https://github.com/sebastianbergmann/comparator.git",
1047
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be"
1048
+ },
1049
+ "dist": {
1050
+ "type": "zip",
1051
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1052
+ "reference": "2b7424b55f5047b47ac6e5ccb20b2aea4011d9be",
1053
+ "shasum": ""
1054
+ },
1055
+ "require": {
1056
+ "php": ">=5.3.3",
1057
+ "sebastian/diff": "~1.2",
1058
+ "sebastian/exporter": "~1.2 || ~2.0"
1059
+ },
1060
+ "require-dev": {
1061
+ "phpunit/phpunit": "~4.4"
1062
+ },
1063
+ "type": "library",
1064
+ "extra": {
1065
+ "branch-alias": {
1066
+ "dev-master": "1.2.x-dev"
1067
+ }
1068
+ },
1069
+ "autoload": {
1070
+ "classmap": [
1071
+ "src/"
1072
+ ]
1073
+ },
1074
+ "notification-url": "https://packagist.org/downloads/",
1075
+ "license": [
1076
+ "BSD-3-Clause"
1077
+ ],
1078
+ "authors": [
1079
+ {
1080
+ "name": "Jeff Welch",
1081
+ "email": "whatthejeff@gmail.com"
1082
+ },
1083
+ {
1084
+ "name": "Volker Dusch",
1085
+ "email": "github@wallbash.com"
1086
+ },
1087
+ {
1088
+ "name": "Bernhard Schussek",
1089
+ "email": "bschussek@2bepublished.at"
1090
+ },
1091
+ {
1092
+ "name": "Sebastian Bergmann",
1093
+ "email": "sebastian@phpunit.de"
1094
+ }
1095
+ ],
1096
+ "description": "Provides the functionality to compare PHP values for equality",
1097
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
1098
+ "keywords": [
1099
+ "comparator",
1100
+ "compare",
1101
+ "equality"
1102
+ ],
1103
+ "time": "2017-01-29 09:50:25"
1104
+ },
1105
+ {
1106
+ "name": "sebastian/diff",
1107
+ "version": "dev-master",
1108
+ "source": {
1109
+ "type": "git",
1110
+ "url": "https://github.com/sebastianbergmann/diff.git",
1111
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
1112
+ },
1113
+ "dist": {
1114
+ "type": "zip",
1115
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
1116
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
1117
+ "shasum": ""
1118
+ },
1119
+ "require": {
1120
+ "php": ">=5.3.3"
1121
+ },
1122
+ "require-dev": {
1123
+ "phpunit/phpunit": "~4.8"
1124
+ },
1125
+ "type": "library",
1126
+ "extra": {
1127
+ "branch-alias": {
1128
+ "dev-master": "1.4-dev"
1129
+ }
1130
+ },
1131
+ "autoload": {
1132
+ "classmap": [
1133
+ "src/"
1134
+ ]
1135
+ },
1136
+ "notification-url": "https://packagist.org/downloads/",
1137
+ "license": [
1138
+ "BSD-3-Clause"
1139
+ ],
1140
+ "authors": [
1141
+ {
1142
+ "name": "Kore Nordmann",
1143
+ "email": "mail@kore-nordmann.de"
1144
+ },
1145
+ {
1146
+ "name": "Sebastian Bergmann",
1147
+ "email": "sebastian@phpunit.de"
1148
+ }
1149
+ ],
1150
+ "description": "Diff implementation",
1151
+ "homepage": "https://github.com/sebastianbergmann/diff",
1152
+ "keywords": [
1153
+ "diff"
1154
+ ],
1155
+ "time": "2016-10-03 07:45:03"
1156
+ },
1157
+ {
1158
+ "name": "sebastian/environment",
1159
+ "version": "1.3.x-dev",
1160
+ "source": {
1161
+ "type": "git",
1162
+ "url": "https://github.com/sebastianbergmann/environment.git",
1163
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1164
+ },
1165
+ "dist": {
1166
+ "type": "zip",
1167
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1168
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1169
+ "shasum": ""
1170
+ },
1171
+ "require": {
1172
+ "php": "^5.3.3 || ^7.0"
1173
+ },
1174
+ "require-dev": {
1175
+ "phpunit/phpunit": "^4.8 || ^5.0"
1176
+ },
1177
+ "type": "library",
1178
+ "extra": {
1179
+ "branch-alias": {
1180
+ "dev-master": "1.3.x-dev"
1181
+ }
1182
+ },
1183
+ "autoload": {
1184
+ "classmap": [
1185
+ "src/"
1186
+ ]
1187
+ },
1188
+ "notification-url": "https://packagist.org/downloads/",
1189
+ "license": [
1190
+ "BSD-3-Clause"
1191
+ ],
1192
+ "authors": [
1193
+ {
1194
+ "name": "Sebastian Bergmann",
1195
+ "email": "sebastian@phpunit.de"
1196
+ }
1197
+ ],
1198
+ "description": "Provides functionality to handle HHVM/PHP environments",
1199
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1200
+ "keywords": [
1201
+ "Xdebug",
1202
+ "environment",
1203
+ "hhvm"
1204
+ ],
1205
+ "time": "2016-08-18 05:49:44"
1206
+ },
1207
+ {
1208
+ "name": "sebastian/exporter",
1209
+ "version": "1.2.x-dev",
1210
+ "source": {
1211
+ "type": "git",
1212
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1213
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
1214
+ },
1215
+ "dist": {
1216
+ "type": "zip",
1217
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1218
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1219
+ "shasum": ""
1220
+ },
1221
+ "require": {
1222
+ "php": ">=5.3.3",
1223
+ "sebastian/recursion-context": "~1.0"
1224
+ },
1225
+ "require-dev": {
1226
+ "ext-mbstring": "*",
1227
+ "phpunit/phpunit": "~4.4"
1228
+ },
1229
+ "type": "library",
1230
+ "extra": {
1231
+ "branch-alias": {
1232
+ "dev-master": "1.3.x-dev"
1233
+ }
1234
+ },
1235
+ "autoload": {
1236
+ "classmap": [
1237
+ "src/"
1238
+ ]
1239
+ },
1240
+ "notification-url": "https://packagist.org/downloads/",
1241
+ "license": [
1242
+ "BSD-3-Clause"
1243
+ ],
1244
+ "authors": [
1245
+ {
1246
+ "name": "Jeff Welch",
1247
+ "email": "whatthejeff@gmail.com"
1248
+ },
1249
+ {
1250
+ "name": "Volker Dusch",
1251
+ "email": "github@wallbash.com"
1252
+ },
1253
+ {
1254
+ "name": "Bernhard Schussek",
1255
+ "email": "bschussek@2bepublished.at"
1256
+ },
1257
+ {
1258
+ "name": "Sebastian Bergmann",
1259
+ "email": "sebastian@phpunit.de"
1260
+ },
1261
+ {
1262
+ "name": "Adam Harvey",
1263
+ "email": "aharvey@php.net"
1264
+ }
1265
+ ],
1266
+ "description": "Provides the functionality to export PHP variables for visualization",
1267
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1268
+ "keywords": [
1269
+ "export",
1270
+ "exporter"
1271
+ ],
1272
+ "time": "2016-10-03 07:44:30"
1273
+ },
1274
+ {
1275
+ "name": "sebastian/global-state",
1276
+ "version": "1.1.x-dev",
1277
+ "source": {
1278
+ "type": "git",
1279
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1280
+ "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d"
1281
+ },
1282
+ "dist": {
1283
+ "type": "zip",
1284
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1285
+ "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1286
+ "shasum": ""
1287
+ },
1288
+ "require": {
1289
+ "php": ">=5.3.3"
1290
+ },
1291
+ "require-dev": {
1292
+ "phpunit/phpunit": "~4.2|~5.0"
1293
+ },
1294
+ "suggest": {
1295
+ "ext-uopz": "*"
1296
+ },
1297
+ "type": "library",
1298
+ "extra": {
1299
+ "branch-alias": {
1300
+ "dev-master": "1.0-dev"
1301
+ }
1302
+ },
1303
+ "autoload": {
1304
+ "classmap": [
1305
+ "src/"
1306
+ ]
1307
+ },
1308
+ "notification-url": "https://packagist.org/downloads/",
1309
+ "license": [
1310
+ "BSD-3-Clause"
1311
+ ],
1312
+ "authors": [
1313
+ {
1314
+ "name": "Sebastian Bergmann",
1315
+ "email": "sebastian@phpunit.de"
1316
+ }
1317
+ ],
1318
+ "description": "Snapshotting of global state",
1319
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1320
+ "keywords": [
1321
+ "global state"
1322
+ ],
1323
+ "time": "2016-10-03 07:46:22"
1324
+ },
1325
+ {
1326
+ "name": "sebastian/recursion-context",
1327
+ "version": "1.0.x-dev",
1328
+ "source": {
1329
+ "type": "git",
1330
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1331
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1332
+ },
1333
+ "dist": {
1334
+ "type": "zip",
1335
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1336
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1337
+ "shasum": ""
1338
+ },
1339
+ "require": {
1340
+ "php": ">=5.3.3"
1341
+ },
1342
+ "require-dev": {
1343
+ "phpunit/phpunit": "~4.4"
1344
+ },
1345
+ "type": "library",
1346
+ "extra": {
1347
+ "branch-alias": {
1348
+ "dev-master": "1.0.x-dev"
1349
+ }
1350
+ },
1351
+ "autoload": {
1352
+ "classmap": [
1353
+ "src/"
1354
+ ]
1355
+ },
1356
+ "notification-url": "https://packagist.org/downloads/",
1357
+ "license": [
1358
+ "BSD-3-Clause"
1359
+ ],
1360
+ "authors": [
1361
+ {
1362
+ "name": "Jeff Welch",
1363
+ "email": "whatthejeff@gmail.com"
1364
+ },
1365
+ {
1366
+ "name": "Sebastian Bergmann",
1367
+ "email": "sebastian@phpunit.de"
1368
+ },
1369
+ {
1370
+ "name": "Adam Harvey",
1371
+ "email": "aharvey@php.net"
1372
+ }
1373
+ ],
1374
+ "description": "Provides functionality to recursively process PHP variables",
1375
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1376
+ "time": "2016-10-03 07:41:43"
1377
+ },
1378
+ {
1379
+ "name": "sebastian/version",
1380
+ "version": "1.0.6",
1381
+ "source": {
1382
+ "type": "git",
1383
+ "url": "https://github.com/sebastianbergmann/version.git",
1384
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1385
+ },
1386
+ "dist": {
1387
+ "type": "zip",
1388
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1389
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1390
+ "shasum": ""
1391
+ },
1392
+ "type": "library",
1393
+ "autoload": {
1394
+ "classmap": [
1395
+ "src/"
1396
+ ]
1397
+ },
1398
+ "notification-url": "https://packagist.org/downloads/",
1399
+ "license": [
1400
+ "BSD-3-Clause"
1401
+ ],
1402
+ "authors": [
1403
+ {
1404
+ "name": "Sebastian Bergmann",
1405
+ "email": "sebastian@phpunit.de",
1406
+ "role": "lead"
1407
+ }
1408
+ ],
1409
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1410
+ "homepage": "https://github.com/sebastianbergmann/version",
1411
+ "time": "2015-06-21 13:59:46"
1412
+ },
1413
+ {
1414
+ "name": "symfony/config",
1415
+ "version": "2.8.x-dev",
1416
+ "source": {
1417
+ "type": "git",
1418
+ "url": "https://github.com/symfony/config.git",
1419
+ "reference": "4537f2413348fe271c2c4b09da219ed615d79f9c"
1420
+ },
1421
+ "dist": {
1422
+ "type": "zip",
1423
+ "url": "https://api.github.com/repos/symfony/config/zipball/4537f2413348fe271c2c4b09da219ed615d79f9c",
1424
+ "reference": "4537f2413348fe271c2c4b09da219ed615d79f9c",
1425
+ "shasum": ""
1426
+ },
1427
+ "require": {
1428
+ "php": ">=5.3.9",
1429
+ "symfony/filesystem": "~2.3|~3.0.0"
1430
+ },
1431
+ "require-dev": {
1432
+ "symfony/yaml": "~2.7|~3.0.0"
1433
+ },
1434
+ "suggest": {
1435
+ "symfony/yaml": "To use the yaml reference dumper"
1436
+ },
1437
+ "type": "library",
1438
+ "extra": {
1439
+ "branch-alias": {
1440
+ "dev-master": "2.8-dev"
1441
+ }
1442
+ },
1443
+ "autoload": {
1444
+ "psr-4": {
1445
+ "Symfony\\Component\\Config\\": ""
1446
+ },
1447
+ "exclude-from-classmap": [
1448
+ "/Tests/"
1449
+ ]
1450
+ },
1451
+ "notification-url": "https://packagist.org/downloads/",
1452
+ "license": [
1453
+ "MIT"
1454
+ ],
1455
+ "authors": [
1456
+ {
1457
+ "name": "Fabien Potencier",
1458
+ "email": "fabien@symfony.com"
1459
+ },
1460
+ {
1461
+ "name": "Symfony Community",
1462
+ "homepage": "https://symfony.com/contributors"
1463
+ }
1464
+ ],
1465
+ "description": "Symfony Config Component",
1466
+ "homepage": "https://symfony.com",
1467
+ "time": "2017-01-02 20:30:24"
1468
+ },
1469
+ {
1470
+ "name": "symfony/console",
1471
+ "version": "2.8.x-dev",
1472
+ "source": {
1473
+ "type": "git",
1474
+ "url": "https://github.com/symfony/console.git",
1475
+ "reference": "783e23a50ac464d9eb82cc7ea35ef260da8ba6bb"
1476
+ },
1477
+ "dist": {
1478
+ "type": "zip",
1479
+ "url": "https://api.github.com/repos/symfony/console/zipball/783e23a50ac464d9eb82cc7ea35ef260da8ba6bb",
1480
+ "reference": "783e23a50ac464d9eb82cc7ea35ef260da8ba6bb",
1481
+ "shasum": ""
1482
+ },
1483
+ "require": {
1484
+ "php": ">=5.3.9",
1485
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
1486
+ "symfony/polyfill-mbstring": "~1.0"
1487
+ },
1488
+ "require-dev": {
1489
+ "psr/log": "~1.0",
1490
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
1491
+ "symfony/process": "~2.1|~3.0.0"
1492
+ },
1493
+ "suggest": {
1494
+ "psr/log": "For using the console logger",
1495
+ "symfony/event-dispatcher": "",
1496
+ "symfony/process": ""
1497
+ },
1498
+ "type": "library",
1499
+ "extra": {
1500
+ "branch-alias": {
1501
+ "dev-master": "2.8-dev"
1502
+ }
1503
+ },
1504
+ "autoload": {
1505
+ "psr-4": {
1506
+ "Symfony\\Component\\Console\\": ""
1507
+ },
1508
+ "exclude-from-classmap": [
1509
+ "/Tests/"
1510
+ ]
1511
+ },
1512
+ "notification-url": "https://packagist.org/downloads/",
1513
+ "license": [
1514
+ "MIT"
1515
+ ],
1516
+ "authors": [
1517
+ {
1518
+ "name": "Fabien Potencier",
1519
+ "email": "fabien@symfony.com"
1520
+ },
1521
+ {
1522
+ "name": "Symfony Community",
1523
+ "homepage": "https://symfony.com/contributors"
1524
+ }
1525
+ ],
1526
+ "description": "Symfony Console Component",
1527
+ "homepage": "https://symfony.com",
1528
+ "time": "2017-01-31 21:48:58"
1529
+ },
1530
+ {
1531
+ "name": "symfony/debug",
1532
+ "version": "2.8.x-dev",
1533
+ "source": {
1534
+ "type": "git",
1535
+ "url": "https://github.com/symfony/debug.git",
1536
+ "reference": "4a99c3a6cabfa0c297fc3531e61483d276133110"
1537
+ },
1538
+ "dist": {
1539
+ "type": "zip",
1540
+ "url": "https://api.github.com/repos/symfony/debug/zipball/4a99c3a6cabfa0c297fc3531e61483d276133110",
1541
+ "reference": "4a99c3a6cabfa0c297fc3531e61483d276133110",
1542
+ "shasum": ""
1543
+ },
1544
+ "require": {
1545
+ "php": ">=5.3.9",
1546
+ "psr/log": "~1.0"
1547
+ },
1548
+ "conflict": {
1549
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1550
+ },
1551
+ "require-dev": {
1552
+ "symfony/class-loader": "~2.2|~3.0.0",
1553
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
1554
+ },
1555
+ "type": "library",
1556
+ "extra": {
1557
+ "branch-alias": {
1558
+ "dev-master": "2.8-dev"
1559
+ }
1560
+ },
1561
+ "autoload": {
1562
+ "psr-4": {
1563
+ "Symfony\\Component\\Debug\\": ""
1564
+ },
1565
+ "exclude-from-classmap": [
1566
+ "/Tests/"
1567
+ ]
1568
+ },
1569
+ "notification-url": "https://packagist.org/downloads/",
1570
+ "license": [
1571
+ "MIT"
1572
+ ],
1573
+ "authors": [
1574
+ {
1575
+ "name": "Fabien Potencier",
1576
+ "email": "fabien@symfony.com"
1577
+ },
1578
+ {
1579
+ "name": "Symfony Community",
1580
+ "homepage": "https://symfony.com/contributors"
1581
+ }
1582
+ ],
1583
+ "description": "Symfony Debug Component",
1584
+ "homepage": "https://symfony.com",
1585
+ "time": "2017-01-27 23:54:58"
1586
+ },
1587
+ {
1588
+ "name": "symfony/event-dispatcher",
1589
+ "version": "2.8.x-dev",
1590
+ "source": {
1591
+ "type": "git",
1592
+ "url": "https://github.com/symfony/event-dispatcher.git",
1593
+ "reference": "74877977f90fb9c3e46378d5764217c55f32df34"
1594
+ },
1595
+ "dist": {
1596
+ "type": "zip",
1597
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/74877977f90fb9c3e46378d5764217c55f32df34",
1598
+ "reference": "74877977f90fb9c3e46378d5764217c55f32df34",
1599
+ "shasum": ""
1600
+ },
1601
+ "require": {
1602
+ "php": ">=5.3.9"
1603
+ },
1604
+ "require-dev": {
1605
+ "psr/log": "~1.0",
1606
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
1607
+ "symfony/dependency-injection": "~2.6|~3.0.0",
1608
+ "symfony/expression-language": "~2.6|~3.0.0",
1609
+ "symfony/stopwatch": "~2.3|~3.0.0"
1610
+ },
1611
+ "suggest": {
1612
+ "symfony/dependency-injection": "",
1613
+ "symfony/http-kernel": ""
1614
+ },
1615
+ "type": "library",
1616
+ "extra": {
1617
+ "branch-alias": {
1618
+ "dev-master": "2.8-dev"
1619
+ }
1620
+ },
1621
+ "autoload": {
1622
+ "psr-4": {
1623
+ "Symfony\\Component\\EventDispatcher\\": ""
1624
+ },
1625
+ "exclude-from-classmap": [
1626
+ "/Tests/"
1627
+ ]
1628
+ },
1629
+ "notification-url": "https://packagist.org/downloads/",
1630
+ "license": [
1631
+ "MIT"
1632
+ ],
1633
+ "authors": [
1634
+ {
1635
+ "name": "Fabien Potencier",
1636
+ "email": "fabien@symfony.com"
1637
+ },
1638
+ {
1639
+ "name": "Symfony Community",
1640
+ "homepage": "https://symfony.com/contributors"
1641
+ }
1642
+ ],
1643
+ "description": "Symfony EventDispatcher Component",
1644
+ "homepage": "https://symfony.com",
1645
+ "time": "2017-01-02 20:30:24"
1646
+ },
1647
+ {
1648
+ "name": "symfony/filesystem",
1649
+ "version": "2.8.x-dev",
1650
+ "source": {
1651
+ "type": "git",
1652
+ "url": "https://github.com/symfony/filesystem.git",
1653
+ "reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d"
1654
+ },
1655
+ "dist": {
1656
+ "type": "zip",
1657
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/5b77d49ab76e5b12743b359ef4b4a712e6f5360d",
1658
+ "reference": "5b77d49ab76e5b12743b359ef4b4a712e6f5360d",
1659
+ "shasum": ""
1660
+ },
1661
+ "require": {
1662
+ "php": ">=5.3.9"
1663
+ },
1664
+ "type": "library",
1665
+ "extra": {
1666
+ "branch-alias": {
1667
+ "dev-master": "2.8-dev"
1668
+ }
1669
+ },
1670
+ "autoload": {
1671
+ "psr-4": {
1672
+ "Symfony\\Component\\Filesystem\\": ""
1673
+ },
1674
+ "exclude-from-classmap": [
1675
+ "/Tests/"
1676
+ ]
1677
+ },
1678
+ "notification-url": "https://packagist.org/downloads/",
1679
+ "license": [
1680
+ "MIT"
1681
+ ],
1682
+ "authors": [
1683
+ {
1684
+ "name": "Fabien Potencier",
1685
+ "email": "fabien@symfony.com"
1686
+ },
1687
+ {
1688
+ "name": "Symfony Community",
1689
+ "homepage": "https://symfony.com/contributors"
1690
+ }
1691
+ ],
1692
+ "description": "Symfony Filesystem Component",
1693
+ "homepage": "https://symfony.com",
1694
+ "time": "2017-01-08 20:43:03"
1695
+ },
1696
+ {
1697
+ "name": "symfony/finder",
1698
+ "version": "2.8.x-dev",
1699
+ "source": {
1700
+ "type": "git",
1701
+ "url": "https://github.com/symfony/finder.git",
1702
+ "reference": "355fccac526522dc5fca8ecf0e62749a149f3b8b"
1703
+ },
1704
+ "dist": {
1705
+ "type": "zip",
1706
+ "url": "https://api.github.com/repos/symfony/finder/zipball/355fccac526522dc5fca8ecf0e62749a149f3b8b",
1707
+ "reference": "355fccac526522dc5fca8ecf0e62749a149f3b8b",
1708
+ "shasum": ""
1709
+ },
1710
+ "require": {
1711
+ "php": ">=5.3.9"
1712
+ },
1713
+ "type": "library",
1714
+ "extra": {
1715
+ "branch-alias": {
1716
+ "dev-master": "2.8-dev"
1717
+ }
1718
+ },
1719
+ "autoload": {
1720
+ "psr-4": {
1721
+ "Symfony\\Component\\Finder\\": ""
1722
+ },
1723
+ "exclude-from-classmap": [
1724
+ "/Tests/"
1725
+ ]
1726
+ },
1727
+ "notification-url": "https://packagist.org/downloads/",
1728
+ "license": [
1729
+ "MIT"
1730
+ ],
1731
+ "authors": [
1732
+ {
1733
+ "name": "Fabien Potencier",
1734
+ "email": "fabien@symfony.com"
1735
+ },
1736
+ {
1737
+ "name": "Symfony Community",
1738
+ "homepage": "https://symfony.com/contributors"
1739
+ }
1740
+ ],
1741
+ "description": "Symfony Finder Component",
1742
+ "homepage": "https://symfony.com",
1743
+ "time": "2017-01-02 20:30:24"
1744
+ },
1745
+ {
1746
+ "name": "symfony/polyfill-mbstring",
1747
+ "version": "dev-master",
1748
+ "source": {
1749
+ "type": "git",
1750
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1751
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
1752
+ },
1753
+ "dist": {
1754
+ "type": "zip",
1755
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
1756
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
1757
+ "shasum": ""
1758
+ },
1759
+ "require": {
1760
+ "php": ">=5.3.3"
1761
+ },
1762
+ "suggest": {
1763
+ "ext-mbstring": "For best performance"
1764
+ },
1765
+ "type": "library",
1766
+ "extra": {
1767
+ "branch-alias": {
1768
+ "dev-master": "1.3-dev"
1769
+ }
1770
+ },
1771
+ "autoload": {
1772
+ "psr-4": {
1773
+ "Symfony\\Polyfill\\Mbstring\\": ""
1774
+ },
1775
+ "files": [
1776
+ "bootstrap.php"
1777
+ ]
1778
+ },
1779
+ "notification-url": "https://packagist.org/downloads/",
1780
+ "license": [
1781
+ "MIT"
1782
+ ],
1783
+ "authors": [
1784
+ {
1785
+ "name": "Nicolas Grekas",
1786
+ "email": "p@tchwork.com"
1787
+ },
1788
+ {
1789
+ "name": "Symfony Community",
1790
+ "homepage": "https://symfony.com/contributors"
1791
+ }
1792
+ ],
1793
+ "description": "Symfony polyfill for the Mbstring extension",
1794
+ "homepage": "https://symfony.com",
1795
+ "keywords": [
1796
+ "compatibility",
1797
+ "mbstring",
1798
+ "polyfill",
1799
+ "portable",
1800
+ "shim"
1801
+ ],
1802
+ "time": "2016-11-14 01:06:16"
1803
+ },
1804
+ {
1805
+ "name": "symfony/process",
1806
+ "version": "2.8.x-dev",
1807
+ "source": {
1808
+ "type": "git",
1809
+ "url": "https://github.com/symfony/process.git",
1810
+ "reference": "699fe81c8a158753be1be3da4768a2ab69a52aa6"
1811
+ },
1812
+ "dist": {
1813
+ "type": "zip",
1814
+ "url": "https://api.github.com/repos/symfony/process/zipball/699fe81c8a158753be1be3da4768a2ab69a52aa6",
1815
+ "reference": "699fe81c8a158753be1be3da4768a2ab69a52aa6",
1816
+ "shasum": ""
1817
+ },
1818
+ "require": {
1819
+ "php": ">=5.3.9"
1820
+ },
1821
+ "type": "library",
1822
+ "extra": {
1823
+ "branch-alias": {
1824
+ "dev-master": "2.8-dev"
1825
+ }
1826
+ },
1827
+ "autoload": {
1828
+ "psr-4": {
1829
+ "Symfony\\Component\\Process\\": ""
1830
+ },
1831
+ "exclude-from-classmap": [
1832
+ "/Tests/"
1833
+ ]
1834
+ },
1835
+ "notification-url": "https://packagist.org/downloads/",
1836
+ "license": [
1837
+ "MIT"
1838
+ ],
1839
+ "authors": [
1840
+ {
1841
+ "name": "Fabien Potencier",
1842
+ "email": "fabien@symfony.com"
1843
+ },
1844
+ {
1845
+ "name": "Symfony Community",
1846
+ "homepage": "https://symfony.com/contributors"
1847
+ }
1848
+ ],
1849
+ "description": "Symfony Process Component",
1850
+ "homepage": "https://symfony.com",
1851
+ "time": "2017-01-21 16:40:50"
1852
+ },
1853
+ {
1854
+ "name": "symfony/stopwatch",
1855
+ "version": "2.8.x-dev",
1856
+ "source": {
1857
+ "type": "git",
1858
+ "url": "https://github.com/symfony/stopwatch.git",
1859
+ "reference": "e8bb9de52febc4ee9922b33b1f04ba5feed457b8"
1860
+ },
1861
+ "dist": {
1862
+ "type": "zip",
1863
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/e8bb9de52febc4ee9922b33b1f04ba5feed457b8",
1864
+ "reference": "e8bb9de52febc4ee9922b33b1f04ba5feed457b8",
1865
+ "shasum": ""
1866
+ },
1867
+ "require": {
1868
+ "php": ">=5.3.9"
1869
+ },
1870
+ "type": "library",
1871
+ "extra": {
1872
+ "branch-alias": {
1873
+ "dev-master": "2.8-dev"
1874
+ }
1875
+ },
1876
+ "autoload": {
1877
+ "psr-4": {
1878
+ "Symfony\\Component\\Stopwatch\\": ""
1879
+ },
1880
+ "exclude-from-classmap": [
1881
+ "/Tests/"
1882
+ ]
1883
+ },
1884
+ "notification-url": "https://packagist.org/downloads/",
1885
+ "license": [
1886
+ "MIT"
1887
+ ],
1888
+ "authors": [
1889
+ {
1890
+ "name": "Fabien Potencier",
1891
+ "email": "fabien@symfony.com"
1892
+ },
1893
+ {
1894
+ "name": "Symfony Community",
1895
+ "homepage": "https://symfony.com/contributors"
1896
+ }
1897
+ ],
1898
+ "description": "Symfony Stopwatch Component",
1899
+ "homepage": "https://symfony.com",
1900
+ "time": "2017-01-02 20:30:24"
1901
+ },
1902
+ {
1903
+ "name": "symfony/yaml",
1904
+ "version": "2.8.x-dev",
1905
+ "source": {
1906
+ "type": "git",
1907
+ "url": "https://github.com/symfony/yaml.git",
1908
+ "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153"
1909
+ },
1910
+ "dist": {
1911
+ "type": "zip",
1912
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/322a8c2dfbca15ad6b1b27e182899f98ec0e0153",
1913
+ "reference": "322a8c2dfbca15ad6b1b27e182899f98ec0e0153",
1914
+ "shasum": ""
1915
+ },
1916
+ "require": {
1917
+ "php": ">=5.3.9"
1918
+ },
1919
+ "type": "library",
1920
+ "extra": {
1921
+ "branch-alias": {
1922
+ "dev-master": "2.8-dev"
1923
+ }
1924
+ },
1925
+ "autoload": {
1926
+ "psr-4": {
1927
+ "Symfony\\Component\\Yaml\\": ""
1928
+ },
1929
+ "exclude-from-classmap": [
1930
+ "/Tests/"
1931
+ ]
1932
+ },
1933
+ "notification-url": "https://packagist.org/downloads/",
1934
+ "license": [
1935
+ "MIT"
1936
+ ],
1937
+ "authors": [
1938
+ {
1939
+ "name": "Fabien Potencier",
1940
+ "email": "fabien@symfony.com"
1941
+ },
1942
+ {
1943
+ "name": "Symfony Community",
1944
+ "homepage": "https://symfony.com/contributors"
1945
+ }
1946
+ ],
1947
+ "description": "Symfony Yaml Component",
1948
+ "homepage": "https://symfony.com",
1949
+ "time": "2017-01-21 16:40:50"
1950
+ }
1951
+ ],
1952
+ "aliases": [],
1953
+ "minimum-stability": "dev",
1954
+ "stability-flags": {
1955
+ "dhii/php-cs-fixer-config": 20
1956
+ },
1957
+ "prefer-stable": false,
1958
+ "prefer-lowest": false,
1959
+ "platform": {
1960
+ "php": "^5.3 | ^7.0"
1961
+ },
1962
+ "platform-dev": []
1963
+ }
vendor/dhii/di-abstract/nbproject/private/private.xml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
4
+ </project-private>
vendor/dhii/di-abstract/nbproject/project.properties ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_create_2e_tests=false
2
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_enabled=false
3
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_path=
4
+ auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_enabled=false
5
+ auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_path=
6
+ auxiliary.org-netbeans-modules-php-phpunit.customSuite_2e_enabled=false
7
+ auxiliary.org-netbeans-modules-php-phpunit.customSuite_2e_path=
8
+ auxiliary.org-netbeans-modules-php-phpunit.phpUnit_2e_enabled=false
9
+ auxiliary.org-netbeans-modules-php-phpunit.phpUnit_2e_path=
10
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_groups_2e_ask=false
11
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_run_2e_all=false
12
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_run_2e_phpunit_2e_only=false
13
+ file.reference.di-abstract-vendor=vendor
14
+ file.reference.test-functional=test/functional
15
+ include.path=\
16
+ ${php.global.include.path}:\
17
+ ${file.reference.di-abstract-vendor}
18
+ php.version=PHP_53
19
+ source.encoding=UTF-8
20
+ src.dir=src
21
+ tags.asp=false
22
+ tags.short=false
23
+ test.src.dir=${file.reference.test-functional}
24
+ testing.providers=PhpUnit
25
+ web.root=.
vendor/dhii/di-abstract/nbproject/project.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://www.netbeans.org/ns/project/1">
3
+ <type>org.netbeans.modules.php.project</type>
4
+ <configuration>
5
+ <data xmlns="http://www.netbeans.org/ns/php-project/1">
6
+ <name>dhii - di-abstract</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/di-abstract/phpmd.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <ruleset name="PHPMD rule set for my project" xmlns="http://pmd.sf.net/ruleset/1.0.0"
3
+ xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:schemaLocation="http://pmd.sf.net/ruleset/1.0.0 http://pmd.sf.net/ruleset_xml_schema.xsd"
5
+ xsi:noNamespaceSchemaLocation="http://pmd.sf.net/ruleset_xml_schema.xsd">
6
+ <description>Custom rules for checking my project</description>
7
+
8
+ <rule ref="rulesets/unusedcode.xml" />
9
+ <rule ref="rulesets/cleancode.xml" />
10
+ <rule ref="rulesets/codesize.xml" />
11
+ <rule ref="rulesets/controversial.xml" />
12
+ <rule ref="rulesets/design.xml" />
13
+ <rule ref="rulesets/naming.xml" />
14
+
15
+ <rule ref="rulesets/controversial.xml/CamelCaseMethodName">
16
+ <properties>
17
+ <property name="allow-underscore" value="true" />
18
+ </properties>
19
+ </rule>
20
+ </ruleset>
vendor/dhii/di-abstract/phpunit.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit
3
+ colors="true"
4
+ bootstrap="test/bootstrap.php"
5
+ >
6
+ <php>
7
+ <ini name="display_errors" value="1" />
8
+ <ini name="display_startup_errors" value="1" />
9
+ </php>
10
+ <testsuites>
11
+ <testsuite name="Unit Tests">
12
+ <directory>./test/unit/</directory>
13
+ </testsuite>
14
+ <testsuite name="Functional Tests">
15
+ <directory>./test/functional/</directory>
16
+ </testsuite>
17
+ </testsuites>
18
+ <filter>
19
+ <whitelist processUncoveredFilesFromWhitelist="true">
20
+ <directory suffix=".php">src</directory>
21
+ </whitelist>
22
+ </filter>
23
+ <logging>
24
+ <log type="coverage-html" target="./test/coverage/html" lowUpperBound="35"
25
+ highLowerBound="80"/>
26
+ <log type="coverage-clover" target="./test/coverage/clover.xml"/>
27
+ <log type="coverage-php" target="./test/coverage/serialized"/>
28
+ <log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
29
+ <log type="json" target="./test/log/logfile.json"/>
30
+ <log type="tap" target="./test/log/logfile.tap"/>
31
+ <log type="junit" target="./test/log/logfile.xml" logIncompleteSkipped="false"/>
32
+ <log type="testdox-html" target="./test/log/testdox.html"/>
33
+ <log type="testdox-text" target="./test/log/testdox.txt"/>
34
+ </logging>
35
+ </phpunit>
vendor/dhii/di-abstract/src/AbstractCompositeContainer.php ADDED
@@ -0,0 +1,135 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+ use Interop\Container\Exception\NotFoundException;
7
+ use Traversable;
8
+
9
+ /**
10
+ * A container that can have many containers.
11
+ *
12
+ * @since 0.1
13
+ */
14
+ abstract class AbstractCompositeContainer extends AbstractParentAwareContainer
15
+ {
16
+ /**
17
+ * The prefix for container IDs.
18
+ *
19
+ * @since 0.1
20
+ */
21
+ const CONTAINER_ID_PREFIX = 'container-';
22
+
23
+ /**
24
+ * Adds a container.
25
+ *
26
+ * @since 0.1
27
+ *
28
+ * @param BaseContainerInterface $container The container to add.
29
+ *
30
+ * @return $this This instance.
31
+ */
32
+ protected function _add(BaseContainerInterface $container)
33
+ {
34
+ $this->_set($this->_createContainerId($container), function (BaseContainerInterface $c, $previous = null) use ($container) {
35
+ return $container;
36
+ });
37
+
38
+ return $this;
39
+ }
40
+
41
+ /**
42
+ * Generates a container ID.
43
+ *
44
+ * @since 0.1
45
+ *
46
+ * @param ContainerInterface $container The container for which an ID will be generated.
47
+ *
48
+ * @return string A new container ID, guaranteed to be unique in the scope of this container.
49
+ */
50
+ protected function _createContainerId(BaseContainerInterface $container)
51
+ {
52
+ do {
53
+ $id = uniqid(static::CONTAINER_ID_PREFIX);
54
+ } while ($this->_hasDefinition($id));
55
+
56
+ return $id;
57
+ }
58
+
59
+ /**
60
+ * Retrieves a service from the first child container that has its definition.
61
+ *
62
+ * @since 0.1
63
+ *
64
+ * @param string $id The ID of the service to retrieve.
65
+ *
66
+ * @return mixed The service.
67
+ *
68
+ * @throws NotFoundException If none of the inner containers have a matching service.
69
+ */
70
+ protected function _getDelegated($id)
71
+ {
72
+ if (!($having = $this->_hasDelegated($id))) {
73
+ throw $this->_createNotFoundException(sprintf('Could not create service for ID "%1$s": no service defined', $id));
74
+ }
75
+
76
+ return $having->get($id);
77
+ }
78
+
79
+ /**
80
+ * Determines which of the child containers has a service with the specified ID.
81
+ *
82
+ * @since 0.1
83
+ *
84
+ * @param string $id The ID of the service to check for.
85
+ *
86
+ * @return ContainerInterface|bool The container, which has the definition with the specified ID, if found;
87
+ * otherwise, false.
88
+ */
89
+ protected function _hasDelegated($id)
90
+ {
91
+ $containers = $this->_getContainersReversed();
92
+
93
+ foreach ($containers as $_container) {
94
+ if ($_container->has($id)) {
95
+ return $_container;
96
+ }
97
+ }
98
+
99
+ return false;
100
+ }
101
+
102
+ /**
103
+ * Gets the child containers.
104
+ *
105
+ * @since 0.1
106
+ * @see CompositeContainerInterface::getContainers()
107
+ *
108
+ * @return ContainerInterface[]|Traversable A list of containers.
109
+ */
110
+ protected function _getContainers()
111
+ {
112
+ $containers = array();
113
+ foreach ($this->serviceDefinitions as $_key => $_value) {
114
+ $service = $this->_get($_key);
115
+ if ($service instanceof BaseContainerInterface) {
116
+ $containers[$_key] = $service;
117
+ }
118
+ }
119
+
120
+ return $containers;
121
+ }
122
+
123
+ /**
124
+ * Gets the child containers in reverse order.
125
+ *
126
+ * @since 0.1
127
+ * @see CompositeContainerInterface::getContainers()
128
+ *
129
+ * @return ContainerInterface[]|Traversable A list of containers.
130
+ */
131
+ protected function _getContainersReversed()
132
+ {
133
+ return array_reverse($this->_getContainers());
134
+ }
135
+ }
vendor/dhii/di-abstract/src/AbstractContainer.php ADDED
@@ -0,0 +1,276 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\Exception\ContainerException as ContainerExceptionInterface;
6
+ use Interop\Container\Exception\NotFoundException as NotFoundExceptionInterface;
7
+ use Exception;
8
+ use Interop\Container\ServiceProvider as BaseServiceProvider;
9
+
10
+ /**
11
+ * Basic functionality of a DI container.
12
+ *
13
+ * @since 0.1
14
+ */
15
+ abstract class AbstractContainer
16
+ {
17
+ /**
18
+ * Cache for created service instances.
19
+ *
20
+ * @since 0.1
21
+ *
22
+ * @var array
23
+ */
24
+ protected $serviceCache = array();
25
+
26
+ /**
27
+ * The service definitions.
28
+ *
29
+ * @since 0.1
30
+ *
31
+ * @var callable[]
32
+ */
33
+ protected $serviceDefinitions = array();
34
+
35
+ /**
36
+ * Retrieves a service by its ID.
37
+ *
38
+ * @since 0.1
39
+ *
40
+ * @param string ID The ID of the service to retrieve.
41
+ *
42
+ * @throws NotFoundExceptionInterface If no service is registered with the given ID.
43
+ *
44
+ * @return mixed The service identified by the given ID.
45
+ */
46
+ protected function _get($id)
47
+ {
48
+ if ($this->_isCached($id)) {
49
+ return $this->_getCached($id);
50
+ }
51
+
52
+ $this->_cacheService($id, $this->_make($id));
53
+
54
+ return $this->_getCached($id);
55
+ }
56
+
57
+ /**
58
+ * Creates a new instance of a service.
59
+ *
60
+ * This can be exposed by a public method to implement FactoryInterface.
61
+ *
62
+ * @param string $id The ID of the service to create.
63
+ * @param mixed $config Some kind of configuration.
64
+ *
65
+ * @throws NotFoundExceptionInterface If no service is registered with the given ID.
66
+ *
67
+ * @return mixed The created service.
68
+ */
69
+ protected function _make($id, $config = array())
70
+ {
71
+ if (!($definition = $this->_getDefinition($id))) {
72
+ throw $this->_createNotFoundException(sprintf('Could not create service for ID "%1$s": no service defined', $id));
73
+ }
74
+
75
+ return $this->_resolveDefinition($definition, $config);
76
+ }
77
+
78
+ /**
79
+ * Checks if a service ID exists in this container.
80
+ *
81
+ * @since 0.1
82
+ *
83
+ * @return bool True if a definition with the specified ID exists in this container;
84
+ * false otherwise.
85
+ */
86
+ protected function _has($id)
87
+ {
88
+ return $this->_hasDefinition($id);
89
+ }
90
+
91
+ /**
92
+ * Registers a service or multiple services to this container.
93
+ *
94
+ * @since 0.1
95
+ *
96
+ * @param string|BaseServiceProvider $id The service ID, or a service provider
97
+ * @param callable|null $definition The service definition.
98
+ *
99
+ * @return $this This instance.
100
+ */
101
+ protected function _set($id, $definition = null)
102
+ {
103
+ if ($id instanceof BaseServiceProvider) {
104
+ $this->_register($id);
105
+
106
+ return $this;
107
+ }
108
+
109
+ $this->_setDefinition($id, $definition);
110
+
111
+ return $this;
112
+ }
113
+
114
+ /**
115
+ * Registers a service provider in this container.
116
+ *
117
+ * @since 0.1
118
+ *
119
+ * @param BaseServiceProvider $provider The service provider to register.
120
+ *
121
+ * @return $this This instance.
122
+ */
123
+ protected function _register(BaseServiceProvider $provider)
124
+ {
125
+ foreach ($provider->getServices() as $_id => $_definition) {
126
+ $this->_setDefinition($_id, $_definition);
127
+ }
128
+
129
+ return $this;
130
+ }
131
+
132
+ /**
133
+ * Retrieves the service definitions.
134
+ *
135
+ * @since 0.1
136
+ *
137
+ * @return callable[] An associative array of all the registered definitions, mapped by their ID.
138
+ */
139
+ protected function _getDefinitions()
140
+ {
141
+ return $this->serviceDefinitions;
142
+ }
143
+
144
+ /**
145
+ * Retrieves a service definition by ID.
146
+ *
147
+ * @since 0.1
148
+ *
149
+ * @param string $id The ID of the service to get the definition for.
150
+ *
151
+ * @return callable|null The service definition mapped to the given ID, if the ID is registered;
152
+ * otherwise null.
153
+ */
154
+ protected function _getDefinition($id)
155
+ {
156
+ return isset($this->serviceDefinitions[$id])
157
+ ? $this->serviceDefinitions[$id]
158
+ : null;
159
+ }
160
+
161
+ /**
162
+ * Checks if a service definition is registered to a given ID.
163
+ *
164
+ * @since 0.1
165
+ *
166
+ * @param string $id The ID of the service definition to check for.
167
+ *
168
+ * @return bool True if a definition with the specified ID is registered;
169
+ * otherwise false.
170
+ */
171
+ protected function _hasDefinition($id)
172
+ {
173
+ return isset($this->serviceDefinitions[$id]);
174
+ }
175
+
176
+ /**
177
+ * Registers a service definition.
178
+ *
179
+ * @since 0.1
180
+ *
181
+ * @param string $id The service ID.
182
+ * @param callable $definition The service definition.
183
+ */
184
+ protected function _setDefinition($id, $definition)
185
+ {
186
+ $this->serviceDefinitions[$id] = $definition;
187
+
188
+ return $this;
189
+ }
190
+
191
+ /**
192
+ * Retrieves the cached instance of a service.
193
+ *
194
+ * @since 0.1
195
+ *
196
+ * @param string $id The ID of the service to retrieve.
197
+ *
198
+ * @return mixed|null The cached service instance if found; otherwise null.
199
+ */
200
+ protected function _getCached($id)
201
+ {
202
+ return isset($this->serviceCache[$id])
203
+ ? $this->serviceCache[$id]
204
+ : null;
205
+ }
206
+
207
+ /**
208
+ * Checks if a service instance is cached.
209
+ *
210
+ * @since 0.1
211
+ *
212
+ * @param string $id The service ID to check.
213
+ *
214
+ * @return bool True if a service with this ID exists in cache; false otherwise.
215
+ */
216
+ protected function _isCached($id)
217
+ {
218
+ return isset($this->serviceCache[$id]);
219
+ }
220
+
221
+ /**
222
+ * Caches a service instance.
223
+ *
224
+ * @since 0.1
225
+ *
226
+ * @param string $id The ID of the service to cache.
227
+ * @param mixed $service The service.
228
+ *
229
+ * @return $this This instance.
230
+ */
231
+ protected function _cacheService($id, $service)
232
+ {
233
+ $this->serviceCache[$id] = $service;
234
+
235
+ return $this;
236
+ }
237
+
238
+ /**
239
+ * Resolves a service definition into a service instance.
240
+ *
241
+ * @since 0.1
242
+ *
243
+ * @param callable $definition The service definition.
244
+ * @param array $config An array of configuration arguments to pass to the definition.
245
+ *
246
+ * @throws ContainerExceptionInterface If the service definition is not a valid callable.
247
+ *
248
+ * @return mixed The service, to which the definition resolves.
249
+ */
250
+ protected function _resolveDefinition($definition, $config)
251
+ {
252
+ if (!is_callable($definition)) {
253
+ throw $this->_createContainerException(sprintf('Could not resolve service definition": definition must be callable'));
254
+ }
255
+
256
+ return call_user_func_array($definition, array($this, null, $config));
257
+ }
258
+
259
+ /**
260
+ * Creates a new exception that represents a case where a container entry is not found.
261
+ *
262
+ * @since 0.1
263
+ *
264
+ * @return NotFoundExceptionInterface The new exception instance.
265
+ */
266
+ abstract protected function _createNotFoundException($message, $code = 0, Exception $innerException = null);
267
+
268
+ /**
269
+ * Creates a new exception that represents a generic DI container error.
270
+ *
271
+ * @since 0.1
272
+ *
273
+ * @return ContainerExceptionInterface The new exception instance.
274
+ */
275
+ abstract protected function _createContainerException($message, $code = 0, Exception $innerException = null);
276
+ }
vendor/dhii/di-abstract/src/AbstractParentAwareContainer.php ADDED
@@ -0,0 +1,102 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+
7
+ /**
8
+ * Functionality that facilitates parent awareness of a container.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ abstract class AbstractParentAwareContainer extends AbstractContainer
13
+ {
14
+ /**
15
+ * The parent container instance.
16
+ *
17
+ * @since 0.1
18
+ *
19
+ * @var BaseContainerInterface
20
+ */
21
+ protected $parentContainer;
22
+
23
+ /**
24
+ * Retrieves the parent container instance.
25
+ *
26
+ * @since 0.1
27
+ *
28
+ * @return BaseContainerInterface|null The parent container or null if this container has no parent.
29
+ */
30
+ protected function _getParentContainer()
31
+ {
32
+ return ($this->_hasParentContainer())
33
+ ? $this->parentContainer
34
+ : null;
35
+ }
36
+
37
+ /**
38
+ * Checks if this container has a parent container.
39
+ *
40
+ * @since 0.1
41
+ *
42
+ * @return bool True if this container has a parent; false otherwise.
43
+ */
44
+ protected function _hasParentContainer()
45
+ {
46
+ return $this->parentContainer instanceof BaseContainerInterface;
47
+ }
48
+
49
+ /**
50
+ * Sets the parent container instance.
51
+ *
52
+ * @since 0.1
53
+ *
54
+ * @param BaseContainerInterface|null $container The parent container or null to remove the parent. Default: null
55
+ *
56
+ * @return $this This instance.
57
+ */
58
+ protected function _setParentContainer(BaseContainerInterface $container = null)
59
+ {
60
+ $this->parentContainer = $container;
61
+
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * Retrieves the container at the root of the hierarchy.
67
+ *
68
+ * @since 0.1
69
+ *
70
+ * @return BaseContainerInterface|null The top-most container in the chain, if exists;
71
+ * null otherwise.
72
+ */
73
+ protected function _getRootContainer()
74
+ {
75
+ $parent = $this->_getParentContainer();
76
+ do {
77
+ $root = $parent;
78
+
79
+ $parent = ($parent instanceof ParentAwareContainerInterface)
80
+ ? $parent->getParentContainer()
81
+ : null;
82
+ } while ($parent);
83
+
84
+ return $root;
85
+ }
86
+
87
+ /**
88
+ * {@inheritdoc}
89
+ *
90
+ * This is what does the magic.
91
+ *
92
+ * @since 0.1
93
+ * @see AbstractContainer::_resolveDefinition()
94
+ */
95
+ protected function _resolveDefinition($definition, $config)
96
+ {
97
+ $root = $this->_getRootContainer();
98
+ $container = $root ? $root : $this;
99
+
100
+ return call_user_func_array($definition, array($container, null, $config));
101
+ }
102
+ }
vendor/dhii/di-abstract/src/AbstractServiceProvider.php ADDED
@@ -0,0 +1,87 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\Exception\ContainerException as ContainerExceptionInterface;
6
+ use Interop\Container\ServiceProvider;
7
+
8
+ /**
9
+ * Abstract implementation of an object that can provide services.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ abstract class AbstractServiceProvider
14
+ {
15
+ /**
16
+ * The service definitions.
17
+ *
18
+ * @since 0.1
19
+ *
20
+ * @var callable[]
21
+ */
22
+ protected $serviceDefinitions = array();
23
+
24
+ /**
25
+ * Gets the service definitions.
26
+ *
27
+ * @since 0.1
28
+ * @see ServiceProvider::getServices()
29
+ *
30
+ * @return callable[]|\Traversable A list of service definitions.
31
+ */
32
+ protected function _getServices()
33
+ {
34
+ return $this->serviceDefinitions;
35
+ }
36
+
37
+ /**
38
+ * Adds a service definition to this provider.
39
+ *
40
+ * @since 0.1
41
+ *
42
+ * @param string $id The ID of the service definition.
43
+ * @param callable $definition The service definition.
44
+ *
45
+ * @throws ContainerException
46
+ */
47
+ protected function _add($id, $definition)
48
+ {
49
+ // Checking only format, because the definition may become available later
50
+ if (!is_callable($definition, true)) {
51
+ throw $this->_createContainerException(
52
+ sprintf('Could not add service definition with ID "%1$s": The definition must be a callable', $id)
53
+ );
54
+ }
55
+
56
+ $this->serviceDefinitions[$id] = $definition;
57
+
58
+ return $this;
59
+ }
60
+
61
+ /**
62
+ * Adds multiple service definitions to this provider.
63
+ *
64
+ * @since 0.1
65
+ *
66
+ * @param array|\Traversable $definitions An associative array of service definitions mapped by string keys.
67
+ *
68
+ * @return $this This instance.
69
+ */
70
+ protected function _addMany($definitions)
71
+ {
72
+ foreach ($definitions as $_id => $_definition) {
73
+ $this->_add($_id, $_definition);
74
+ }
75
+
76
+ return $this;
77
+ }
78
+
79
+ /**
80
+ * Creates a new exception that represents a generic DI container error.
81
+ *
82
+ * @since 0.1
83
+ *
84
+ * @return ContainerExceptionInterface The new exception instance.
85
+ */
86
+ abstract protected function _createContainerException($message, $code = 0, \Exception $innerException = null);
87
+ }
vendor/dhii/di-abstract/test/bootstrap.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ error_reporting(E_ALL | E_STRICT);
4
+
5
+ require_once dirname(__FILE__).'/../vendor/autoload.php';
vendor/dhii/di-abstract/test/functional/AbstractCompositeContainerTest.php ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Di\AbstractCompositeContainer}.
7
+ *
8
+ * The {@see Dhii\Di\Stub\AbstractCompositeContainerStub} class is used to make the test subject
9
+ * implement the {@see Interop\Container\ContainerInterface} interface.
10
+ *
11
+ * This is required for some tests to pass since the code of the test subject relies on the
12
+ * container being passed as the first argument to service factory closures to be a container
13
+ * that implements the standard interop interface.
14
+ *
15
+ * @since 0.1
16
+ */
17
+ class AbstractCompositeContainerTest extends \Xpmock\TestCase
18
+ {
19
+ /**
20
+ * The name of the test subject.
21
+ */
22
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\Stub\\AbstractCompositeContainerStub';
23
+
24
+ /**
25
+ * Creates a new instance of the test subject.
26
+ *
27
+ * @since 0.1
28
+ *
29
+ * @return AbstractCompositeContainer
30
+ */
31
+ public function createInstance(array $definitions = array())
32
+ {
33
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
34
+ ->_createNotFoundException(function ($msg, $code = 0, \Exception $prev = null) {
35
+ return new \Exception($msg, $code, $prev);
36
+ })
37
+ ->_createContainerException(function ($m, $code = 0, \Exception $prev = null) {
38
+ return new \Exception($m, $code, $prev);
39
+ })
40
+ ->new();
41
+
42
+ foreach ($definitions as $_id => $_definition) {
43
+ $mock->this()->serviceDefinitions = array_merge(
44
+ $mock->this()->serviceDefinitions,
45
+ array($_id => $_definition)
46
+ );
47
+ }
48
+
49
+ return $mock;
50
+ }
51
+
52
+ /**
53
+ * Creates a child container.
54
+ *
55
+ * This method differs from {@see createInstance} in that it creates the container mock from the
56
+ * {@see Interop\Container\ContainerInterface} interface rather than from
57
+ * {@see AbstractCompositeContainer} class.
58
+ *
59
+ * @param array $definitions Optional array of service definitions.
60
+ *
61
+ * @return ParentAwareContainerInterface The created instance.
62
+ */
63
+ public function createChildContainer(array $definitions = array())
64
+ {
65
+ $mock = $this->mock('Interop\\Container\\ContainerInterface')
66
+ ->has(function ($id) use ($definitions) {
67
+ return isset($definitions[$id]);
68
+ })
69
+ ->get(function ($id) use ($definitions) {
70
+ return call_user_func_array($definitions[$id], array(null, null));
71
+ })
72
+ ->new();
73
+
74
+ return $mock;
75
+ }
76
+
77
+ /**
78
+ * Create a service definition that returns a simple value.
79
+ *
80
+ * @param mixed $value The value that the service definition will return.
81
+ *
82
+ * @return callable A service definition that will return the given value.
83
+ */
84
+ public function createDefinition($value)
85
+ {
86
+ return function () use ($value) {
87
+ return $value;
88
+ };
89
+ }
90
+
91
+ /**
92
+ * Tests the container ID generator method to ensure that different containers result in
93
+ * different keys.
94
+ *
95
+ * @since 0.1
96
+ */
97
+ public function testCreateContainerId()
98
+ {
99
+ $subject = $this->createInstance();
100
+ $child1 = $this->createChildContainer();
101
+ $child2 = $this->createChildContainer();
102
+
103
+ $id1 = $subject->this()->_createContainerId($child1);
104
+ $id2 = $subject->this()->_createContainerId($child2);
105
+
106
+ $this->assertNotEquals($id1, $id2);
107
+ }
108
+
109
+ /**
110
+ * Tests the method that adds containers to ensure that the container is correctly registered
111
+ * inside a definition and that the definition correctly returns the same registered instance.
112
+ *
113
+ * @since 0.1
114
+ */
115
+ public function testAdd()
116
+ {
117
+ $subject = $this->createInstance();
118
+ $child = $this->createChildContainer();
119
+
120
+ $subject->this()->_add($child);
121
+
122
+ // Assert that container service definition has been added
123
+ $this->assertEquals(1, count($subject->this()->serviceDefinitions));
124
+
125
+ // Get generated container ID
126
+ $ids = array_keys($subject->this()->serviceDefinitions);
127
+ $childId = $ids[0];
128
+
129
+ // Assert that the container returned is the same instance that was added
130
+ $this->assertTrue($child === $subject->this()->_get($childId));
131
+ }
132
+
133
+ /**
134
+ * Tests the container getter method to ensure that the containers, and only containers,
135
+ * are correctly retrieved in an array - as instances and not definitions.
136
+ *
137
+ * @since 0.1
138
+ */
139
+ public function testGetContainers()
140
+ {
141
+ $subject = $this->createInstance();
142
+ $child1 = $this->createChildContainer();
143
+ $child2 = $this->createChildContainer();
144
+
145
+ // Add a non-container service in the mix.
146
+ // This should not be returned by `_getContainers()`
147
+ $subject->this()->serviceDefinitions = array(
148
+ $subject->this()->_createContainerId($child1) => $this->createDefinition($child1),
149
+ $subject->this()->_createContainerId($child2) => $this->createDefinition($child2),
150
+ 'test' => $this->createDefinition('random'),
151
+ );
152
+
153
+ $containers = array_values($subject->this()->_getContainers());
154
+
155
+ $this->assertEquals(array($child1, $child2), $containers);
156
+ }
157
+
158
+ /**
159
+ * Tests the container getter reverse method to ensure that the containers, and only containers,
160
+ * are correctly retrieved in reverse order as an array - as instances and not definitions.
161
+ *
162
+ * @since 0.1
163
+ */
164
+ public function testGetContainersReversed()
165
+ {
166
+ $subject = $this->createInstance();
167
+ $child1 = $this->createChildContainer();
168
+ $child2 = $this->createChildContainer();
169
+
170
+ // Add a non-container service in the mix.
171
+ // This should not be returned by `_getContainers()`
172
+ $subject->this()->serviceDefinitions = array(
173
+ $subject->this()->_createContainerId($child1) => $this->createDefinition($child1),
174
+ $subject->this()->_createContainerId($child2) => $this->createDefinition($child2),
175
+ 'test' => $this->createDefinition('random'),
176
+ );
177
+
178
+ $containers = array_values($subject->this()->_getContainers());
179
+
180
+ $this->assertEquals(array($child2, $child1), $containers);
181
+ }
182
+
183
+ /**
184
+ * Tests the method that checks if a service is delegated to a child container.
185
+ *
186
+ * The method is also expected to return the container instance that has the delegated service.
187
+ *
188
+ * In the event of service keys being registered across multiple child containers, the service
189
+ * will be retrieved from the last child container registered.
190
+ *
191
+ * @since 0.1
192
+ */
193
+ public function testHasDelegated()
194
+ {
195
+ $subject = $this->createInstance(array(
196
+ 'mine' => $this->createDefinition('service in self'),
197
+ ));
198
+ $child1 = $this->createChildContainer(array(
199
+ 'dupe' => $this->createDefinition('duplicate from 1'),
200
+ ));
201
+ $child2 = $this->createChildContainer(array(
202
+ 'test' => $this->createDefinition(123456),
203
+ 'dupe' => $this->createDefinition('duplicate from 2'),
204
+ ));
205
+
206
+ $subject->this()->serviceDefinitions = array(
207
+ $subject->this()->_createContainerId($child1) => $this->createDefinition($child1),
208
+ $subject->this()->_createContainerId($child2) => $this->createDefinition($child2),
209
+ );
210
+
211
+ // Nothing has "foobar"
212
+ $this->assertFalse($subject->this()->_hasDelegated('foobar'));
213
+
214
+ // Services in self container are not acknowledged
215
+ $this->assertFalse($subject->this()->_hasDelegated('mine'));
216
+
217
+ // Child2 has "test"
218
+ $this->assertEquals($child2, $subject->this()->_hasDelegated('test'));
219
+
220
+ // Both children have "dupe" but Child2 is the expected return since it was registered last
221
+ $this->assertEquals($child2, $subject->this()->_hasDelegated('dupe'));
222
+ }
223
+
224
+ /**
225
+ * Tests the method that checks if a service is delegated to a child container, when the containers
226
+ * are provided through an iterator.
227
+ *
228
+ * The method is also expected to return the container instance that has the delegated service.
229
+ *
230
+ * In the event of service keys being registered across multiple child containers, the service
231
+ * will be retrieved from the last child container registered.
232
+ *
233
+ * @since 0.1
234
+ */
235
+ public function testHasDelegatedIterator()
236
+ {
237
+ $child1 = $this->createChildContainer(array(
238
+ 'dupe' => $this->createDefinition('duplicate from 1'),
239
+ ));
240
+ $child2 = $this->createChildContainer(array(
241
+ 'test' => $this->createDefinition(123456),
242
+ 'dupe' => $this->createDefinition('duplicate from 2'),
243
+ ));
244
+
245
+ $subject = $this->mock(static::TEST_SUBJECT_CLASSNAME)
246
+ ->_createNotFoundException(function ($msg, $code = 0, Exception $prev = null) {
247
+ return new Exception($msg, $code, $prev);
248
+ })
249
+ ->_createContainerException(function ($m, $code = 0, Exception $prev = null) {
250
+ return new Exception($m, $code, $prev);
251
+ })
252
+ ->_getContainersReversed(function () use ($child1, $child2) {
253
+ // in reverse order
254
+ $containers = array(
255
+ uniqid('child2') => $child2,
256
+ uniqid('child1') => $child1
257
+ );
258
+ $iterator = new \AppendIterator();
259
+ $iterator->append(new \ArrayIterator($containers));
260
+ return $iterator;
261
+ })
262
+ ->new();
263
+
264
+ // Nothing has "foobar"
265
+ $this->assertFalse($subject->this()->_hasDelegated('foobar'));
266
+
267
+ // Services in self container are not acknowledged
268
+ $this->assertFalse($subject->this()->_hasDelegated('mine'));
269
+
270
+ // Child2 has "test"
271
+ $this->assertEquals($child2, $subject->this()->_hasDelegated('test'));
272
+
273
+ // Both children have "dupe" but Child2 is the expected return since it was registered last
274
+ $this->assertEquals($child2, $subject->this()->_hasDelegated('dupe'));
275
+ }
276
+
277
+ /**
278
+ * Tests the delegated service getter method to ensure that any services that are registered
279
+ * to child containers are retrievable.
280
+ *
281
+ * This test also ensures that in the event of service keys being registered across multiple
282
+ * child containers, the service will be retrieved from the last child container registered.
283
+ *
284
+ * @since 0.1
285
+ */
286
+ public function testGetDelegated()
287
+ {
288
+ $subject = $this->createInstance();
289
+
290
+ $child1 = $this->createChildContainer(array(
291
+ 'dupe' => $this->createDefinition('duplicate from 1'),
292
+ ));
293
+ $child2 = $this->createChildContainer(array(
294
+ 'test' => $this->createDefinition(123456),
295
+ 'dupe' => $this->createDefinition('duplicate from 2'),
296
+ ));
297
+
298
+ $subject->this()->serviceDefinitions = array(
299
+ $subject->this()->_createContainerId($child1) => $this->createDefinition($child1),
300
+ $subject->this()->_createContainerId($child2) => $this->createDefinition($child2),
301
+ );
302
+
303
+ $this->assertEquals(123456, $subject->this()->_getDelegated('test'));
304
+
305
+ $this->assertEquals('duplicate from 2', $subject->this()->_getDelegated('dupe'));
306
+ }
307
+
308
+ /**
309
+ * Tests that the composite container will throw an exception if none of the
310
+ * child containers have a matching service.
311
+ *
312
+ * @expectedException \Exception
313
+ * @expectedExceptionMessage no service defined
314
+ *
315
+ * @since 0.1
316
+ */
317
+ public function testGetDelegatedThrowsNotFound()
318
+ {
319
+ $subject = $this->createInstance();
320
+ $reflection = $this->reflect($subject);
321
+
322
+ $child1 = $this->createChildContainer(array(
323
+ 'test1' => $this->createDefinition(321654),
324
+ ));
325
+ $child2 = $this->createChildContainer(array(
326
+ 'test2' => $this->createDefinition(123456),
327
+ 'test3' => $this->createDefinition('asdasdasd'),
328
+ ));
329
+
330
+ $reflection->serviceDefinitions = array(
331
+ $reflection->_createContainerId($child1) => $this->createDefinition($child1),
332
+ $reflection->_createContainerId($child2) => $this->createDefinition($child2),
333
+ );
334
+
335
+ $reflection->_getDelegated('non existing service');
336
+ }
337
+ }
vendor/dhii/di-abstract/test/functional/AbstractContainerTest.php ADDED
@@ -0,0 +1,458 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\AbstractContainer;
6
+ use Exception;
7
+ use Interop\Container\ServiceProvider;
8
+ use Xpmock\TestCase;
9
+
10
+ /**
11
+ * Tests {@see Dhii\Di\AbstractContainer}.
12
+ *
13
+ * @since 0.1
14
+ */
15
+ class AbstractContainerTest extends TestCase
16
+ {
17
+ /**
18
+ * The name of the test subject.
19
+ */
20
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\AbstractContainer';
21
+
22
+ /**
23
+ * Creates a new instance of the test subject.
24
+ *
25
+ * @since 0.1
26
+ *
27
+ * @param ServiceProvider $provider Optional service provider. Default: null
28
+ *
29
+ * @return AbstractContainer
30
+ */
31
+ public function createInstance(ServiceProvider $provider = null)
32
+ {
33
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
34
+ ->_createNotFoundException(function ($msg, $code = 0, Exception $prev = null) {
35
+ return new Exception($msg, $code, $prev);
36
+ })
37
+ ->_createContainerException(function ($m, $code = 0, Exception $prev = null) {
38
+ return new Exception($m, $code, $prev);
39
+ })
40
+ ->new();
41
+
42
+ if ($provider !== null) {
43
+ foreach ($provider->getServices() as $_id => $_definition) {
44
+ $mock->this()->serviceDefinitions = array_merge(
45
+ $mock->this()->serviceDefinitions,
46
+ array($_id => $_definition)
47
+ );
48
+ }
49
+ }
50
+
51
+ return $mock;
52
+ }
53
+
54
+ /**
55
+ * Creates a service provider.
56
+ *
57
+ * @since 0.1
58
+ *
59
+ * @param array $definitions The service definitions.
60
+ *
61
+ * @return ServiceProvider
62
+ */
63
+ public function createServiceProvider(array $definitions = array())
64
+ {
65
+ $mock = $this->mock('Interop\\Container\\ServiceProvider')
66
+ ->getServices(function () use ($definitions) {
67
+ return $definitions;
68
+ })
69
+ ->new();
70
+
71
+ return $mock;
72
+ }
73
+
74
+ /**
75
+ * Create a service definition that returns a simple value.
76
+ *
77
+ * @since 0.1
78
+ *
79
+ * @param mixed $value The value that the service definition will return.
80
+ *
81
+ * @return callable A service definition that will return the given value.
82
+ */
83
+ public function createDefinition($value)
84
+ {
85
+ return function ($container, $previous = null) use ($value) {
86
+ return $value;
87
+ };
88
+ }
89
+
90
+ /**
91
+ * Tests whether a valid instance of the test subject can be created.
92
+ *
93
+ * @since 0.1
94
+ */
95
+ public function testCanBeCreated()
96
+ {
97
+ $subject = $this->createInstance();
98
+
99
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
100
+ }
101
+
102
+ /**
103
+ * Tests the service getter to retrieve a new service instance.
104
+ *
105
+ * @since 0.1
106
+ */
107
+ public function testGetNewService()
108
+ {
109
+ $serviceProvider = $this->createServiceProvider(array(
110
+ 'test' => function () {
111
+ return new \SplObjectStorage();
112
+ },
113
+ ));
114
+
115
+ $subject = $this->createInstance($serviceProvider);
116
+
117
+ $this->assertEquals(new \SplObjectStorage(), $subject->this()->_get('test'));
118
+ }
119
+
120
+ /**
121
+ * Tests the service getter to ensure that multiple retrievals of the same service return
122
+ * the same instance.
123
+ *
124
+ * @since 0.1
125
+ */
126
+ public function testGetSameService()
127
+ {
128
+ $serviceProvider = $this->createServiceProvider(array(
129
+ 'test' => function () {
130
+ return new \SplObjectStorage();
131
+ },
132
+ ));
133
+
134
+ $subject = $this->createInstance($serviceProvider);
135
+
136
+ // Get first time
137
+ $first = $subject->this()->_get('test');
138
+
139
+ $this->assertTrue($first === $subject->this()->_get('test'));
140
+ }
141
+
142
+ /**
143
+ * Tests the factory method to ensure that a new service instance is created.
144
+ *
145
+ * @since 0.1
146
+ */
147
+ public function testMakeOnce()
148
+ {
149
+ $serviceProvider = $this->createServiceProvider(array(
150
+ 'test' => function () {
151
+ return new \SplObjectStorage();
152
+ },
153
+ ));
154
+
155
+ $subject = $this->createInstance($serviceProvider);
156
+
157
+ $this->assertFalse($subject->this()->_get('test') === $subject->this()->_make('test'));
158
+ }
159
+
160
+ /**
161
+ * Tests the factory method to ensure that multiple calls still result in different instances.
162
+ *
163
+ * @since 0.1
164
+ */
165
+ public function testMakeTwice()
166
+ {
167
+ $serviceProvider = $this->createServiceProvider(array(
168
+ 'test' => function () {
169
+ return new \SplObjectStorage();
170
+ },
171
+ ));
172
+
173
+ $subject = $this->createInstance($serviceProvider);
174
+
175
+ $this->assertFalse($subject->this()->_make('test') === $subject->this()->_make('test'));
176
+ }
177
+
178
+ /**
179
+ * Tests that the container throws correct exception when service not found.
180
+ *
181
+ * @expectedException \Exception
182
+ * @expectedExceptionMessage no service defined
183
+ *
184
+ * @since 0.1
185
+ */
186
+ public function testMakeThrowsNotFound()
187
+ {
188
+ $serviceProvider = $this->createServiceProvider(array(
189
+ 'test' => function () {
190
+ return new \SplObjectStorage();
191
+ },
192
+ ));
193
+
194
+ $subject = $this->createInstance($serviceProvider);
195
+ $reflection = $this->reflect($subject);
196
+ $reflection->_make('non_existing');
197
+ }
198
+
199
+ /**
200
+ * Tests the service ID checker method.
201
+ *
202
+ * @since 0.1
203
+ */
204
+ public function testHas()
205
+ {
206
+ $serviceProvider = $this->createServiceProvider(array(
207
+ 'one' => $this->createDefinition(1),
208
+ 'two' => $this->createDefinition(2),
209
+ 'three' => $this->createDefinition(3),
210
+ ));
211
+
212
+ $subject = $this->createInstance($serviceProvider);
213
+
214
+ $this->assertTrue($subject->this()->_has('one'));
215
+ $this->assertTrue($subject->this()->_has('two'));
216
+ $this->assertTrue($subject->this()->_has('three'));
217
+ $this->assertFalse($subject->this()->_has('random'));
218
+ }
219
+
220
+ /**
221
+ * Tests the method that registers a service provider to ensure that all services are
222
+ * correctly registered from the provider to the container.
223
+ *
224
+ * @since 0.1
225
+ */
226
+ public function testRegister()
227
+ {
228
+ $subject = $this->createInstance();
229
+ $provider = $this->createServiceProvider(array(
230
+ 'one' => $this->createDefinition(1),
231
+ 'two' => $this->createDefinition(2),
232
+ 'three' => $this->createDefinition(3),
233
+ ));
234
+ $expected = $provider->getServices();
235
+
236
+ $subject->this()->_register($provider);
237
+
238
+ $this->assertEquals($expected, $subject->this()->serviceDefinitions);
239
+ }
240
+
241
+ /**
242
+ * Tests the definition setter method to ensure that the definition is correctly registered
243
+ * to the container.
244
+ *
245
+ * @since 0.1
246
+ */
247
+ public function testSetDefintion()
248
+ {
249
+ $subject = $this->createInstance();
250
+ $definition = $this->createDefinition('test');
251
+ $expected = array('test' => $definition);
252
+
253
+ $subject->this()->_setDefinition('test', $definition);
254
+
255
+ $this->assertEquals($expected, $subject->this()->serviceDefinitions);
256
+ }
257
+
258
+ /**
259
+ * Tests the main setter method with a service definition to ensure that the
260
+ * service definition is correctly registered in the container.
261
+ *
262
+ * @since 0.1
263
+ */
264
+ public function testSetWithDefinition()
265
+ {
266
+ $subject = $this->createInstance();
267
+ $definition = $this->createDefinition('test');
268
+ $expected = array('test' => $definition);
269
+
270
+ $subject->this()->_set('test', $definition);
271
+
272
+ $this->assertEquals($expected, $subject->this()->serviceDefinitions);
273
+ }
274
+
275
+ /**
276
+ * Tests the main setter method with a service definition to ensure that the
277
+ * service definition is correctly registered in the container.
278
+ *
279
+ * @since 0.1
280
+ */
281
+ public function testSetWithProvider()
282
+ {
283
+ $subject = $this->createInstance();
284
+ $provider = $this->createServiceProvider(array(
285
+ 'one' => $this->createDefinition(1),
286
+ 'two' => $this->createDefinition(2),
287
+ 'three' => $this->createDefinition(3),
288
+ ));
289
+ $expected = $provider->getServices();
290
+
291
+ $subject->this()->_set($provider);
292
+
293
+ $this->assertEquals($expected, $subject->this()->serviceDefinitions);
294
+ }
295
+
296
+ /**
297
+ * Tests the definitions getter method to ensure that the definitions returned
298
+ * all correct, previously registered definitions.
299
+ *
300
+ * @since 0.1
301
+ */
302
+ public function testGetDefinitions()
303
+ {
304
+ $provider = $this->createServiceProvider(array(
305
+ 'one' => $this->createDefinition(1),
306
+ 'two' => $this->createDefinition(2),
307
+ 'three' => $this->createDefinition(3),
308
+ ));
309
+ $subject = $this->createInstance($provider);
310
+ $expected = $provider->getServices();
311
+
312
+ $this->assertEquals($expected, $subject->this()->_getDefinitions());
313
+ }
314
+
315
+ /**
316
+ * Tests the single definition getter method to ensure that it returns the
317
+ * correct definition when given an existing ID and `null` when given a
318
+ * non-existing ID.
319
+ *
320
+ * @since 0.1
321
+ */
322
+ public function testGetDefinition()
323
+ {
324
+ $subject = $this->createInstance();
325
+ $definition = $this->createDefinition('test');
326
+
327
+ $subject->this()->_set('one', $definition);
328
+ $subject->this()->_set('two', $this->createDefinition('two'));
329
+
330
+ $this->assertEquals($definition, $subject->this()->_getDefinition('one'));
331
+ $this->assertEquals(null, $subject->this()->_getDefinition('random'));
332
+ }
333
+
334
+ /**
335
+ * Tests the definition checker method to ensure that it correctly asserts
336
+ * if the container has specific definitions, by ID.
337
+ *
338
+ * @since 0.1
339
+ */
340
+ public function testHasDefinition()
341
+ {
342
+ $subject = $this->createInstance();
343
+
344
+ $subject->this()->_set('test', $this->createDefinition('test'));
345
+
346
+ $this->assertTrue($subject->this()->_hasDefinition('test'));
347
+ $this->assertFalse($subject->this()->_hasDefinition('random'));
348
+ }
349
+
350
+ /**
351
+ * Tests the cached service instance getter method to assert whether
352
+ * previously retrieved services are correctly cached while others
353
+ * are not.
354
+ *
355
+ * @since 0.1
356
+ */
357
+ public function testGetCached()
358
+ {
359
+ $definitions = array(
360
+ 'one' => $this->createDefinition(1),
361
+ 'two' => $this->createDefinition(2),
362
+ 'three' => $this->createDefinition(3),
363
+ );
364
+ $provider = $this->createServiceProvider($definitions);
365
+ $subject = $this->createInstance($provider);
366
+
367
+ // Call `_get()` to cache the instance
368
+ $subject->this()->_get('one');
369
+
370
+ $this->assertEquals(1, $subject->this()->_getCached('one'));
371
+ $this->assertEquals(null, $subject->this()->_getCached('two'));
372
+ $this->assertEquals(null, $subject->this()->_getCached('three'));
373
+ }
374
+
375
+ /**
376
+ * Tests the cached service instance checker method to ensure that
377
+ * it correctly asserts whether a service instance is cached or not.
378
+ *
379
+ * @since 0.1
380
+ */
381
+ public function testIsCached()
382
+ {
383
+ $definitions = array(
384
+ 'one' => $this->createDefinition(1),
385
+ 'two' => $this->createDefinition(2),
386
+ 'three' => $this->createDefinition(3),
387
+ );
388
+ $provider = $this->createServiceProvider($definitions);
389
+ $subject = $this->createInstance($provider);
390
+
391
+ // Call `_get()` to cache the instance
392
+ $subject->this()->_get('two');
393
+
394
+ $this->assertFalse($subject->this()->_isCached('one'));
395
+ $this->assertTrue($subject->this()->_isCached('two'));
396
+ $this->assertFalse($subject->this()->_isCached('three'));
397
+ }
398
+
399
+ /**
400
+ * Tests the service caching method to ensure that the given service is
401
+ * correctly cached.
402
+ *
403
+ * @since 0.1
404
+ */
405
+ public function testCacheService()
406
+ {
407
+ // Add some definitions to be sure
408
+ $definitions = array(
409
+ 'one' => $this->createDefinition(1),
410
+ 'two' => $this->createDefinition(2),
411
+ );
412
+ $provider = $this->createServiceProvider($definitions);
413
+ $subject = $this->createInstance($provider);
414
+
415
+ $subject->this()->_cacheService('three', $this->createDefinition(3));
416
+ $expected = array('three' => $this->createDefinition(3));
417
+
418
+ $this->assertEquals($expected, $subject->this()->services);
419
+ }
420
+
421
+ /**
422
+ * Tests the definition resolver method to ensure that a valid service instance
423
+ * is created.
424
+ *
425
+ * @since 0.1
426
+ */
427
+ public function testResolveDefinition()
428
+ {
429
+ $definition = function ($container, $previous = null, $args) {
430
+ return new \DateTimeZone($args['tz']);
431
+ };
432
+ $subject = $this->createInstance();
433
+ $resolved = $subject->this()->_resolveDefinition(
434
+ $definition,
435
+ array('tz' => 'Europe/Malta')
436
+ );
437
+
438
+ $this->assertEquals(new \DateTimeZone('Europe/Malta'), $resolved);
439
+ }
440
+
441
+ /**
442
+ * Tests to ensure that an exception is thrown when definition is invalid.
443
+ *
444
+ * @expectedException \Exception
445
+ * @expectedExceptionMessage must be callable
446
+ *
447
+ * @since 0.1
448
+ */
449
+ public function testResolveDefinitionThrowsInvalid()
450
+ {
451
+ $definition = 'invalid definition';
452
+ $subject = $this->createInstance();
453
+ $subject->this()->_resolveDefinition(
454
+ $definition,
455
+ array()
456
+ );
457
+ }
458
+ }
vendor/dhii/di-abstract/test/functional/AbstractParentAwareContainerTest.php ADDED
@@ -0,0 +1,270 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Interop\Container\ContainerInterface;
6
+ use Dhii\Di\AbstractParentAwareContainer;
7
+ use Exception;
8
+ use Interop\Container\ServiceProvider;
9
+ use Xpmock\TestCase;
10
+
11
+ /**
12
+ * Tests {@see Dhii\Di\AbstractParentAwareContainer}.
13
+ *
14
+ * @since 0.1
15
+ */
16
+ class AbstractParentAwareContainerTest extends TestCase
17
+ {
18
+ /**
19
+ * The name of the test subject.
20
+ */
21
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\AbstractParentAwareContainer';
22
+
23
+ /**
24
+ * Creates a new instance of the test subject.
25
+ *
26
+ * @since 0.1
27
+ *
28
+ * @return AbstractParentAwareContainer
29
+ */
30
+ public function createInstance(ServiceProvider $provider = null, ContainerInterface $parent = null)
31
+ {
32
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
33
+ ->_createNotFoundException(function ($msg, $code = 0, Exception $prev = null) {
34
+ return new Exception($msg, $code, $prev);
35
+ })
36
+ ->_createContainerException(function ($m, $code = 0, Exception $prev = null) {
37
+ return new Exception($m, $code, $prev);
38
+ })
39
+ ->new();
40
+
41
+ if ($provider !== null) {
42
+ foreach ($provider->getServices() as $_id => $_definition) {
43
+ $mock->this()->serviceDefinitions = array_merge(
44
+ $mock->this()->serviceDefinitions,
45
+ array($_id => $_definition)
46
+ );
47
+ }
48
+ }
49
+
50
+ $mock->this()->parentContainer = $parent;
51
+
52
+ return $mock;
53
+ }
54
+
55
+ /**
56
+ * Creates a parent container.
57
+ *
58
+ * This method differs from {@see createInstance} in that it creates the container mock from the
59
+ * {@see ParentAwareContainerInterface} rather than from {@see AbstractParentAwareContainer}.
60
+ *
61
+ * @param array $definitions Optional array of service definitions.
62
+ * @param ContainerInterface $parent Optional parent container.
63
+ *
64
+ * @return ParentAwareContainerInterface The created instance.
65
+ */
66
+ public function createParentContainer(array $definitions = array(), $parent = null)
67
+ {
68
+ $mock = $this->mock('Dhii\\Di\\ParentAwareContainerInterface')
69
+ ->has(function ($id) use ($definitions) {
70
+ return isset($definitions[$id]);
71
+ })
72
+ ->get(function ($id) use ($definitions) {
73
+ return $definitions[$id];
74
+ })
75
+ ->getParentContainer(function () use ($parent) {
76
+ return $parent;
77
+ })
78
+ ->new();
79
+
80
+ return $mock;
81
+ }
82
+
83
+ /**
84
+ * Creates a service provider.
85
+ *
86
+ * @param array $definitions The service definitions.
87
+ *
88
+ * @return ServiceProvider
89
+ */
90
+ public function createServiceProvider(array $definitions = array())
91
+ {
92
+ $mock = $this->mock('Interop\\Container\\ServiceProvider')
93
+ ->getServices(function () use ($definitions) {
94
+ return $definitions;
95
+ })
96
+ ->new();
97
+
98
+ return $mock;
99
+ }
100
+
101
+ /**
102
+ * Create a service definition that returns a simple value.
103
+ *
104
+ * @param mixed $value The value that the service definition will return.
105
+ *
106
+ * @return callable A service definition that will return the given value.
107
+ */
108
+ public function createDefinition($value)
109
+ {
110
+ return function ($container, $previous = null) use ($value) {
111
+ return $value;
112
+ };
113
+ }
114
+
115
+ /**
116
+ * Tests whether a valid instance of the test subject can be created.
117
+ *
118
+ * @since 0.1
119
+ */
120
+ public function testCanBeCreated()
121
+ {
122
+ $subject = $this->createInstance();
123
+
124
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
125
+ }
126
+
127
+ /**
128
+ * Tests the parent container checker method when the container has no parent.
129
+ *
130
+ * @since 0.1
131
+ */
132
+ public function testHasParentContainerNoParent()
133
+ {
134
+ $subject = $this->createInstance();
135
+
136
+ $this->assertFalse($subject->this()->_hasParentContainer());
137
+ }
138
+
139
+ /**
140
+ * Tests the parent container checker method when the container has a parent.
141
+ *
142
+ * @since 0.1
143
+ */
144
+ public function testHasParentContainerWithParent()
145
+ {
146
+ $parent = $this->createParentContainer();
147
+ $subject = $this->createInstance(null, $parent);
148
+
149
+ $this->assertTrue($subject->this()->_hasParentContainer());
150
+ }
151
+
152
+ /**
153
+ * Tests the parent container getter method when the container has no parent.
154
+ *
155
+ * @since 0.1
156
+ */
157
+ public function testGetParentContainerNoParent()
158
+ {
159
+ $subject = $this->createInstance();
160
+
161
+ $this->assertNull($subject->this()->_getParentContainer());
162
+ }
163
+
164
+ /**
165
+ * Tests the parent container getter method when the container has a parent.
166
+ *
167
+ * @since 0.1
168
+ */
169
+ public function testGetParentContainerWithParent()
170
+ {
171
+ $parent = $this->createParentContainer();
172
+ $subject = $this->createInstance(null, $parent);
173
+
174
+ $this->assertEquals($parent, $subject->this()->_getParentContainer());
175
+ }
176
+
177
+ /**
178
+ * Tests the parent container setter method with a container argument.
179
+ *
180
+ * @since 0.1
181
+ */
182
+ public function testSetParentContainer()
183
+ {
184
+ $subject = $this->createInstance();
185
+ $parent = $this->createParentContainer();
186
+
187
+ $subject->this()->_setParentContainer($parent);
188
+
189
+ $this->assertEquals($parent, $subject->this()->parentContainer);
190
+ }
191
+
192
+ /**
193
+ * Tests the parent container setter method with a container argument and then a null
194
+ * argument to assert if the parent container previously set is correctly cleared.
195
+ *
196
+ * @since 0.1
197
+ */
198
+ public function testSetParentContainerNull()
199
+ {
200
+ $subject = $this->createInstance();
201
+ $parent = $this->createParentContainer();
202
+
203
+ $subject->this()->_setParentContainer($parent);
204
+ $subject->this()->_setParentContainer(null);
205
+
206
+ $this->assertNull($subject->this()->parentContainer);
207
+ }
208
+
209
+ /**
210
+ * Tests the root container resolver method with a single level of parent hierarchy.
211
+ *
212
+ * @since 0.1
213
+ */
214
+ public function testGetRootContainerOneLevel()
215
+ {
216
+ $parent = $this->createParentContainer();
217
+ $subject = $this->createInstance(null, $parent);
218
+
219
+ $this->assertEquals($parent, $subject->this()->_getRootContainer());
220
+ }
221
+
222
+ /**
223
+ * Tests the root container resolver method with two levels of parent hierarchy.
224
+ *
225
+ * @since 0.1
226
+ */
227
+ public function testGetRootContainerTwoLevels()
228
+ {
229
+ $root = $this->createParentContainer();
230
+ $parent = $this->createParentContainer(array(), $root);
231
+ $subject = $this->createInstance(null, $parent);
232
+
233
+ $this->assertEquals($root, $subject->this()->_getRootContainer());
234
+ }
235
+
236
+ /**
237
+ * Tests the definition resolver method to ensure that a valid service instance
238
+ * is created.
239
+ *
240
+ * It also ensures that the container instance passed as argument to the service factory closure
241
+ * is the root container of the hierarchy.
242
+ *
243
+ * @since 0.1
244
+ */
245
+ public function testResolveDefinition()
246
+ {
247
+ $root = $this->createParentContainer();
248
+ $parent = $this->createParentContainer(array(), $root);
249
+ $subject = $this->createInstance(null, $parent);
250
+
251
+ // Service resolves to passed args with the container instance appended at index `c`
252
+ $definition = function ($container, $previous = null, $args) {
253
+ return array_merge(
254
+ $args,
255
+ array('c' => $container)
256
+ );
257
+ };
258
+
259
+ $resolved = $subject->this()->_resolveDefinition($definition, array(
260
+ 'num' => 12345,
261
+ ));
262
+
263
+ $expected = array(
264
+ 'num' => 12345,
265
+ 'c' => $root,
266
+ );
267
+
268
+ $this->assertEquals($expected, $resolved);
269
+ }
270
+ }
vendor/dhii/di-abstract/test/functional/AbstractServiceProviderTest.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Exception;
6
+ use Dhii\Di\AbstractContainer;
7
+ use Interop\Container\ServiceProvider;
8
+ use Dhii\Di\Stub\ContainerException;
9
+ use Xpmock\TestCase;
10
+
11
+ /**
12
+ * Tests {@see Dhii\Di\AbstractServiceProvider}.
13
+ *
14
+ * @since 0.1
15
+ */
16
+ class AbstractServiceProviderTest extends TestCase
17
+ {
18
+ /**
19
+ * The name of the test subject.
20
+ */
21
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\AbstractServiceProvider';
22
+
23
+ /**
24
+ * Creates a new instance of the test subject.
25
+ *
26
+ * @since 0.1
27
+ *
28
+ * @param ServiceProvider $provider Optional service provider. Default: null
29
+ *
30
+ * @return AbstractContainer
31
+ */
32
+ public function createInstance(array $definitions = array())
33
+ {
34
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
35
+ ->_createContainerException(function ($m, $code = 0, Exception $prev = null) {
36
+ return new ContainerException($m, $code, $prev);
37
+ })
38
+ ->new();
39
+
40
+ foreach ($definitions as $_id => $_definition) {
41
+ $mock->this()->serviceDefinitions = array_merge(
42
+ $mock->this()->serviceDefinitions,
43
+ array($_id => $_definition)
44
+ );
45
+ }
46
+
47
+ return $mock;
48
+ }
49
+
50
+ /**
51
+ * Create a service definition that returns a simple value.
52
+ *
53
+ * @param mixed $value The value that the service definition will return.
54
+ *
55
+ * @return callable A service definition that will return the given value.
56
+ */
57
+ public function createDefinition($value)
58
+ {
59
+ return function ($container = null, $previous = null) use ($value) {
60
+ return $value;
61
+ };
62
+ }
63
+
64
+ /**
65
+ * Tests the service getter method to ensure that all services are correctly retrieved in an array.
66
+ *
67
+ * @since 0.1
68
+ */
69
+ public function testGetServices()
70
+ {
71
+ $definitions = array(
72
+ 'one' => $this->createDefinition('one'),
73
+ 'two' => $this->createDefinition(2),
74
+ 'three' => $this->createDefinition('three'),
75
+ );
76
+ $subject = $this->createInstance($definitions);
77
+
78
+ $this->assertEquals($definitions, $subject->this()->_getServices());
79
+ }
80
+
81
+ /**
82
+ * Tests the service definition registration method to ensure that definitions are correctly
83
+ * registered in the provider.
84
+ *
85
+ * @since 0.1
86
+ */
87
+ public function testAdd()
88
+ {
89
+ $subject = $this->createInstance();
90
+
91
+ $subject->this()->_add('test', $this->createDefinition('this is a test'));
92
+ $subject->this()->_add('pi', $this->createDefinition(3.14159265359));
93
+
94
+ $this->assertArrayHasKey('test', $subject->this()->serviceDefinitions);
95
+ $this->assertArrayHasKey('pi', $subject->this()->serviceDefinitions);
96
+ }
97
+
98
+ /**
99
+ * Tests the multiple service definition registration method to ensure that definitions are
100
+ * correctly registered in the provider.
101
+ *
102
+ * @since 0.1
103
+ */
104
+ public function testAddMany()
105
+ {
106
+ $subject = $this->createInstance();
107
+
108
+ $subject->this()->_addMany(array(
109
+ 'test' => $this->createDefinition('this is a test'),
110
+ 'pi' => $this->createDefinition(3.14159265359)
111
+ ));
112
+
113
+ $this->assertArrayHasKey('test', $subject->this()->serviceDefinitions);
114
+ $this->assertArrayHasKey('pi', $subject->this()->serviceDefinitions);
115
+ }
116
+
117
+ /**
118
+ * Tests the service definition registration method with an invalid definition to ensure that an
119
+ * exception is thrown in such cases.
120
+ *
121
+ * @since 0.1
122
+ */
123
+ public function testAddInvalidDefinition()
124
+ {
125
+ $subject = $this->createInstance();
126
+
127
+ $this->setExpectedException('\\Interop\\Container\\Exception\\ContainerException');
128
+
129
+ $subject->this()->_add('test', new \DOMText('this is not a definition!'));
130
+ }
131
+ }
vendor/dhii/di-abstract/test/stub/AbstractCompositeContainerStub.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\Stub;
4
+
5
+ use Dhii\Di\AbstractCompositeContainer;
6
+ use Interop\Container\ContainerInterface;
7
+
8
+ /**
9
+ * Stub class - used for testing the {@see AbstractCompositeContainer}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ abstract class AbstractCompositeContainerStub extends AbstractCompositeContainer
14
+ implements ContainerInterface
15
+ {
16
+ public function get($id)
17
+ {
18
+ return $this->_get($id);
19
+ }
20
+
21
+ public function has($id)
22
+ {
23
+ return $this->_has($id);
24
+ }
25
+ }
vendor/dhii/di-abstract/test/stub/ContainerException.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\Stub;
4
+
5
+ use Exception;
6
+ use Interop\Container\Exception\ContainerException as BaseContainerException;
7
+
8
+ /**
9
+ * Stub class for container exceptions.
10
+ *
11
+ * Used in testing to allow mocked methods to throw {@see Exception} instances that implement {@see ContainerException}.
12
+ *
13
+ * @since 0.1
14
+ */
15
+ class ContainerException extends Exception implements BaseContainerException
16
+ {
17
+ }
vendor/dhii/di-interface/.codeclimate.yml ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ---
2
+ engines:
3
+ duplication:
4
+ enabled: true
5
+ config:
6
+ languages:
7
+ - php
8
+ fixme:
9
+ enabled: true
10
+ phpmd:
11
+ enabled: true
12
+ ratings:
13
+ paths:
14
+ - "**.inc"
15
+ - "**.php"
16
+ exclude_paths:
17
+ - test/
vendor/dhii/di-interface/.php_cs ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
3
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
4
+ $fixers = $config->getFixers();
5
+ $toRemove = array();
6
+ foreach ($toRemove as $_fixer) {
7
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
8
+ continue;
9
+ }
10
+
11
+ unset($fixers[$removeIndex]);
12
+ }
13
+ $toAdd = array();
14
+ foreach ($toAdd as $_fixer) {
15
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
16
+ continue;
17
+ }
18
+
19
+ $fixers[] = $_fixer;
20
+ }
21
+ $config->fixers($fixers);
22
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
23
+ return $config;
vendor/dhii/di-interface/.travis.yml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ language: php
2
+ php:
3
+ - '5.3'
4
+ - '5.4'
5
+ - '5.5'
6
+ - '5.6'
7
+ - '7.0'
8
+ - '7.1'
9
+ - nightly
10
+
11
+ before_script:
12
+ - composer update
13
+
14
+ script:
15
+ - vendor/bin/phpunit
16
+
17
+ after_script:
18
+ - vendor/bin/test-reporter --coverage-report="test/coverage/clover.xml"
vendor/dhii/di-interface/CHANGELOG.md ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Change log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [0.1] - 2017-02-02
8
+ Initial release, containing interop interfaces.
9
+
10
+ ### Added
11
+ - Interop interfaces;
12
+ - Interface tests.
vendor/dhii/di-interface/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2016-2017 Dhii
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/dhii/di-interface/README.md ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Dhii - DI Interface ##
2
+ [![Build Status](https://travis-ci.org/Dhii/di-interface.svg?branch=master)](https://travis-ci.org/Dhii/di-interface)
3
+ [![Code Climate](https://codeclimate.com/github/Dhii/di-interface/badges/gpa.svg)](https://codeclimate.com/github/Dhii/di-interface)
4
+ [![Test Coverage](https://codeclimate.com/github/Dhii/di-interface/badges/coverage.svg)](https://codeclimate.com/github/Dhii/di-interface/coverage)
5
+
6
+ Interfaces for DI container implementations.
7
+ In addition to existing [container-interop][] and
8
+ [service-provider][] proxies, provides the following:
9
+
10
+ - [`CompositeContainerInterface`][] - enables [lookup delegation][].
11
+ - [`WritableCompositeContainerInterface`][] - a composite container that can have containers added.
12
+ - [`WritableContainerInterface`][] - a container that can have service definitions added.
13
+ - [`FactoryInterface`][] - enables standard [factory][] implementation.
14
+ - [`ExceptionInterface`][] - any DI exception.
15
+
16
+ The packages adheres to the [SemVer][] specification, and there will be full backward compatibility between minor versions.
17
+ Additionally, it follows the rule of the [caret operator][], i.e. there will be full backward compatibility between patch pre-release versions.
18
+
19
+ [container-interop]: https://github.com/container-interop/container-interop
20
+ [service-provider]: https://github.com/container-interop/service-provider
21
+ [`CompositeContainerInterface`]: https://github.com/Dhii/di-interface/blob/master/src/CompositeContainerInterface.php
22
+ [`WritableCompositeContainerInterface`]: https://github.com/Dhii/di-interface/blob/master/src/WritableCompositeContainerInterface.php
23
+ [`WritableContainerInterface`]: https://github.com/Dhii/di-interface/blob/master/src/WritableContainerInterface.php
24
+ [`FactoryInterface`]: https://github.com/Dhii/di-interface/blob/master/src/FactoryInterface.php
25
+ [`ExceptionInterface`]: https://github.com/Dhii/di-interface/blob/master/src/ExceptionInterface.php
26
+ [lookup delegation]: https://github.com/container-interop/container-interop/blob/master/docs/Delegate-lookup.md
27
+ [factory]: https://github.com/container-interop/container-interop/issues/44
28
+ [SemVer]: http://semver.org/
29
+ [caret operator]: https://getcomposer.org/doc/articles/versions.md#caret
vendor/dhii/di-interface/composer.json ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/di-interface",
3
+ "description": "Interfaces for DI container implementations",
4
+ "type": "library",
5
+ "license": "MIT",
6
+ "authors": [
7
+ {
8
+ "name": "Dhii Team",
9
+ "email": "development@dhii.co"
10
+ }
11
+ ],
12
+ "minimum-stability": "dev",
13
+ "require": {
14
+ "php": "^5.3 | ^7.0",
15
+ "container-interop/container-interop": "^1.1",
16
+ "container-interop/service-provider": "^0.3"
17
+ },
18
+ "require-dev": {
19
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
20
+ "phpunit/phpunit": "^4.8",
21
+ "ptrofimov/xpmock": "^1.1",
22
+ "codeclimate/php-test-reporter": "<=0.3.2"
23
+ },
24
+ "autoload": {
25
+ "psr-4": {
26
+ "Dhii\\Di\\": "src/"
27
+ }
28
+ }
29
+ }
vendor/dhii/di-interface/composer.lock ADDED
@@ -0,0 +1,2075 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "_readme": [
3
+ "This file locks the dependencies of your project to a known state",
4
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
5
+ "This file is @generated automatically"
6
+ ],
7
+ "hash": "7f8908aa350c0252cf17032dc6a2f197",
8
+ "content-hash": "2e098c76d358ab36e37c44a3346175d9",
9
+ "packages": [
10
+ {
11
+ "name": "container-interop/container-interop",
12
+ "version": "1.1.0",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/container-interop/container-interop.git",
16
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/container-interop/container-interop/zipball/fc08354828f8fd3245f77a66b9e23a6bca48297e",
21
+ "reference": "fc08354828f8fd3245f77a66b9e23a6bca48297e",
22
+ "shasum": ""
23
+ },
24
+ "type": "library",
25
+ "autoload": {
26
+ "psr-4": {
27
+ "Interop\\Container\\": "src/Interop/Container/"
28
+ }
29
+ },
30
+ "notification-url": "https://packagist.org/downloads/",
31
+ "license": [
32
+ "MIT"
33
+ ],
34
+ "description": "Promoting the interoperability of container objects (DIC, SL, etc.)",
35
+ "time": "2014-12-30 15:22:37"
36
+ },
37
+ {
38
+ "name": "container-interop/service-provider",
39
+ "version": "v0.3.0",
40
+ "source": {
41
+ "type": "git",
42
+ "url": "https://github.com/container-interop/service-provider.git",
43
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf"
44
+ },
45
+ "dist": {
46
+ "type": "zip",
47
+ "url": "https://api.github.com/repos/container-interop/service-provider/zipball/5cb38893b836edb00d3e1ace26c20ee1d29957cf",
48
+ "reference": "5cb38893b836edb00d3e1ace26c20ee1d29957cf",
49
+ "shasum": ""
50
+ },
51
+ "require": {
52
+ "container-interop/container-interop": "^1.1"
53
+ },
54
+ "type": "library",
55
+ "autoload": {
56
+ "psr-4": {
57
+ "Interop\\Container\\": "src/"
58
+ }
59
+ },
60
+ "notification-url": "https://packagist.org/downloads/",
61
+ "license": [
62
+ "MIT"
63
+ ],
64
+ "description": "Promoting container interoperability through standard service providers",
65
+ "homepage": "https://github.com/container-interop/service-provider",
66
+ "time": "2016-05-16 07:42:22"
67
+ }
68
+ ],
69
+ "packages-dev": [
70
+ {
71
+ "name": "codeclimate/php-test-reporter",
72
+ "version": "v0.3.2",
73
+ "source": {
74
+ "type": "git",
75
+ "url": "https://github.com/codeclimate/php-test-reporter.git",
76
+ "reference": "3a2d3ebdc1df5acf372458c15041af240a6fc016"
77
+ },
78
+ "dist": {
79
+ "type": "zip",
80
+ "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/3a2d3ebdc1df5acf372458c15041af240a6fc016",
81
+ "reference": "3a2d3ebdc1df5acf372458c15041af240a6fc016",
82
+ "shasum": ""
83
+ },
84
+ "require": {
85
+ "ext-curl": "*",
86
+ "php": ">=5.3",
87
+ "satooshi/php-coveralls": "1.0.*",
88
+ "symfony/console": ">=2.0"
89
+ },
90
+ "require-dev": {
91
+ "ext-xdebug": "*",
92
+ "phpunit/phpunit": "3.7.*@stable"
93
+ },
94
+ "bin": [
95
+ "composer/bin/test-reporter"
96
+ ],
97
+ "type": "library",
98
+ "extra": {
99
+ "branch-alias": {
100
+ "dev-master": "0.3.x-dev"
101
+ }
102
+ },
103
+ "autoload": {
104
+ "psr-0": {
105
+ "CodeClimate\\Component": "src/",
106
+ "CodeClimate\\Bundle": "src/"
107
+ }
108
+ },
109
+ "notification-url": "https://packagist.org/downloads/",
110
+ "license": [
111
+ "MIT"
112
+ ],
113
+ "authors": [
114
+ {
115
+ "name": "Code Climate",
116
+ "email": "hello@codeclimate.com",
117
+ "homepage": "https://codeclimate.com"
118
+ }
119
+ ],
120
+ "description": "PHP client for reporting test coverage to Code Climate",
121
+ "homepage": "https://github.com/codeclimate/php-test-reporter",
122
+ "keywords": [
123
+ "codeclimate",
124
+ "coverage"
125
+ ],
126
+ "time": "2016-04-19 16:54:33"
127
+ },
128
+ {
129
+ "name": "dhii/php-cs-fixer-config",
130
+ "version": "dev-php-5.3",
131
+ "source": {
132
+ "type": "git",
133
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
134
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
135
+ },
136
+ "dist": {
137
+ "type": "zip",
138
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
139
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
140
+ "shasum": ""
141
+ },
142
+ "require": {
143
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
144
+ "php": "^5.3 | ^7.0"
145
+ },
146
+ "require-dev": {
147
+ "phpunit/phpunit": "^4.8"
148
+ },
149
+ "type": "library",
150
+ "autoload": {
151
+ "psr-4": {
152
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
153
+ }
154
+ },
155
+ "notification-url": "https://packagist.org/downloads/",
156
+ "license": [
157
+ "MIT"
158
+ ],
159
+ "authors": [
160
+ {
161
+ "name": "Dhii Team",
162
+ "email": "development@dhii.co"
163
+ }
164
+ ],
165
+ "description": "A default PHP CS Fixer config implementation",
166
+ "time": "2016-09-03 14:45:03"
167
+ },
168
+ {
169
+ "name": "doctrine/instantiator",
170
+ "version": "dev-master",
171
+ "source": {
172
+ "type": "git",
173
+ "url": "https://github.com/doctrine/instantiator.git",
174
+ "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac"
175
+ },
176
+ "dist": {
177
+ "type": "zip",
178
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/68099b02b60bbf3b088ff5cb67bf506770ef9cac",
179
+ "reference": "68099b02b60bbf3b088ff5cb67bf506770ef9cac",
180
+ "shasum": ""
181
+ },
182
+ "require": {
183
+ "php": ">=5.3,<8.0-DEV"
184
+ },
185
+ "require-dev": {
186
+ "athletic/athletic": "~0.1.8",
187
+ "ext-pdo": "*",
188
+ "ext-phar": "*",
189
+ "phpunit/phpunit": "~4.0",
190
+ "squizlabs/php_codesniffer": "~2.0"
191
+ },
192
+ "type": "library",
193
+ "extra": {
194
+ "branch-alias": {
195
+ "dev-master": "1.0.x-dev"
196
+ }
197
+ },
198
+ "autoload": {
199
+ "psr-4": {
200
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
201
+ }
202
+ },
203
+ "notification-url": "https://packagist.org/downloads/",
204
+ "license": [
205
+ "MIT"
206
+ ],
207
+ "authors": [
208
+ {
209
+ "name": "Marco Pivetta",
210
+ "email": "ocramius@gmail.com",
211
+ "homepage": "http://ocramius.github.com/"
212
+ }
213
+ ],
214
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
215
+ "homepage": "https://github.com/doctrine/instantiator",
216
+ "keywords": [
217
+ "constructor",
218
+ "instantiate"
219
+ ],
220
+ "time": "2017-01-23 09:23:06"
221
+ },
222
+ {
223
+ "name": "friendsofphp/php-cs-fixer",
224
+ "version": "v1.11.8",
225
+ "source": {
226
+ "type": "git",
227
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
228
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
229
+ },
230
+ "dist": {
231
+ "type": "zip",
232
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
233
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
234
+ "shasum": ""
235
+ },
236
+ "require": {
237
+ "ext-tokenizer": "*",
238
+ "php": ">=5.3.6",
239
+ "sebastian/diff": "~1.1",
240
+ "symfony/console": "~2.3|~3.0",
241
+ "symfony/event-dispatcher": "~2.1|~3.0",
242
+ "symfony/filesystem": "~2.1|~3.0",
243
+ "symfony/finder": "~2.1|~3.0",
244
+ "symfony/process": "~2.3|~3.0",
245
+ "symfony/stopwatch": "~2.5|~3.0"
246
+ },
247
+ "conflict": {
248
+ "hhvm": "<3.9"
249
+ },
250
+ "require-dev": {
251
+ "phpunit/phpunit": "^4.5|^5",
252
+ "satooshi/php-coveralls": "^0.7.1"
253
+ },
254
+ "bin": [
255
+ "php-cs-fixer"
256
+ ],
257
+ "type": "application",
258
+ "autoload": {
259
+ "psr-4": {
260
+ "Symfony\\CS\\": "Symfony/CS/"
261
+ }
262
+ },
263
+ "notification-url": "https://packagist.org/downloads/",
264
+ "license": [
265
+ "MIT"
266
+ ],
267
+ "authors": [
268
+ {
269
+ "name": "Dariusz Rumiński",
270
+ "email": "dariusz.ruminski@gmail.com"
271
+ },
272
+ {
273
+ "name": "Fabien Potencier",
274
+ "email": "fabien@symfony.com"
275
+ }
276
+ ],
277
+ "description": "A tool to automatically fix PHP code style",
278
+ "time": "2016-08-16 23:31:05"
279
+ },
280
+ {
281
+ "name": "guzzle/guzzle",
282
+ "version": "v3.8.1",
283
+ "source": {
284
+ "type": "git",
285
+ "url": "https://github.com/guzzle/guzzle.git",
286
+ "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba"
287
+ },
288
+ "dist": {
289
+ "type": "zip",
290
+ "url": "https://api.github.com/repos/guzzle/guzzle/zipball/4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
291
+ "reference": "4de0618a01b34aa1c8c33a3f13f396dcd3882eba",
292
+ "shasum": ""
293
+ },
294
+ "require": {
295
+ "ext-curl": "*",
296
+ "php": ">=5.3.3",
297
+ "symfony/event-dispatcher": ">=2.1"
298
+ },
299
+ "replace": {
300
+ "guzzle/batch": "self.version",
301
+ "guzzle/cache": "self.version",
302
+ "guzzle/common": "self.version",
303
+ "guzzle/http": "self.version",
304
+ "guzzle/inflection": "self.version",
305
+ "guzzle/iterator": "self.version",
306
+ "guzzle/log": "self.version",
307
+ "guzzle/parser": "self.version",
308
+ "guzzle/plugin": "self.version",
309
+ "guzzle/plugin-async": "self.version",
310
+ "guzzle/plugin-backoff": "self.version",
311
+ "guzzle/plugin-cache": "self.version",
312
+ "guzzle/plugin-cookie": "self.version",
313
+ "guzzle/plugin-curlauth": "self.version",
314
+ "guzzle/plugin-error-response": "self.version",
315
+ "guzzle/plugin-history": "self.version",
316
+ "guzzle/plugin-log": "self.version",
317
+ "guzzle/plugin-md5": "self.version",
318
+ "guzzle/plugin-mock": "self.version",
319
+ "guzzle/plugin-oauth": "self.version",
320
+ "guzzle/service": "self.version",
321
+ "guzzle/stream": "self.version"
322
+ },
323
+ "require-dev": {
324
+ "doctrine/cache": "*",
325
+ "monolog/monolog": "1.*",
326
+ "phpunit/phpunit": "3.7.*",
327
+ "psr/log": "1.0.*",
328
+ "symfony/class-loader": "*",
329
+ "zendframework/zend-cache": "<2.3",
330
+ "zendframework/zend-log": "<2.3"
331
+ },
332
+ "type": "library",
333
+ "extra": {
334
+ "branch-alias": {
335
+ "dev-master": "3.8-dev"
336
+ }
337
+ },
338
+ "autoload": {
339
+ "psr-0": {
340
+ "Guzzle": "src/",
341
+ "Guzzle\\Tests": "tests/"
342
+ }
343
+ },
344
+ "notification-url": "https://packagist.org/downloads/",
345
+ "license": [
346
+ "MIT"
347
+ ],
348
+ "authors": [
349
+ {
350
+ "name": "Michael Dowling",
351
+ "email": "mtdowling@gmail.com",
352
+ "homepage": "https://github.com/mtdowling"
353
+ },
354
+ {
355
+ "name": "Guzzle Community",
356
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
357
+ }
358
+ ],
359
+ "description": "Guzzle is a PHP HTTP client library and framework for building RESTful web service clients",
360
+ "homepage": "http://guzzlephp.org/",
361
+ "keywords": [
362
+ "client",
363
+ "curl",
364
+ "framework",
365
+ "http",
366
+ "http client",
367
+ "rest",
368
+ "web service"
369
+ ],
370
+ "abandoned": "guzzlehttp/guzzle",
371
+ "time": "2014-01-28 22:29:15"
372
+ },
373
+ {
374
+ "name": "phpdocumentor/reflection-common",
375
+ "version": "dev-master",
376
+ "source": {
377
+ "type": "git",
378
+ "url": "https://github.com/phpDocumentor/ReflectionCommon.git",
379
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c"
380
+ },
381
+ "dist": {
382
+ "type": "zip",
383
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
384
+ "reference": "144c307535e82c8fdcaacbcfc1d6d8eeb896687c",
385
+ "shasum": ""
386
+ },
387
+ "require": {
388
+ "php": ">=5.5"
389
+ },
390
+ "require-dev": {
391
+ "phpunit/phpunit": "^4.6"
392
+ },
393
+ "type": "library",
394
+ "extra": {
395
+ "branch-alias": {
396
+ "dev-master": "1.0.x-dev"
397
+ }
398
+ },
399
+ "autoload": {
400
+ "psr-4": {
401
+ "phpDocumentor\\Reflection\\": [
402
+ "src"
403
+ ]
404
+ }
405
+ },
406
+ "notification-url": "https://packagist.org/downloads/",
407
+ "license": [
408
+ "MIT"
409
+ ],
410
+ "authors": [
411
+ {
412
+ "name": "Jaap van Otterdijk",
413
+ "email": "opensource@ijaap.nl"
414
+ }
415
+ ],
416
+ "description": "Common reflection classes used by phpdocumentor to reflect the code structure",
417
+ "homepage": "http://www.phpdoc.org",
418
+ "keywords": [
419
+ "FQSEN",
420
+ "phpDocumentor",
421
+ "phpdoc",
422
+ "reflection",
423
+ "static analysis"
424
+ ],
425
+ "time": "2015-12-27 11:43:31"
426
+ },
427
+ {
428
+ "name": "phpdocumentor/reflection-docblock",
429
+ "version": "3.1.1",
430
+ "source": {
431
+ "type": "git",
432
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
433
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e"
434
+ },
435
+ "dist": {
436
+ "type": "zip",
437
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/8331b5efe816ae05461b7ca1e721c01b46bafb3e",
438
+ "reference": "8331b5efe816ae05461b7ca1e721c01b46bafb3e",
439
+ "shasum": ""
440
+ },
441
+ "require": {
442
+ "php": ">=5.5",
443
+ "phpdocumentor/reflection-common": "^1.0@dev",
444
+ "phpdocumentor/type-resolver": "^0.2.0",
445
+ "webmozart/assert": "^1.0"
446
+ },
447
+ "require-dev": {
448
+ "mockery/mockery": "^0.9.4",
449
+ "phpunit/phpunit": "^4.4"
450
+ },
451
+ "type": "library",
452
+ "autoload": {
453
+ "psr-4": {
454
+ "phpDocumentor\\Reflection\\": [
455
+ "src/"
456
+ ]
457
+ }
458
+ },
459
+ "notification-url": "https://packagist.org/downloads/",
460
+ "license": [
461
+ "MIT"
462
+ ],
463
+ "authors": [
464
+ {
465
+ "name": "Mike van Riel",
466
+ "email": "me@mikevanriel.com"
467
+ }
468
+ ],
469
+ "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.",
470
+ "time": "2016-09-30 07:12:33"
471
+ },
472
+ {
473
+ "name": "phpdocumentor/type-resolver",
474
+ "version": "0.2.1",
475
+ "source": {
476
+ "type": "git",
477
+ "url": "https://github.com/phpDocumentor/TypeResolver.git",
478
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb"
479
+ },
480
+ "dist": {
481
+ "type": "zip",
482
+ "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
483
+ "reference": "e224fb2ea2fba6d3ad6fdaef91cd09a172155ccb",
484
+ "shasum": ""
485
+ },
486
+ "require": {
487
+ "php": ">=5.5",
488
+ "phpdocumentor/reflection-common": "^1.0"
489
+ },
490
+ "require-dev": {
491
+ "mockery/mockery": "^0.9.4",
492
+ "phpunit/phpunit": "^5.2||^4.8.24"
493
+ },
494
+ "type": "library",
495
+ "extra": {
496
+ "branch-alias": {
497
+ "dev-master": "1.0.x-dev"
498
+ }
499
+ },
500
+ "autoload": {
501
+ "psr-4": {
502
+ "phpDocumentor\\Reflection\\": [
503
+ "src/"
504
+ ]
505
+ }
506
+ },
507
+ "notification-url": "https://packagist.org/downloads/",
508
+ "license": [
509
+ "MIT"
510
+ ],
511
+ "authors": [
512
+ {
513
+ "name": "Mike van Riel",
514
+ "email": "me@mikevanriel.com"
515
+ }
516
+ ],
517
+ "time": "2016-11-25 06:54:22"
518
+ },
519
+ {
520
+ "name": "phpspec/prophecy",
521
+ "version": "dev-master",
522
+ "source": {
523
+ "type": "git",
524
+ "url": "https://github.com/phpspec/prophecy.git",
525
+ "reference": "6c52c2722f8460122f96f86346600e1077ce22cb"
526
+ },
527
+ "dist": {
528
+ "type": "zip",
529
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/6c52c2722f8460122f96f86346600e1077ce22cb",
530
+ "reference": "6c52c2722f8460122f96f86346600e1077ce22cb",
531
+ "shasum": ""
532
+ },
533
+ "require": {
534
+ "doctrine/instantiator": "^1.0.2",
535
+ "php": "^5.3|^7.0",
536
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
537
+ "sebastian/comparator": "^1.1",
538
+ "sebastian/recursion-context": "^1.0|^2.0"
539
+ },
540
+ "require-dev": {
541
+ "phpspec/phpspec": "^2.0",
542
+ "phpunit/phpunit": "^4.8 || ^5.6.5"
543
+ },
544
+ "type": "library",
545
+ "extra": {
546
+ "branch-alias": {
547
+ "dev-master": "1.6.x-dev"
548
+ }
549
+ },
550
+ "autoload": {
551
+ "psr-0": {
552
+ "Prophecy\\": "src/"
553
+ }
554
+ },
555
+ "notification-url": "https://packagist.org/downloads/",
556
+ "license": [
557
+ "MIT"
558
+ ],
559
+ "authors": [
560
+ {
561
+ "name": "Konstantin Kudryashov",
562
+ "email": "ever.zet@gmail.com",
563
+ "homepage": "http://everzet.com"
564
+ },
565
+ {
566
+ "name": "Marcello Duarte",
567
+ "email": "marcello.duarte@gmail.com"
568
+ }
569
+ ],
570
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
571
+ "homepage": "https://github.com/phpspec/prophecy",
572
+ "keywords": [
573
+ "Double",
574
+ "Dummy",
575
+ "fake",
576
+ "mock",
577
+ "spy",
578
+ "stub"
579
+ ],
580
+ "time": "2016-11-21 14:58:47"
581
+ },
582
+ {
583
+ "name": "phpunit/php-code-coverage",
584
+ "version": "2.2.x-dev",
585
+ "source": {
586
+ "type": "git",
587
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
588
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
589
+ },
590
+ "dist": {
591
+ "type": "zip",
592
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
593
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
594
+ "shasum": ""
595
+ },
596
+ "require": {
597
+ "php": ">=5.3.3",
598
+ "phpunit/php-file-iterator": "~1.3",
599
+ "phpunit/php-text-template": "~1.2",
600
+ "phpunit/php-token-stream": "~1.3",
601
+ "sebastian/environment": "^1.3.2",
602
+ "sebastian/version": "~1.0"
603
+ },
604
+ "require-dev": {
605
+ "ext-xdebug": ">=2.1.4",
606
+ "phpunit/phpunit": "~4"
607
+ },
608
+ "suggest": {
609
+ "ext-dom": "*",
610
+ "ext-xdebug": ">=2.2.1",
611
+ "ext-xmlwriter": "*"
612
+ },
613
+ "type": "library",
614
+ "extra": {
615
+ "branch-alias": {
616
+ "dev-master": "2.2.x-dev"
617
+ }
618
+ },
619
+ "autoload": {
620
+ "classmap": [
621
+ "src/"
622
+ ]
623
+ },
624
+ "notification-url": "https://packagist.org/downloads/",
625
+ "license": [
626
+ "BSD-3-Clause"
627
+ ],
628
+ "authors": [
629
+ {
630
+ "name": "Sebastian Bergmann",
631
+ "email": "sb@sebastian-bergmann.de",
632
+ "role": "lead"
633
+ }
634
+ ],
635
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
636
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
637
+ "keywords": [
638
+ "coverage",
639
+ "testing",
640
+ "xunit"
641
+ ],
642
+ "time": "2015-10-06 15:47:00"
643
+ },
644
+ {
645
+ "name": "phpunit/php-file-iterator",
646
+ "version": "dev-master",
647
+ "source": {
648
+ "type": "git",
649
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
650
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
651
+ },
652
+ "dist": {
653
+ "type": "zip",
654
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
655
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
656
+ "shasum": ""
657
+ },
658
+ "require": {
659
+ "php": ">=5.3.3"
660
+ },
661
+ "type": "library",
662
+ "extra": {
663
+ "branch-alias": {
664
+ "dev-master": "1.4.x-dev"
665
+ }
666
+ },
667
+ "autoload": {
668
+ "classmap": [
669
+ "src/"
670
+ ]
671
+ },
672
+ "notification-url": "https://packagist.org/downloads/",
673
+ "license": [
674
+ "BSD-3-Clause"
675
+ ],
676
+ "authors": [
677
+ {
678
+ "name": "Sebastian Bergmann",
679
+ "email": "sb@sebastian-bergmann.de",
680
+ "role": "lead"
681
+ }
682
+ ],
683
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
684
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
685
+ "keywords": [
686
+ "filesystem",
687
+ "iterator"
688
+ ],
689
+ "time": "2016-10-03 07:40:28"
690
+ },
691
+ {
692
+ "name": "phpunit/php-text-template",
693
+ "version": "1.2.1",
694
+ "source": {
695
+ "type": "git",
696
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
697
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
698
+ },
699
+ "dist": {
700
+ "type": "zip",
701
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
702
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
703
+ "shasum": ""
704
+ },
705
+ "require": {
706
+ "php": ">=5.3.3"
707
+ },
708
+ "type": "library",
709
+ "autoload": {
710
+ "classmap": [
711
+ "src/"
712
+ ]
713
+ },
714
+ "notification-url": "https://packagist.org/downloads/",
715
+ "license": [
716
+ "BSD-3-Clause"
717
+ ],
718
+ "authors": [
719
+ {
720
+ "name": "Sebastian Bergmann",
721
+ "email": "sebastian@phpunit.de",
722
+ "role": "lead"
723
+ }
724
+ ],
725
+ "description": "Simple template engine.",
726
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
727
+ "keywords": [
728
+ "template"
729
+ ],
730
+ "time": "2015-06-21 13:50:34"
731
+ },
732
+ {
733
+ "name": "phpunit/php-timer",
734
+ "version": "1.0.8",
735
+ "source": {
736
+ "type": "git",
737
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
738
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
739
+ },
740
+ "dist": {
741
+ "type": "zip",
742
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
743
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
744
+ "shasum": ""
745
+ },
746
+ "require": {
747
+ "php": ">=5.3.3"
748
+ },
749
+ "require-dev": {
750
+ "phpunit/phpunit": "~4|~5"
751
+ },
752
+ "type": "library",
753
+ "autoload": {
754
+ "classmap": [
755
+ "src/"
756
+ ]
757
+ },
758
+ "notification-url": "https://packagist.org/downloads/",
759
+ "license": [
760
+ "BSD-3-Clause"
761
+ ],
762
+ "authors": [
763
+ {
764
+ "name": "Sebastian Bergmann",
765
+ "email": "sb@sebastian-bergmann.de",
766
+ "role": "lead"
767
+ }
768
+ ],
769
+ "description": "Utility class for timing",
770
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
771
+ "keywords": [
772
+ "timer"
773
+ ],
774
+ "time": "2016-05-12 18:03:57"
775
+ },
776
+ {
777
+ "name": "phpunit/php-token-stream",
778
+ "version": "dev-master",
779
+ "source": {
780
+ "type": "git",
781
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
782
+ "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b"
783
+ },
784
+ "dist": {
785
+ "type": "zip",
786
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/3b402f65a4cc90abf6e1104e388b896ce209631b",
787
+ "reference": "3b402f65a4cc90abf6e1104e388b896ce209631b",
788
+ "shasum": ""
789
+ },
790
+ "require": {
791
+ "ext-tokenizer": "*",
792
+ "php": ">=5.3.3"
793
+ },
794
+ "require-dev": {
795
+ "phpunit/phpunit": "~4.2"
796
+ },
797
+ "type": "library",
798
+ "extra": {
799
+ "branch-alias": {
800
+ "dev-master": "1.4-dev"
801
+ }
802
+ },
803
+ "autoload": {
804
+ "classmap": [
805
+ "src/"
806
+ ]
807
+ },
808
+ "notification-url": "https://packagist.org/downloads/",
809
+ "license": [
810
+ "BSD-3-Clause"
811
+ ],
812
+ "authors": [
813
+ {
814
+ "name": "Sebastian Bergmann",
815
+ "email": "sebastian@phpunit.de"
816
+ }
817
+ ],
818
+ "description": "Wrapper around PHP's tokenizer extension.",
819
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
820
+ "keywords": [
821
+ "tokenizer"
822
+ ],
823
+ "time": "2016-11-15 14:06:22"
824
+ },
825
+ {
826
+ "name": "phpunit/phpunit",
827
+ "version": "4.8.x-dev",
828
+ "source": {
829
+ "type": "git",
830
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
831
+ "reference": "7eb45205d27edd94bd2b3614085ea158bd1e2bca"
832
+ },
833
+ "dist": {
834
+ "type": "zip",
835
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7eb45205d27edd94bd2b3614085ea158bd1e2bca",
836
+ "reference": "7eb45205d27edd94bd2b3614085ea158bd1e2bca",
837
+ "shasum": ""
838
+ },
839
+ "require": {
840
+ "ext-dom": "*",
841
+ "ext-json": "*",
842
+ "ext-pcre": "*",
843
+ "ext-reflection": "*",
844
+ "ext-spl": "*",
845
+ "php": ">=5.3.3",
846
+ "phpspec/prophecy": "^1.3.1",
847
+ "phpunit/php-code-coverage": "~2.1",
848
+ "phpunit/php-file-iterator": "~1.4",
849
+ "phpunit/php-text-template": "~1.2",
850
+ "phpunit/php-timer": "^1.0.6",
851
+ "phpunit/phpunit-mock-objects": "~2.3",
852
+ "sebastian/comparator": "~1.2.2",
853
+ "sebastian/diff": "~1.2",
854
+ "sebastian/environment": "~1.3",
855
+ "sebastian/exporter": "~1.2",
856
+ "sebastian/global-state": "~1.0",
857
+ "sebastian/version": "~1.0",
858
+ "symfony/yaml": "~2.1|~3.0"
859
+ },
860
+ "suggest": {
861
+ "phpunit/php-invoker": "~1.1"
862
+ },
863
+ "bin": [
864
+ "phpunit"
865
+ ],
866
+ "type": "library",
867
+ "extra": {
868
+ "branch-alias": {
869
+ "dev-master": "4.8.x-dev"
870
+ }
871
+ },
872
+ "autoload": {
873
+ "classmap": [
874
+ "src/"
875
+ ]
876
+ },
877
+ "notification-url": "https://packagist.org/downloads/",
878
+ "license": [
879
+ "BSD-3-Clause"
880
+ ],
881
+ "authors": [
882
+ {
883
+ "name": "Sebastian Bergmann",
884
+ "email": "sebastian@phpunit.de",
885
+ "role": "lead"
886
+ }
887
+ ],
888
+ "description": "The PHP Unit Testing framework.",
889
+ "homepage": "https://phpunit.de/",
890
+ "keywords": [
891
+ "phpunit",
892
+ "testing",
893
+ "xunit"
894
+ ],
895
+ "time": "2017-01-26 16:15:36"
896
+ },
897
+ {
898
+ "name": "phpunit/phpunit-mock-objects",
899
+ "version": "2.3.x-dev",
900
+ "source": {
901
+ "type": "git",
902
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
903
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
904
+ },
905
+ "dist": {
906
+ "type": "zip",
907
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
908
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
909
+ "shasum": ""
910
+ },
911
+ "require": {
912
+ "doctrine/instantiator": "^1.0.2",
913
+ "php": ">=5.3.3",
914
+ "phpunit/php-text-template": "~1.2",
915
+ "sebastian/exporter": "~1.2"
916
+ },
917
+ "require-dev": {
918
+ "phpunit/phpunit": "~4.4"
919
+ },
920
+ "suggest": {
921
+ "ext-soap": "*"
922
+ },
923
+ "type": "library",
924
+ "extra": {
925
+ "branch-alias": {
926
+ "dev-master": "2.3.x-dev"
927
+ }
928
+ },
929
+ "autoload": {
930
+ "classmap": [
931
+ "src/"
932
+ ]
933
+ },
934
+ "notification-url": "https://packagist.org/downloads/",
935
+ "license": [
936
+ "BSD-3-Clause"
937
+ ],
938
+ "authors": [
939
+ {
940
+ "name": "Sebastian Bergmann",
941
+ "email": "sb@sebastian-bergmann.de",
942
+ "role": "lead"
943
+ }
944
+ ],
945
+ "description": "Mock Object library for PHPUnit",
946
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
947
+ "keywords": [
948
+ "mock",
949
+ "xunit"
950
+ ],
951
+ "time": "2015-10-02 06:51:40"
952
+ },
953
+ {
954
+ "name": "psr/log",
955
+ "version": "dev-master",
956
+ "source": {
957
+ "type": "git",
958
+ "url": "https://github.com/php-fig/log.git",
959
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
960
+ },
961
+ "dist": {
962
+ "type": "zip",
963
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
964
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
965
+ "shasum": ""
966
+ },
967
+ "require": {
968
+ "php": ">=5.3.0"
969
+ },
970
+ "type": "library",
971
+ "extra": {
972
+ "branch-alias": {
973
+ "dev-master": "1.0.x-dev"
974
+ }
975
+ },
976
+ "autoload": {
977
+ "psr-4": {
978
+ "Psr\\Log\\": "Psr/Log/"
979
+ }
980
+ },
981
+ "notification-url": "https://packagist.org/downloads/",
982
+ "license": [
983
+ "MIT"
984
+ ],
985
+ "authors": [
986
+ {
987
+ "name": "PHP-FIG",
988
+ "homepage": "http://www.php-fig.org/"
989
+ }
990
+ ],
991
+ "description": "Common interface for logging libraries",
992
+ "homepage": "https://github.com/php-fig/log",
993
+ "keywords": [
994
+ "log",
995
+ "psr",
996
+ "psr-3"
997
+ ],
998
+ "time": "2016-10-10 12:19:37"
999
+ },
1000
+ {
1001
+ "name": "ptrofimov/xpmock",
1002
+ "version": "1.1.5",
1003
+ "source": {
1004
+ "type": "git",
1005
+ "url": "https://github.com/ptrofimov/xpmock.git",
1006
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
1007
+ },
1008
+ "dist": {
1009
+ "type": "zip",
1010
+ "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
1011
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
1012
+ "shasum": ""
1013
+ },
1014
+ "require": {
1015
+ "php": ">=5.3.0"
1016
+ },
1017
+ "require-dev": {
1018
+ "phpunit/phpunit": "3.7.*"
1019
+ },
1020
+ "type": "library",
1021
+ "autoload": {
1022
+ "psr-0": {
1023
+ "Xpmock": "src"
1024
+ }
1025
+ },
1026
+ "notification-url": "https://packagist.org/downloads/",
1027
+ "license": [
1028
+ "MIT"
1029
+ ],
1030
+ "description": "PHPUnit: simple syntax to create mock-objects",
1031
+ "time": "2014-01-02 16:42:27"
1032
+ },
1033
+ {
1034
+ "name": "satooshi/php-coveralls",
1035
+ "version": "1.0.x-dev",
1036
+ "source": {
1037
+ "type": "git",
1038
+ "url": "https://github.com/satooshi/php-coveralls.git",
1039
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
1040
+ },
1041
+ "dist": {
1042
+ "type": "zip",
1043
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
1044
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
1045
+ "shasum": ""
1046
+ },
1047
+ "require": {
1048
+ "ext-json": "*",
1049
+ "ext-simplexml": "*",
1050
+ "guzzle/guzzle": "^2.8|^3.0",
1051
+ "php": ">=5.3.3",
1052
+ "psr/log": "^1.0",
1053
+ "symfony/config": "^2.1|^3.0",
1054
+ "symfony/console": "^2.1|^3.0",
1055
+ "symfony/stopwatch": "^2.0|^3.0",
1056
+ "symfony/yaml": "^2.0|^3.0"
1057
+ },
1058
+ "suggest": {
1059
+ "symfony/http-kernel": "Allows Symfony integration"
1060
+ },
1061
+ "bin": [
1062
+ "bin/coveralls"
1063
+ ],
1064
+ "type": "library",
1065
+ "autoload": {
1066
+ "psr-4": {
1067
+ "Satooshi\\": "src/Satooshi/"
1068
+ }
1069
+ },
1070
+ "notification-url": "https://packagist.org/downloads/",
1071
+ "license": [
1072
+ "MIT"
1073
+ ],
1074
+ "authors": [
1075
+ {
1076
+ "name": "Kitamura Satoshi",
1077
+ "email": "with.no.parachute@gmail.com",
1078
+ "homepage": "https://www.facebook.com/satooshi.jp"
1079
+ }
1080
+ ],
1081
+ "description": "PHP client library for Coveralls API",
1082
+ "homepage": "https://github.com/satooshi/php-coveralls",
1083
+ "keywords": [
1084
+ "ci",
1085
+ "coverage",
1086
+ "github",
1087
+ "test"
1088
+ ],
1089
+ "time": "2016-01-20 17:35:46"
1090
+ },
1091
+ {
1092
+ "name": "sebastian/comparator",
1093
+ "version": "dev-master",
1094
+ "source": {
1095
+ "type": "git",
1096
+ "url": "https://github.com/sebastianbergmann/comparator.git",
1097
+ "reference": "7c391956f8086a22a257cb26461544e4fc8e02e0"
1098
+ },
1099
+ "dist": {
1100
+ "type": "zip",
1101
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/7c391956f8086a22a257cb26461544e4fc8e02e0",
1102
+ "reference": "7c391956f8086a22a257cb26461544e4fc8e02e0",
1103
+ "shasum": ""
1104
+ },
1105
+ "require": {
1106
+ "php": "^5.3.3 || ^7.0",
1107
+ "sebastian/diff": "^1.2",
1108
+ "sebastian/exporter": "^1.2 || ^2.0"
1109
+ },
1110
+ "require-dev": {
1111
+ "phpunit/phpunit": "^4.8"
1112
+ },
1113
+ "type": "library",
1114
+ "extra": {
1115
+ "branch-alias": {
1116
+ "dev-master": "1.2.x-dev"
1117
+ }
1118
+ },
1119
+ "autoload": {
1120
+ "classmap": [
1121
+ "src/"
1122
+ ]
1123
+ },
1124
+ "notification-url": "https://packagist.org/downloads/",
1125
+ "license": [
1126
+ "BSD-3-Clause"
1127
+ ],
1128
+ "authors": [
1129
+ {
1130
+ "name": "Jeff Welch",
1131
+ "email": "whatthejeff@gmail.com"
1132
+ },
1133
+ {
1134
+ "name": "Volker Dusch",
1135
+ "email": "github@wallbash.com"
1136
+ },
1137
+ {
1138
+ "name": "Bernhard Schussek",
1139
+ "email": "bschussek@2bepublished.at"
1140
+ },
1141
+ {
1142
+ "name": "Sebastian Bergmann",
1143
+ "email": "sebastian@phpunit.de"
1144
+ }
1145
+ ],
1146
+ "description": "Provides the functionality to compare PHP values for equality",
1147
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
1148
+ "keywords": [
1149
+ "comparator",
1150
+ "compare",
1151
+ "equality"
1152
+ ],
1153
+ "time": "2017-01-29 09:51:01"
1154
+ },
1155
+ {
1156
+ "name": "sebastian/diff",
1157
+ "version": "dev-master",
1158
+ "source": {
1159
+ "type": "git",
1160
+ "url": "https://github.com/sebastianbergmann/diff.git",
1161
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
1162
+ },
1163
+ "dist": {
1164
+ "type": "zip",
1165
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
1166
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
1167
+ "shasum": ""
1168
+ },
1169
+ "require": {
1170
+ "php": ">=5.3.3"
1171
+ },
1172
+ "require-dev": {
1173
+ "phpunit/phpunit": "~4.8"
1174
+ },
1175
+ "type": "library",
1176
+ "extra": {
1177
+ "branch-alias": {
1178
+ "dev-master": "1.4-dev"
1179
+ }
1180
+ },
1181
+ "autoload": {
1182
+ "classmap": [
1183
+ "src/"
1184
+ ]
1185
+ },
1186
+ "notification-url": "https://packagist.org/downloads/",
1187
+ "license": [
1188
+ "BSD-3-Clause"
1189
+ ],
1190
+ "authors": [
1191
+ {
1192
+ "name": "Kore Nordmann",
1193
+ "email": "mail@kore-nordmann.de"
1194
+ },
1195
+ {
1196
+ "name": "Sebastian Bergmann",
1197
+ "email": "sebastian@phpunit.de"
1198
+ }
1199
+ ],
1200
+ "description": "Diff implementation",
1201
+ "homepage": "https://github.com/sebastianbergmann/diff",
1202
+ "keywords": [
1203
+ "diff"
1204
+ ],
1205
+ "time": "2016-10-03 07:45:03"
1206
+ },
1207
+ {
1208
+ "name": "sebastian/environment",
1209
+ "version": "1.3.x-dev",
1210
+ "source": {
1211
+ "type": "git",
1212
+ "url": "https://github.com/sebastianbergmann/environment.git",
1213
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1214
+ },
1215
+ "dist": {
1216
+ "type": "zip",
1217
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1218
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1219
+ "shasum": ""
1220
+ },
1221
+ "require": {
1222
+ "php": "^5.3.3 || ^7.0"
1223
+ },
1224
+ "require-dev": {
1225
+ "phpunit/phpunit": "^4.8 || ^5.0"
1226
+ },
1227
+ "type": "library",
1228
+ "extra": {
1229
+ "branch-alias": {
1230
+ "dev-master": "1.3.x-dev"
1231
+ }
1232
+ },
1233
+ "autoload": {
1234
+ "classmap": [
1235
+ "src/"
1236
+ ]
1237
+ },
1238
+ "notification-url": "https://packagist.org/downloads/",
1239
+ "license": [
1240
+ "BSD-3-Clause"
1241
+ ],
1242
+ "authors": [
1243
+ {
1244
+ "name": "Sebastian Bergmann",
1245
+ "email": "sebastian@phpunit.de"
1246
+ }
1247
+ ],
1248
+ "description": "Provides functionality to handle HHVM/PHP environments",
1249
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1250
+ "keywords": [
1251
+ "Xdebug",
1252
+ "environment",
1253
+ "hhvm"
1254
+ ],
1255
+ "time": "2016-08-18 05:49:44"
1256
+ },
1257
+ {
1258
+ "name": "sebastian/exporter",
1259
+ "version": "1.2.x-dev",
1260
+ "source": {
1261
+ "type": "git",
1262
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1263
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
1264
+ },
1265
+ "dist": {
1266
+ "type": "zip",
1267
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1268
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1269
+ "shasum": ""
1270
+ },
1271
+ "require": {
1272
+ "php": ">=5.3.3",
1273
+ "sebastian/recursion-context": "~1.0"
1274
+ },
1275
+ "require-dev": {
1276
+ "ext-mbstring": "*",
1277
+ "phpunit/phpunit": "~4.4"
1278
+ },
1279
+ "type": "library",
1280
+ "extra": {
1281
+ "branch-alias": {
1282
+ "dev-master": "1.3.x-dev"
1283
+ }
1284
+ },
1285
+ "autoload": {
1286
+ "classmap": [
1287
+ "src/"
1288
+ ]
1289
+ },
1290
+ "notification-url": "https://packagist.org/downloads/",
1291
+ "license": [
1292
+ "BSD-3-Clause"
1293
+ ],
1294
+ "authors": [
1295
+ {
1296
+ "name": "Jeff Welch",
1297
+ "email": "whatthejeff@gmail.com"
1298
+ },
1299
+ {
1300
+ "name": "Volker Dusch",
1301
+ "email": "github@wallbash.com"
1302
+ },
1303
+ {
1304
+ "name": "Bernhard Schussek",
1305
+ "email": "bschussek@2bepublished.at"
1306
+ },
1307
+ {
1308
+ "name": "Sebastian Bergmann",
1309
+ "email": "sebastian@phpunit.de"
1310
+ },
1311
+ {
1312
+ "name": "Adam Harvey",
1313
+ "email": "aharvey@php.net"
1314
+ }
1315
+ ],
1316
+ "description": "Provides the functionality to export PHP variables for visualization",
1317
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1318
+ "keywords": [
1319
+ "export",
1320
+ "exporter"
1321
+ ],
1322
+ "time": "2016-10-03 07:44:30"
1323
+ },
1324
+ {
1325
+ "name": "sebastian/global-state",
1326
+ "version": "1.1.x-dev",
1327
+ "source": {
1328
+ "type": "git",
1329
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1330
+ "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d"
1331
+ },
1332
+ "dist": {
1333
+ "type": "zip",
1334
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1335
+ "reference": "5a2b9ba59e8cf82fd1fdd7efb7d7846fd69ac36d",
1336
+ "shasum": ""
1337
+ },
1338
+ "require": {
1339
+ "php": ">=5.3.3"
1340
+ },
1341
+ "require-dev": {
1342
+ "phpunit/phpunit": "~4.2|~5.0"
1343
+ },
1344
+ "suggest": {
1345
+ "ext-uopz": "*"
1346
+ },
1347
+ "type": "library",
1348
+ "extra": {
1349
+ "branch-alias": {
1350
+ "dev-master": "1.0-dev"
1351
+ }
1352
+ },
1353
+ "autoload": {
1354
+ "classmap": [
1355
+ "src/"
1356
+ ]
1357
+ },
1358
+ "notification-url": "https://packagist.org/downloads/",
1359
+ "license": [
1360
+ "BSD-3-Clause"
1361
+ ],
1362
+ "authors": [
1363
+ {
1364
+ "name": "Sebastian Bergmann",
1365
+ "email": "sebastian@phpunit.de"
1366
+ }
1367
+ ],
1368
+ "description": "Snapshotting of global state",
1369
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1370
+ "keywords": [
1371
+ "global state"
1372
+ ],
1373
+ "time": "2016-10-03 07:46:22"
1374
+ },
1375
+ {
1376
+ "name": "sebastian/recursion-context",
1377
+ "version": "1.0.x-dev",
1378
+ "source": {
1379
+ "type": "git",
1380
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1381
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1382
+ },
1383
+ "dist": {
1384
+ "type": "zip",
1385
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1386
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1387
+ "shasum": ""
1388
+ },
1389
+ "require": {
1390
+ "php": ">=5.3.3"
1391
+ },
1392
+ "require-dev": {
1393
+ "phpunit/phpunit": "~4.4"
1394
+ },
1395
+ "type": "library",
1396
+ "extra": {
1397
+ "branch-alias": {
1398
+ "dev-master": "1.0.x-dev"
1399
+ }
1400
+ },
1401
+ "autoload": {
1402
+ "classmap": [
1403
+ "src/"
1404
+ ]
1405
+ },
1406
+ "notification-url": "https://packagist.org/downloads/",
1407
+ "license": [
1408
+ "BSD-3-Clause"
1409
+ ],
1410
+ "authors": [
1411
+ {
1412
+ "name": "Jeff Welch",
1413
+ "email": "whatthejeff@gmail.com"
1414
+ },
1415
+ {
1416
+ "name": "Sebastian Bergmann",
1417
+ "email": "sebastian@phpunit.de"
1418
+ },
1419
+ {
1420
+ "name": "Adam Harvey",
1421
+ "email": "aharvey@php.net"
1422
+ }
1423
+ ],
1424
+ "description": "Provides functionality to recursively process PHP variables",
1425
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1426
+ "time": "2016-10-03 07:41:43"
1427
+ },
1428
+ {
1429
+ "name": "sebastian/version",
1430
+ "version": "1.0.6",
1431
+ "source": {
1432
+ "type": "git",
1433
+ "url": "https://github.com/sebastianbergmann/version.git",
1434
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1435
+ },
1436
+ "dist": {
1437
+ "type": "zip",
1438
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1439
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1440
+ "shasum": ""
1441
+ },
1442
+ "type": "library",
1443
+ "autoload": {
1444
+ "classmap": [
1445
+ "src/"
1446
+ ]
1447
+ },
1448
+ "notification-url": "https://packagist.org/downloads/",
1449
+ "license": [
1450
+ "BSD-3-Clause"
1451
+ ],
1452
+ "authors": [
1453
+ {
1454
+ "name": "Sebastian Bergmann",
1455
+ "email": "sebastian@phpunit.de",
1456
+ "role": "lead"
1457
+ }
1458
+ ],
1459
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1460
+ "homepage": "https://github.com/sebastianbergmann/version",
1461
+ "time": "2015-06-21 13:59:46"
1462
+ },
1463
+ {
1464
+ "name": "symfony/config",
1465
+ "version": "dev-master",
1466
+ "source": {
1467
+ "type": "git",
1468
+ "url": "https://github.com/symfony/config.git",
1469
+ "reference": "ba3da262813160b4963fb36f573c886592da6acb"
1470
+ },
1471
+ "dist": {
1472
+ "type": "zip",
1473
+ "url": "https://api.github.com/repos/symfony/config/zipball/ba3da262813160b4963fb36f573c886592da6acb",
1474
+ "reference": "ba3da262813160b4963fb36f573c886592da6acb",
1475
+ "shasum": ""
1476
+ },
1477
+ "require": {
1478
+ "php": ">=5.5.9",
1479
+ "symfony/filesystem": "~2.8|~3.0"
1480
+ },
1481
+ "require-dev": {
1482
+ "symfony/yaml": "~3.0"
1483
+ },
1484
+ "suggest": {
1485
+ "symfony/yaml": "To use the yaml reference dumper"
1486
+ },
1487
+ "type": "library",
1488
+ "extra": {
1489
+ "branch-alias": {
1490
+ "dev-master": "3.3-dev"
1491
+ }
1492
+ },
1493
+ "autoload": {
1494
+ "psr-4": {
1495
+ "Symfony\\Component\\Config\\": ""
1496
+ },
1497
+ "exclude-from-classmap": [
1498
+ "/Tests/"
1499
+ ]
1500
+ },
1501
+ "notification-url": "https://packagist.org/downloads/",
1502
+ "license": [
1503
+ "MIT"
1504
+ ],
1505
+ "authors": [
1506
+ {
1507
+ "name": "Fabien Potencier",
1508
+ "email": "fabien@symfony.com"
1509
+ },
1510
+ {
1511
+ "name": "Symfony Community",
1512
+ "homepage": "https://symfony.com/contributors"
1513
+ }
1514
+ ],
1515
+ "description": "Symfony Config Component",
1516
+ "homepage": "https://symfony.com",
1517
+ "time": "2017-01-09 21:03:44"
1518
+ },
1519
+ {
1520
+ "name": "symfony/console",
1521
+ "version": "dev-master",
1522
+ "source": {
1523
+ "type": "git",
1524
+ "url": "https://github.com/symfony/console.git",
1525
+ "reference": "1525be80933b825f64cf56d78bf2f117201933cd"
1526
+ },
1527
+ "dist": {
1528
+ "type": "zip",
1529
+ "url": "https://api.github.com/repos/symfony/console/zipball/1525be80933b825f64cf56d78bf2f117201933cd",
1530
+ "reference": "1525be80933b825f64cf56d78bf2f117201933cd",
1531
+ "shasum": ""
1532
+ },
1533
+ "require": {
1534
+ "php": ">=5.5.9",
1535
+ "symfony/debug": "~2.8|~3.0",
1536
+ "symfony/polyfill-mbstring": "~1.0"
1537
+ },
1538
+ "require-dev": {
1539
+ "psr/log": "~1.0",
1540
+ "symfony/dependency-injection": "~2.8|~3.0",
1541
+ "symfony/event-dispatcher": "~2.8|~3.0",
1542
+ "symfony/filesystem": "~2.8|~3.0",
1543
+ "symfony/http-kernel": "~2.8|~3.0",
1544
+ "symfony/process": "~2.8|~3.0"
1545
+ },
1546
+ "suggest": {
1547
+ "psr/log": "For using the console logger",
1548
+ "symfony/event-dispatcher": "",
1549
+ "symfony/filesystem": "",
1550
+ "symfony/process": ""
1551
+ },
1552
+ "type": "library",
1553
+ "extra": {
1554
+ "branch-alias": {
1555
+ "dev-master": "3.3-dev"
1556
+ }
1557
+ },
1558
+ "autoload": {
1559
+ "psr-4": {
1560
+ "Symfony\\Component\\Console\\": ""
1561
+ },
1562
+ "exclude-from-classmap": [
1563
+ "/Tests/"
1564
+ ]
1565
+ },
1566
+ "notification-url": "https://packagist.org/downloads/",
1567
+ "license": [
1568
+ "MIT"
1569
+ ],
1570
+ "authors": [
1571
+ {
1572
+ "name": "Fabien Potencier",
1573
+ "email": "fabien@symfony.com"
1574
+ },
1575
+ {
1576
+ "name": "Symfony Community",
1577
+ "homepage": "https://symfony.com/contributors"
1578
+ }
1579
+ ],
1580
+ "description": "Symfony Console Component",
1581
+ "homepage": "https://symfony.com",
1582
+ "time": "2017-01-31 21:52:27"
1583
+ },
1584
+ {
1585
+ "name": "symfony/debug",
1586
+ "version": "dev-master",
1587
+ "source": {
1588
+ "type": "git",
1589
+ "url": "https://github.com/symfony/debug.git",
1590
+ "reference": "84a2c430d9dc835189cbd8739eb14ba94b5f4a07"
1591
+ },
1592
+ "dist": {
1593
+ "type": "zip",
1594
+ "url": "https://api.github.com/repos/symfony/debug/zipball/84a2c430d9dc835189cbd8739eb14ba94b5f4a07",
1595
+ "reference": "84a2c430d9dc835189cbd8739eb14ba94b5f4a07",
1596
+ "shasum": ""
1597
+ },
1598
+ "require": {
1599
+ "php": ">=5.5.9",
1600
+ "psr/log": "~1.0"
1601
+ },
1602
+ "conflict": {
1603
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1604
+ },
1605
+ "require-dev": {
1606
+ "symfony/http-kernel": "~2.8|~3.0"
1607
+ },
1608
+ "type": "library",
1609
+ "extra": {
1610
+ "branch-alias": {
1611
+ "dev-master": "3.3-dev"
1612
+ }
1613
+ },
1614
+ "autoload": {
1615
+ "psr-4": {
1616
+ "Symfony\\Component\\Debug\\": ""
1617
+ },
1618
+ "exclude-from-classmap": [
1619
+ "/Tests/"
1620
+ ]
1621
+ },
1622
+ "notification-url": "https://packagist.org/downloads/",
1623
+ "license": [
1624
+ "MIT"
1625
+ ],
1626
+ "authors": [
1627
+ {
1628
+ "name": "Fabien Potencier",
1629
+ "email": "fabien@symfony.com"
1630
+ },
1631
+ {
1632
+ "name": "Symfony Community",
1633
+ "homepage": "https://symfony.com/contributors"
1634
+ }
1635
+ ],
1636
+ "description": "Symfony Debug Component",
1637
+ "homepage": "https://symfony.com",
1638
+ "time": "2017-01-28 02:39:08"
1639
+ },
1640
+ {
1641
+ "name": "symfony/event-dispatcher",
1642
+ "version": "dev-master",
1643
+ "source": {
1644
+ "type": "git",
1645
+ "url": "https://github.com/symfony/event-dispatcher.git",
1646
+ "reference": "26e38eefa5b9333fa94e845541f5f025a98fbe2d"
1647
+ },
1648
+ "dist": {
1649
+ "type": "zip",
1650
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/26e38eefa5b9333fa94e845541f5f025a98fbe2d",
1651
+ "reference": "26e38eefa5b9333fa94e845541f5f025a98fbe2d",
1652
+ "shasum": ""
1653
+ },
1654
+ "require": {
1655
+ "php": ">=5.5.9"
1656
+ },
1657
+ "conflict": {
1658
+ "symfony/dependency-injection": "<3.3"
1659
+ },
1660
+ "require-dev": {
1661
+ "psr/log": "~1.0",
1662
+ "symfony/config": "~2.8|~3.0",
1663
+ "symfony/dependency-injection": "~3.3",
1664
+ "symfony/expression-language": "~2.8|~3.0",
1665
+ "symfony/stopwatch": "~2.8|~3.0"
1666
+ },
1667
+ "suggest": {
1668
+ "symfony/dependency-injection": "",
1669
+ "symfony/http-kernel": ""
1670
+ },
1671
+ "type": "library",
1672
+ "extra": {
1673
+ "branch-alias": {
1674
+ "dev-master": "3.3-dev"
1675
+ }
1676
+ },
1677
+ "autoload": {
1678
+ "psr-4": {
1679
+ "Symfony\\Component\\EventDispatcher\\": ""
1680
+ },
1681
+ "exclude-from-classmap": [
1682
+ "/Tests/"
1683
+ ]
1684
+ },
1685
+ "notification-url": "https://packagist.org/downloads/",
1686
+ "license": [
1687
+ "MIT"
1688
+ ],
1689
+ "authors": [
1690
+ {
1691
+ "name": "Fabien Potencier",
1692
+ "email": "fabien@symfony.com"
1693
+ },
1694
+ {
1695
+ "name": "Symfony Community",
1696
+ "homepage": "https://symfony.com/contributors"
1697
+ }
1698
+ ],
1699
+ "description": "Symfony EventDispatcher Component",
1700
+ "homepage": "https://symfony.com",
1701
+ "time": "2017-01-07 15:57:09"
1702
+ },
1703
+ {
1704
+ "name": "symfony/filesystem",
1705
+ "version": "dev-master",
1706
+ "source": {
1707
+ "type": "git",
1708
+ "url": "https://github.com/symfony/filesystem.git",
1709
+ "reference": "b2de62936fea037d501159f52b7b6172cc962282"
1710
+ },
1711
+ "dist": {
1712
+ "type": "zip",
1713
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/b2de62936fea037d501159f52b7b6172cc962282",
1714
+ "reference": "b2de62936fea037d501159f52b7b6172cc962282",
1715
+ "shasum": ""
1716
+ },
1717
+ "require": {
1718
+ "php": ">=5.5.9"
1719
+ },
1720
+ "type": "library",
1721
+ "extra": {
1722
+ "branch-alias": {
1723
+ "dev-master": "3.3-dev"
1724
+ }
1725
+ },
1726
+ "autoload": {
1727
+ "psr-4": {
1728
+ "Symfony\\Component\\Filesystem\\": ""
1729
+ },
1730
+ "exclude-from-classmap": [
1731
+ "/Tests/"
1732
+ ]
1733
+ },
1734
+ "notification-url": "https://packagist.org/downloads/",
1735
+ "license": [
1736
+ "MIT"
1737
+ ],
1738
+ "authors": [
1739
+ {
1740
+ "name": "Fabien Potencier",
1741
+ "email": "fabien@symfony.com"
1742
+ },
1743
+ {
1744
+ "name": "Symfony Community",
1745
+ "homepage": "https://symfony.com/contributors"
1746
+ }
1747
+ ],
1748
+ "description": "Symfony Filesystem Component",
1749
+ "homepage": "https://symfony.com",
1750
+ "time": "2017-01-08 21:15:04"
1751
+ },
1752
+ {
1753
+ "name": "symfony/finder",
1754
+ "version": "dev-master",
1755
+ "source": {
1756
+ "type": "git",
1757
+ "url": "https://github.com/symfony/finder.git",
1758
+ "reference": "791ac099b1687c0bd82f7230ec0d8fc8550c81dc"
1759
+ },
1760
+ "dist": {
1761
+ "type": "zip",
1762
+ "url": "https://api.github.com/repos/symfony/finder/zipball/791ac099b1687c0bd82f7230ec0d8fc8550c81dc",
1763
+ "reference": "791ac099b1687c0bd82f7230ec0d8fc8550c81dc",
1764
+ "shasum": ""
1765
+ },
1766
+ "require": {
1767
+ "php": ">=5.5.9"
1768
+ },
1769
+ "type": "library",
1770
+ "extra": {
1771
+ "branch-alias": {
1772
+ "dev-master": "3.3-dev"
1773
+ }
1774
+ },
1775
+ "autoload": {
1776
+ "psr-4": {
1777
+ "Symfony\\Component\\Finder\\": ""
1778
+ },
1779
+ "exclude-from-classmap": [
1780
+ "/Tests/"
1781
+ ]
1782
+ },
1783
+ "notification-url": "https://packagist.org/downloads/",
1784
+ "license": [
1785
+ "MIT"
1786
+ ],
1787
+ "authors": [
1788
+ {
1789
+ "name": "Fabien Potencier",
1790
+ "email": "fabien@symfony.com"
1791
+ },
1792
+ {
1793
+ "name": "Symfony Community",
1794
+ "homepage": "https://symfony.com/contributors"
1795
+ }
1796
+ ],
1797
+ "description": "Symfony Finder Component",
1798
+ "homepage": "https://symfony.com",
1799
+ "time": "2017-01-02 20:33:09"
1800
+ },
1801
+ {
1802
+ "name": "symfony/polyfill-mbstring",
1803
+ "version": "dev-master",
1804
+ "source": {
1805
+ "type": "git",
1806
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1807
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4"
1808
+ },
1809
+ "dist": {
1810
+ "type": "zip",
1811
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/e79d363049d1c2128f133a2667e4f4190904f7f4",
1812
+ "reference": "e79d363049d1c2128f133a2667e4f4190904f7f4",
1813
+ "shasum": ""
1814
+ },
1815
+ "require": {
1816
+ "php": ">=5.3.3"
1817
+ },
1818
+ "suggest": {
1819
+ "ext-mbstring": "For best performance"
1820
+ },
1821
+ "type": "library",
1822
+ "extra": {
1823
+ "branch-alias": {
1824
+ "dev-master": "1.3-dev"
1825
+ }
1826
+ },
1827
+ "autoload": {
1828
+ "psr-4": {
1829
+ "Symfony\\Polyfill\\Mbstring\\": ""
1830
+ },
1831
+ "files": [
1832
+ "bootstrap.php"
1833
+ ]
1834
+ },
1835
+ "notification-url": "https://packagist.org/downloads/",
1836
+ "license": [
1837
+ "MIT"
1838
+ ],
1839
+ "authors": [
1840
+ {
1841
+ "name": "Nicolas Grekas",
1842
+ "email": "p@tchwork.com"
1843
+ },
1844
+ {
1845
+ "name": "Symfony Community",
1846
+ "homepage": "https://symfony.com/contributors"
1847
+ }
1848
+ ],
1849
+ "description": "Symfony polyfill for the Mbstring extension",
1850
+ "homepage": "https://symfony.com",
1851
+ "keywords": [
1852
+ "compatibility",
1853
+ "mbstring",
1854
+ "polyfill",
1855
+ "portable",
1856
+ "shim"
1857
+ ],
1858
+ "time": "2016-11-14 01:06:16"
1859
+ },
1860
+ {
1861
+ "name": "symfony/process",
1862
+ "version": "dev-master",
1863
+ "source": {
1864
+ "type": "git",
1865
+ "url": "https://github.com/symfony/process.git",
1866
+ "reference": "a8c0522f1f99d9c2542fe282c51e5331b7ca1e9f"
1867
+ },
1868
+ "dist": {
1869
+ "type": "zip",
1870
+ "url": "https://api.github.com/repos/symfony/process/zipball/a8c0522f1f99d9c2542fe282c51e5331b7ca1e9f",
1871
+ "reference": "a8c0522f1f99d9c2542fe282c51e5331b7ca1e9f",
1872
+ "shasum": ""
1873
+ },
1874
+ "require": {
1875
+ "php": ">=5.5.9"
1876
+ },
1877
+ "type": "library",
1878
+ "extra": {
1879
+ "branch-alias": {
1880
+ "dev-master": "3.3-dev"
1881
+ }
1882
+ },
1883
+ "autoload": {
1884
+ "psr-4": {
1885
+ "Symfony\\Component\\Process\\": ""
1886
+ },
1887
+ "exclude-from-classmap": [
1888
+ "/Tests/"
1889
+ ]
1890
+ },
1891
+ "notification-url": "https://packagist.org/downloads/",
1892
+ "license": [
1893
+ "MIT"
1894
+ ],
1895
+ "authors": [
1896
+ {
1897
+ "name": "Fabien Potencier",
1898
+ "email": "fabien@symfony.com"
1899
+ },
1900
+ {
1901
+ "name": "Symfony Community",
1902
+ "homepage": "https://symfony.com/contributors"
1903
+ }
1904
+ ],
1905
+ "description": "Symfony Process Component",
1906
+ "homepage": "https://symfony.com",
1907
+ "time": "2017-01-31 14:22:24"
1908
+ },
1909
+ {
1910
+ "name": "symfony/stopwatch",
1911
+ "version": "dev-master",
1912
+ "source": {
1913
+ "type": "git",
1914
+ "url": "https://github.com/symfony/stopwatch.git",
1915
+ "reference": "edfe3407825f9657fd38a05171eb5b8df8563146"
1916
+ },
1917
+ "dist": {
1918
+ "type": "zip",
1919
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/edfe3407825f9657fd38a05171eb5b8df8563146",
1920
+ "reference": "edfe3407825f9657fd38a05171eb5b8df8563146",
1921
+ "shasum": ""
1922
+ },
1923
+ "require": {
1924
+ "php": ">=5.5.9"
1925
+ },
1926
+ "type": "library",
1927
+ "extra": {
1928
+ "branch-alias": {
1929
+ "dev-master": "3.3-dev"
1930
+ }
1931
+ },
1932
+ "autoload": {
1933
+ "psr-4": {
1934
+ "Symfony\\Component\\Stopwatch\\": ""
1935
+ },
1936
+ "exclude-from-classmap": [
1937
+ "/Tests/"
1938
+ ]
1939
+ },
1940
+ "notification-url": "https://packagist.org/downloads/",
1941
+ "license": [
1942
+ "MIT"
1943
+ ],
1944
+ "authors": [
1945
+ {
1946
+ "name": "Fabien Potencier",
1947
+ "email": "fabien@symfony.com"
1948
+ },
1949
+ {
1950
+ "name": "Symfony Community",
1951
+ "homepage": "https://symfony.com/contributors"
1952
+ }
1953
+ ],
1954
+ "description": "Symfony Stopwatch Component",
1955
+ "homepage": "https://symfony.com",
1956
+ "time": "2017-01-02 20:33:09"
1957
+ },
1958
+ {
1959
+ "name": "symfony/yaml",
1960
+ "version": "dev-master",
1961
+ "source": {
1962
+ "type": "git",
1963
+ "url": "https://github.com/symfony/yaml.git",
1964
+ "reference": "7928849b226f065dae93ec0e8be3b829f73ba67b"
1965
+ },
1966
+ "dist": {
1967
+ "type": "zip",
1968
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/7928849b226f065dae93ec0e8be3b829f73ba67b",
1969
+ "reference": "7928849b226f065dae93ec0e8be3b829f73ba67b",
1970
+ "shasum": ""
1971
+ },
1972
+ "require": {
1973
+ "php": ">=5.5.9"
1974
+ },
1975
+ "require-dev": {
1976
+ "symfony/console": "~2.8|~3.0"
1977
+ },
1978
+ "suggest": {
1979
+ "symfony/console": "For validating YAML files using the lint command"
1980
+ },
1981
+ "type": "library",
1982
+ "extra": {
1983
+ "branch-alias": {
1984
+ "dev-master": "3.3-dev"
1985
+ }
1986
+ },
1987
+ "autoload": {
1988
+ "psr-4": {
1989
+ "Symfony\\Component\\Yaml\\": ""
1990
+ },
1991
+ "exclude-from-classmap": [
1992
+ "/Tests/"
1993
+ ]
1994
+ },
1995
+ "notification-url": "https://packagist.org/downloads/",
1996
+ "license": [
1997
+ "MIT"
1998
+ ],
1999
+ "authors": [
2000
+ {
2001
+ "name": "Fabien Potencier",
2002
+ "email": "fabien@symfony.com"
2003
+ },
2004
+ {
2005
+ "name": "Symfony Community",
2006
+ "homepage": "https://symfony.com/contributors"
2007
+ }
2008
+ ],
2009
+ "description": "Symfony Yaml Component",
2010
+ "homepage": "https://symfony.com",
2011
+ "time": "2017-01-21 17:10:26"
2012
+ },
2013
+ {
2014
+ "name": "webmozart/assert",
2015
+ "version": "dev-master",
2016
+ "source": {
2017
+ "type": "git",
2018
+ "url": "https://github.com/webmozart/assert.git",
2019
+ "reference": "4a8bf11547e139e77b651365113fc12850c43d9a"
2020
+ },
2021
+ "dist": {
2022
+ "type": "zip",
2023
+ "url": "https://api.github.com/repos/webmozart/assert/zipball/4a8bf11547e139e77b651365113fc12850c43d9a",
2024
+ "reference": "4a8bf11547e139e77b651365113fc12850c43d9a",
2025
+ "shasum": ""
2026
+ },
2027
+ "require": {
2028
+ "php": "^5.3.3 || ^7.0"
2029
+ },
2030
+ "require-dev": {
2031
+ "phpunit/phpunit": "^4.6",
2032
+ "sebastian/version": "^1.0.1"
2033
+ },
2034
+ "type": "library",
2035
+ "extra": {
2036
+ "branch-alias": {
2037
+ "dev-master": "1.3-dev"
2038
+ }
2039
+ },
2040
+ "autoload": {
2041
+ "psr-4": {
2042
+ "Webmozart\\Assert\\": "src/"
2043
+ }
2044
+ },
2045
+ "notification-url": "https://packagist.org/downloads/",
2046
+ "license": [
2047
+ "MIT"
2048
+ ],
2049
+ "authors": [
2050
+ {
2051
+ "name": "Bernhard Schussek",
2052
+ "email": "bschussek@gmail.com"
2053
+ }
2054
+ ],
2055
+ "description": "Assertions to validate method input/output with nice error messages.",
2056
+ "keywords": [
2057
+ "assert",
2058
+ "check",
2059
+ "validate"
2060
+ ],
2061
+ "time": "2016-11-23 20:04:41"
2062
+ }
2063
+ ],
2064
+ "aliases": [],
2065
+ "minimum-stability": "dev",
2066
+ "stability-flags": {
2067
+ "dhii/php-cs-fixer-config": 20
2068
+ },
2069
+ "prefer-stable": false,
2070
+ "prefer-lowest": false,
2071
+ "platform": {
2072
+ "php": "^5.3 | ^7.0"
2073
+ },
2074
+ "platform-dev": []
2075
+ }
vendor/dhii/di-interface/nbproject/private/private.xml ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project-private xmlns="http://www.netbeans.org/ns/project-private/1">
3
+ <editor-bookmarks xmlns="http://www.netbeans.org/ns/editor-bookmarks/2" lastBookmarkId="0"/>
4
+ </project-private>
vendor/dhii/di-interface/nbproject/project.properties ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ auxiliary.org-netbeans-modules-css-prep.less_2e_compiler_2e_options=
2
+ auxiliary.org-netbeans-modules-css-prep.less_2e_enabled=false
3
+ auxiliary.org-netbeans-modules-css-prep.less_2e_mappings=/less:/css
4
+ auxiliary.org-netbeans-modules-css-prep.sass_2e_compiler_2e_options=
5
+ auxiliary.org-netbeans-modules-css-prep.sass_2e_enabled=false
6
+ auxiliary.org-netbeans-modules-css-prep.sass_2e_mappings=/scss:/css
7
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_create_2e_tests=false
8
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_enabled=false
9
+ auxiliary.org-netbeans-modules-php-phpunit.bootstrap_2e_path=
10
+ auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_enabled=false
11
+ auxiliary.org-netbeans-modules-php-phpunit.configuration_2e_path=
12
+ auxiliary.org-netbeans-modules-php-phpunit.customSuite_2e_enabled=false
13
+ auxiliary.org-netbeans-modules-php-phpunit.customSuite_2e_path=
14
+ auxiliary.org-netbeans-modules-php-phpunit.phpUnit_2e_enabled=false
15
+ auxiliary.org-netbeans-modules-php-phpunit.phpUnit_2e_path=
16
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_groups_2e_ask=false
17
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_run_2e_all=false
18
+ auxiliary.org-netbeans-modules-php-phpunit.test_2e_run_2e_phpunit_2e_only=false
19
+ file.reference.di-interface-vendor=vendor
20
+ file.reference.test-functional=test/functional
21
+ include.path=\
22
+ ${php.global.include.path}:\
23
+ ${file.reference.di-interface-vendor}
24
+ php.version=PHP_53
25
+ source.encoding=UTF-8
26
+ src.dir=src
27
+ tags.asp=false
28
+ tags.short=false
29
+ test.src.dir=${file.reference.test-functional}
30
+ testing.providers=PhpUnit
31
+ web.root=.
vendor/dhii/di-interface/nbproject/project.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <project xmlns="http://www.netbeans.org/ns/project/1">
3
+ <type>org.netbeans.modules.php.project</type>
4
+ <configuration>
5
+ <data xmlns="http://www.netbeans.org/ns/php-project/1">
6
+ <name>dhii - di-interface</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/di-interface/phpunit.xml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <phpunit
3
+ colors="true"
4
+ bootstrap="test/bootstrap.php"
5
+ >
6
+ <php>
7
+ <ini name="display_errors" value="1" />
8
+ <ini name="display_startup_errors" value="1" />
9
+ </php>
10
+ <testsuites>
11
+ <testsuite name="Unit Tests">
12
+ <directory>./test/unit/</directory>
13
+ </testsuite>
14
+ <testsuite name="Functional Tests">
15
+ <directory>./test/functional/</directory>
16
+ </testsuite>
17
+ </testsuites>
18
+ <filter>
19
+ <whitelist processUncoveredFilesFromWhitelist="true">
20
+ <directory suffix=".php">src</directory>
21
+ </whitelist>
22
+ </filter>
23
+ <logging>
24
+ <log type="coverage-html" target="./test/coverage/html" lowUpperBound="35"
25
+ highLowerBound="80"/>
26
+ <log type="coverage-clover" target="./test/coverage/clover.xml"/>
27
+ <log type="coverage-php" target="./test/coverage/serialized"/>
28
+ <log type="coverage-text" target="php://stdout" showUncoveredFiles="false"/>
29
+ <log type="json" target="./test/log/logfile.json"/>
30
+ <log type="tap" target="./test/log/logfile.tap"/>
31
+ <log type="junit" target="./test/log/logfile.xml" logIncompleteSkipped="false"/>
32
+ <log type="testdox-html" target="./test/log/testdox.html"/>
33
+ <log type="testdox-text" target="./test/log/testdox.txt"/>
34
+ </logging>
35
+ </phpunit>
vendor/dhii/di-interface/src/CompositeContainerInterface.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ /**
6
+ * Something that can act as a composite container.
7
+ *
8
+ * A composite container is a container that can contain other containers,
9
+ * and perform queries on them.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ interface CompositeContainerInterface extends
14
+ ContainerInterface,
15
+ ContainersAwareInterface
16
+ {
17
+ }
vendor/dhii/di-interface/src/ContainerInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+
7
+ /**
8
+ * Something that can be a DI container.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ interface ContainerInterface extends BaseContainerInterface
13
+ {
14
+ }
vendor/dhii/di-interface/src/ContainersAwareInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Traversable;
6
+
7
+ /**
8
+ * Something that can have a container list retrieved from it.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ interface ContainersAwareInterface
13
+ {
14
+ /**
15
+ * Return a list of containers that belong to this instance.
16
+ *
17
+ * @since 0.1
18
+ *
19
+ * @return array|Traversable The list of containers belonging to this instance.
20
+ */
21
+ public function getContainers();
22
+ }
vendor/dhii/di-interface/src/ExceptionInterface.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ /**
6
+ * Something that can represent a DI exception.
7
+ *
8
+ * @since 0.1
9
+ */
10
+ interface ExceptionInterface
11
+ {
12
+ }
vendor/dhii/di-interface/src/FactoryInterface.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ /**
6
+ * Something that can create service instances.
7
+ *
8
+ * @since 0.1
9
+ */
10
+ interface FactoryInterface
11
+ {
12
+ /**
13
+ * Creates a new instance of a service.
14
+ *
15
+ * @since 0.1
16
+ *
17
+ * @param string $id The ID of the service to create.
18
+ * @param mixed $config Some kind of configuration.
19
+ *
20
+ * @throws NotFoundException If the given ID does not represent a known service.
21
+ * @throws ContainerException If an error occurred while resolving the service definition.
22
+ *
23
+ * @return object|null The created service instance or null if the given ID does not represent
24
+ */
25
+ public function make($id, array $config = array());
26
+ }
vendor/dhii/di-interface/src/ParentAwareContainerInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ /**
6
+ * A container that can have a parent container.
7
+ *
8
+ * This interface is often used to delegate lookup.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ interface ParentAwareContainerInterface extends ContainerInterface
13
+ {
14
+ /**
15
+ * Retrieve the container that is the parent of this container.
16
+ *
17
+ * @since 0.1
18
+ *
19
+ * @return ContainerInterface
20
+ */
21
+ public function getParentContainer();
22
+ }
vendor/dhii/di-interface/src/ServiceProviderInterface.php ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ServiceProvider as BaseServiceProviderInterface;
6
+
7
+ /**
8
+ * Something that can provide service definitions.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ interface ServiceProviderInterface extends BaseServiceProviderInterface
13
+ {
14
+ }
vendor/dhii/di-interface/src/WritableCompositeContainerInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+
7
+ /**
8
+ * A composite container that can have child containers added.
9
+ *
10
+ * @since [*next-version*]
11
+ */
12
+ interface WritableCompositeContainerInterface extends CompositeContainerInterface
13
+ {
14
+ /**
15
+ * Adds a child container.
16
+ *
17
+ * @since [*next-version*]
18
+ *
19
+ * @param BaseContainerInterface $container The container to add.
20
+ */
21
+ public function add(BaseContainerInterface $container);
22
+ }
vendor/dhii/di-interface/src/WritableContainerInterface.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ServiceProvider as BaseServiceProviderInterface;
6
+
7
+ /**
8
+ * Something that can represent a container, services of which can be added.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ interface WritableContainerInterface extends ContainerInterface
13
+ {
14
+ /**
15
+ * Sets a definition for the specified identifier in this container.
16
+ *
17
+ * @since 0.1
18
+ *
19
+ * @param string $id The identifier of the definition to set.
20
+ * @param callable $definition
21
+ */
22
+ public function set($id, $definition);
23
+
24
+ /**
25
+ * Registers a service provider in this container.
26
+ *
27
+ * After this, the container will be able to use definitions in the provider
28
+ * to retrieve services.
29
+ *
30
+ * @since 0.1
31
+ *
32
+ * @param BaseServiceProviderInterface $serviceProvieder The provider to register.
33
+ */
34
+ public function register(BaseServiceProviderInterface $serviceProvieder);
35
+ }
vendor/dhii/di-interface/test/bootstrap.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ error_reporting(E_ALL | E_STRICT);
4
+
5
+ require_once dirname(__FILE__).'/../vendor/autoload.php';
vendor/dhii/di-interface/test/functional/CompositeContainerInterfaceTest.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\CompositeContainerInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\CompositeContainerInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class CompositeContainerInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\CompositeContainerInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return CompositeContainerInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->get()
31
+ ->has()
32
+ ->getContainers()
33
+ ->new();
34
+
35
+ return $mock;
36
+ }
37
+
38
+ /**
39
+ * Tests whether a valid instance of the test subject can be created.
40
+ *
41
+ * @since 0.1
42
+ */
43
+ public function testCanBeCreated()
44
+ {
45
+ $subject = $this->createInstance();
46
+
47
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
48
+ $this->assertInstanceOf('Dhii\\Di\\ContainerInterface', $subject);
49
+ $this->assertInstanceOf('Dhii\\Di\\ContainersAwareInterface', $subject);
50
+ }
51
+ }
vendor/dhii/di-interface/test/functional/ContainerInterfaceTest.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\ContainerInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\ContainerInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ContainerInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\ContainerInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return ContainerInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->get()
31
+ ->has()
32
+ ->new();
33
+
34
+ return $mock;
35
+ }
36
+
37
+ /**
38
+ * Tests whether a valid instance of the test subject can be created.
39
+ *
40
+ * @since 0.1
41
+ */
42
+ public function testCanBeCreated()
43
+ {
44
+ $subject = $this->createInstance();
45
+
46
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
47
+ $this->assertInstanceOf('Interop\Container\ContainerInterface', $subject);
48
+ }
49
+ }
vendor/dhii/di-interface/test/functional/ContainersAwareInterfaceTest.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\ContainersAwareInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\ContainersAwareInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ContainersAwareInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\ContainersAwareInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return ContainersAwareInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->getContainers()
31
+ ->new();
32
+
33
+ return $mock;
34
+ }
35
+
36
+ /**
37
+ * Tests whether a valid instance of the test subject can be created.
38
+ *
39
+ * @since 0.1
40
+ */
41
+ public function testCanBeCreated()
42
+ {
43
+ $subject = $this->createInstance();
44
+
45
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
46
+ }
47
+ }
vendor/dhii/di-interface/test/functional/ExceptionInterfaceTest.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\ExceptionInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\ExceptionInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ExceptionInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\ExceptionInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return ExceptionInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->new();
31
+
32
+ return $mock;
33
+ }
34
+
35
+ /**
36
+ * Tests whether a valid instance of the test subject can be created.
37
+ *
38
+ * @since 0.1
39
+ */
40
+ public function testCanBeCreated()
41
+ {
42
+ $subject = $this->createInstance();
43
+
44
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
45
+ }
46
+ }
vendor/dhii/di-interface/test/functional/FactoryInterface.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\FactoryInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\FactoryInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class FactoryInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\FactoryInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return FactoryInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->make()
31
+ ->new();
32
+
33
+ return $mock;
34
+ }
35
+
36
+ /**
37
+ * Tests whether a valid instance of the test subject can be created.
38
+ *
39
+ * @since 0.1
40
+ */
41
+ public function testCanBeCreated()
42
+ {
43
+ $subject = $this->createInstance();
44
+
45
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
46
+ }
47
+ }
vendor/dhii/di-interface/test/functional/ParentAwareContainerInterfaceTest.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\ParentAwareContainerInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\ParentAwareContainerInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ParentAwareContainerInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * @since 0.1
17
+ *
18
+ * The name of the test subject.
19
+ */
20
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\ParentAwareContainerInterface';
21
+
22
+ /**
23
+ * Name of the test subject's ancestor.
24
+ *
25
+ * @since 0.1
26
+ */
27
+ const TEST_SUBJECT_ANCESTOR = 'Dhii\\Di\\ContainerInterface';
28
+
29
+ /**
30
+ * Creates a new instance of the test subject.
31
+ *
32
+ * @since 0.1
33
+ *
34
+ * @return ParentAwareContainerInterface
35
+ */
36
+ public function createInstance()
37
+ {
38
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
39
+ ->getParentContainer()
40
+ ->get()
41
+ ->has()
42
+ ->new();
43
+
44
+ return $mock;
45
+ }
46
+
47
+ /**
48
+ * Tests whether a valid instance of the test subject can be created.
49
+ *
50
+ * @since 0.1
51
+ */
52
+ public function testCanBeCreated()
53
+ {
54
+ $subject = $this->createInstance();
55
+
56
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
57
+ $this->assertInstanceOf(static::TEST_SUBJECT_ANCESTOR, $subject);
58
+ }
59
+ }
vendor/dhii/di-interface/test/functional/ServiceProviderInterfaceTest.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\ServiceProviderInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\ServiceProviderInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ServiceProviderInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\ServiceProviderInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return ServiceProviderInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->getServices()
31
+ ->new();
32
+
33
+ return $mock;
34
+ }
35
+
36
+ /**
37
+ * Tests whether a valid instance of the test subject can be created.
38
+ *
39
+ * @since 0.1
40
+ */
41
+ public function testCanBeCreated()
42
+ {
43
+ $subject = $this->createInstance();
44
+
45
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
46
+ $this->assertInstanceOf('Interop\\Container\\ServiceProvider', $subject);
47
+ }
48
+ }
vendor/dhii/di-interface/test/functional/WritableCompositeContainerInterfaceTest.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Dhii\Di\WritableCompositeContainerInterface;
6
+ use Xpmock\TestCase;
7
+
8
+ /**
9
+ * Tests {@see \Dhii\Di\WritableCompositeContainerInterface}.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class WritableCompositeContainerInterfaceTest extends TestCase
14
+ {
15
+ /**
16
+ * The name of the test subject.
17
+ */
18
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\WritableCompositeContainerInterface';
19
+
20
+ /**
21
+ * Creates a new instance of the test subject.
22
+ *
23
+ * @since 0.1
24
+ *
25
+ * @return WritableCompositeContainerInterface
26
+ */
27
+ public function createInstance()
28
+ {
29
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
30
+ ->get()
31
+ ->has()
32
+ ->getContainers()
33
+ ->add()
34
+ ->new();
35
+
36
+ return $mock;
37
+ }
38
+
39
+ /**
40
+ * Tests whether a valid instance of the test subject can be created.
41
+ *
42
+ * @since 0.1
43
+ */
44
+ public function testCanBeCreated()
45
+ {
46
+ $subject = $this->createInstance();
47
+
48
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
49
+ $this->assertInstanceOf('Dhii\\Di\\ContainerInterface', $subject);
50
+ $this->assertInstanceOf('Dhii\\Di\\ContainersAwareInterface', $subject);
51
+ $this->assertInstanceOf('Dhii\\Di\\WritableCompositeContainerInterface', $subject);
52
+ }
53
+ }
vendor/dhii/di-interface/test/functional/WritableContainerInterfaceTest.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\FuncTest;
4
+
5
+ use Xpmock\TestCase;
6
+
7
+ /**
8
+ * Tests {@see \Dhii\Di\WritableContainerInterface}.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ class WritableContainerInterfaceTest extends TestCase
13
+ {
14
+ /**
15
+ * The name of the test subject.
16
+ *
17
+ * @since 0.1
18
+ */
19
+ const TEST_SUBJECT_CLASSNAME = 'Dhii\\Di\\WritableContainerInterface';
20
+
21
+ /**
22
+ * Creates a new instance of the test subject.
23
+ *
24
+ * @since 0.1
25
+ *
26
+ * @return \Dhii\Di\WritableContainerInterface
27
+ */
28
+ public function createInstance()
29
+ {
30
+ $mock = $this->mock(static::TEST_SUBJECT_CLASSNAME)
31
+ ->get()
32
+ ->has()
33
+ ->set()
34
+ ->register()
35
+ ->new();
36
+
37
+ return $mock;
38
+ }
39
+
40
+ /**
41
+ * Tests whether a valid instance of the test subject can be created.
42
+ *
43
+ * @since 0.1
44
+ */
45
+ public function testCanBeCreated()
46
+ {
47
+ $subject = $this->createInstance();
48
+
49
+ $this->assertInstanceOf(static::TEST_SUBJECT_CLASSNAME, $subject);
50
+ $this->assertInstanceOf('Dhii\\Di\\ContainerInterface', $subject);
51
+ $this->assertInstanceOf('Interop\\Container\\ContainerInterface', $subject);
52
+ }
53
+ }
vendor/dhii/di/CHANGELOG.md ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # Change log
2
+ All notable changes to this project will be documented in this file.
3
+
4
+ The format is based on [Keep a Changelog](http://keepachangelog.com/)
5
+ and this project adheres to [Semantic Versioning](http://semver.org/).
6
+
7
+ ## [0.1.1] - 2017-02-03
8
+ Non-BC-breaking bugfixes.
9
+ Reduced size of dist archive.
10
+ Added Gitter notifications of Travis events, and Gitter badge.
11
+
12
+ ### Fixed
13
+ - `CompositeContainer#__construct()` not accepting interop containers.
14
+ - `CompositeContainer#add()` not implementing interface method.
15
+ - `CompositeContainer` not throwing exceptions correctly.
16
+
17
+ ## [0.1] - 2017-02-02
18
+ Initial release, containing concrete implementations.
19
+
20
+ ### Added
21
+ - Implementations of regular and compound containers, with service provider support.
22
+ - Tests.
vendor/dhii/di/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ MIT License
2
+
3
+ Copyright (c) 2016-2017 Dhii
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
vendor/dhii/di/README.md ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ ## Dhii - DI ##
2
+
3
+ [![Build Status](https://travis-ci.org/Dhii/di.svg?branch=master)](https://travis-ci.org/Dhii/di)
4
+ [![Code Climate](https://codeclimate.com/github/Dhii/di/badges/gpa.svg)](https://codeclimate.com/github/Dhii/di)
5
+ [![Test Coverage](https://codeclimate.com/github/Dhii/di/badges/coverage.svg)](https://codeclimate.com/github/Dhii/di/coverage)
6
+ [![Join the chat at https://gitter.im/Dhii/di](https://badges.gitter.im/Dhii/di.svg)](https://gitter.im/Dhii/di?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
7
+
8
+ A simple, granular, standards-compliant dependency injection container and factory implementation.
9
+
10
+ ### Features
11
+ - Complies with [container-interop v1.1](https://github.com/container-interop/container-interop/tree/1.1.0) specification.
12
+ - Mostly supports the proposed [service-provider v0.3](https://github.com/container-interop/service-provider/tree/v0.3.0) standard.
13
+ - Includes the [delegate lookup](https://github.com/container-interop/container-interop/blob/master/docs/Delegate-lookup-meta.md) feature, a.k.a. composite containers, with intuitive override order.
14
+ - Uses some other [standards](https://github.com/Dhii/di-interface) published separately.
15
+ - Granular approach, with an [implementation](https://github.com/Dhii/di-abstract) agnostic of concrete behaviour published separately: rely on this re-usable, tested, standards-compliant functionality to make your own container implementation.
16
+ - [`ContainerInterface#get()`](https://github.com/container-interop/container-interop/blob/master/src/Interop/Container/ContainerInterface.php#L26) guaranteed to return same instance every time.
17
+ - [`FactoryInterface#make()`](https://github.com/Dhii/di-interface/blob/master/src/FactoryInterface.php#L26) guaranteed to return new instance every time.
18
+
19
+ ### Disadvantages
20
+ - Does not support the factories' 2nd parameter, i.e. [`$getPrevious`](https://github.com/container-interop/service-provider/blob/v0.3.0/src/ServiceProvider.php#L22).
21
+ - Container and factory unified into one class (to be separated soon).
vendor/dhii/di/composer.json ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/di",
3
+ "description": "A DI container implementation",
4
+ "type": "library",
5
+ "license": "MIT",
6
+ "keywords": [
7
+ "container",
8
+ "di",
9
+ "dependency injection"
10
+ ],
11
+ "authors": [
12
+ {
13
+ "name": "Dhii Team",
14
+ "email": "development@dhii.co"
15
+ }
16
+ ],
17
+ "minimum-stability": "dev",
18
+ "require": {
19
+ "php": "^5.3 | ^7.0",
20
+ "dhii/di-interface": "^0.1",
21
+ "dhii/di-abstract": "^0.1",
22
+ "container-interop/container-interop": "^1.1",
23
+ "container-interop/service-provider": "^0.3"
24
+ },
25
+ "require-dev": {
26
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
27
+ "phpunit/phpunit": "^4.8",
28
+ "ptrofimov/xpmock": "^1.1",
29
+ "codeclimate/php-test-reporter": "<=0.3.2"
30
+ },
31
+ "autoload": {
32
+ "psr-4": {
33
+ "Dhii\\Di\\": "src/"
34
+ }
35
+ },
36
+ "provide": {
37
+ "container-interop/container-interop-implementation": "^1.0"
38
+ }
39
+ }
vendor/dhii/di/src/AbstractContainerBase.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Exception;
6
+ use Dhii\Di\Exception\NotFoundException;
7
+ use Dhii\Di\Exception\ContainerException;
8
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
9
+
10
+ /**
11
+ * Common public functionality.
12
+ *
13
+ * @since 0.1
14
+ */
15
+ abstract class AbstractContainerBase extends AbstractContainer
16
+ {
17
+ /**
18
+ * Checks if a service exists with a specific ID.
19
+ *
20
+ * @since 0.1
21
+ * @see BaseContainerInterface::has()
22
+ *
23
+ * @param string $id The ID of the service to check for.
24
+ *
25
+ * @return bool True if a service exists with the given ID; false otherwise.
26
+ */
27
+ public function has($id)
28
+ {
29
+ return $this->_has($id);
30
+ }
31
+
32
+ /**
33
+ * Retrieves the service with a specific ID.
34
+ *
35
+ * @since 0.1
36
+ * @see BaseContainerInterface::get()
37
+ *
38
+ * @param string $id The ID of the service to retrieve.
39
+ *
40
+ * @throws NotFoundException If no service with the given ID exists in the container.
41
+ *
42
+ * @return mixed The service with the matching ID.
43
+ */
44
+ public function get($id)
45
+ {
46
+ return $this->_get($id);
47
+ }
48
+
49
+ /**
50
+ * {@inheritdoc}
51
+ *
52
+ * @since 0.1
53
+ */
54
+ public function make($id, array $config = array())
55
+ {
56
+ return $this->_make($id, $config);
57
+ }
58
+
59
+ /**
60
+ * {@inheritdoc}
61
+ *
62
+ * @since 0.1
63
+ *
64
+ * @return NotFoundException The new exception instance.
65
+ */
66
+ protected function _createNotFoundException($message, $code = 0, Exception $innerException = null)
67
+ {
68
+ return new NotFoundException($message, $code, $innerException);
69
+ }
70
+
71
+ /**
72
+ * {@inheritdoc}
73
+ *
74
+ * @since 0.1
75
+ *
76
+ * @return ContainerException The new exception instance.
77
+ */
78
+ protected function _createContainerException($message, $code = 0, Exception $innerException = null)
79
+ {
80
+ return new ContainerException($message, $code, $innerException);
81
+ }
82
+ }
vendor/dhii/di/src/CompositeContainer.php ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Exception;
6
+ use Dhii\Di\Exception\ContainerException;
7
+ use Dhii\Di\Exception\NotFoundException;
8
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
9
+
10
+ /**
11
+ * Concrete implementation of a container that can have child containers.
12
+ *
13
+ * @since 0.1
14
+ */
15
+ class CompositeContainer extends AbstractCompositeContainer implements
16
+ ParentAwareContainerInterface,
17
+ WritableCompositeContainerInterface
18
+ {
19
+ /**
20
+ * Constructor.
21
+ *
22
+ * @since 0.1
23
+ *
24
+ * @param BaseContainerInterface $parent The parent container of this instance.
25
+ */
26
+ public function __construct(BaseContainerInterface $parent = null)
27
+ {
28
+ $this->_setParentContainer($parent);
29
+ }
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ *
34
+ * @since 0.1
35
+ */
36
+ public function get($id)
37
+ {
38
+ return $this->_getDelegated($id);
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ *
44
+ * @since 0.1
45
+ */
46
+ public function has($id)
47
+ {
48
+ return $this->_hasDelegated($id);
49
+ }
50
+
51
+ /**
52
+ * {@inheritdoc}
53
+ *
54
+ * @since 0.1
55
+ */
56
+ public function getParentContainer()
57
+ {
58
+ return $this->_getParentContainer();
59
+ }
60
+
61
+ /**
62
+ * {@inheritdoc}
63
+ *
64
+ * @since 0.1
65
+ */
66
+ public function getContainers()
67
+ {
68
+ return $this->_getContainers();
69
+ }
70
+
71
+ /**
72
+ * Adds a child container.
73
+ *
74
+ * @since 0.1
75
+ *
76
+ * @param BaseContainerInterface $container The container to add.
77
+ *
78
+ * @return $this This instance.
79
+ */
80
+ public function add(BaseContainerInterface $container)
81
+ {
82
+ $this->_add($container);
83
+
84
+ return $this;
85
+ }
86
+
87
+ /**
88
+ * {@inheritdoc}
89
+ *
90
+ * @since 0.1
91
+ *
92
+ * @return NotFoundException The new exception instance.
93
+ */
94
+ protected function _createNotFoundException($message, $code = 0, Exception $innerException = null)
95
+ {
96
+ return new NotFoundException($message, $code, $innerException);
97
+ }
98
+
99
+ /**
100
+ * {@inheritdoc}
101
+ *
102
+ * @since 0.1
103
+ *
104
+ * @return ContainerException The new exception instance.
105
+ */
106
+ protected function _createContainerException($message, $code = 0, Exception $innerException = null)
107
+ {
108
+ return new ContainerException($message, $code, $innerException);
109
+ }
110
+ }
vendor/dhii/di/src/Container.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ServiceProvider as BaseServiceProviderInterface;
6
+
7
+ /**
8
+ * A simple, parent-agnostic container implementation.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ class Container extends AbstractContainerBase implements
13
+ ContainerInterface,
14
+ WritableContainerInterface,
15
+ FactoryInterface
16
+ {
17
+ /**
18
+ * Constructor.
19
+ *
20
+ * @since 0.1
21
+ *
22
+ * @param BaseServiceProviderInterface $definitions Service definitions to add to this container.
23
+ */
24
+ public function __construct(BaseServiceProviderInterface $definitions = null)
25
+ {
26
+ if (!is_null($definitions)) {
27
+ $this->_set($definitions);
28
+ }
29
+ }
30
+
31
+ /**
32
+ * {@inheritdoc}
33
+ *
34
+ * @since 0.1
35
+ */
36
+ public function set($id, $definition = null)
37
+ {
38
+ $this->_set($id, $definition);
39
+
40
+ return $this;
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ *
46
+ * @since 0.1
47
+ */
48
+ public function register(BaseServiceProviderInterface $serviceProvider)
49
+ {
50
+ $this->_register($serviceProvider);
51
+
52
+ return $this;
53
+ }
54
+ }
vendor/dhii/di/src/ContainerWithImmutableParent.php ADDED
@@ -0,0 +1,88 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Dhii\Di\Exception\ContainerException;
6
+ use Dhii\Di\Exception\NotFoundException;
7
+ use Exception;
8
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
9
+ use Interop\Container\ServiceProvider as BaseServiceProviderInterface;
10
+
11
+ /**
12
+ * This container accepts a parent instance, which cannot be changed from external objects.
13
+ *
14
+ * @since 0.1
15
+ */
16
+ class ContainerWithImmutableParent extends AbstractParentAwareContainer implements ParentAwareContainerInterface
17
+ {
18
+ /**
19
+ * Constructor.
20
+ *
21
+ * @since 0.1
22
+ *
23
+ * @param BaseServiceProviderInterface $definitions Service definitions to add to this container.
24
+ * @param BaseContainerInterface $parent The container, which is to become this container's parent.
25
+ */
26
+ public function __construct(BaseServiceProviderInterface $definitions = null, BaseContainerInterface $parent = null)
27
+ {
28
+ if (!is_null($definitions)) {
29
+ $this->_set($definitions);
30
+ }
31
+
32
+ $this->_setParentContainer($parent);
33
+ }
34
+
35
+ /**
36
+ * {@inheritdoc}
37
+ *
38
+ * @since 0.1
39
+ */
40
+ public function getParentContainer()
41
+ {
42
+ return $this->_getParentContainer();
43
+ }
44
+
45
+ /**
46
+ * {@inheritdoc}
47
+ *
48
+ * @since 0.1
49
+ */
50
+ public function get($id)
51
+ {
52
+ return $this->_get($id);
53
+ }
54
+
55
+ /**
56
+ * {@inheritdoc}
57
+ *
58
+ * @since 0.1
59
+ */
60
+ public function has($id)
61
+ {
62
+ return $this->_has($id);
63
+ }
64
+
65
+ /**
66
+ * {@inheritdoc}
67
+ *
68
+ * @since 0.1
69
+ *
70
+ * @return NotFoundException The new exception instance.
71
+ */
72
+ protected function _createNotFoundException($message, $code = 0, Exception $innerException = null)
73
+ {
74
+ return new NotFoundException($message, $code, $innerException);
75
+ }
76
+
77
+ /**
78
+ * {@inheritdoc}
79
+ *
80
+ * @since 0.1
81
+ *
82
+ * @return ContainerException The new exception instance.
83
+ */
84
+ protected function _createContainerException($message, $code = 0, Exception $innerException = null)
85
+ {
86
+ return new ContainerException($message, $code, $innerException);
87
+ }
88
+ }
vendor/dhii/di/src/ContainerWithMutableParent.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Interop\Container\ContainerInterface as BaseContainerInterface;
6
+
7
+ /**
8
+ * A container that can have its parent changed after initialization.
9
+ *
10
+ * @since 0.1
11
+ */
12
+ class ContainerWithMutableParent extends ContainerWithImmutableParent
13
+ {
14
+ /**
15
+ * Sets the parent container.
16
+ *
17
+ * @since 0.1
18
+ *
19
+ * @param BaseContainerInterface $container The container to become this instance's parent.
20
+ *
21
+ * @return $this This instance.
22
+ */
23
+ public function setParentContainer(BaseContainerInterface $container)
24
+ {
25
+ $this->_setParentContainer($container);
26
+
27
+ return $this;
28
+ }
29
+ }
vendor/dhii/di/src/Exception/ContainerException.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\Exception;
4
+
5
+ use Interop\Container\Exception\ContainerException as ContainerExceptionInterface;
6
+ use Dhii\Di\ExceptionInterface as DiExceptionInterface;
7
+
8
+ /**
9
+ * An exception related to DI containers.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class ContainerException extends \Exception implements
14
+ DiExceptionInterface,
15
+ ContainerExceptionInterface
16
+ {
17
+ }
vendor/dhii/di/src/Exception/NotFoundException.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di\Exception;
4
+
5
+ use Interop\Container\Exception\NotFoundException as NotFoundExceptionInterface;
6
+ use Dhii\Di\ExceptionInterface as DiExceptionInterface;
7
+
8
+ /**
9
+ * An exception that is thrown when a service definition is not found by a DI container.
10
+ *
11
+ * @since 0.1
12
+ */
13
+ class NotFoundException extends \Exception implements
14
+ DiExceptionInterface,
15
+ NotFoundExceptionInterface
16
+ {
17
+ }
vendor/dhii/di/src/ServiceProvider.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Di;
4
+
5
+ use Exception;
6
+ use Dhii\Di\Exception\ContainerException;
7
+ use Traversable;
8
+
9
+ /**
10
+ * Generic standards-compliant immutable DI service provider.
11
+ *
12
+ * @since 0.1
13
+ */
14
+ class ServiceProvider extends AbstractServiceProvider implements ServiceProviderInterface
15
+ {
16
+ /**
17
+ * Constructor.
18
+ *
19
+ * @since 0.1
20
+ *
21
+ * @param callable[]|Traversable $definitions A list of definitions for this provider.
22
+ */
23
+ public function __construct($definitions = array())
24
+ {
25
+ $this->_addMany($definitions);
26
+ }
27
+
28
+ /**
29
+ * {@inheritdoc}
30
+ *
31
+ * @since 0.1
32
+ */
33
+ public function getServices()
34
+ {
35
+ return $this->_getServices();
36
+ }
37
+
38
+ /**
39
+ * {@inheritdoc}
40
+ *
41
+ * @since 0.1
42
+ *
43
+ * @return ContainerException The new exception instance.
44
+ */
45
+ protected function _createContainerException($message, $code = 0, Exception $innerException = null)
46
+ {
47
+ return new ContainerException($message, $code, $innerException);
48
+ }
49
+ }
wp-rss-aggregator.php CHANGED
@@ -3,7 +3,7 @@
3
  * Plugin Name: WP RSS Aggregator
4
  * Plugin URI: https://www.wprssaggregator.com/#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wpraplugin
5
  * Description: Imports and aggregates multiple RSS Feeds.
6
- * Version: 4.10
7
  * Author: RebelCode
8
  * Author URI: https://www.wprssaggregator.com
9
  * Text Domain: wprss
@@ -30,7 +30,7 @@
30
 
31
  /**
32
  * @package WPRSSAggregator
33
- * @version 4.10
34
  * @since 1.0
35
  * @author RebelCode
36
  * @copyright Copyright (c) 2012-2016, RebelCode Ltd.
@@ -44,7 +44,7 @@
44
 
45
  // Set the version number of the plugin.
46
  if( !defined( 'WPRSS_VERSION' ) )
47
- define( 'WPRSS_VERSION', '4.10', true );
48
 
49
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
50
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
@@ -116,7 +116,28 @@
116
  define( 'WPRACORE_DIAG_TESTS_DIR', WPRSS_DIR . 'test/diag' );
117
  }
118
 
119
- define( 'WPRSS_CORE_PLUGIN_NAME', 'WP RSS Aggregator' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
 
121
  /**
122
  * Load required files.
@@ -144,9 +165,11 @@
144
  /* Only function definitions, no effect! */
145
  require_once(WPRSS_INC . 'functions.php');
146
 
 
 
 
147
  /* Load install, upgrade and migration code. */
148
  require_once ( WPRSS_INC . 'update.php' );
149
-
150
  /* Load the shortcodes functions file. */
151
  require_once ( WPRSS_INC . 'shortcodes.php' );
152
 
@@ -273,49 +296,18 @@
273
  register_activation_hook( __FILE__ , 'wprss_activate' );
274
  register_deactivation_hook( __FILE__ , 'wprss_deactivate' );
275
 
 
276
 
277
  /**
278
  * Returns the Core plugin singleton instance.
279
  *
 
 
280
  * @since 4.8.1
281
  * @return Aventura\Wprss\Core\Plugin
282
  */
283
  function wprss() {
284
- static $plugin = null;
285
-
286
-
287
- // One time initialization
288
- if (is_null($plugin)) {
289
- static $timesCalled = 0;
290
- if ($timesCalled) {
291
- throw new Exception( sprintf('%1$s has been initialized recursively', WPRSS_CORE_PLUGIN_NAME) );
292
- }
293
- $timesCalled++;
294
-
295
- /**
296
- * Basically, we could just do this here:
297
- * Factory::create();
298
- *
299
- * However, the actual setup allows for even further customization.
300
- * In fact, the factory can be substituted by some entirely different factory,
301
- * that creates and initializes a different plugin in a different way.
302
- */
303
-
304
- $factoryClassName = apply_filters('wprss_core_plugin_factory_class_name',
305
- 'Aventura\\Wprss\\Core\\Factory');
306
-
307
- if (!class_exists($factoryClassName)) {
308
- throw new Aventura\Wprss\Exception(
309
- sprintf('Could not initialize add-on: Factory class "%1$s" does not exist', $factoryClassName));
310
- }
311
-
312
- $plugin = call_user_func_array(array($factoryClassName, 'create'), array(array(
313
- 'basename' => __FILE__,
314
- 'name' => WPRSS_CORE_PLUGIN_NAME
315
- )));
316
- }
317
-
318
- return $plugin;
319
  }
320
 
321
  try {
@@ -327,7 +319,6 @@
327
  wp_die( $e->getMessage() );
328
  }
329
 
330
-
331
  add_action( 'init', 'wprss_init' );
332
  /**
333
  * Initialise the plugin
@@ -727,6 +718,6 @@
727
  if ( is_null( $extension ) )
728
  $extension = '.js';
729
 
730
- $script_url = WPRSS_JS . $url . (wprss_is_script_debug() ? wprss_get_minified_extension_prefix() : '') . $extension;
731
  return apply_filters( 'wprss_script_url', $script_url, $url, $extension );
732
  }
3
  * Plugin Name: WP RSS Aggregator
4
  * Plugin URI: https://www.wprssaggregator.com/#utm_source=wpadmin&utm_medium=plugin&utm_campaign=wpraplugin
5
  * Description: Imports and aggregates multiple RSS Feeds.
6
+ * Version: 4.11
7
  * Author: RebelCode
8
  * Author URI: https://www.wprssaggregator.com
9
  * Text Domain: wprss
30
 
31
  /**
32
  * @package WPRSSAggregator
33
+ * @version 4.11
34
  * @since 1.0
35
  * @author RebelCode
36
  * @copyright Copyright (c) 2012-2016, RebelCode Ltd.
44
 
45
  // Set the version number of the plugin.
46
  if( !defined( 'WPRSS_VERSION' ) )
47
+ define( 'WPRSS_VERSION', '4.11', true );
48
 
49
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
50
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
116
  define( 'WPRACORE_DIAG_TESTS_DIR', WPRSS_DIR . 'test/diag' );
117
  }
118
 
119
+ define('WPRSS_CORE_PLUGIN_NAME', 'WP RSS Aggregator');
120
+
121
+ /**
122
+ * Code of the Core plugin.
123
+ *
124
+ * @since 4.11
125
+ */
126
+ define('WPRSS_PLUGIN_CODE', 'wprss');
127
+
128
+ /**
129
+ * Prefix for events used by this plugin.
130
+ *
131
+ * @since 4.11
132
+ */
133
+ define('WPRSS_EVENT_PREFIX', \WPRSS_PLUGIN_CODE . '_');
134
+
135
+ /**
136
+ * Whether this plugin is in debug mode.
137
+ *
138
+ * @since 4.11
139
+ */
140
+ define('WPRSS_DEBUG', \WP_DEBUG);
141
 
142
  /**
143
  * Load required files.
165
  /* Only function definitions, no effect! */
166
  require_once(WPRSS_INC . 'functions.php');
167
 
168
+ /* Dependency injection */
169
+ require_once ( WPRSS_INC . 'di.php' );
170
+
171
  /* Load install, upgrade and migration code. */
172
  require_once ( WPRSS_INC . 'update.php' );
 
173
  /* Load the shortcodes functions file. */
174
  require_once ( WPRSS_INC . 'shortcodes.php' );
175
 
296
  register_activation_hook( __FILE__ , 'wprss_activate' );
297
  register_deactivation_hook( __FILE__ , 'wprss_deactivate' );
298
 
299
+ do_action('wprss_pre_init');
300
 
301
  /**
302
  * Returns the Core plugin singleton instance.
303
  *
304
+ * Using DI container since 4.11.
305
+ *
306
  * @since 4.8.1
307
  * @return Aventura\Wprss\Core\Plugin
308
  */
309
  function wprss() {
310
+ return wprss_wp_container()->get(sprintf('%1$splugin', \WPRSS_SERVICE_ID_PREFIX));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
311
  }
312
 
313
  try {
319
  wp_die( $e->getMessage() );
320
  }
321
 
 
322
  add_action( 'init', 'wprss_init' );
323
  /**
324
  * Initialise the plugin
718
  if ( is_null( $extension ) )
719
  $extension = '.js';
720
 
721
+ $script_url = WPRSS_JS . $url . (!wprss_is_script_debug() ? wprss_get_minified_extension_prefix() : '') . $extension;
722
  return apply_filters( 'wprss_script_url', $script_url, $url, $extension );
723
  }