WP RSS Aggregator - Version 4.10

Version Description

(2016-12-29) = * Fixed bug with feed error output breaking tooltips on "Feed Sources" page. * Fixed bug with nonces on the "Feed Sources" page that broke some source actions. * Fixed problem with image cache filenames being too long. * Fixed problem with permalink URLs sometimes being URL-encoded. * Fixed problem with large logs causing OOM errors and breaking Debugging page. * Fixed conflict with function unparse_url(). * Fixed bug with _getDataOrConst() not retrieving single value. * Fixed future incompatibility with class-feed.php for WP 4.7+. * Fixed conflicts with many JS scripts by only adding JS on our admin pages. * Fixed conflicts with some classes by loading only valid root namespace components. * Fixed PHP warning related to retrieving unique titles. * Added a per-feed-source "Link Source" option. * Added a per-feed-source "Feed Request User Agent" option. * The "Add New" button no longer appears for feed items. * Added "Leave a Review" notification. * Now using Composer! * Now using Phing! * Added RegEx HTML Encodifier. * Added integration with Diagnostics plugin, and tests. * Logs are now created in wp-content/log/wprss, and are named more descriptively.

Download this release

Release Info

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

Code changes from version 4.9.1 to 4.10

Files changed (153) hide show
  1. css/admin-styles.css +5 -0
  2. includes/Aventura/Wprss/Core/Block/Html/AbstractRegularTag.php +28 -0
  3. includes/Aventura/Wprss/Core/Block/Html/AbstractSelfClosingTag.php +45 -0
  4. includes/Aventura/Wprss/Core/Block/Html/Anchor.php +1 -18
  5. includes/Aventura/Wprss/Core/Block/Html/Span.php +36 -0
  6. includes/Aventura/Wprss/Core/Component/AdminAjaxNotices.php +42 -0
  7. includes/Aventura/Wprss/Core/Component/AdminHelper.php +68 -0
  8. includes/Aventura/Wprss/Core/Component/LeaveReviewNotification.php +548 -0
  9. includes/Aventura/Wprss/Core/ComponentFactory.php +44 -1
  10. includes/Aventura/Wprss/Core/Model/Collection/AbstractCollection.php +34 -0
  11. includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php +6 -2
  12. includes/Aventura/Wprss/Core/Model/ModelAbstract.php +2 -2
  13. includes/Aventura/Wprss/Core/Model/Regex/AbstractRegex.php +111 -0
  14. includes/Aventura/Wprss/Core/Model/Regex/HtmlEncoder.php +621 -0
  15. includes/Aventura/Wprss/Core/Model/Set/AbstractCompositeSet.php +20 -0
  16. includes/Aventura/Wprss/Core/Model/Set/AbstractGenericSet.php +139 -0
  17. includes/Aventura/Wprss/Core/Model/Set/AbstractGenericSetSet.php +44 -0
  18. includes/Aventura/Wprss/Core/Model/Set/AbstractSet.php +32 -0
  19. includes/Aventura/Wprss/Core/Model/Set/AbstractSetSet.php +71 -0
  20. includes/Aventura/Wprss/Core/Model/Set/Set.php +12 -0
  21. includes/Aventura/Wprss/Core/Model/Set/SetInterface.php +22 -0
  22. includes/Aventura/Wprss/Core/Model/Set/SetSet.php +12 -0
  23. includes/Aventura/Wprss/Core/Model/Set/SetSetInterface.php +31 -0
  24. includes/Aventura/Wprss/Core/Model/Set/Synonym/AbstractGenericSynonymSet.php +26 -0
  25. includes/Aventura/Wprss/Core/Model/Set/Synonym/AbstractSynonymSet.php +45 -0
  26. includes/Aventura/Wprss/Core/Model/Set/Synonym/Set.php +61 -0
  27. includes/Aventura/Wprss/Core/Model/Set/Synonym/Simple.php +12 -0
  28. includes/Aventura/Wprss/Core/Model/Set/Synonym/SynonymSetInterface.php +24 -0
  29. includes/Aventura/Wprss/Core/Model/Set/Synonym/SynonymSetSetInterface.php +27 -0
  30. includes/Aventura/Wprss/Core/Plugin.php +68 -0
  31. includes/Aventura/Wprss/Core/Plugin/ComponentFactoryAbstract.php +48 -13
  32. includes/admin-ajax-notice.php +42 -11
  33. includes/admin-display.php +90 -73
  34. includes/admin-help-metaboxes.php +5 -0
  35. includes/admin-help-settings.php +16 -0
  36. includes/admin-help.php +37 -4
  37. includes/admin-log.php +441 -290
  38. includes/admin-metaboxes.php +17 -1
  39. includes/admin-options.php +49 -0
  40. includes/autoload.php +38 -20
  41. includes/cpt-feeds.php +3 -3
  42. includes/custom-post-types.php +2 -0
  43. includes/feed-access.php +165 -17
  44. includes/feed-display.php +7 -3
  45. includes/feed-importing.php +57 -59
  46. includes/feed-processing.php +2 -2
  47. includes/image-caching.php +48 -9
  48. includes/leave-review-notification.php +26 -0
  49. includes/libraries/EDD_licensing/EDD_SL_Plugin_Updater.php +0 -0
  50. includes/scripts.php +78 -71
  51. includes/update.php +0 -1
  52. js/admin-custom.js +2 -2
  53. languages/wprss-es.mo +0 -0
  54. languages/wprss-es.po +0 -0
  55. readme.txt +168 -74
  56. test/diag/Aventura/Wprss/Core/DiagTest/DiagTest.php +21 -0
  57. test/diag/Aventura/Wprss/Core/DiagTest/Model/ModelAbstractTest.php +94 -0
  58. test/diag/Aventura/Wprss/Core/DiagTest/Model/Regex/HtmlEncoderTest.php +121 -0
  59. test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/SetTest.php +92 -0
  60. test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/Synonym/SetTest.php +94 -0
  61. test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/Synonym/SimpleTest.php +72 -0
  62. vendor/autoload.php +7 -0
  63. vendor/composer/ClassLoader.php +415 -0
  64. vendor/composer/LICENSE +21 -0
  65. vendor/composer/autoload_classmap.php +9 -0
  66. vendor/composer/autoload_namespaces.php +9 -0
  67. vendor/composer/autoload_psr4.php +11 -0
  68. vendor/composer/autoload_real.php +52 -0
  69. vendor/composer/autoload_static.php +39 -0
  70. vendor/composer/installed.json +219 -0
  71. vendor/dhii/collections-abstract-base/.codeclimate.yml +17 -0
  72. vendor/dhii/collections-abstract-base/.php_cs +27 -0
  73. vendor/dhii/collections-abstract-base/.travis.yml +22 -0
  74. vendor/dhii/collections-abstract-base/CHANGELOG.md +8 -0
  75. vendor/dhii/collections-abstract-base/README.md +10 -0
  76. vendor/dhii/collections-abstract-base/composer.json +27 -0
  77. vendor/dhii/collections-abstract-base/composer.lock +2015 -0
  78. vendor/dhii/collections-abstract-base/nbproject/project.properties +24 -0
  79. vendor/dhii/collections-abstract-base/nbproject/project.xml +9 -0
  80. vendor/dhii/collections-abstract-base/phpunit.xml +35 -0
  81. vendor/dhii/collections-abstract-base/src/AbstractCollection.php +489 -0
  82. vendor/dhii/collections-abstract-base/src/AbstractHasher.php +62 -0
  83. vendor/dhii/collections-abstract-base/src/AbstractIterableCollection.php +286 -0
  84. vendor/dhii/collections-abstract-base/test/bootstrap.php +5 -0
  85. vendor/dhii/collections-abstract-base/test/functional/AbstractCollectionTest.php +111 -0
  86. vendor/dhii/collections-abstract-base/test/functional/AbstractHasherTest.php +60 -0
  87. vendor/dhii/collections-abstract-base/test/functional/AbstractIterableCollectionTest.php +131 -0
  88. vendor/dhii/collections-abstract/.php_cs +27 -0
  89. vendor/dhii/collections-abstract/.travis.yml +15 -0
  90. vendor/dhii/collections-abstract/CHANGELOG.md +8 -0
  91. vendor/dhii/collections-abstract/composer.json +28 -0
  92. vendor/dhii/collections-abstract/composer.lock +1755 -0
  93. vendor/dhii/collections-abstract/nbproject/project.properties +24 -0
  94. vendor/dhii/collections-abstract/nbproject/project.xml +9 -0
  95. vendor/dhii/collections-abstract/phpunit.xml +35 -0
  96. vendor/dhii/collections-abstract/src/AbstractCallbackCollection.php +23 -0
  97. vendor/dhii/collections-abstract/src/AbstractCallbackCollectionBase.php +49 -0
  98. vendor/dhii/collections-abstract/src/AbstractCallbackIterator.php +176 -0
  99. vendor/dhii/collections-abstract/src/AbstractGenericAccessibleCollection.php +41 -0
  100. vendor/dhii/collections-abstract/src/AbstractGenericCollection.php +33 -0
  101. vendor/dhii/collections-abstract/src/AbstractGenericMutableCollection.php +65 -0
  102. vendor/dhii/collections-abstract/src/AbstractSearchableCollection.php +73 -0
  103. vendor/dhii/collections-abstract/src/AppendIterator.php +13 -0
  104. vendor/dhii/collections-abstract/src/CallbackIterator.php +37 -0
  105. vendor/dhii/collections-abstract/test/bootstrap.php +5 -0
  106. vendor/dhii/collections-abstract/test/functional/AbstractCallbackCollectionBaseTest.php +81 -0
  107. vendor/dhii/collections-abstract/test/functional/AbstractCallbackIteratorTest.php +40 -0
  108. vendor/dhii/collections-interface/.codeclimate.yml +17 -0
  109. vendor/dhii/collections-interface/.php_cs +27 -0
  110. vendor/dhii/collections-interface/.travis.yml +22 -0
  111. vendor/dhii/collections-interface/CHANGELOG.md +25 -0
  112. vendor/dhii/collections-interface/composer.json +32 -0
  113. vendor/dhii/collections-interface/composer.lock +1941 -0
  114. vendor/dhii/collections-interface/nbproject/project.properties +24 -0
  115. vendor/dhii/collections-interface/nbproject/project.xml +9 -0
  116. vendor/dhii/collections-interface/phpunit.xml +35 -0
  117. vendor/dhii/collections-interface/src/AccessibleCollectionInterface.php +44 -0
  118. vendor/dhii/collections-interface/src/CallbackIterableInterface.php +28 -0
  119. vendor/dhii/collections-interface/src/CallbackIteratorInterface.php +37 -0
  120. vendor/dhii/collections-interface/src/CollectionInterface.php +23 -0
  121. vendor/dhii/collections-interface/src/MutableCollectionInterface.php +55 -0
  122. vendor/dhii/collections-interface/src/SearchableCollectionInterface.php +24 -0
  123. vendor/dhii/collections-interface/src/SequenceIteratorIteratorInterface.php +28 -0
  124. vendor/dhii/collections-interface/src/SetInterface.php +83 -0
  125. vendor/dhii/collections-interface/test/bootstrap.php +5 -0
  126. vendor/dhii/collections-interface/test/unit/AccessibleCollectionInterfaceTest.php +37 -0
  127. vendor/dhii/collections-interface/test/unit/CallbackIterableInterfaceTest.php +37 -0
  128. vendor/dhii/collections-interface/test/unit/CallbackIteratorInterfaceTest.php +38 -0
  129. vendor/dhii/collections-interface/test/unit/CollectionInterfaceTest.php +37 -0
  130. vendor/dhii/collections-interface/test/unit/MutableCollectionInterfaceTest.php +37 -0
  131. vendor/dhii/collections-interface/test/unit/SearchableCollectionInterfaceTest.php +37 -0
  132. vendor/dhii/collections-interface/test/unit/SequenceIteratorIteratorInterfaceTest.php +38 -0
  133. vendor/dhii/collections-interface/test/unit/SetInterfaceTest.php +39 -0
  134. vendor/dhii/stats-abstract/.php_cs +27 -0
  135. vendor/dhii/stats-abstract/.travis.yml +15 -0
  136. vendor/dhii/stats-abstract/CHANGELOG.md +8 -0
  137. vendor/dhii/stats-abstract/composer.json +27 -0
  138. vendor/dhii/stats-abstract/composer.lock +1713 -0
  139. vendor/dhii/stats-abstract/nbproject/project.properties +24 -0
  140. vendor/dhii/stats-abstract/nbproject/project.xml +9 -0
  141. vendor/dhii/stats-abstract/phpunit.xml +35 -0
  142. vendor/dhii/stats-abstract/src/AbstractAggregatableCollection.php +156 -0
  143. vendor/dhii/stats-abstract/src/AbstractAggregator.php +150 -0
  144. vendor/dhii/stats-abstract/test/bootstrap.php +5 -0
  145. vendor/dhii/stats-abstract/test/functional/AbstractAggregatorTest.php +48 -0
  146. vendor/dhii/stats-interface/.php_cs +27 -0
  147. vendor/dhii/stats-interface/CHANGELOG.md +8 -0
  148. vendor/dhii/stats-interface/composer.json +24 -0
  149. vendor/dhii/stats-interface/composer.lock +653 -0
  150. vendor/dhii/stats-interface/nbproject/project.properties +7 -0
  151. vendor/dhii/stats-interface/nbproject/project.xml +9 -0
  152. vendor/dhii/stats-interface/src/AggregatorInterface.php +25 -0
  153. wp-rss-aggregator.php +42 -16
css/admin-styles.css CHANGED
@@ -733,3 +733,8 @@ body.post-type-wprss_blacklist .alignleft.actions.bulkactions {
733
  .ajax-error:active {
734
  color: #a00;
735
  }
 
 
 
 
 
733
  .ajax-error:active {
734
  color: #a00;
735
  }
736
+
737
+ /* Removes the "Add New" button for Feed Items */
738
+ .post-type-wprss_feed_item .page-title-action {
739
+ display: none
740
+ }
includes/Aventura/Wprss/Core/Block/Html/AbstractRegularTag.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Block\Html;
4
+
5
+ /**
6
+ * Base functionality for a regular tag.
7
+ * A regular tag is one that requires a closing tag, e.g. is not self-closing.
8
+ */
9
+ class AbstractRegularTag extends AbstractTag
10
+ {
11
+
12
+ /**
13
+ * Renders the tag HTML.
14
+ *
15
+ * @since 4.10
16
+ */
17
+ public function getOutput()
18
+ {
19
+ $attributes = $this->getAttributes();
20
+ $attributes = count($attributes)
21
+ ? ' '.static::getAttributesStringFromArray($attributes)
22
+ : '';
23
+ $content = $this->getContent();
24
+ $tagName = $this->getTagName();
25
+
26
+ return sprintf('<%1$s%2$s>%3$s</%1$s>', $tagName, $attributes, $content);
27
+ }
28
+ }
includes/Aventura/Wprss/Core/Block/Html/AbstractSelfClosingTag.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Block\Html;
4
+
5
+ /**
6
+ * Base functionality for a regular tag.
7
+ * A regular tag is one that requires a closing tag, e.g. is not self-closing.
8
+ */
9
+ class AbstractSelfClosingTag extends AbstractTag
10
+ {
11
+
12
+ /**
13
+ * Renders the tag HTML.
14
+ *
15
+ * @since 4.10
16
+ */
17
+ public function getOutput()
18
+ {
19
+ $attributes = $this->getAttributes();
20
+ $attributes = count($attributes)
21
+ ? ' '.static::getAttributesStringFromArray($attributes)
22
+ : '';
23
+ $tagName = $this->getTagName();
24
+
25
+ return sprintf('<%1$s%2$s>', $tagName, $attributes);
26
+ }
27
+
28
+ /**
29
+ * {@inheritdoc}
30
+ *
31
+ * A self-closing tag has no content, and therefore content is now allowed
32
+ * to be an attribute.
33
+ *
34
+ * @since 4.10
35
+ */
36
+ protected function _getNonAttributeKeys()
37
+ {
38
+ $keys = parent::_getNonAttributeKeys();
39
+ if (isset($keys[static::K_CONTENT])) {
40
+ unset($keys[static::K_CONTENT]);
41
+ }
42
+
43
+ return $keys;
44
+ }
45
+ }
includes/Aventura/Wprss/Core/Block/Html/Anchor.php CHANGED
@@ -6,24 +6,7 @@ namespace Aventura\Wprss\Core\Block\Html;
6
  *
7
  * @since 4.9
8
  */
9
- class Anchor extends AbstractTag
10
  {
11
  const TAG_NAME = 'a';
12
-
13
- /**
14
- * Renders the anchor HTML.
15
- *
16
- * @since 4.9
17
- */
18
- public function getOutput()
19
- {
20
- $attributes = $this->getAttributes();
21
- $attributes = count($attributes)
22
- ? ' '.static::getAttributesStringFromArray($attributes)
23
- : '';
24
- $content = $this->getContent();
25
- $tagName = $this->getTagName();
26
-
27
- return sprintf('<%1$s%2$s>%3$s</%1$s>', $tagName, $attributes, $content);
28
- }
29
  }
6
  *
7
  * @since 4.9
8
  */
9
+ class Anchor extends AbstractRegularTag
10
  {
11
  const TAG_NAME = 'a';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
12
  }
includes/Aventura/Wprss/Core/Block/Html/Span.php ADDED
@@ -0,0 +1,36 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * To change this license header, choose License Headers in Project Properties.
5
+ * To change this template file, choose Tools | Templates
6
+ * and open the template in the editor.
7
+ */
8
+
9
+ namespace Aventura\Wprss\Core\Block\Html;
10
+
11
+ /**
12
+ * Description of Span
13
+ *
14
+ * @author Xedin Unknown
15
+ */
16
+ class Span extends AbstractTag
17
+ {
18
+ const TAG_NAME = 'span';
19
+
20
+ /**
21
+ * Renders the anchor HTML.
22
+ *
23
+ * @since 4.9
24
+ */
25
+ public function getOutput()
26
+ {
27
+ $attributes = $this->getAttributes();
28
+ $attributes = count($attributes)
29
+ ? ' '.static::getAttributesStringFromArray($attributes)
30
+ : '';
31
+ $content = $this->getContent();
32
+ $tagName = $this->getTagName();
33
+
34
+ return sprintf('<%1$s%2$s>%3$s</%1$s>', $tagName, $attributes, $content);
35
+ }
36
+ }
includes/Aventura/Wprss/Core/Component/AdminAjaxNotices.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Component;
4
+
5
+ use Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * Component responsible for notices in the backend.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class AdminAjaxNotices extends Core\Plugin\ComponentAbstract
13
+ {
14
+
15
+ /**
16
+ * Retrieve the notice collection.
17
+ *
18
+ * @see wprss_admin_notice_get_collection()
19
+ *
20
+ * @since 4.10
21
+ *
22
+ * @return \WPRSS_Admin_Notices The notice collection object.
23
+ */
24
+ public function getNoticeCollection()
25
+ {
26
+ return wprss_admin_notice_get_collection();
27
+ }
28
+
29
+ /**
30
+ * Add a notice.
31
+ *
32
+ * @see wprss_admin_notice_add()
33
+ *
34
+ * @param array $notice Data of the notice
35
+ *
36
+ * @return bool|WP_Error True if notice added, false if collection unavailable, or WP_Error if something went wrong.
37
+ */
38
+ public function addNotice($notice)
39
+ {
40
+ return wprss_admin_notice_add($notice);
41
+ }
42
+ }
includes/Aventura/Wprss/Core/Component/AdminHelper.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Component;
4
+
5
+ use Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * Helper component for things related to the backend.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class AdminHelper extends Core\Plugin\ComponentAbstract
13
+ {
14
+ /**
15
+ * Determine if currently showing page is related to WPRSS.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @return bool True if currently showing a WPRSS-related page; false otherwise.
20
+ */
21
+ public function isWprssPage()
22
+ {
23
+ require_once(WPRSS_INC . 'functions.php');
24
+ require_once(WPRSS_INC . 'admin-ajax-notice.php');
25
+
26
+ return wprss_is_wprss_page();
27
+ }
28
+
29
+ /**
30
+ * Creates a new instance of a Command.
31
+ *
32
+ * A command is a callable object that can contain all data necessary to invoke a callback.
33
+ *
34
+ * @since 4.10
35
+ *
36
+ * @param array|callable $data A callable, or an array with the follwing indices:
37
+ * - `function` - The callable to assign to the command;
38
+ * - `args` - An array of arguments to invoke the command with.
39
+ *
40
+ * @return Core\Model\Command
41
+ */
42
+ public function createCommand($data)
43
+ {
44
+ $cmd = new Core\Model\Command($data);
45
+
46
+ return $cmd;
47
+ }
48
+
49
+ /**
50
+ * Resolves a value to something concrete.
51
+ *
52
+ * If the value is a callable, calls it. Otherwise, returns value.
53
+ *
54
+ * @since 4.10
55
+ *
56
+ * @param mixed $value Anything.
57
+ *
58
+ * @return mixed A non-callable value.
59
+ */
60
+ public function resolveValue($value)
61
+ {
62
+ if (is_callable($value)) {
63
+ $value = call_user_func_array($value, array());
64
+ }
65
+
66
+ return $value;
67
+ }
68
+ }
includes/Aventura/Wprss/Core/Component/LeaveReviewNotification.php ADDED
@@ -0,0 +1,548 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Component;
4
+
5
+ use Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * The component responsible for the "Leave a Review" notification.
9
+ *
10
+ * On plugin activation, records that time, if not already recorded.
11
+ * When retrieved, looks for that time. If not recorded, deduces it from the
12
+ * creation time of the first feed source. If no feed sources, assumes current
13
+ * time at the moment of retrieval. This result is recorded as the first
14
+ * activation time, and is used in subsequent requests.
15
+ *
16
+ * @since 4.10
17
+ */
18
+ class LeaveReviewNotification extends Core\Plugin\ComponentAbstract
19
+ {
20
+ const FIRST_ACTIVATION_TIME_OPTION_SUFFIX = '_first_activation_time';
21
+ const NOTICE_ID_SUFFIX = '_leave_review';
22
+ const REVIEW_PAGE_URL = 'https://wordpress.org/support/plugin/wp-rss-aggregator/reviews/#new-topic-0';
23
+ const NOTICE_DELAY_PERIOD = WPRSS_LEAVE_REVIEW_NOTIFICATION_DELAY;
24
+ const MIN_ACTIVE_FEED_SOURCE_COUNT = WPRSS_LEAVE_REVIEW_NOTIFICATION_MIN_ACTIVE_FEED_SOURCES;
25
+
26
+ protected $firstActivationTime;
27
+ protected $firstActivationTimeOptionName;
28
+ protected $noticeId;
29
+
30
+ /**
31
+ * Runs when this component is initialized.
32
+ *
33
+ * @since 4.10
34
+ */
35
+ public function hook()
36
+ {
37
+ $this->init();
38
+
39
+ $hookName = sprintf('!activate_%1$s', $this->getPlugin()->getBasename());
40
+ $this->on($hookName, 'onPluginActivated');
41
+ }
42
+
43
+ /**
44
+ * Runs when the parent plugin is activated.
45
+ *
46
+ * @since 4.10
47
+ */
48
+ public function onPluginActivated()
49
+ {
50
+ $this->_recordEarliestTimeIfNotPresent();
51
+ }
52
+
53
+ /**
54
+ * Runs when all plugins have finished loading.
55
+ *
56
+ * @since 4.10
57
+ */
58
+ public function init()
59
+ {
60
+ $this->addLeaveReviewNotice();
61
+ }
62
+
63
+ /**
64
+ * Adds the notification.
65
+ *
66
+ * @since 4.10
67
+ *
68
+ * @return LeaveReviewNotification This instance.
69
+ */
70
+ public function addLeaveReviewNotice()
71
+ {
72
+ $notices = $this->_getNoticesComponent();
73
+
74
+ $noticeParams = array(
75
+ 'id' => $this->getNoticeId(),
76
+ 'content' => $this->getNoticeContent(),
77
+ 'condition' => $this->getNoticeCondition()
78
+ );
79
+ $this->event('leave_review_notice_before_add', array('notice_params' => &$noticeParams));
80
+
81
+ $notices->addNotice($noticeParams);
82
+ }
83
+
84
+ /**
85
+ * Retrieve the ID of the "Leave a Review" admin notice.
86
+ *
87
+ * @since 4.10
88
+ *
89
+ * @return string The ID of the notice.
90
+ */
91
+ public function getNoticeId()
92
+ {
93
+ $idSuffix = static::NOTICE_ID_SUFFIX;
94
+ if (is_null($this->noticeId)) {
95
+ $this->noticeId = $this->getPlugin()->getCode() . $idSuffix;
96
+ }
97
+
98
+ $noticeId = $this->noticeId;
99
+ $this->event('leave_review_notice_id', array(
100
+ 'notice_id' => &$noticeId,
101
+ 'id_suffix' => $idSuffix
102
+ ));
103
+
104
+ return $noticeId;
105
+ }
106
+
107
+ /**
108
+ * Retrieve the content for the "Leave a Review" notice.
109
+ *
110
+ * @since 4.10
111
+ *
112
+ * @return string The content for the notice.
113
+ */
114
+ public function getNoticeContent()
115
+ {
116
+ $message = <<<'MSG'
117
+ It looks like you've been using WP RSS Aggregator for a while. Would you please consider <a href="%2$s" target="_blank">leaving a review</a>? Thank you!
118
+ MSG;
119
+ $content = wpautop(sprintf(
120
+ $message,
121
+ $this->getPlugin()->getName(),
122
+ $this->getReviewPageUrl()
123
+ ));
124
+
125
+ $this->event('leave_review_notification_content', array(
126
+ 'content' => &$content
127
+ ));
128
+
129
+ return $content;
130
+ }
131
+
132
+ /**
133
+ * Retrieve the condition for the notice to show.
134
+ *
135
+ * @since 4.10
136
+ *
137
+ * @return callable The callable that determines whether or not to display the notice.
138
+ */
139
+ public function getNoticeCondition()
140
+ {
141
+ $condition = $this->_createCommand(array(
142
+ 'function' => array($this, 'isShowLeaveReviewNotification')
143
+ ));
144
+
145
+ $this->event('leave_review_notice_condition', array('condition' => &$condition));
146
+
147
+ return $condition;
148
+ }
149
+
150
+ /**
151
+ * Determines if the notice is allowed to be displayed on the current page.
152
+ *
153
+ * @since 4.10
154
+ *
155
+ * @return bool True if the notice is allowed to be displayed on the current page; false otherwise.
156
+ */
157
+ public function isShowLeaveReviewNotification()
158
+ {
159
+ $isWprssPage = $this->isWprssPage();
160
+ $isDelayExpired = $this->isNoticeDelayPeriodExpired();
161
+ $isMinCountReached = $this->isMinFeedSourceCountReached();
162
+ $isShow = $isWprssPage
163
+ && $isDelayExpired
164
+ && $isMinCountReached;
165
+
166
+ $this->event('leave_review_notification_is_show', array(
167
+ 'is_show' => &$isShow,
168
+ 'is_wprss_page' => $isWprssPage,
169
+ 'is_delay_expired' => $isDelayExpired,
170
+ 'is_min_count_reached' => $isMinCountReached
171
+ ));
172
+
173
+ return $isShow;
174
+ }
175
+
176
+ /**
177
+ * Determines whether a certain amount of time has passed since first activation of the plugin.
178
+ *
179
+ * @since 4.10
180
+ *
181
+ * @see WPRSS_LEAVE_REVIEW_NOTIFICATION_DELAY
182
+ *
183
+ * @return bool True if the pre-configured amount of time since first activation has passed; false otherwise.
184
+ */
185
+ public function isNoticeDelayPeriodExpired()
186
+ {
187
+ $now = $this->_getCurrentTimestampGmt();
188
+ $delay = $this->getNoticeDelayPeriod();
189
+ $firstActivation = $this->getFirstActivationTime();
190
+ $isExpired = $now - $firstActivation >= $delay;
191
+
192
+ $this->event('leave_review_notification_delay_period_is_expired', array(
193
+ 'is_expired' => &$isExpired,
194
+ 'now' => $now,
195
+ 'delay' => $delay,
196
+ 'first_activation' => $firstActivation
197
+ ));
198
+
199
+ return $isExpired;
200
+ }
201
+
202
+ /**
203
+ * Determines if the minimal amount of sources required to display the notification exists.
204
+ *
205
+ * @since 4.10
206
+ *
207
+ * @return bool True if the minimal amount of feed sources exists; false otherwise.
208
+ */
209
+ public function isMinFeedSourceCountReached()
210
+ {
211
+ $minCount = $this->getMinFeedSourceCount();
212
+ $activeSourceIds = $this->_getActiveFeedSourceIds($minCount);
213
+ $isReached = count($activeSourceIds) >= $minCount;
214
+
215
+ $this->event('leave_review_notification_min_feed_source_count_reached', array(
216
+ 'is_reached' => &$isReached,
217
+ 'min_count' => $minCount,
218
+ 'active_source_ids' => $activeSourceIds
219
+ ));
220
+
221
+ return $isReached;
222
+ }
223
+
224
+ /**
225
+ * Retrieve the minimal amount of active feed source required for the notification to be displayed.
226
+ *
227
+ * @since 4.10
228
+ *
229
+ * @return int The amount of feed sources required.
230
+ */
231
+ public function getMinFeedSourceCount()
232
+ {
233
+ $minCount = intval(static::MIN_ACTIVE_FEED_SOURCE_COUNT);
234
+ $this->event('leave_review_notice_min_active_feed_source_count', array('min_count' => &$minCount));
235
+
236
+ return $minCount;
237
+ }
238
+
239
+ /**
240
+ * Retrieve IDs of feed sources that are active.
241
+ *
242
+ * @since 4.10
243
+ *
244
+ * @param array|int $args If array, will be merged with default query params.
245
+ * Otherwise, treated as the maximal number of IDs to return.
246
+ *
247
+ * @return array A numeric array containing IDs of feed sources that are active
248
+ */
249
+ protected function _getActiveFeedSourceIds($args = null)
250
+ {
251
+ if (!is_array($args)) {
252
+ $args = is_null($args)
253
+ ? -1
254
+ : intval($args);
255
+ $args = array('posts_per_page' => $args);
256
+ }
257
+
258
+ $defaults = array(
259
+ 'per_page' => -1,
260
+ 'fields' => 'ids',
261
+ 'meta_query' => array(
262
+ array(
263
+ 'key' => 'wprss_state',
264
+ 'value' => 'active'
265
+ )
266
+ )
267
+ );
268
+ $args = array_merge_recursive_distinct($defaults, $args);
269
+
270
+ $ids = $this->_getFeedSources($args);
271
+
272
+ return $ids;
273
+ }
274
+
275
+ /**
276
+ * Get the delay before notice gets displayed.
277
+ *
278
+ * @since 4.10
279
+ *
280
+ * @return int The amount of seconds, by which to delay displaying the notice.
281
+ */
282
+ public function getNoticeDelayPeriod()
283
+ {
284
+ return intval(static::NOTICE_DELAY_PERIOD);
285
+ }
286
+
287
+ /**
288
+ * Determines if the curren page is related to WPRSS.
289
+ *
290
+ * @since 4.10
291
+ *
292
+ * @return bool True if the current page is related to WPRSS; false otherwise.
293
+ */
294
+ public function isWprssPage()
295
+ {
296
+ return $this->getAdminHelper()->isWprssPage();
297
+ }
298
+
299
+ /**
300
+ * Retrieves the URL of the page where to send visitors to leave a review.
301
+ *
302
+ * @since 4.10
303
+ *
304
+ * @return string The page URL.
305
+ */
306
+ public function getReviewPageUrl()
307
+ {
308
+ $url = static::REVIEW_PAGE_URL;
309
+ $this->event('leave_review_page_url', array('url' => &$url));
310
+
311
+ return $url;
312
+ }
313
+
314
+ /**
315
+ * Retrieve the time of the first activation of the plugin.
316
+ *
317
+ * @since 4.10
318
+ *
319
+ * @return int|string The first activation time in GMT as Unix timestamp.
320
+ * If `$format` is not `null`, formats the timestamp using the specified format string.
321
+ */
322
+ public function getFirstActivationTime($format = null)
323
+ {
324
+ $this->_recordEarliestTimeIfNotPresent();
325
+ $time = $this->_getFirstActivationTimeDb();
326
+
327
+ $formatted = is_null($format)
328
+ ? $time
329
+ : date($format, $time);
330
+
331
+ $this->event('leave_review_first_activation_time', array(
332
+ 'time' => $time,
333
+ 'format' => $format,
334
+ 'time_formatted' => &$formatted
335
+ ));
336
+
337
+ return $formatted;
338
+ }
339
+
340
+ /**
341
+ * Deduces what the first activation time is, if it is not recorded.
342
+ *
343
+ * @since 4.10
344
+ *
345
+ * @return int The first activation time, calculated, in the GMT zone.
346
+ */
347
+ protected function _calculateFirstActivationTime()
348
+ {
349
+ $feedSources = $this->_getFeedSources(1);
350
+ if (!count($feedSources)) {
351
+ return $this->_getCurrentTimestampGmt();
352
+ }
353
+
354
+ $firstFeedSource = $feedSources[0];
355
+ /* @var $firstFeedSource \WP_Post */
356
+ $firstFeedSourceCreated = $firstFeedSource->post_date_gmt;
357
+ $firstFeedSourceCreated = $this->_dateToTimestamp($firstFeedSourceCreated);
358
+
359
+ return $firstFeedSourceCreated;
360
+ }
361
+
362
+ /**
363
+ * Converts a date string into a Unix timestamp.
364
+ *
365
+ * @since 4.10
366
+ *
367
+ * @see \DateTime::createFromFormat()
368
+ *
369
+ * @param string $date The string representation of the date.
370
+ * @param string $format The format in which the date is specified.
371
+ * @param string $timezone The string representation of the timezone, in which the date is specified.
372
+ *
373
+ * @return type
374
+ */
375
+ protected function _dateToTimestamp($date, $format = 'Y-m-d H:i:s', $timezone = 'UTC')
376
+ {
377
+ $date = \DateTime::createFromFormat(
378
+ $format,
379
+ $date,
380
+ new \DateTimeZone($timezone)
381
+ );
382
+ $timestamp = $date->getTimestamp();
383
+
384
+ return $timestamp;
385
+ }
386
+
387
+ /**
388
+ * Retrieve feed sources for specific conditions.
389
+ *
390
+ * @since 4.10
391
+ *
392
+ * @param array|int|null $args The maximal amount of feed sources to retrieve.
393
+ * If array, will be treated as query args, and merged with defaults.
394
+ * @return WP_Post[]|\Traversable A list of feed sources that obey the specified conditions.
395
+ */
396
+ protected function _getFeedSources($args = null)
397
+ {
398
+ if (!is_array($args)) {
399
+ $args = is_null($args)
400
+ ? -1
401
+ : intval($args);
402
+ $args = array('posts_per_page' => $args);
403
+ }
404
+
405
+ $defaults = array(
406
+ 'post_type' => $this->_getFeedSourcePostType(),
407
+ 'posts_per_page' => -1,
408
+ 'orderby' => 'date',
409
+ 'order' => 'ASC',
410
+ );
411
+ $args = array_merge_recursive_distinct($defaults, $args);
412
+
413
+ $query = new \WP_Query($args);
414
+
415
+ return $query->posts;
416
+ }
417
+
418
+ /**
419
+ * Retrieves the first activation time value from the database.
420
+ *
421
+ * @since 4.10
422
+ *
423
+ * @return int|null
424
+ */
425
+ protected function _getFirstActivationTimeDb()
426
+ {
427
+ $optionName = $this->_getFirstActivationTimeOptionName();
428
+ $value = get_option($optionName, null);
429
+
430
+ if (!is_null($value )){
431
+ $value = intval($value);
432
+ }
433
+
434
+ return $value;
435
+ }
436
+
437
+ /**
438
+ * Sets the value of the option, which stores the first activation time in the database.
439
+ *
440
+ * @since 4.10
441
+ *
442
+ * @param int $time The GMT time as a Unix timestamp.
443
+ * @return bool True if time set successfully, false otherwise.
444
+ */
445
+ protected function _setFirstActivationTimeDb($time)
446
+ {
447
+ $optionName = $this->_getFirstActivationTimeOptionName();
448
+
449
+ return update_option($optionName, $time);
450
+ }
451
+
452
+ /**
453
+ * Retrieves the name of the option, which stores the first activation time.
454
+ *
455
+ * @since 4.10
456
+ *
457
+ * @return string Name of the option.
458
+ */
459
+ protected function _getFirstActivationTimeOptionName()
460
+ {
461
+ if (is_null($this->firstActivationTimeOptionName)) {
462
+ $this->firstActivationTimeOptionName =
463
+ $this->getPlugin()->getCode() . static::FIRST_ACTIVATION_TIME_OPTION_SUFFIX;
464
+ }
465
+
466
+ return $this->firstActivationTimeOptionName;
467
+ }
468
+
469
+ /**
470
+ * Records the current time as first activation time, if not already recorded.
471
+ *
472
+ * @since 4.10
473
+ *
474
+ * @return LeaveReviewNotification This instance.
475
+ */
476
+ protected function _recordEarliestTimeIfNotPresent()
477
+ {
478
+ $time = $this->_getFirstActivationTimeDb();
479
+
480
+ if (empty($time)) {
481
+ $time = $this->_calculateFirstActivationTime();
482
+ $this->_setFirstActivationTimeDb($time);
483
+ }
484
+
485
+ return $this;
486
+ }
487
+
488
+ /**
489
+ * Retrieves the current timestamp in the GMT zone.
490
+ *
491
+ * @since 4.10
492
+ *
493
+ * @return int The number of seconds from the start of the Unix epoch, GMT.
494
+ */
495
+ protected function _getCurrentTimestampGmt()
496
+ {
497
+ return intval(current_time('timestamp', true));
498
+ }
499
+
500
+ /**
501
+ * Retrieves the name of the feed source post type.
502
+ *
503
+ * @since 4.10
504
+ *
505
+ * @return string The post type name of the feed source post type.
506
+ */
507
+ protected function _getFeedSourcePostType()
508
+ {
509
+ return $this->getPlugin()->getFeedSourcePostType();
510
+ }
511
+
512
+ /**
513
+ * Retrieve the component responsible for admin AJAX notices.
514
+ *
515
+ * @since 4.10
516
+ *
517
+ * @return AdminAjaxNotices The component instance.
518
+ */
519
+ protected function _getNoticesComponent()
520
+ {
521
+ return $this->getPlugin()->getAdminAjaxNotices();
522
+ }
523
+
524
+ /**
525
+ * Retrieve the admin helper singleton.
526
+ *
527
+ * @since 4.10
528
+ *
529
+ * @return AdminHelper The helper singleton instance.
530
+ */
531
+ public function getAdminHelper()
532
+ {
533
+ return $this->getPlugin()->getAdminHelper();
534
+ }
535
+
536
+ /**
537
+ * Creates a callable command instance.
538
+ *
539
+ * @since 4.10
540
+ *
541
+ * @param array|callable $data See {@see Core\Model\Command}.
542
+ * @return Core\Model\Command|callable See {@see Core\Model\Command}.
543
+ */
544
+ protected function _createCommand($data)
545
+ {
546
+ return $this->getAdminHelper()->createCommand($data);
547
+ }
548
+ }
includes/Aventura/Wprss/Core/ComponentFactory.php CHANGED
@@ -7,7 +7,7 @@ namespace Aventura\Wprss\Core;
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
  */
@@ -46,4 +46,47 @@ class ComponentFactory extends Plugin\ComponentFactoryAbstract
46
  $events = $this->createComponent('EventManager', $this->getPlugin(), $data);
47
  return $events;
48
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  }
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
  */
46
  $events = $this->createComponent('EventManager', $this->getPlugin(), $data);
47
  return $events;
48
  }
49
+
50
+ /**
51
+ * Creates a component that is responsible for the "Leave a Review" notification.
52
+ *
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
+ }
64
+
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
+ }
78
+
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
+ }
92
  }
includes/Aventura/Wprss/Core/Model/Collection/AbstractCollection.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Collection;
4
+
5
+ use Dhii\Collection\AbstractSearchableCollection;
6
+
7
+ /**
8
+ * Common functionality for all collections.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ abstract class AbstractCollection extends AbstractSearchableCollection
13
+ {
14
+ /**
15
+ * @inheritdoc
16
+ *
17
+ * @since 4.10
18
+ */
19
+ protected function _construct()
20
+ {
21
+ $this->_clearItems();
22
+ $this->_clearItemCache();
23
+ }
24
+
25
+ /**
26
+ * Returns the item set of this instance to its initial state.
27
+ *
28
+ * @since 4.10
29
+ */
30
+ protected function _clearItems()
31
+ {
32
+ $this->items = array();
33
+ }
34
+ }
includes/Aventura/Wprss/Core/Model/Event/EventManagerAbstract.php CHANGED
@@ -160,9 +160,13 @@ class EventManagerAbstract extends Core\Plugin\ComponentAbstract implements Even
160
  protected function _createEvent($name, $args = array())
161
  {
162
  $event = new Event($name);
163
- foreach($args as $_key => $_val) {
164
- $event->setData($_key, $_val);
 
165
  }
 
 
 
166
  return $event;
167
  }
168
  }
160
  protected function _createEvent($name, $args = array())
161
  {
162
  $event = new Event($name);
163
+
164
+ if (!is_array($args)) {
165
+ throw $this->exception('Args must be an array');
166
  }
167
+
168
+ $event->setData($args);
169
+
170
  return $event;
171
  }
172
  }
includes/Aventura/Wprss/Core/Model/ModelAbstract.php CHANGED
@@ -175,7 +175,7 @@ abstract class ModelAbstract extends Core\DataObject implements ModelInterface
175
  $text = $this->__($text, $translate);
176
  $className = $this->getExceptionClassName($className);
177
  if (!class_exists($className)) {
178
- throw new Exception(sprintf('Could not create exception: Class "%1$s" does not exist'));
179
  }
180
 
181
  $exception = new $className($text);
@@ -271,7 +271,7 @@ abstract class ModelAbstract extends Core\DataObject implements ModelInterface
271
  protected function _getDataOrConst($key, $default = null)
272
  {
273
  if ($this->hasData($key)) {
274
- return $this->getData();
275
  }
276
 
277
  $const = $this->constant($key);
175
  $text = $this->__($text, $translate);
176
  $className = $this->getExceptionClassName($className);
177
  if (!class_exists($className)) {
178
+ throw new Core\Exception(sprintf('Could not create exception: Class "%1$s" does not exist', $className));
179
  }
180
 
181
  $exception = new $className($text);
271
  protected function _getDataOrConst($key, $default = null)
272
  {
273
  if ($this->hasData($key)) {
274
+ return $this->getData($key);
275
  }
276
 
277
  $const = $this->constant($key);
includes/Aventura/Wprss/Core/Model/Regex/AbstractRegex.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Regex;
4
+
5
+ use Aventura\Wprss\Core;
6
+
7
+ /**
8
+ * Common regex functionality
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class AbstractRegex extends Core\Model\ModelAbstract
13
+ {
14
+ const DELIMITER = '!';
15
+ const K_DELIMITER = 'delimiter';
16
+ const REPLACE_LIMIT = -1;
17
+ const K_REPLACE_LIMIT = 'replace_limit';
18
+
19
+ /**
20
+ * Escapes all special regex characters in all supplied strings.
21
+ *
22
+ * @since 4.10
23
+ *
24
+ * @param array|string $string A string or array of strings to escape.
25
+ * @param string|null $delimiter The delimiter, which, if specified, will also be quoted.
26
+ * Default: '!'.
27
+ *
28
+ * @return array All strings escaped for use in regex.
29
+ */
30
+ public function quoteAll($string, $delimiter = null)
31
+ {
32
+ // Default delimiter
33
+ if (is_null($delimiter)) {
34
+ $delimiter = $this->getDelimiter();
35
+ }
36
+
37
+ $string = (array)$string;
38
+ return array_map(function ($string) use ($delimiter) {
39
+ if (is_array($string)) {
40
+ return $this->quoteAll($string, $delimiter);
41
+ }
42
+ return preg_quote($string, $delimiter);
43
+ }, $string);
44
+ }
45
+
46
+ /**
47
+ * Gets the RegEx delimiter used by this instance.
48
+ *
49
+ * @since 4.10
50
+ *
51
+ * @return string
52
+ */
53
+ public function getDelimiter()
54
+ {
55
+ return $this->_getDataOrConst(self::K_DELIMITER);
56
+ }
57
+
58
+ /**
59
+ * Get the limit used by this instance's RegEx replacement functions.
60
+ *
61
+ * @since 4.10
62
+ *
63
+ * @return int
64
+ */
65
+ public function getReplaceLimit()
66
+ {
67
+ return intval($this->_getDataOrConst(static::K_REPLACE_LIMIT));
68
+ }
69
+
70
+ /**
71
+ * Uses a regex to replace parts of the input string.
72
+ *
73
+ * @since 4.10
74
+ *
75
+ * @param string|array $pattern See {@see preg_replace_callback()}
76
+ * @param callable $callback See {@see preg_replace_callback()}
77
+ * @param string|array $subject See {@see preg_replace_callback()}
78
+ * @param int $limit See {@see preg_replace_callback()}
79
+ * @param int $count See {@see preg_replace_callback()}
80
+ *
81
+ * @return array|string|null See {@see preg_replace_callback()}
82
+ */
83
+ public function replaceCallback($pattern, $callback, $subject, $limit = null, &$count = null)
84
+ {
85
+ if (is_null($limit)) {
86
+ $limit = $this->getReplaceLimit();
87
+ }
88
+
89
+ return preg_replace_callback($pattern, $callback, $subject, $limit, $count);
90
+ }
91
+
92
+ /**
93
+ * Attempts a RegEx match.
94
+ *
95
+ * @since 4.10
96
+ *
97
+ * @see preg_match()
98
+ *
99
+ * @param string $pattern
100
+ * @param string $subject
101
+ * @param array $matches
102
+ * @param int $flags
103
+ * @param int $offset
104
+ *
105
+ * @return int|bool Returns 1 if the pattern is found, 0 if not found, or false if an error occurred.
106
+ */
107
+ public function match($pattern, $subject, &$matches = null, $flags = 0, $offset = 0)
108
+ {
109
+ return preg_match($pattern, $subject, $matches, $flags, $offset);
110
+ }
111
+ }
includes/Aventura/Wprss/Core/Model/Regex/HtmlEncoder.php ADDED
@@ -0,0 +1,621 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Regex;
4
+
5
+ use Aventura\Wprss\Core\Model\Collection;
6
+ use Aventura\Wprss\Core\Model\Set;
7
+
8
+ /**
9
+ * Aids in adaprting regular expressions for use with HTML
10
+ * by HTML-encodifying them.
11
+ * HTML-encodifying transforms a regex in a way that HTML special chars in the expression get replaced
12
+ * with all possibilities, each of which has the same meaning as the special char.
13
+ * For example, encodifying "<div>" would produce "(?:\<|&lt;)div(?:\<|&lt;)", which would match both
14
+ * the text "<div>" and the text "&lt;div&lt;", where the latter is the HTML-encoded version
15
+ * of the original text.
16
+ * While quotes are transformed in the same way, but by default they are considered do be "symmetrical",
17
+ * i.e. an "opening" quote must be matched with an identical "closing" quote.
18
+ *
19
+ * @since 4.10
20
+ */
21
+ class HtmlEncoder extends AbstractRegex
22
+ {
23
+ const K_SYM_PREFIX = 'sym_prefix';
24
+ const SYM_PREFIX = '_sym';
25
+ const CHARC_TOKEN_PREFIX = '_charc';
26
+
27
+ protected $synonymSets;
28
+ // protected $htmlCharMap = null;
29
+ protected $symChars = array();
30
+
31
+ protected $occurrences = array();
32
+ protected $replacementCount = 0;
33
+
34
+ /**
35
+ * @since 4.10
36
+ */
37
+ protected function _construct()
38
+ {
39
+ parent::_construct();
40
+ $this->reset();
41
+
42
+ $this->addHtmlChars(array('<', '>', '\''));
43
+ $this->addHtmlCharSynonyms('"', array("'", '&#039;', '&apos;'));
44
+ $this->addSymmetricalChars('"');
45
+ }
46
+
47
+ /**
48
+ * Resets usage stats.
49
+ *
50
+ * @since 4.10
51
+ *
52
+ * @see getOccurrenceCount()
53
+ * @see getReplacementCount()
54
+ *
55
+ * @return HtmlEncoder
56
+ */
57
+ public function reset()
58
+ {
59
+ $this->occurrences = array();
60
+ $this->replacementCount = 0;
61
+
62
+ return $this;
63
+ }
64
+
65
+ /**
66
+ * @since 4.10
67
+ *
68
+ * @param string $expr The regex to encodify.
69
+ *
70
+ * @return string The regular expression that has been HTML-encodified.
71
+ */
72
+ public function encodify($expr)
73
+ {
74
+ $delimiter = $this->getDelimiter();
75
+ $symPrefix = $this->getSymPrefix();
76
+ $chars = $this->getSynonymSets();
77
+ $symmetrical = $this->getSymmetricalChars();
78
+ return $this->htmlEncodifyRegex($expr, $chars, $delimiter, $symmetrical, $symPrefix);
79
+ }
80
+
81
+ /**
82
+ * Retrieve the prefix that is used to introduced named groups.
83
+ *
84
+ * Currently, named groups are used for matching symmetric quotes.
85
+ *
86
+ * @since 4.10
87
+ *
88
+ * @return string The group name prefix.
89
+ */
90
+ public function getSymPrefix()
91
+ {
92
+ return $this->_getDataOrConst(self::K_SYM_PREFIX);
93
+ }
94
+
95
+ /**
96
+ * Retrieve all symmetrical chars.
97
+ *
98
+ * @since 4.10
99
+ *
100
+ * @return array Array of strings, each one being a char that must be matched in pairs by the transformed regex.
101
+ */
102
+ public function getSymmetricalChars()
103
+ {
104
+ return $this->symChars;
105
+ }
106
+
107
+ /**
108
+ * Adds chars that must be symmetrical, e.g. must me matched in pairs by the transformed regex
109
+ *
110
+ * @since 4.10
111
+ *
112
+ * @param string|array $chars A char, string of chars, or array of chars, each of which to add.
113
+ *
114
+ * @return HtmlEncoder This instance.
115
+ */
116
+ public function addSymmetricalChars($chars)
117
+ {
118
+ $chars = $this->normalizeCharArray($chars);
119
+
120
+ $chars = array_merge($this->symChars, $chars);
121
+ $chars = array_keys(array_flip($chars));
122
+ $this->_setSymmetricalChars($chars);
123
+
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ * @since 4.10
129
+ *
130
+ * @param type $chars
131
+ *
132
+ * @return HtmlEncoder
133
+ */
134
+ protected function _setSymmetricalChars($chars)
135
+ {
136
+ $this->symChars = (array) $chars;
137
+ return $this;
138
+ }
139
+
140
+ /**
141
+ * Retrieves the set of synonym sets used by this instance.
142
+ *
143
+ * Each inner set contains characters or sequences, all of which are synonymous with each other.
144
+ *
145
+ * @since 4.10
146
+ *
147
+ * @return Set\Synonym\Set The set of synonym sets.
148
+ */
149
+ public function getSynonymSets()
150
+ {
151
+ if (is_null($this->synonymSets)) {
152
+ $this->_setSynonymSets(new Set\Synonym\Set());
153
+ }
154
+
155
+ return $this->synonymSets;
156
+ }
157
+
158
+ /**
159
+ * Assigns the set of synonym sets.
160
+ *
161
+ * @since 4.10
162
+ *
163
+ * @param Set\Synonym\Set $set The synonym set.
164
+ *
165
+ * @return HtmlEncoder This instance.
166
+ */
167
+ protected function _setSynonymSets(Set\Synonym\Set $set)
168
+ {
169
+ $this->synonymSets = $set;
170
+
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * Checks whether or not a char is registered as being an HTML char.
176
+ *
177
+ * @since 4.10
178
+ *
179
+ * @param string $char The char to check for.
180
+ *
181
+ * @return boolean True if this HTML char is registered; false otherwise.
182
+ */
183
+ public function hasHtmlChar($char)
184
+ {
185
+ $char = $this->normalizeChar($char);
186
+ return $this->_hasHtmlChar($char);
187
+ }
188
+
189
+ /**
190
+ * Determines if this instance's char map contains the specified character.
191
+ *
192
+ * @since 4.10
193
+ *
194
+ * @param string $char The character to check.
195
+ *
196
+ * @return bool True if the char map has the specified character; false otherwise.
197
+ */
198
+ protected function _hasHtmlChar($char)
199
+ {
200
+ return isset($this->htmlCharMap[$char]);
201
+ }
202
+
203
+ /**
204
+ * Get the set of HTML char synonyms for a specific character.
205
+ *
206
+ * @see [*next-char*]
207
+ *
208
+ * @param string $char The char, for which to get the synonym set.
209
+ *
210
+ * @return Set\Synonym\Set The synonym set. This set might only contain the original char.
211
+ */
212
+ public function getHtmlCharSynonymSet($char)
213
+ {
214
+ $char = $this->normalizeChar($char);
215
+ return $this->getSynonymSets()->getSetForTerm($char);
216
+ }
217
+
218
+ /**
219
+ * Retrieve synonyms for the specified character.
220
+ *
221
+ * @since 4.10
222
+ *
223
+ * @param string $char The character, for which to get synonyms.
224
+ * @param array $other Additional characters to include in the result.
225
+ *
226
+ * @return An array of unique characters or sequences, all of which are synonymous with each other.
227
+ * Contains the original character.
228
+ */
229
+ public function getHtmlCharSynonyms($char, $other = null)
230
+ {
231
+ if (is_null($other)) {
232
+ $other = array();
233
+ }
234
+
235
+ $set = $this->getHtmlCharSynonymSet($char);
236
+ $synonyms = $set->items();
237
+
238
+ return array_keys(array_flip(array_merge($synonyms, $other)));
239
+ }
240
+
241
+ /**
242
+ * Adds synonyms to a specified character.
243
+ *
244
+ * If the character does not exist, it will be added.
245
+ *
246
+ * @since 4.10
247
+ *
248
+ * @param string $char The character, for which to add synonyms.
249
+ *
250
+ * @param array $synonyms The synonyms to add.
251
+ * @return HtmlEncoder This instance.
252
+ */
253
+ public function addHtmlCharSynonyms($char, $synonyms)
254
+ {
255
+ $set = $this->getHtmlCharSynonymSet($char);
256
+ $set->addMany($synonyms);
257
+
258
+ return $this;
259
+ }
260
+
261
+ /**
262
+ * Removes a character from the set of chars to encodify.
263
+ *
264
+ * @since 4.10
265
+ *
266
+ * @todo This method may be redundant or broken. Verify.
267
+ *
268
+ * @param string $char The character to remove.
269
+ * @return HtmlEncoder This instance.
270
+ */
271
+ public function removeHtmlChar($char)
272
+ {
273
+ $synonyms = array_flip($this->getHtmlCharSynonyms($char));
274
+ if (array_key_exists($char, $synonyms)) {
275
+ unset($synonyms[$char]);
276
+ }
277
+ $synonyms = array_keys($synonyms);
278
+ $this->_mapHtmlChar($char, $synonyms);
279
+
280
+ return $this;
281
+ }
282
+
283
+ /**
284
+ * Adds a character to be encodified.
285
+ *
286
+ * @since 4.10
287
+ *
288
+ * @todo This method may be incomplete. Confirm and fix.
289
+ *
290
+ * @param string $char The character.
291
+ *
292
+ * @return HtmlEncoder This instance.
293
+ */
294
+ public function addHtmlChar($char, $synonyms = null)
295
+ {
296
+ $this->getHtmlCharSynonymSet($char);
297
+
298
+ return $this;
299
+ }
300
+
301
+ /**
302
+ * Adds multiple HTML characters to be encodified.
303
+ *
304
+ * @since 4.10
305
+ *
306
+ * @param string[] $chars The characters to be added.
307
+ *
308
+ * @return HtmlEncoder
309
+ */
310
+ public function addHtmlChars($chars)
311
+ {
312
+ foreach ($chars as $_char) {
313
+ $this->getHtmlCharSynonymSet($_char);
314
+ }
315
+
316
+ return $this;
317
+ }
318
+
319
+ /**
320
+ * Normalizes input to a single character.
321
+ *
322
+ * If array, uses the first element.
323
+ * If string, uses the first character.
324
+ *
325
+ * @since 4.10
326
+ *
327
+ * @param type $char
328
+ *
329
+ * @return string A string of exactly 1 character in length.
330
+ * @throws \Aventura\Wprss\Core\Exception If input could not be normalized.
331
+ */
332
+ public function normalizeChar($char)
333
+ {
334
+ if (is_array($char)) {
335
+ if (isset($char[0])) {
336
+ return $char[0];
337
+ }
338
+ throw $this->exception('Could not normalize char: input is array, but index 0 is empty');
339
+ }
340
+ return substr($char, 0, 1);
341
+ }
342
+
343
+ /**
344
+ * Normalizes input to an array of characters.
345
+ *
346
+ * @since 4.10
347
+ *
348
+ * @param string|array $chars The character set to normalize.
349
+ *
350
+ * @return string[] An array of 1-char long strings.
351
+ */
352
+ public function normalizeCharArray($chars)
353
+ {
354
+ if (is_array($chars)) {
355
+ return $chars;
356
+ }
357
+ return str_split($chars);
358
+ }
359
+
360
+ /**
361
+ * @access protected
362
+ * @since 4.10
363
+ *
364
+ * @param string $char
365
+ * @return HtmlEncoder
366
+ */
367
+ public function _incrementOccurrence($char)
368
+ {
369
+ $char = $this->normalizeChar($char);
370
+ $current = $this->getOccurrenceCount($char);
371
+ $this->occurrences[$char] = ++$current;
372
+
373
+ return $this;
374
+ }
375
+
376
+ /**
377
+ * Retrieve the number of occurrences of the specified encodified character since last reset, or since instantiation.
378
+ *
379
+ * @since 4.10
380
+ *
381
+ * @param string $char The char to retrieve the occurrence count for.
382
+ * @return int The number of occurrences.
383
+ */
384
+ public function getOccurrenceCount($char)
385
+ {
386
+ return isset($this->occurrences[$char])
387
+ ? (int) $this->occurrences[$char]
388
+ : 0;
389
+ }
390
+
391
+ /**
392
+ * @access protected
393
+ * @since 4.10
394
+ */
395
+ public function _incrementReplacement()
396
+ {
397
+ $this->replacementCount++;
398
+ }
399
+
400
+ /**
401
+ * Retrieve the total number of replacements of encodifiable characters performed since last reset, or since instantiation.
402
+ *
403
+ * @since 4.10
404
+ *
405
+ * @return int
406
+ */
407
+ public function getReplacementCount()
408
+ {
409
+ return $this->replacementCount;
410
+ }
411
+
412
+ /**
413
+ * Get auto-generated synonyms for the specified character.
414
+ *
415
+ * @since 4.10
416
+ *
417
+ * @param string $char The character to get synonyms for.
418
+ *
419
+ * @return string[] The array of synonyms, excluding the original character.
420
+ */
421
+ public function getAutoSynonyms($char)
422
+ {
423
+ return array(htmlspecialchars($char, /* ENT_HTML401 | */ ENT_QUOTES));
424
+ }
425
+
426
+ /**
427
+ * Replaces character classes in a regex expression with a token, and remembers the values.
428
+ *
429
+ * Caters for escaped "\[" and "\]";
430
+ *
431
+ * @since 4.10
432
+ *
433
+ * @param string $string The regex expression.
434
+ * @param array $classes This will be populated with a token-value map, where value is the character class that was replaced by token.
435
+ *
436
+ * @return string The string with character classes replaced by tokens.
437
+ */
438
+ protected function _extractCharClass($string, &$classes = array())
439
+ {
440
+ // Matches "[.*]", and allows escaping "\]"
441
+ $expr = '(?<!\\\)\[.*(?<!\\\)\]';
442
+ $prefix = static::CHARC_TOKEN_PREFIX;
443
+ $index = 0;
444
+ $string = $this->replaceCallback('~' . $expr . '~U', function($matches) use ($prefix, &$classes, &$index)
445
+ {
446
+ $replacement = $prefix . $index;
447
+ $classes[$replacement] = $matches[0];
448
+ $index++;
449
+
450
+ return $replacement;
451
+ }, $string);
452
+
453
+ return $string;
454
+ }
455
+
456
+ /**
457
+ * Puts the char classes back in place of their corresponding tokens.
458
+ *
459
+ * @since 4.10
460
+ *
461
+ * @see _extractCharClass()
462
+ * @param string $string The regular expression.
463
+ * @param array $classes The token-value map, where value is the char class definition.
464
+ *
465
+ * @return string The regular expression with tokens replaced by char classes from map.
466
+ */
467
+ protected function _injectCharClass($string, $classes)
468
+ {
469
+ return str_replace(array_keys($classes), array_values($classes), $string);
470
+ }
471
+
472
+ /**
473
+ * HTML-encodify a regex expresion to match HTML-encoded variants of the strings.
474
+ *
475
+ * @since 4.10
476
+ *
477
+ * @param string $expr The expression to HTML-encodify.
478
+ * @param Set\Synonym\Set $synonymSets A set of synonym sets.
479
+ * Each char in any of the synonym sets will be encodified.
480
+ * @param string|null $delimiter The delimiter used by the regex. Default: ! (exclamation mark).
481
+ * @param array|string|null $symmetricChars Chars that come in pairs
482
+ *
483
+ * @return type
484
+ */
485
+ public function htmlEncodifyRegex($expr, $synonymSets, $delimiter, $symmetricChars, $symPrefix)
486
+ {
487
+ $chars = iterator_to_array($synonymSets->getAllItems());
488
+ $chars = $this->quoteAll($chars, $delimiter);
489
+ // Preserving character classes
490
+ $classes = array();
491
+ $expr = $this->_extractCharClass($expr, $classes);
492
+ $charsRegex = sprintf('%2$s(%1$s)%2$s', implode('|', $chars), $delimiter);
493
+ $me = $this;
494
+
495
+ $result = $this->replaceCallback(
496
+ $charsRegex, // Replace potentially encoded symbols that have significance in HTML
497
+ function($matches) use ($delimiter, $symmetricChars, $symPrefix, $synonymSets, $me) {
498
+ if (!isset($matches[0])) {
499
+ return null;
500
+ }
501
+ $char = $matches[0]; // Only one character will match
502
+ /* The return value should be a regular expression that
503
+ * represents the HTML-significant char and all of its
504
+ * HTML-encoded alternatives.
505
+ */
506
+ $me->_incrementOccurrence($char);
507
+ $currentOccurrence = $me->getOccurrenceCount($char);
508
+ $synonymSet = $synonymSets->getSetForTerm($char);
509
+ $synonyms = $synonymSet->getSynonyms($char);
510
+ $synonyms = array_merge(array($char), $synonyms, $me->getAutoSynonyms($char));
511
+ $synonyms = array_unique($synonyms);
512
+ $synonyms = $me->quoteAll($synonyms, $delimiter);
513
+
514
+ // Dealing with symmetric chars
515
+ $return = '';
516
+ $isSymmetric = $synonymSet->hasOneOf($symmetricChars);
517
+ if ($isSymmetric && $currentOccurrence) {
518
+ // if even occurrence, replace with lookbehind of the previous occurrence
519
+ $return = $currentOccurrence % 2
520
+ ? sprintf('(?<%2$s%3$s>%1$s)', implode('|', $synonyms), $symPrefix, $currentOccurrence)
521
+ : sprintf('\\g{%1$s%2$s}', $symPrefix, $currentOccurrence-1);
522
+ }
523
+ else {
524
+ // The final substitute regex, which by default is non-capturing
525
+ $return = sprintf('(?:%1$s)', implode('|', $synonyms));
526
+ }
527
+
528
+ $me->_incrementReplacement();
529
+ return $return;
530
+ },
531
+ $expr);
532
+
533
+ // Restoring character classes
534
+ $result = $this->_injectCharClass($result, $classes);
535
+
536
+ return $result;
537
+ }
538
+
539
+ /**
540
+ * Cleans an array of matches from symmetric char matches.
541
+ *
542
+ * Those matches are added as a result of HTML-encodifying a regular expressions,
543
+ * and may cause desired matches to not appear at their normal indexes.
544
+ *
545
+ * @since 4.10
546
+ *
547
+ * @param array $matches The matches array to clean.
548
+ * @param string $symPrefix The symmetric char match name prefix used by the matcher function.
549
+ *
550
+ * @return array The matches array with symmetrical character matches removed.
551
+ */
552
+ public function cleanMatches(array $matches, $symPrefix = null)
553
+ {
554
+ if (is_null($symPrefix)) {
555
+ $symPrefix = $this->getSymPrefix();
556
+ }
557
+
558
+ /**
559
+ * Iterating through all matches.
560
+ * http://php.net/manual/en/control-structures.foreach.php#88578
561
+ */
562
+ while (list($key, $value) = each($matches)) {
563
+ // Is this a symmetrical char match key?
564
+ if (!$this->isSymKey($key, $symPrefix)) {
565
+ continue;
566
+ }
567
+
568
+ $keys = array_keys($matches);
569
+ // The index of the current key
570
+ $keyIndex = array_search($key, $keys, true);
571
+ // The next key
572
+ $nextKey = $keys[$keyIndex+1];
573
+
574
+ if (array_key_exists($nextKey, $matches)) {
575
+ // Remove the numeric copy of the symmetric char match
576
+ unset($matches[$nextKey]);
577
+ }
578
+ // Remove the symmetric char match
579
+ unset($matches[$key]);
580
+ }
581
+
582
+ $matches = array_merge($matches);
583
+ return $matches;
584
+ }
585
+
586
+ /**
587
+ * Determines is a key could represent a symmetric character synonym group.
588
+ *
589
+ * @since 4.10
590
+ *
591
+ * @see getSymPrefix()
592
+ *
593
+ * @param string $key The key to check.
594
+ * @param string|null $symPrefix The prefix to check for. Default: default prefix.
595
+ * @return bool True if the specified key could be a sym key; false otherwise.
596
+ */
597
+ public function isSymKey($key, $symPrefix = null)
598
+ {
599
+
600
+ if (is_null($symPrefix)) {
601
+ $symPrefix = $this->getSymPrefix();
602
+ }
603
+
604
+ return $this->_isStringStartsWith($key, $symPrefix);
605
+ }
606
+
607
+ /**
608
+ * Determines whether a string starts with the specified prefix.
609
+ *
610
+ * @since 4.10
611
+ *
612
+ * @param string $string The string to check.
613
+ * @param string $start The prefix to check for.
614
+ * @return bool True if the specified string starts with the specified prefix; false otherwise.
615
+ */
616
+ protected function _isStringStartsWith($string, $start)
617
+ {
618
+ $startLength = strlen($start);
619
+ return ($actualStart = substr($string, 0, $startLength)) === $start;
620
+ }
621
+ }
includes/Aventura/Wprss/Core/Model/Set/AbstractCompositeSet.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ /**
6
+ * Common functionality for sets that contain other collection descendants.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ abstract class AbstractCompositeSet extends AbstractGenericSet
11
+ {
12
+ /**
13
+ * Get items from all internal sets.
14
+ *
15
+ * @since 4.10
16
+ *
17
+ * @return mixed[]|\Traversable A list of unique items from all sets in this set.
18
+ */
19
+ abstract protected function _getAllItems();
20
+ }
includes/Aventura/Wprss/Core/Model/Set/AbstractGenericSet.php ADDED
@@ -0,0 +1,139 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ /**
6
+ * Base functionality for generic sets with a set interface.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ abstract class AbstractGenericSet extends AbstractSet implements SetInterface
11
+ {
12
+ /**
13
+ * @since 4.10
14
+ *
15
+ * @param mixed[]|\Traversable $items The items to add to the set.
16
+ */
17
+ public function __construct(array $items = array())
18
+ {
19
+ $this->_construct();
20
+
21
+ $this->addMany($items);
22
+ }
23
+
24
+ /**
25
+ * @inheritdoc
26
+ *
27
+ * @since 4.10
28
+ */
29
+ public function add($item)
30
+ {
31
+ $this->_validateItem($item);
32
+ $this->_addItem($item);
33
+ $this->_clearItemCache();
34
+
35
+ return $this;
36
+ }
37
+
38
+ /**
39
+ * @inheritdoc
40
+ *
41
+ * @since 4.10
42
+ */
43
+ public function addMany($items)
44
+ {
45
+ $this->_addItems($items);
46
+ $this->_clearItemCache();
47
+
48
+ return $this;
49
+ }
50
+
51
+ /**
52
+ * @inheritdoc
53
+ *
54
+ * @since 4.10
55
+ */
56
+ public function remove($item)
57
+ {
58
+ $this->_removeItem($item);
59
+ $this->_clearItemCache();
60
+
61
+ return $this;
62
+ }
63
+
64
+ /**
65
+ * @inheritdoc
66
+ *
67
+ * @since 4.10
68
+ */
69
+ public function removeMany($items)
70
+ {
71
+ foreach ($items as $_item) {
72
+ $this->_removeItem($_item);
73
+ }
74
+ $this->_clearItemCache();
75
+
76
+ return $this;
77
+ }
78
+
79
+ /**
80
+ * @inheritdoc
81
+ *
82
+ * @since 4.10
83
+ */
84
+ public function has($item)
85
+ {
86
+ return $this->_hasItem($item);
87
+ }
88
+
89
+ /**
90
+ * @inheritdoc
91
+ *
92
+ * @since 4.10
93
+ */
94
+ public function clear()
95
+ {
96
+ $this->_construct();
97
+ $this->_clearItemCache();
98
+ }
99
+
100
+ /**
101
+ * @inheritdoc
102
+ *
103
+ * @since 4.10
104
+ */
105
+ public function items()
106
+ {
107
+ return $this->_getCachedItems();
108
+ }
109
+
110
+ /**
111
+ * @inheritdoc
112
+ *
113
+ * @since 4.10
114
+ */
115
+ public function count()
116
+ {
117
+ return $this->_count();
118
+ }
119
+
120
+ /**
121
+ * @inheritdoc
122
+ *
123
+ * @since 4.10
124
+ */
125
+ protected function _validateItem($item)
126
+ {
127
+ // No exception means all items are valid.
128
+ }
129
+
130
+ /**
131
+ * @inheritdoc
132
+ *
133
+ * @since 4.10
134
+ */
135
+ public function hasOneOf($items)
136
+ {
137
+ return $this->_hasOneOf($items);
138
+ }
139
+ }
includes/Aventura/Wprss/Core/Model/Set/AbstractGenericSetSet.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ /**
6
+ * A base set for sets of sets that expose relevant interfaces.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ class AbstractGenericSetSet extends AbstractSetSet implements SetSetInterface
11
+ {
12
+ /**
13
+ * @inheritdoc
14
+ *
15
+ * @since 4.10
16
+ */
17
+ protected function _createAllItemsSet($items)
18
+ {
19
+ $set = new Set();
20
+ $set->addMany($items);
21
+
22
+ return $set;
23
+ }
24
+
25
+ /**
26
+ * @inheritdoc
27
+ *
28
+ * @since 4.10
29
+ */
30
+ public function getAllItems()
31
+ {
32
+ return $this->_getAllItems();
33
+ }
34
+
35
+ /**
36
+ * @inheritdoc
37
+ *
38
+ * @since 4.10
39
+ */
40
+ public function getContaining($item)
41
+ {
42
+ return $this->_getContaining($item);
43
+ }
44
+ }
includes/Aventura/Wprss/Core/Model/Set/AbstractSet.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ use Aventura\Wprss\Core\Model\Collection;
6
+
7
+ /**
8
+ * Base functionality for sets.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ abstract class AbstractSet extends Collection\AbstractCollection
13
+ {
14
+ /**
15
+ * Determine if this instance contains at least one items in the given list.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @param mixed[]|\Traversable $items The list of items to for.
20
+ * @return boolean True if this instance contains at least one of the items in the given list; false otherwise.
21
+ */
22
+ protected function _hasOneOf($items)
23
+ {
24
+ foreach ($items as $_item) {
25
+ if ($this->_hasItem($_item)) {
26
+ return true;
27
+ }
28
+ }
29
+
30
+ return false;
31
+ }
32
+ }
includes/Aventura/Wprss/Core/Model/Set/AbstractSetSet.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ use Dhii\Collection;
6
+
7
+ /**
8
+ * Common functionality for sets of sets.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ abstract class AbstractSetSet extends AbstractCompositeSet
13
+ {
14
+ /**
15
+ * @inheritdoc
16
+ *
17
+ * @since 4.10
18
+ */
19
+ protected function _getAllItems()
20
+ {
21
+ $items = array();
22
+
23
+ foreach ($this->_getItems() as $_set) {
24
+ /* @var $_set Collection\SetInterface */
25
+ $items = array_merge($items, $_set->items());
26
+ }
27
+
28
+ return $this->_createAllItemsSet($items);
29
+ }
30
+
31
+ /**
32
+ * Creates a set that will hold items from all internal sets.
33
+ *
34
+ * @since 4.10
35
+ *
36
+ * @return Collection\SetInterface A set to be populated by items from all internal sets.
37
+ */
38
+ abstract protected function _createAllItemsSet($items);
39
+
40
+ /**
41
+ * Search evaluator to find sets that contain a certain item.
42
+ *
43
+ * @since 4.10
44
+ *
45
+ * @param Collection\SetInterface $set The set to check in.
46
+ * @param mixed $item The item to check for.
47
+ *
48
+ * @return Collection\SetInterface|null The set, if it contains item; null otherwise.
49
+ */
50
+ public function _evalSetByHavingItem($idx, Collection\SetInterface $set, &$isContinue, $item)
51
+ {
52
+ return $set->has($item)
53
+ ? $set
54
+ : null;
55
+ }
56
+
57
+ /**
58
+ * Gets a list of internal sets that contain the given item.
59
+ *
60
+ * @since 4.10
61
+ *
62
+ * @return Collection\SetInterface[]|\Traversable The list of internal sets with the matching item.
63
+ */
64
+ protected function _getContaining($item)
65
+ {
66
+ $me = $this;
67
+ return $this->_search(function($idx, $set, &$isContinue) use ($item, $me) {
68
+ return $me->_evalSetByHavingItem($idx, $set, $isContinue, $item);
69
+ });
70
+ }
71
+ }
includes/Aventura/Wprss/Core/Model/Set/Set.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ /**
6
+ * Simple concrete set implementation.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ class Set extends AbstractGenericSet
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/Set/SetInterface.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ use Dhii\Collection;
6
+
7
+ /**
8
+ * Something that behaves like a set.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ interface SetInterface extends Collection\SetInterface
13
+ {
14
+ /**
15
+ * Determines whether this instance contains at least one of the items in the given list.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @param mixed[]|\Traversable $items The list of items to check for.
20
+ */
21
+ public function hasOneOf($items);
22
+ }
includes/Aventura/Wprss/Core/Model/Set/SetSet.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ /**
6
+ * A set of sets.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ class SetSet extends AbstractGenericSetSet
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/Set/SetSetInterface.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set;
4
+
5
+ use Dhii\Collection;
6
+
7
+ /**
8
+ * Something that can act as a set of sets.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ interface SetSetInterface extends SetInterface
13
+ {
14
+ /**
15
+ * Returns a list of items from all internal sets.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @return mixed[]|\Traversable A list of items from all sets in this instance.
20
+ */
21
+ public function getAllItems();
22
+
23
+ /**
24
+ * Gets internal sets that contain a specific item.
25
+ *
26
+ * @since 4.10
27
+ *
28
+ * @param Collection\SetInterface[]|\Traversable $item A list of internal sets that contain the given item.
29
+ */
30
+ public function getContaining($item);
31
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/AbstractGenericSynonymSet.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ /**
6
+ * Base functionality of a synonym set.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ abstract class AbstractGenericSynonymSet extends AbstractSynonymSet implements SynonymSetInterface
11
+ {
12
+ public function __construct(array $items = array())
13
+ {
14
+ parent::__construct($items);
15
+ }
16
+
17
+ /**
18
+ * @inheritdoc
19
+ *
20
+ * @since 4.10
21
+ */
22
+ public function getSynonyms($term)
23
+ {
24
+ return $this->_getSynonyms($term);
25
+ }
26
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/AbstractSynonymSet.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ use Aventura\Wprss\Core\Model\Set\AbstractGenericSet;
6
+
7
+ /**
8
+ * Common functionality for synonym sets.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class AbstractSynonymSet extends AbstractGenericSet
13
+ {
14
+ /**
15
+ * Gets a list of terms in this instance that are synonymous to the specified term.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @param string $term The term to get synonyms for.
20
+ *
21
+ * @return string[]|\Traversable A list of terms that are synonymous to the specified term.
22
+ */
23
+ protected function _getSynonyms($term)
24
+ {
25
+ if (!$this->_hasItem($term)) {
26
+ return array();
27
+ }
28
+
29
+ $items = $this->_getItems();
30
+ $items = $this->_arrayConvert($items);
31
+ return array_values(array_diff($items, array($term)));
32
+ }
33
+
34
+ /**
35
+ * @inheritdoc
36
+ *
37
+ * @since 4.10
38
+ */
39
+ protected function _validateItem($item)
40
+ {
41
+ if (!is_string($item)) {
42
+ throw new \RuntimeException('The items in this set must be strings');
43
+ }
44
+ }
45
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/Set.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ use Aventura\Wprss\Core\Model\Set as Sets;
6
+ use Dhii\Collection;
7
+
8
+ /**
9
+ * A set of synonym sets.
10
+ *
11
+ * @since 4.10
12
+ */
13
+ class Set extends Sets\AbstractGenericSetSet implements SynonymSetSetInterface
14
+ {
15
+ /**
16
+ * Get a set, to which the specified set belongs.
17
+ *
18
+ * @since 4.10
19
+ *
20
+ * @param string $term The term, for which to get the synonyms set.
21
+ *
22
+ * @return Simple The synonym set, to which the specified term belongs.
23
+ * If the set does not exist, creates it and adds the term to it.
24
+ */
25
+ public function getSetForTerm($term)
26
+ {
27
+ $synonymSets = $this->_getSetsForTerm($term);
28
+ $synonymSets = $this->_arrayConvert($synonymSets);
29
+ if (!($set = array_shift($synonymSets))) {
30
+ $set = new Sets\Synonym\Simple(array($term));
31
+ $this->add($set);
32
+ }
33
+
34
+ return $set;
35
+ }
36
+
37
+ /**
38
+ * Retrieves all internal synonym sets that contain the specified term.
39
+ *
40
+ * @since 4.10
41
+ *
42
+ * @param string $term The term to check for.
43
+ * @return Collection\SetInterface[]|\Traversable A list of sets that contain the specified term.
44
+ */
45
+ protected function _getSetsForTerm($term)
46
+ {
47
+ return $this->_getContaining($term);
48
+ }
49
+
50
+ /**
51
+ * @inheritdoc
52
+ *
53
+ * @since 4.10
54
+ */
55
+ protected function _validateItem($item)
56
+ {
57
+ if (!($item instanceof Sets\Synonym\Simple)) {
58
+ throw new \RuntimeException(sprintf('The items in this set must be simple synonym sets'));
59
+ }
60
+ }
61
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/Simple.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ /**
6
+ * A simple set of synonyms.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ class Simple extends AbstractGenericSynonymSet implements SynonymSetInterface
11
+ {
12
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/SynonymSetInterface.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ use Aventura\Wprss\Core\Model\Set as BaseSets;
6
+
7
+ /**
8
+ * Something that behaves like a synonym set.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ interface SynonymSetInterface extends BaseSets\SetInterface
13
+ {
14
+ /**
15
+ * Retrieves a list of terms from this set that are synonymous to the specified term.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @param string $term The term, for which to get the synonyms.
20
+ *
21
+ * @return string[]|\Traversable A list of terms that are synonymous to the specified term.
22
+ */
23
+ public function getSynonyms($term);
24
+ }
includes/Aventura/Wprss/Core/Model/Set/Synonym/SynonymSetSetInterface.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\Model\Set\Synonym;
4
+
5
+ use Aventura\Wprss\Core\Model\Set\SetSetInterface;
6
+
7
+ /**
8
+ * Something that can behave like a set of synonym sets.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ interface SynonymSetSetInterface extends SetSetInterface
13
+ {
14
+ /**
15
+ * Guaranteed to retrieve a set containing the specified term.
16
+ *
17
+ * If this instance has a set containing the term, that set will be returned.
18
+ * Otherwise, a new set is created, and populated with the specified term.
19
+ *
20
+ * @since 4.10
21
+ *
22
+ * @param string $term The term, for which to get the synonym set.
23
+ *
24
+ * @return SynonymSetInterface The synonym set containing the specified term.
25
+ */
26
+ public function getSetForTerm($term);
27
+ }
includes/Aventura/Wprss/Core/Plugin.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace Aventura\Wprss\Core;
4
 
 
 
5
  /**
6
  * The Core instance of WP RSS Aggregator.
7
  *
@@ -12,6 +14,12 @@ class Plugin extends Plugin\PluginAbstract
12
  const CODE = 'wprss';
13
  const VERSION = WPRSS_VERSION;
14
 
 
 
 
 
 
 
15
  /**
16
  * Hooks the rest of the functionality of this class.
17
  *
@@ -136,4 +144,64 @@ class Plugin extends Plugin\PluginAbstract
136
 
137
  return $response;
138
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  }
2
 
3
  namespace Aventura\Wprss\Core;
4
 
5
+ use Aventura\Wprss\Core\Component;
6
+
7
  /**
8
  * The Core instance of WP RSS Aggregator.
9
  *
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.
25
  *
144
 
145
  return $response;
146
  }
147
+
148
+ /**
149
+ * Retrieve the post type of feed sources.
150
+ *
151
+ * @since 4.10
152
+ *
153
+ * @return string The post type string of the feed source post type.
154
+ */
155
+ public function getFeedSourcePostType()
156
+ {
157
+ return static::POST_TYPE_FEED_SOURCE;
158
+ }
159
+
160
+ /**
161
+ * Retrieve the admin AJAX notices component singleton.
162
+ *
163
+ * @since 4.10
164
+ *
165
+ * @return Component\AdminAjaxNotices
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
+ /**
177
+ * Retrieve the "Leave Review" notification component singleton.
178
+ *
179
+ * @since 4.10
180
+ *
181
+ * @return Component\LeaveReviewNotification
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
+ /**
193
+ * Retrieve the "Leave Review" notification component singleton.
194
+ *
195
+ * @since 4.10
196
+ *
197
+ * @return Component\AdminHelper
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
  }
includes/Aventura/Wprss/Core/Plugin/ComponentFactoryAbstract.php CHANGED
@@ -10,6 +10,8 @@ namespace Aventura\Wprss\Core\Plugin;
10
  */
11
  abstract class ComponentFactoryAbstract extends ComponentAbstract implements ComponentFactoryInterface
12
  {
 
 
13
  /**
14
  * Creates a new component instance.
15
  *
@@ -23,8 +25,7 @@ abstract class ComponentFactoryAbstract extends ComponentAbstract implements Com
23
  public function createComponent($class, PluginInterface $parent, array $data = array())
24
  {
25
  $className = $this->getComponentClassName($class);
26
- $componentBase = 'Aventura\Wprss\Core\Plugin\ComponentInterface';
27
- if (!static::classImplements($className, $componentBase)) {
28
  throw $this->exception(array('Could not create component: "%1$s" is not a component class as it does not implement "%2$s"', $className, $componentBase), array(__NAMESPACE__, 'Exception'));
29
  }
30
 
@@ -35,7 +36,7 @@ abstract class ComponentFactoryAbstract extends ComponentAbstract implements Com
35
  $data['plugin'] = $parent;
36
  $component = new $className($data);
37
  $component->hook();
38
-
39
  return $component;
40
  }
41
 
@@ -43,22 +44,56 @@ abstract class ComponentFactoryAbstract extends ComponentAbstract implements Com
43
  * Get the name of a component class, based on it's relative or absolute name, or mapped ID.
44
  *
45
  * @since 4.8.1
46
- * @param string $className A relative or absolute class name, or some other class identifier that is mapped
 
47
  * to a class name. If relative, then relative to the {@see getBaseNamespace()}.
 
48
  * @return string Name of the component class.
49
  */
50
- public function getComponentClassName($className)
51
  {
 
52
  // Namespace specified as array of parts; assume root namespace
53
- if (is_array($className)) {
54
- $className = '\\' . trim(implode('\\', $className), '\\');
 
 
 
 
 
 
 
55
  }
56
-
57
- if (static::isRootNamespace($className)) {
58
- return $className;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
59
  }
60
 
61
- $rootNamespace = $this->getBaseNamespace();
62
- return sprintf('%1$s\\%2$s', $rootNamespace, $className);
63
  }
64
- }
10
  */
11
  abstract class ComponentFactoryAbstract extends ComponentAbstract implements ComponentFactoryInterface
12
  {
13
+ const COMPONENT_INTERFACE = 'Aventura\\Wprss\\Core\\Plugin\\ComponentInterface';
14
+
15
  /**
16
  * Creates a new component instance.
17
  *
25
  public function createComponent($class, PluginInterface $parent, array $data = array())
26
  {
27
  $className = $this->getComponentClassName($class);
28
+ if (!$this->validComponentClass($className)) {
 
29
  throw $this->exception(array('Could not create component: "%1$s" is not a component class as it does not implement "%2$s"', $className, $componentBase), array(__NAMESPACE__, 'Exception'));
30
  }
31
 
36
  $data['plugin'] = $parent;
37
  $component = new $className($data);
38
  $component->hook();
39
+
40
  return $component;
41
  }
42
 
44
  * Get the name of a component class, based on it's relative or absolute name, or mapped ID.
45
  *
46
  * @since 4.8.1
47
+ *
48
+ * @param string $name A relative or absolute class name, or some other class identifier that is mapped
49
  * to a class name. If relative, then relative to the {@see getBaseNamespace()}.
50
+ *
51
  * @return string Name of the component class.
52
  */
53
+ public function getComponentClassName($name)
54
  {
55
+ $className = null;
56
  // Namespace specified as array of parts; assume root namespace
57
+ if (is_array($name)) {
58
+ $name = '\\' . trim(implode('\\', $name), '\\');
59
+ }
60
+
61
+ if (static::isRootNamespace($name) && $this->validComponentClass($name)) {
62
+ $className = $name;
63
+ } else {
64
+ $rootNamespace = $this->getBaseNamespace();
65
+ $className = sprintf('%1$s\\%2$s', $rootNamespace, $name);
66
  }
67
+
68
+ $this->event('component_class_name', array(
69
+ 'name' => $name,
70
+ 'class_name' => &$className
71
+ ));
72
+
73
+ return $className;
74
+ }
75
+
76
+ /**
77
+ * Determines if a class name is of a valid component.
78
+ *
79
+ * @since 4.10
80
+ *
81
+ * @param string|object $className A class name or object to check.
82
+ *
83
+ * @return bool
84
+ *
85
+ * @throws \InvalidArgumentException If supplied argument is not a string or object.
86
+ */
87
+ public function validComponentClass($className)
88
+ {
89
+ if (is_object($className)) {
90
+ $className = get_class($className);
91
+ }
92
+
93
+ if (!is_string($className)) {
94
+ throw new \InvalidArgumentException('Could not validate component class: class name must be a string or object');
95
  }
96
 
97
+ return static::classImplements($className, static::COMPONENT_INTERFACE);
 
98
  }
99
+ }
includes/admin-ajax-notice.php CHANGED
@@ -506,7 +506,11 @@ class WPRSS_Admin_Notices {
506
 
507
  // Auto-generate nonce
508
  if ( is_null( $data['nonce'] ) && !is_null( $data['id'] ) ) {
509
- $data['nonce'] = $this->generate_nonce_for_notice( $data['id'] );
 
 
 
 
510
  }
511
 
512
  // Auto-generate nonce element ID
@@ -806,7 +810,7 @@ class WPRSS_Admin_Notices {
806
  $event_name = $this->prefix( 'admin_notice_conditions_evaluated' );
807
  $result = true; // By default, evaluation passes
808
  if ( empty( $conditions ) ) return apply_filters ( $event_name, $result, $condition_type, $this ); // Unconditional ;)
809
- if ( !is_array( $conditions ) ) $conditions = (array)$conditions; // Normalizing
810
 
811
  foreach ( $conditions as $_idx => $_condition ) {
812
  $func = is_array( $_condition ) && isset( $_condition['func'] )
@@ -1071,6 +1075,9 @@ class WPRSS_Admin_Notices {
1071
 
1072
  if ( !$notice )
1073
  throw new Exception( sprintf( 'Could not render notice: no notice found for ID "%1$s"' ), $id );
 
 
 
1074
  ob_start();
1075
  $notice = apply_filters( $this->prefix( 'admin_notice_render_before' ), $notice, $this );
1076
  ?>
@@ -1080,7 +1087,7 @@ class WPRSS_Admin_Notices {
1080
  <?php echo $notice['content'] ?>
1081
  </div>
1082
  <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>
1083
- <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 $notice['nonce'] ?></span>
1084
  </div>
1085
  <?php
1086
  do_action( $this->prefix( 'admin_notice_render_after' ), $notice, $this );
@@ -1113,7 +1120,8 @@ class WPRSS_Admin_Notices {
1113
  throw new Exception( sprintf( 'Could not hide notice: No notice found for ID "%1$s"', $notice_id ) );
1114
 
1115
  // Is it the right nonce?
1116
- if ( $notice['nonce'] !== $nonce )
 
1117
  throw new Exception( sprintf( 'Could not hide notice: Nonce "%1$s" does not belong to notice "%2$s"', $nonce, $notice_id ) );
1118
 
1119
  // Verify nonce
@@ -1158,7 +1166,7 @@ function wprss_admin_notice_get_collection() {
1158
  $collection->init();
1159
  $collection = apply_filters( 'wprss_admin_notice_collection_after_init', $collection );
1160
 
1161
- add_action( 'admin_enqueue_scripts', 'wprss_admin_notices_collection_enqueue_scripts' );
1162
  }
1163
 
1164
  return $collection;
@@ -1263,14 +1271,37 @@ function wprss_admin_notice_hide() {
1263
  function wprss_is_wprss_page() {
1264
  global $typenow;
1265
 
1266
- if ( empty( $typenow ) && !empty( $_GET['post'] ) ) {
1267
- $post = get_post( $_GET['post'] );
1268
- if ( $post !== NULL && !is_wp_error( $post ) )
1269
- $typenow = $post->post_type;
 
1270
  }
1271
 
1272
- $is_wprss_page = ( $typenow == 'wprss_feed' ) || ( $typenow == 'wprss_feed_item' );
1273
- return apply_filters( 'wprss_is_wprss_page', $is_wprss_page );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1274
  }
1275
 
1276
 
506
 
507
  // Auto-generate nonce
508
  if ( is_null( $data['nonce'] ) && !is_null( $data['id'] ) ) {
509
+ $me = $this;
510
+ $data['nonce'] = wprss()->getAdminHelper()->createCommand(function() use ($me, $data) {
511
+ $nonce = $me->generate_nonce_for_notice( $data['id'] );
512
+ return $nonce;
513
+ });
514
  }
515
 
516
  // Auto-generate nonce element ID
810
  $event_name = $this->prefix( 'admin_notice_conditions_evaluated' );
811
  $result = true; // By default, evaluation passes
812
  if ( empty( $conditions ) ) return apply_filters ( $event_name, $result, $condition_type, $this ); // Unconditional ;)
813
+ if ( !is_array( $conditions ) ) $conditions = array($conditions); // Normalizing
814
 
815
  foreach ( $conditions as $_idx => $_condition ) {
816
  $func = is_array( $_condition ) && isset( $_condition['func'] )
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
+
1081
  ob_start();
1082
  $notice = apply_filters( $this->prefix( 'admin_notice_render_before' ), $notice, $this );
1083
  ?>
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
1093
  do_action( $this->prefix( 'admin_notice_render_after' ), $notice, $this );
1120
  throw new Exception( sprintf( 'Could not hide notice: No notice found for ID "%1$s"', $notice_id ) );
1121
 
1122
  // Is it the right nonce?
1123
+ $noticeNonce = wprss()->getAdminHelper()->resolveValue($notice['nonce']);
1124
+ if ( $noticeNonce !== $nonce )
1125
  throw new Exception( sprintf( 'Could not hide notice: Nonce "%1$s" does not belong to notice "%2$s"', $nonce, $notice_id ) );
1126
 
1127
  // Verify nonce
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;
1271
  function wprss_is_wprss_page() {
1272
  global $typenow;
1273
 
1274
+ $postType = $typenow;
1275
+ if ( empty( $postType ) && isset( $_GET['post'] ) && !empty( $_GET['post'] ) ) {
1276
+ $post = get_post(filter_var($_GET['post'], FILTER_SANITIZE_NUMBER_INT));
1277
+ if ( $post !== NULL && !is_wp_error( $post ) )
1278
+ $postType = $post->post_type;
1279
  }
1280
 
1281
+ $filterFlags = FILTER_FLAG_STRIP_BACKTICK | FILTER_FLAG_STRIP_LOW | FILTER_FLAG_STRIP_HIGH;
1282
+ if (empty($postType) && isset($_GET['post_type'])) {
1283
+ $postType = filter_var(trim($_GET['post_type']), FILTER_SANITIZE_STRING, $filterFlags);
1284
+ }
1285
+
1286
+ $pagenow = isset($_GET['page']) ? filter_var($_GET['page'], FILTER_SANITIZE_STRING, $filterFlags) : null;
1287
+ $wprss_post_types = apply_filters('wprss_post_types', array(
1288
+ 'wprss_feed',
1289
+ 'wprss_feed_item',
1290
+ 'wprss_blacklist',
1291
+ ));
1292
+ $wprss_pages = apply_filters('wprss_page_slugs', array(
1293
+ 'wprss-aggregator',
1294
+ 'wprss-aggregator-settings',
1295
+ 'wprss-import-export-settings',
1296
+ 'wprss-debugging',
1297
+ 'wprss-addons',
1298
+ 'wprss-welcome',
1299
+ 'wprss-help'
1300
+ ));
1301
+
1302
+ $is_wprss_post = in_array($postType, $wprss_post_types, true);
1303
+ $is_wprss_page = in_array($pagenow, $wprss_pages, true);
1304
+ return apply_filters( 'wprss_is_wprss_page', $is_wprss_post || $is_wprss_page );
1305
  }
1306
 
1307
 
includes/admin-display.php CHANGED
@@ -1,17 +1,17 @@
1
- <?php
2
  /**
3
- * Functions for the admin section, columns and row actions
4
- *
5
  * @package WP RSS Aggregator
6
- */
7
 
8
 
9
- add_filter( 'manage_wprss_feed_posts_columns', 'wprss_set_feed_custom_columns', 20, 1 );
10
- /**
11
  * Set up the custom columns for the wprss_feed list
12
- *
13
  * @since 2.0
14
- */
15
  function wprss_set_feed_custom_columns( $columns ) {
16
 
17
  $columns = array(
@@ -30,24 +30,24 @@
30
  }
31
 
32
  return $columns;
33
- }
34
 
35
 
36
  add_action( "manage_wprss_feed_posts_custom_column", "wprss_show_custom_columns", 10, 2 );
37
  /**
38
  * Show up the custom columns for the wprss_feed list
39
- *
40
  * @since 2.0
41
- */
42
  function wprss_show_custom_columns( $column, $post_id ) {
43
-
44
- switch ( $column ) {
45
  case 'errors':
46
  $errors = get_post_meta( $post_id, 'wprss_error_last_import', true );
47
  $showClass = ( $errors !== '' )? 'wprss-show' : '';
48
  $default_msg = __( "This feed source experienced an error during the last feed fetch or validation check. Re-check the feed source URL or check the Error Log in the Debugging page for more details.", WPRSS_TEXT_DOMAIN );
49
  $msg = strlen( $errors ) > 0 ? $errors : $default_msg;
50
- echo "<i title=\"$msg\" class=\"fa fa-warning fa-fw wprss-feed-error-symbol $showClass\"></i>";
51
  break;
52
  case 'state':
53
  $active = wprss_is_feed_source_active( $post_id );
@@ -83,7 +83,7 @@
83
  if ( $update_interval === wprss_get_default_feed_source_update_interval() || $update_interval === '' ) {
84
  $next_update = wp_next_scheduled( 'wprss_fetch_all_feeds_hook', array() );
85
  }
86
-
87
  // Update the meta field
88
  if ( wprss_is_feed_source_active( $post_id ) ) {
89
  $next_update_text = $next_update === FALSE ? __( 'None', WPRSS_TEXT_DOMAIN ) : human_time_diff( $next_update, time() );
@@ -91,7 +91,7 @@
91
  $next_update_text = __( 'Paused', WPRSS_TEXT_DOMAIN );
92
  }
93
  update_post_meta( $post_id, 'wprss_next_update', $next_update_text );
94
-
95
  ?>
96
 
97
  <p>
@@ -127,7 +127,7 @@
127
 
128
  // Set meta field for items imported
129
  update_post_meta( $post_id, 'wprss_items_imported', $items->post_count );
130
-
131
  break;
132
  }
133
  }
@@ -136,9 +136,9 @@
136
  add_filter( "manage_edit-wprss_feed_sortable_columns", "wprss_feed_sortable_columns" );
137
  /**
138
  * Make the custom columns sortable for wprss_feed post type
139
- *
140
  * @since 2.0
141
- */
142
  function wprss_feed_sortable_columns() {
143
  $sortable_columns = array(
144
  // meta column id => sortby value used in query
@@ -154,9 +154,9 @@
154
  add_action( 'pre_get_posts', 'wprss_feed_source_order' );
155
  /**
156
  * Change order of feed sources to alphabetical ascending according to feed name
157
- *
158
  * @since 2.2
159
- */
160
  function wprss_feed_source_order( $query ) {
161
  // Check if the query is being processed in WP Admin, is the main query, and is targetted
162
  // for the wprss_feed CPT. If not, stop
@@ -165,14 +165,14 @@
165
  }
166
  // Check if the orderby query variable is set
167
  if ( !( $orderby = $query->get( 'orderby' ) ) ) return;
168
-
169
  // We will be sorting using the meta value (unless sorting by title)
170
  $query->set('orderby', 'meta_value' );
171
  // Get the current order
172
  $order = strtoupper( $query->get( 'order' ) );
173
  // Check if it is valid
174
  $got_order = $order === 'ASC' || $order === 'DESC';
175
-
176
  // Check what we are sorting by
177
  switch ( $orderby ) {
178
  case 'title':
@@ -192,19 +192,19 @@
192
  if ( !$got_order ) $query->set( 'order', 'DESC' );
193
  break;
194
  }
195
-
196
  if ( !$got_order ){
197
  $query->set( 'order', 'ASC' );
198
  }
199
  }
200
 
201
 
202
- add_filter( 'manage_wprss_feed_item_posts_columns', 'wprss_set_feed_item_custom_columns', 20, 1 );
203
  /**
204
  * Set up the custom columns for the wprss_feed source list
205
- *
206
  * @since 2.0
207
- */
208
  function wprss_set_feed_item_custom_columns( $columns ) {
209
 
210
  $columns = array (
@@ -221,39 +221,39 @@
221
  add_action( "manage_wprss_feed_item_posts_custom_column", "wprss_show_feed_item_custom_columns", 10, 2 );
222
  /**
223
  * Show up the custom columns for the wprss_feed list
224
- *
225
  * @since 2.0
226
- */
227
  function wprss_show_feed_item_custom_columns( $column, $post_id ) {
228
-
229
- switch ( $column ) {
230
  case "permalink":
231
  $url = get_post_meta( $post_id, 'wprss_item_permalink', true);
232
  echo '<a href="' . $url . '">' . $url. '</a>';
233
- break;
234
-
235
  case "publishdate":
236
  $item_date = get_the_time( 'U', get_the_ID() );
237
  $item_date = ( $item_date === '' )? date('U') : $item_date;
238
- $publishdate = date( 'Y-m-d H:i:s', $item_date ) ;
239
  echo $publishdate;
240
- break;
241
-
242
- case "source":
243
- $query = new WP_Query();
244
- $source = '<a href="' . get_edit_post_link( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '">' . get_the_title( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '</a>';
245
  echo $source;
246
- break;
247
  }
248
  }
249
 
250
 
251
  add_filter( "manage_edit-wprss_feed_item_sortable_columns", "wprss_feed_item_sortable_columns" );
252
- /**
253
  * Make the custom columns sortable
254
- *
255
  * @since 2.0
256
- */
257
  function wprss_feed_item_sortable_columns() {
258
  $sortable_columns = array(
259
  // meta column id => sortby value used in query
@@ -265,19 +265,19 @@
265
 
266
 
267
  add_action( 'pre_get_posts', 'wprss_feed_item_orderby' );
268
- /**
269
  * Change ordering of posts on wprss_feed_item screen
270
- *
271
  * @since 2.0
272
- */
273
  function wprss_feed_item_orderby( $query ) {
274
  if( ! is_admin() )
275
  return;
276
-
277
  $post_type = $query->get('post_type');
278
-
279
  // If we're on the feed listing admin page
280
- if ( $post_type == 'wprss_feed_item') {
281
  // Set general orderby to date the feed item was published
282
  $query->set('orderby','publishdate');
283
  // If user clicks on the reorder link, implement reordering
@@ -287,15 +287,15 @@
287
  $query->set( 'orderby', 'date' );
288
  }
289
  }
290
- }
291
 
292
 
293
- add_filter( 'post_updated_messages', 'wprss_feed_updated_messages' );
294
  /**
295
  * Change default notification message when new feed is added or updated
296
- *
297
  * @since 2.0
298
- */
299
  function wprss_feed_updated_messages( $messages ) {
300
  global $post, $post_ID;
301
 
@@ -304,7 +304,7 @@
304
  1 => __( 'Feed source updated. ', WPRSS_TEXT_DOMAIN ),
305
  2 => __( 'Custom field updated.', WPRSS_TEXT_DOMAIN ),
306
  3 => __( 'Custom field deleted.', WPRSS_TEXT_DOMAIN ),
307
- 4 => __( 'Feed source updated.', WPRSS_TEXT_DOMAIN ),
308
  5 => '',
309
  6 => __( 'Feed source saved.', WPRSS_TEXT_DOMAIN ),
310
  7 => __( 'Feed source saved.', WPRSS_TEXT_DOMAIN ),
@@ -314,18 +314,18 @@
314
  );
315
 
316
  return apply_filters( 'wprss_feed_updated_messages', $messages );
317
- }
318
 
319
 
320
  add_filter( 'post_row_actions', 'wprss_remove_row_actions', 10, 2 );
321
  /**
322
  * Remove actions row for imported feed items, we don't want them to be editable or viewable
323
- *
324
  * @since 2.0
325
- */
326
  function wprss_remove_row_actions( $actions, $post )
327
  {
328
-
329
  $page = isset( $_GET['paged'] )? '&paged=' . $_GET['paged'] : '';
330
  if ( get_post_type($post) === 'wprss_feed_item' ) {
331
  unset( $actions[ 'edit' ] );
@@ -337,7 +337,7 @@
337
  $actions = array_reverse( $actions );
338
  $actions['id'] = '<span class="wprss-row-id">' . sprintf( __( 'ID: %1$s', WPRSS_TEXT_DOMAIN ), $post->ID ) . '</span>';
339
  $actions = array_reverse( $actions );
340
-
341
  unset( $actions[ 'view'] );
342
  unset( $actions[ 'inline hide-if-no-js'] );
343
  if ( get_post_status( $post->ID ) !== 'trash' ) {
@@ -354,12 +354,11 @@
354
 
355
  $fetch_items_row_action_text = apply_filters( 'wprss_fetch_items_row_action_text', __( 'Fetch Items', WPRSS_TEXT_DOMAIN ) );
356
  $actions[ 'fetch' ] = '<a href="javascript:;" class="wprss_ajax_action" pid="'. $post->ID .'" purl="'.home_url().'/wp-admin/admin-ajax.php">' . $fetch_items_row_action_text . '</a>';
357
- $actions[ 'fetch' ] .= wp_nonce_field( sprintf( 'wprss-fetch-items-for-%s', $post->ID ) );
358
 
359
  $purge_feeds_row_action_text = apply_filters( 'wprss_purge_feeds_row_action_text', __( 'Delete Items', WPRSS_TEXT_DOMAIN ) );
360
  $purge_feeds_row_action_title = apply_filters( 'wprss_purge_feeds_row_action_title', __( 'Delete feed items imported by this feed source', WPRSS_TEXT_DOMAIN ) );
361
  $actions['purge-posts'] = "<a href='".admin_url("edit.php?post_type=wprss_feed&purge-feed-items=" . $post->ID . $page ) . "' title='" . $purge_feeds_row_action_title . "' >" . __( $purge_feeds_row_action_text, WPRSS_TEXT_DOMAIN ) . "</a>";
362
-
363
  $actions['trash'] = $trash;
364
  }
365
  }
@@ -370,7 +369,7 @@
370
  add_action( 'admin_init', 'check_delete_for_feed_source' );
371
  /**
372
  * Checks the GET data for the delete per feed source action request
373
- *
374
  * @since 3.5
375
  */
376
  function check_delete_for_feed_source( $source_id = NULL ) {
@@ -407,7 +406,7 @@
407
  add_action( 'wprss_delete_feed_items_from_source_hook', 'wprss_delete_feed_items_of_feed_source', 10 , 1 );
408
  /**
409
  * Deletes the feed items of the feed source identified by the given ID.
410
- *
411
  * @param $source_id The ID of the feed source
412
  * @since 3.5
413
  */
@@ -440,7 +439,7 @@
440
 
441
  /**
442
  * Shows a notification that tells the user that feed items for a particular source are being deleted
443
- *
444
  * @since 3.5
445
  */
446
  function wprss_notify_about_deleting_source_feed_items() {
@@ -473,7 +472,7 @@
473
  }
474
 
475
  // Verify admin referer
476
- if (!wprss_verify_nonce( sprintf( 'wprss-fetch-items-for-%s', $id ), 'wprss_admin_ajax_nonce' )) {
477
  throw new Exception($wprss->__(array('Could not schedule fetch for source #%1$s: nonce is expired', $id)));
478
  }
479
 
@@ -515,12 +514,30 @@
515
  }
516
 
517
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
518
  add_filter( 'bulk_actions-edit-wprss_feed_item', 'wprss_custom_feed_item_bulk_actions' );
519
  /**
520
  * Allow filtering bulk actions for feed items
521
- *
522
  * @since 2.0
523
- */
524
  function wprss_custom_feed_item_bulk_actions( $actions ){
525
  return apply_filters( 'wprss_custom_feed_item_bulk_actions', $actions );
526
  }
@@ -529,14 +546,14 @@
529
  add_action( 'admin_footer-edit.php', 'wprss_remove_a_from_feed_title' );
530
  /**
531
  * Remove hyperlink from imported feed titles in list posts screen
532
- *
533
  * @since 2.0
534
- */
535
  function wprss_remove_a_from_feed_title() {
536
  if ( 'edit-wprss_feed_item' !== get_current_screen()->id )
537
  return;
538
  ?>
539
-
540
  <script type="text/javascript">
541
  jQuery('table.wp-list-table a.row-title').contents().unwrap();
542
  </script>
@@ -547,16 +564,16 @@
547
  add_filter( 'gettext', 'wprss_change_publish_button_text', 10, 2 );
548
  /**
549
  * Modify 'Publish' button text when adding a new feed source
550
- *
551
  * @since 2.0
552
- */
553
  function wprss_change_publish_button_text( $translation, $text ) {
554
  if ( 'wprss_feed' == get_post_type()) {
555
  if ( $text == 'Publish' )
556
  return __( 'Publish Feed', WPRSS_TEXT_DOMAIN );
557
  }
558
  return apply_filters( 'wprss_change_publish_button_text', $translation );
559
- }
560
 
561
 
562
 
1
+ <?php
2
  /**
3
+ * Functions for the admin section, columns and row actions
4
+ *
5
  * @package WP RSS Aggregator
6
+ */
7
 
8
 
9
+ add_filter( 'manage_wprss_feed_posts_columns', 'wprss_set_feed_custom_columns', 20, 1 );
10
+ /**
11
  * Set up the custom columns for the wprss_feed list
12
+ *
13
  * @since 2.0
14
+ */
15
  function wprss_set_feed_custom_columns( $columns ) {
16
 
17
  $columns = array(
30
  }
31
 
32
  return $columns;
33
+ }
34
 
35
 
36
  add_action( "manage_wprss_feed_posts_custom_column", "wprss_show_custom_columns", 10, 2 );
37
  /**
38
  * Show up the custom columns for the wprss_feed list
39
+ *
40
  * @since 2.0
41
+ */
42
  function wprss_show_custom_columns( $column, $post_id ) {
43
+
44
+ switch ( $column ) {
45
  case 'errors':
46
  $errors = get_post_meta( $post_id, 'wprss_error_last_import', true );
47
  $showClass = ( $errors !== '' )? 'wprss-show' : '';
48
  $default_msg = __( "This feed source experienced an error during the last feed fetch or validation check. Re-check the feed source URL or check the Error Log in the Debugging page for more details.", WPRSS_TEXT_DOMAIN );
49
  $msg = strlen( $errors ) > 0 ? $errors : $default_msg;
50
+ echo sprintf('<i title="%1$s" class="fa fa-warning fa-fw wprss-feed-error-symbol %2$s"></i>', esc_attr($msg), $showClass);
51
  break;
52
  case 'state':
53
  $active = wprss_is_feed_source_active( $post_id );
83
  if ( $update_interval === wprss_get_default_feed_source_update_interval() || $update_interval === '' ) {
84
  $next_update = wp_next_scheduled( 'wprss_fetch_all_feeds_hook', array() );
85
  }
86
+
87
  // Update the meta field
88
  if ( wprss_is_feed_source_active( $post_id ) ) {
89
  $next_update_text = $next_update === FALSE ? __( 'None', WPRSS_TEXT_DOMAIN ) : human_time_diff( $next_update, time() );
91
  $next_update_text = __( 'Paused', WPRSS_TEXT_DOMAIN );
92
  }
93
  update_post_meta( $post_id, 'wprss_next_update', $next_update_text );
94
+
95
  ?>
96
 
97
  <p>
127
 
128
  // Set meta field for items imported
129
  update_post_meta( $post_id, 'wprss_items_imported', $items->post_count );
130
+
131
  break;
132
  }
133
  }
136
  add_filter( "manage_edit-wprss_feed_sortable_columns", "wprss_feed_sortable_columns" );
137
  /**
138
  * Make the custom columns sortable for wprss_feed post type
139
+ *
140
  * @since 2.0
141
+ */
142
  function wprss_feed_sortable_columns() {
143
  $sortable_columns = array(
144
  // meta column id => sortby value used in query
154
  add_action( 'pre_get_posts', 'wprss_feed_source_order' );
155
  /**
156
  * Change order of feed sources to alphabetical ascending according to feed name
157
+ *
158
  * @since 2.2
159
+ */
160
  function wprss_feed_source_order( $query ) {
161
  // Check if the query is being processed in WP Admin, is the main query, and is targetted
162
  // for the wprss_feed CPT. If not, stop
165
  }
166
  // Check if the orderby query variable is set
167
  if ( !( $orderby = $query->get( 'orderby' ) ) ) return;
168
+
169
  // We will be sorting using the meta value (unless sorting by title)
170
  $query->set('orderby', 'meta_value' );
171
  // Get the current order
172
  $order = strtoupper( $query->get( 'order' ) );
173
  // Check if it is valid
174
  $got_order = $order === 'ASC' || $order === 'DESC';
175
+
176
  // Check what we are sorting by
177
  switch ( $orderby ) {
178
  case 'title':
192
  if ( !$got_order ) $query->set( 'order', 'DESC' );
193
  break;
194
  }
195
+
196
  if ( !$got_order ){
197
  $query->set( 'order', 'ASC' );
198
  }
199
  }
200
 
201
 
202
+ add_filter( 'manage_wprss_feed_item_posts_columns', 'wprss_set_feed_item_custom_columns', 20, 1 );
203
  /**
204
  * Set up the custom columns for the wprss_feed source list
205
+ *
206
  * @since 2.0
207
+ */
208
  function wprss_set_feed_item_custom_columns( $columns ) {
209
 
210
  $columns = array (
221
  add_action( "manage_wprss_feed_item_posts_custom_column", "wprss_show_feed_item_custom_columns", 10, 2 );
222
  /**
223
  * Show up the custom columns for the wprss_feed list
224
+ *
225
  * @since 2.0
226
+ */
227
  function wprss_show_feed_item_custom_columns( $column, $post_id ) {
228
+
229
+ switch ( $column ) {
230
  case "permalink":
231
  $url = get_post_meta( $post_id, 'wprss_item_permalink', true);
232
  echo '<a href="' . $url . '">' . $url. '</a>';
233
+ break;
234
+
235
  case "publishdate":
236
  $item_date = get_the_time( 'U', get_the_ID() );
237
  $item_date = ( $item_date === '' )? date('U') : $item_date;
238
+ $publishdate = date( 'Y-m-d H:i:s', $item_date ) ;
239
  echo $publishdate;
240
+ break;
241
+
242
+ case "source":
243
+ $query = new WP_Query();
244
+ $source = '<a href="' . get_edit_post_link( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '">' . get_the_title( get_post_meta( $post_id, 'wprss_feed_id', true ) ) . '</a>';
245
  echo $source;
246
+ break;
247
  }
248
  }
249
 
250
 
251
  add_filter( "manage_edit-wprss_feed_item_sortable_columns", "wprss_feed_item_sortable_columns" );
252
+ /**
253
  * Make the custom columns sortable
254
+ *
255
  * @since 2.0
256
+ */
257
  function wprss_feed_item_sortable_columns() {
258
  $sortable_columns = array(
259
  // meta column id => sortby value used in query
265
 
266
 
267
  add_action( 'pre_get_posts', 'wprss_feed_item_orderby' );
268
+ /**
269
  * Change ordering of posts on wprss_feed_item screen
270
+ *
271
  * @since 2.0
272
+ */
273
  function wprss_feed_item_orderby( $query ) {
274
  if( ! is_admin() )
275
  return;
276
+
277
  $post_type = $query->get('post_type');
278
+
279
  // If we're on the feed listing admin page
280
+ if ( $post_type == 'wprss_feed_item') {
281
  // Set general orderby to date the feed item was published
282
  $query->set('orderby','publishdate');
283
  // If user clicks on the reorder link, implement reordering
287
  $query->set( 'orderby', 'date' );
288
  }
289
  }
290
+ }
291
 
292
 
293
+ add_filter( 'post_updated_messages', 'wprss_feed_updated_messages' );
294
  /**
295
  * Change default notification message when new feed is added or updated
296
+ *
297
  * @since 2.0
298
+ */
299
  function wprss_feed_updated_messages( $messages ) {
300
  global $post, $post_ID;
301
 
304
  1 => __( 'Feed source updated. ', WPRSS_TEXT_DOMAIN ),
305
  2 => __( 'Custom field updated.', WPRSS_TEXT_DOMAIN ),
306
  3 => __( 'Custom field deleted.', WPRSS_TEXT_DOMAIN ),
307
+ 4 => __( 'Feed source updated.', WPRSS_TEXT_DOMAIN ),
308
  5 => '',
309
  6 => __( 'Feed source saved.', WPRSS_TEXT_DOMAIN ),
310
  7 => __( 'Feed source saved.', WPRSS_TEXT_DOMAIN ),
314
  );
315
 
316
  return apply_filters( 'wprss_feed_updated_messages', $messages );
317
+ }
318
 
319
 
320
  add_filter( 'post_row_actions', 'wprss_remove_row_actions', 10, 2 );
321
  /**
322
  * Remove actions row for imported feed items, we don't want them to be editable or viewable
323
+ *
324
  * @since 2.0
325
+ */
326
  function wprss_remove_row_actions( $actions, $post )
327
  {
328
+
329
  $page = isset( $_GET['paged'] )? '&paged=' . $_GET['paged'] : '';
330
  if ( get_post_type($post) === 'wprss_feed_item' ) {
331
  unset( $actions[ 'edit' ] );
337
  $actions = array_reverse( $actions );
338
  $actions['id'] = '<span class="wprss-row-id">' . sprintf( __( 'ID: %1$s', WPRSS_TEXT_DOMAIN ), $post->ID ) . '</span>';
339
  $actions = array_reverse( $actions );
340
+
341
  unset( $actions[ 'view'] );
342
  unset( $actions[ 'inline hide-if-no-js'] );
343
  if ( get_post_status( $post->ID ) !== 'trash' ) {
354
 
355
  $fetch_items_row_action_text = apply_filters( 'wprss_fetch_items_row_action_text', __( 'Fetch Items', WPRSS_TEXT_DOMAIN ) );
356
  $actions[ 'fetch' ] = '<a href="javascript:;" class="wprss_ajax_action" pid="'. $post->ID .'" purl="'.home_url().'/wp-admin/admin-ajax.php">' . $fetch_items_row_action_text . '</a>';
 
357
 
358
  $purge_feeds_row_action_text = apply_filters( 'wprss_purge_feeds_row_action_text', __( 'Delete Items', WPRSS_TEXT_DOMAIN ) );
359
  $purge_feeds_row_action_title = apply_filters( 'wprss_purge_feeds_row_action_title', __( 'Delete feed items imported by this feed source', WPRSS_TEXT_DOMAIN ) );
360
  $actions['purge-posts'] = "<a href='".admin_url("edit.php?post_type=wprss_feed&purge-feed-items=" . $post->ID . $page ) . "' title='" . $purge_feeds_row_action_title . "' >" . __( $purge_feeds_row_action_text, WPRSS_TEXT_DOMAIN ) . "</a>";
361
+
362
  $actions['trash'] = $trash;
363
  }
364
  }
369
  add_action( 'admin_init', 'check_delete_for_feed_source' );
370
  /**
371
  * Checks the GET data for the delete per feed source action request
372
+ *
373
  * @since 3.5
374
  */
375
  function check_delete_for_feed_source( $source_id = NULL ) {
406
  add_action( 'wprss_delete_feed_items_from_source_hook', 'wprss_delete_feed_items_of_feed_source', 10 , 1 );
407
  /**
408
  * Deletes the feed items of the feed source identified by the given ID.
409
+ *
410
  * @param $source_id The ID of the feed source
411
  * @since 3.5
412
  */
439
 
440
  /**
441
  * Shows a notification that tells the user that feed items for a particular source are being deleted
442
+ *
443
  * @since 3.5
444
  */
445
  function wprss_notify_about_deleting_source_feed_items() {
472
  }
473
 
474
  // Verify admin referer
475
+ if (!wprss_verify_nonce( 'wprss_feed_source_action', 'wprss_admin_ajax_nonce' )) {
476
  throw new Exception($wprss->__(array('Could not schedule fetch for source #%1$s: nonce is expired', $id)));
477
  }
478
 
514
  }
515
 
516
 
517
+ add_action('manage_posts_extra_tablenav', function($which) {
518
+ $screen = get_current_screen();
519
+ $postType = $screen->post_type;
520
+ // Only add on feed source list
521
+ if ($postType !== 'wprss_feed') {
522
+ return;
523
+ }
524
+
525
+ $nonceEl = new \Aventura\Wprss\Core\Block\Html\Span(array(
526
+ 'data-value' => wp_create_nonce('wprss_feed_source_action'),
527
+ 'id' => 'wprss_feed_source_action_nonce',
528
+ 'class' => 'hidden'
529
+ ));
530
+ echo (string) $nonceEl;
531
+ // wp_nonce_field('wprss_feed_source_action', 'wprss_feed_source_action_nonce', false);
532
+ });
533
+
534
+
535
  add_filter( 'bulk_actions-edit-wprss_feed_item', 'wprss_custom_feed_item_bulk_actions' );
536
  /**
537
  * Allow filtering bulk actions for feed items
538
+ *
539
  * @since 2.0
540
+ */
541
  function wprss_custom_feed_item_bulk_actions( $actions ){
542
  return apply_filters( 'wprss_custom_feed_item_bulk_actions', $actions );
543
  }
546
  add_action( 'admin_footer-edit.php', 'wprss_remove_a_from_feed_title' );
547
  /**
548
  * Remove hyperlink from imported feed titles in list posts screen
549
+ *
550
  * @since 2.0
551
+ */
552
  function wprss_remove_a_from_feed_title() {
553
  if ( 'edit-wprss_feed_item' !== get_current_screen()->id )
554
  return;
555
  ?>
556
+
557
  <script type="text/javascript">
558
  jQuery('table.wp-list-table a.row-title').contents().unwrap();
559
  </script>
564
  add_filter( 'gettext', 'wprss_change_publish_button_text', 10, 2 );
565
  /**
566
  * Modify 'Publish' button text when adding a new feed source
567
+ *
568
  * @since 2.0
569
+ */
570
  function wprss_change_publish_button_text( $translation, $text ) {
571
  if ( 'wprss_feed' == get_post_type()) {
572
  if ( $text == 'Publish' )
573
  return __( 'Publish Feed', WPRSS_TEXT_DOMAIN );
574
  }
575
  return apply_filters( 'wprss_change_publish_button_text', $translation );
576
+ }
577
 
578
 
579
 
includes/admin-help-metaboxes.php CHANGED
@@ -34,6 +34,11 @@
34
 
35
  '. 'This can be useful in cases where permalinks change, or where multiple permalinks refer to the same item.', WPRSS_TEXT_DOMAIN),
36
 
 
 
 
 
 
37
 
38
  /* -------------------------
39
  * Feed Processing Metabox
34
 
35
  '. 'This can be useful in cases where permalinks change, or where multiple permalinks refer to the same item.', WPRSS_TEXT_DOMAIN),
36
 
37
+ 'wprss_source_link' => __('Enable this option to link the feed source name to the RSS feed\'s source site.
38
+
39
+ ' . 'Selecting "Default" will cause the value chosen in the general Source Display Settings to be used.
40
+
41
+ ' . 'This option only applies when using the shortcode to output feed items.', WPRSS_TEXT_DOMAIN),
42
 
43
  /* -------------------------
44
  * Feed Processing Metabox
includes/admin-help-settings.php CHANGED
@@ -3,6 +3,7 @@
3
  add_action( 'plugins_loaded', 'wprss_settings_add_tooltips', 11 );
4
  function wprss_settings_add_tooltips() {
5
  if( class_exists('WPRSS_Help') ) {
 
6
  $help = WPRSS_Help::get_instance();
7
 
8
  // Feed source setting fields
@@ -144,5 +145,20 @@ function wprss_settings_add_tooltips() {
144
 
145
  );
146
  $help->add_tooltips( $tooltips, $prefix );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
147
  }
148
  }
3
  add_action( 'plugins_loaded', 'wprss_settings_add_tooltips', 11 );
4
  function wprss_settings_add_tooltips() {
5
  if( class_exists('WPRSS_Help') ) {
6
+ $wprss = wprss();
7
  $help = WPRSS_Help::get_instance();
8
 
9
  // Feed source setting fields
145
 
146
  );
147
  $help->add_tooltips( $tooltips, $prefix );
148
+
149
+ // Feed source specific
150
+ $prefix = 'field_';
151
+ $help->add_tooltips(array(
152
+ WPRSS_Feed_Access::SETTING_KEY_FEED_REQUEST_USERAGENT => $wprss->__( array('The string to be used as the useragent for feed requests.
153
+
154
+ '. 'If non-empty, this exact string will be sent with every request made by %1$s for a feed source XML document.
155
+
156
+ '. 'Leave this empty to inherit the general setting.
157
+
158
+ '. 'Some servers react in unexpected ways to the default value. In such cases, try changing this to something else.
159
+
160
+ '. 'The default value is determined by the SimplePie library, and reflects its name, version and build numbers, and some other information.',
161
+ $wprss->getName()))
162
+ ), $prefix);
163
  }
164
  }
includes/admin-help.php CHANGED
@@ -354,13 +354,41 @@ class WPRSS_Help {
354
  return self::$_instance;
355
  }
356
 
357
-
358
- public static function init() {
359
- // Actions
 
 
 
360
  add_action( 'admin_enqueue_scripts', array( self::get_instance(), '_admin_enqueue_scripts' ) );
361
  add_action( 'admin_footer', array( self::get_instance(), '_admin_footer' ) );
 
362
  }
363
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
364
 
365
  /**
366
  * Filters used:
@@ -519,7 +547,12 @@ class WPRSS_Help {
519
  *
520
  * @return WPRSS_Help This instance.
521
  */
522
- public function _admin_enqueue_scripts() {
 
 
 
 
 
523
  $scripts = $this->apply_filters( 'admin_scripts', array(
524
  'jquery-ui-tooltip' => array()
525
  ));
354
  return self::$_instance;
355
  }
356
 
357
+ /**
358
+ * @since 4.10
359
+ */
360
+ public static function init()
361
+ {
362
+ if (static::get_instance()->_isEnqueueScripts()) {
363
  add_action( 'admin_enqueue_scripts', array( self::get_instance(), '_admin_enqueue_scripts' ) );
364
  add_action( 'admin_footer', array( self::get_instance(), '_admin_footer' ) );
365
+ }
366
  }
367
 
368
+ /**
369
+ * Determines if the admin scripts should get enqueued.
370
+ *
371
+ * @since 4.10
372
+ *
373
+ * @return bool True if admin scripts should be enqueued; false otherwise.
374
+ */
375
+ protected function _isEnqueueScripts()
376
+ {
377
+ return $this->_isWprssPage();
378
+ }
379
+
380
+ /**
381
+ * Determines if the current page is related to WPRSS.
382
+ *
383
+ * @since 4.10
384
+ *
385
+ * @return bool True if the current page is related to WPRSS; false otherwise.
386
+ */
387
+ protected function _isWprssPage()
388
+ {
389
+ return wprss_is_wprss_page();
390
+ }
391
+
392
 
393
  /**
394
  * Filters used:
547
  *
548
  * @return WPRSS_Help This instance.
549
  */
550
+ public function _admin_enqueue_scripts()
551
+ {
552
+ if (!wprss_is_wprss_page()) {
553
+ return $this;
554
+ }
555
+
556
  $scripts = $this->apply_filters( 'admin_scripts', array(
557
  'jquery-ui-tooltip' => array()
558
  ));
includes/admin-log.php CHANGED
@@ -1,292 +1,443 @@
1
  <?php
 
 
 
 
 
 
 
 
2
 
3
- define( 'WPRSS_LOG_DISPLAY_LIMIT', 100000 ); // Number of chars to display in log
4
- define( 'WPRSS_OPTION_CODE_LOG_LEVEL', 'log_level' );
5
- define( 'WPRSS_LOG_LEVEL_NONE', 0 );
6
- define( 'WPRSS_LOG_LEVEL_SYSTEM', 1 );
7
- define( 'WPRSS_LOG_LEVEL_INFO', 2 );
8
- define( 'WPRSS_LOG_LEVEL_NOTICE', 4 );
9
- define( 'WPRSS_LOG_LEVEL_WARNING', 8 );
10
- define( 'WPRSS_LOG_LEVEL_ERROR', 16 );
11
- define( 'WPRSS_LOG_LEVEL_DEFAULT', 'default' );
12
-
13
-
14
- /**
15
- * Returns the log file path.
16
- *
17
- * @since 4.0.4
18
- */
19
- function wprss_log_file() {
20
- return WPRSS_LOG_FILE . '-' . get_current_blog_id() . WPRSS_LOG_FILE_EXT;
21
- }
22
-
23
-
24
- /**
25
- * Clears the log file.
26
- *
27
- * @since 3.9.6
28
- */
29
- function wprss_clear_log() {
30
- file_put_contents( wprss_log_file(), '' );
31
- }
32
-
33
-
34
- /**
35
- * Alias for wprss_clear_log(). Used for code readability.
36
- *
37
- * @since 3.9.6
38
- */
39
- function wprss_reset_log() {
40
- wprss_clear_log();
41
- }
42
-
43
- /**
44
- * Gets log level from the database.
45
- * @return string The string representing the log level threshold or type.
46
- */
47
- function wprss_log_get_level_db() {
48
- return wprss_get_general_setting( WPRSS_OPTION_CODE_LOG_LEVEL );
49
- }
50
-
51
- /**
52
- * Gets log level used.
53
- * @return string The string representing the log level threshold.
54
- */
55
- function wprss_log_get_level() {
56
- $log_level = wprss_log_get_level_db();
57
- if ( $log_level === WPRSS_LOG_LEVEL_DEFAULT )
58
- $log_level = WPRSS_LOG_LEVEL;
59
-
60
- return apply_filters( 'wprss_log_level', $log_level );
61
- }
62
-
63
-
64
- /**
65
- * Check whether or not the specified logging level is the same as, or one of (only for positive),
66
- * the currently used logging level.
67
- *
68
- * @param int $log_level The log level to check. Must be an unsiged whole number.
69
- */
70
- function wprss_log_is_level( $log_level, $used_log_level = null ) {
71
- $used_log_level = is_null( $used_log_level ) ? wprss_log_get_level() : $used_log_level;
72
-
73
- if( is_numeric( $log_level ) ) {
74
- $log_level = intval( $log_level );
75
- $used_log_level = intval( $used_log_level );
76
-
77
- return ($log_level > 0 && $used_log_level > 0)
78
- // Mostly for the case of 0
79
- ? intval( $log_level ) & intval( $used_log_level )
80
- : $log_level === $used_log_level;
81
- }
82
-
83
- return trim( $log_level ) === trim( $used_log_level );
84
- }
85
-
86
-
87
- /**
88
- * Check whether or not messages with the specified logging level should be logged.
89
- *
90
- * @param int $log_level The log level to check. Must be an unsigned whole number
91
- * @return bool True if messages with the specified logging level should be logged; false otherwise.
92
- */
93
- function wprss_log_is_logging_level( $log_level ) {
94
- $original_used_level = $used_log_level = wprss_log_get_level();
95
-
96
- // Whether to use the indicated level and below
97
- $is_below = ( substr( $used_log_level, 0, 1 ) === '-' );
98
- if ( $is_below )
99
- $used_log_level = substr( $used_log_level, 1 );
100
-
101
- if( (int)$used_log_level === WPRSS_LOG_LEVEL_NONE ) {
102
- $is_log_level = WPRSS_LOG_LEVEL_NONE;
103
- }
104
- else {
105
- $is_log_level = $is_below
106
- ? ((int)$log_level <= (int)$used_log_level && (int)$log_level !== WPRSS_LOG_LEVEL_NONE)
107
- : wprss_log_is_level( (int)$log_level, $used_log_level );
108
- }
109
-
110
- return apply_filters( 'wprss_is_logging_level', $is_log_level, $log_level, $used_log_level, $is_below );
111
- }
112
-
113
-
114
- /**
115
- * Get the available log levels.
116
- *
117
- * @param bool $levels_only Whether or not only numeric actual levels are to be returned.
118
- * If false, returns other types as well.
119
- * @return array An array, where key is level, and value is level's human-readable name
120
- */
121
- function wprss_log_get_levels( $levels_only = true ) {
122
- $log_levels = array(
123
- WPRSS_LOG_LEVEL_NONE => 'None',
124
- WPRSS_LOG_LEVEL_SYSTEM => 'System',
125
- WPRSS_LOG_LEVEL_INFO => 'Info',
126
- WPRSS_LOG_LEVEL_NOTICE => 'Notice',
127
- WPRSS_LOG_LEVEL_WARNING => 'Warning',
128
- WPRSS_LOG_LEVEL_ERROR => 'Error'
129
- );
130
-
131
- if( !$levels_only )
132
- $log_levels[ WPRSS_LOG_LEVEL_DEFAULT ] = 'Default';
133
-
134
- return apply_filters( 'wprss_log_levels', $log_levels, $levels_only );
135
- }
136
-
137
-
138
- /**
139
- *
140
- * @param string|int $level Any valid level value.
141
- * @return string The untranslated label of the specified level, or $default if no such level exists.
142
- */
143
- function wprss_log_get_level_label( $level, $default = 'N/A' ) {
144
- $levels = wprss_log_get_levels( false );
145
- return isset( $levels[$level] ) ? $levels[ $level ] : $default;
146
- }
147
-
148
-
149
- /**
150
- * Adds a log entry to the log file.
151
- *
152
- * @since 3.9.6
153
- */
154
- function wprss_log( $message, $src = NULL, $log_level = WPRSS_LOG_LEVEL_ERROR ) {
155
- if( !wprss_log_is_logging_level( $log_level ) ) return;
156
-
157
- if ( $src === NULL ) {
158
- $callers = debug_backtrace();
159
- $src = $callers[1]['function'];
160
- if ( $src === 'wprss_log_obj' ) {
161
- $src = $callers[2]['function'];
162
- }
163
- }
164
- $log_level_label = wprss_log_get_level_label( $log_level );
165
- $date = date( 'd-m-Y H:i:s' );
166
- $source = 'WPRSS' . ( ( strlen( $src ) > 0 )? " > $src" : '' ) ;
167
- $str = "[$date] [$log_level_label] $source:\n";
168
- $str .= "$message\n\n";
169
- file_put_contents( wprss_log_file() , $str, FILE_APPEND );
170
-
171
- add_action( 'shutdown', 'wprss_log_separator' );
172
- }
173
-
174
-
175
- /**
176
- * Dumps an object to the log file.
177
- *
178
- * @since 3.9.6
179
- */
180
- function wprss_log_obj( $message, $obj, $src = '', $log_level = WPRSS_LOG_LEVEL_ERROR ) {
181
- wprss_log( "$message: " . print_r( $obj, TRUE ), $src, $log_level );
182
- }
183
-
184
-
185
- /**
186
- * Returns the contents of the log file.
187
- *
188
- * @since 3.9.6
189
- */
190
- function wprss_get_log() {
191
- if ( !file_exists( wprss_log_file() ) ) {
192
- wprss_clear_log();
193
- }
194
- $contents = file_get_contents( wprss_log_file() , '' );
195
- // Trim the log file to a fixed number of chars
196
- $limit = WPRSS_LOG_DISPLAY_LIMIT;
197
- if ( strlen( $contents ) > $limit ) {
198
- file_put_contents( wprss_log_file(), substr( $contents, 0, $limit ) );
199
- return wprss_get_log();
200
- } else {
201
- return $contents;
202
- }
203
- }
204
-
205
-
206
- /**
207
- * Downloads the log file.
208
- *
209
- * @since 4.7.8
210
- */
211
- function wprss_download_log() {
212
- if ( !file_exists( wprss_log_file() ) ) {
213
- wprss_clear_log();
214
- }
215
- else {
216
- $file = wprss_log_file();
217
- header( 'Content-Description: File Transfer' );
218
- header( 'Content-type: text/plain' );
219
- header( 'Content-Disposition: attachment; filename="error-log.txt"' );
220
- header( 'Expires: 0' );
221
- header( 'Cache-Control: must-revalidate' );
222
- header( 'Pragma: public' );
223
- header( 'Content-Length: ' . filesize( $file ) );
224
- readfile( $file );
225
- exit;
226
- }
227
- }
228
-
229
-
230
- /**
231
- * Adds an empty line at the end of the log file.
232
- *
233
- * This function is called on wordpress shutdown, if at least one new line
234
- * is logged in the log file, to separate logs from different page loads.
235
- *
236
- * @since 3.9.6
237
- */
238
- function wprss_log_separator() {
239
- file_put_contents( wprss_log_file(), "\n", FILE_APPEND );
240
- }
241
-
242
-
243
- /**
244
- * Adding the default setting value.
245
- */
246
- add_filter( 'wprss_default_settings_general', 'wprss_log_default_settings_general' );
247
- function wprss_log_default_settings_general( $settings ) {
248
- /* @todo Add version info */
249
- $settings[ WPRSS_OPTION_CODE_LOG_LEVEL ] = WPRSS_LOG_LEVEL_DEFAULT;
250
- return $settings;
251
- }
252
-
253
-
254
- /**
255
- * Adding the setting field
256
- */
257
- add_filter( 'wprss_settings_array', 'wprss_log_settings_array' );
258
- function wprss_log_settings_array( $sections ) {
259
- $sections['general'][ WPRSS_OPTION_CODE_LOG_LEVEL ] = array(
260
- 'label' => __( 'Log level threshold', WPRSS_TEXT_DOMAIN ),
261
- 'callback' => 'wprss_setting_' . WPRSS_OPTION_CODE_LOG_LEVEL . '_callback'
262
- );
263
- return $sections;
264
- }
265
-
266
-
267
- /**
268
- * Renders the 'log_level' setting field.
269
- *
270
- * @param array $field Info about the field
271
- */
272
- function wprss_setting_log_level_callback( $field ) {
273
- $log_level = wprss_get_general_setting( $field['field_id'] );
274
-
275
- foreach( wprss_log_get_levels( false ) as $_level => $_label ) {
276
- $options[ $_level ] = $_label;
277
- if( is_numeric( $_level ) && ($_level/2 >= 1) ) $options[ (int)$_level * -1 ] = $_label . ' and below';
278
- }
279
-
280
- krsort( $options, defined( 'SORT_NATURAL' ) ? SORT_NATURAL : SORT_STRING );
281
- ?>
282
- <select id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]">
283
- <?php
284
- foreach( $options as $value => $text ) {
285
- $selected = ( (string)$value === (string)$log_level )? 'selected="selected"' : '';
286
- ?><option value="<?php echo $value ?>" <?php echo $selected ?>><?php echo __( $text, WPRSS_TEXT_DOMAIN ) ?></option><?php
287
- }
288
- ?>
289
- </select>
290
- <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
291
- }
292
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  <?php
2
+ define( 'WPRSS_OPTION_CODE_LOG_LEVEL', 'log_level' );
3
+ define( 'WPRSS_LOG_LEVEL_NONE', 0 );
4
+ define( 'WPRSS_LOG_LEVEL_SYSTEM', 1 );
5
+ define( 'WPRSS_LOG_LEVEL_INFO', 2 );
6
+ define( 'WPRSS_LOG_LEVEL_NOTICE', 4 );
7
+ define( 'WPRSS_LOG_LEVEL_WARNING', 8 );
8
+ define( 'WPRSS_LOG_LEVEL_ERROR', 16 );
9
+ define( 'WPRSS_LOG_LEVEL_DEFAULT', 'default' );
10
 
11
+ if (!defined('WPRSS_LOG_FILENAME_SEPARATOR'))
12
+ define('WPRSS_LOG_FILENAME_SEPARATOR', '_');
13
+
14
+ if (!defined('WPRSS_LOG_FILENAME_CONCATENATOR'))
15
+ define('WPRSS_LOG_FILENAME_CONCATENATOR', '-');
16
+
17
+ // Number of chars to display in log
18
+ if (!defined('WPRSS_LOG_DISPLAY_LIMIT'))
19
+ define( 'WPRSS_LOG_DISPLAY_LIMIT', 100000 ); // 100Kb
20
+
21
+
22
+ /**
23
+ * Returns the log file path.
24
+ *
25
+ * @since 4.0.4
26
+ */
27
+ function wprss_log_file()
28
+ {
29
+ return WPRSS_LOG_FILE . wprss_log_suffix() . WPRSS_LOG_FILE_EXT;
30
+ }
31
+
32
+ /**
33
+ * Writes a message to the log file.
34
+ *
35
+ * If directories on the log filepath don't exist, creates them.
36
+ *
37
+ * @since 4.10
38
+ *
39
+ * @param string $message The message to write to the log.
40
+ * @param int $flags Flags to be used with {@see file_put_contents()} for writing.
41
+ * @return bool True if message written successfully; false otherwise.
42
+ */
43
+ function wprss_log_write($message, $flags = 0)
44
+ {
45
+ $file = wprss_log_file();
46
+ $dir = dirname($file);
47
+ if (!file_exists($dir)) {
48
+ if (!wp_mkdir_p($dir)) {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ return file_put_contents($file, $message, $flags);
54
+ }
55
+
56
+ /**
57
+ * Reads a certain amount of data from the log file.
58
+ *
59
+ * By default, reads that data from the end of the file.
60
+ *
61
+ * @since 4.10
62
+ *
63
+ * @param null|int $length How many characters at most to read from the log.
64
+ * Default: {@see WPRSS_LOG_DISPLAY_LIMIT}.
65
+ * @param null|int $start Position, at which to start reading.
66
+ * If negative, represents that number of chars from the end.
67
+ * Default: The amount of characters equal to $length away from the end of the file,
68
+ * or the beginning of the file if the size of the file is less than or equal to $length.
69
+ *
70
+ * @return string|bool The content of the log, or false if the read operation failed.
71
+ */
72
+ function wprss_log_read($length = null, $start = null)
73
+ {
74
+ $origStart = $start;
75
+
76
+ if (is_null($length)) {
77
+ $length = WPRSS_LOG_DISPLAY_LIMIT;
78
+ }
79
+
80
+ $file = wprss_log_file();
81
+
82
+ if (!($fh = fopen($file, 'r'))) {
83
+ return false;
84
+ }
85
+
86
+ $info = fstat($fh);
87
+ $size = $info['size'];
88
+
89
+ if ($size === 0 || $length === 0) {
90
+ return '';
91
+ }
92
+
93
+ // Can't read more than the length of the file
94
+ if ($length > $size) {
95
+ $length = $size;
96
+ }
97
+
98
+ // Default start is length before end
99
+ if (is_null($start)) {
100
+ $start = -$length;
101
+ }
102
+
103
+ // Allowing negative
104
+ if ($start < 0) {
105
+ $start = $size - abs($start);
106
+ }
107
+
108
+ // Can't start before start of file
109
+ if ($start < 0) {
110
+ $start = 0;
111
+ }
112
+
113
+ // If reading over EOF,
114
+ $end = $start + $length;
115
+ if ($end > $size) {
116
+ $over = $end - $size;
117
+ // If start is not fixed, shift start to allow reading as much length as possible
118
+ if (is_null($origStart)) {
119
+ $start = $start - $over;
120
+ }
121
+ // If start is fixed, shift length to allow reading from start until end
122
+ else {
123
+ $length = $length - $over;
124
+ }
125
+ }
126
+
127
+ // Can't start before start of file
128
+ if ($start < 0) {
129
+ $start = 0;
130
+ }
131
+
132
+ // Returns 0 when failed
133
+ if (fseek($fh, $start)) {
134
+ return false;
135
+ }
136
+
137
+ $str = fread($fh, $length);
138
+ fclose($fh);
139
+
140
+ return $str;
141
+ }
142
+
143
+ /**
144
+ * Determines a suffix for a log file based on context and some globally accessible variables.
145
+ *
146
+ * @since 4.10
147
+ *
148
+ * @param array $context Options for the suffix.
149
+ * Default: ['blog_id' => {{current blog id}}]
150
+ *
151
+ * @return string The log file suffix. Prefixed with separator.
152
+ */
153
+ function wprss_log_suffix(array $context = null)
154
+ {
155
+ if (is_null($context)) {
156
+ $context = array('blog_id' => get_current_blog_id());
157
+ }
158
+
159
+ $s = WPRSS_LOG_FILENAME_SEPARATOR;
160
+ $c = WPRSS_LOG_FILENAME_CONCATENATOR;
161
+ $parts = array();
162
+
163
+ if (isset($context['blog_id'])) {
164
+ $parts[] = 'blg' . $c . $context['blog_id'];
165
+ }
166
+
167
+ $suffix = $s . implode($s, $parts);
168
+ $suffix = apply_filters('wprss_log_suffix', $suffix, $context);
169
+
170
+ return $suffix;
171
+ }
172
+
173
+ /**
174
+ * Clears the log file.
175
+ *
176
+ * @since 3.9.6
177
+ */
178
+ function wprss_clear_log()
179
+ {
180
+ wprss_log_write( '' );
181
+ }
182
+
183
+ /**
184
+ * Alias for wprss_clear_log().
185
+ *
186
+ * Used for code readability.
187
+ *
188
+ * @since 3.9.6
189
+ */
190
+ function wprss_reset_log()
191
+ {
192
+ wprss_clear_log();
193
+ }
194
+
195
+ /**
196
+ * Gets log level from the database.
197
+ * @return string The string representing the log level threshold or type.
198
+ */
199
+ function wprss_log_get_level_db()
200
+ {
201
+ return wprss_get_general_setting( WPRSS_OPTION_CODE_LOG_LEVEL );
202
+ }
203
+
204
+ /**
205
+ * Gets log level used.
206
+ * @return string The string representing the log level threshold.
207
+ */
208
+ function wprss_log_get_level()
209
+ {
210
+ $log_level = wprss_log_get_level_db();
211
+ if ( $log_level === WPRSS_LOG_LEVEL_DEFAULT ) {
212
+ $log_level = WPRSS_LOG_LEVEL;
213
+ }
214
+
215
+ return apply_filters( 'wprss_log_level', $log_level );
216
+ }
217
+
218
+ /**
219
+ * Check whether or not the specified logging level is the same as, or one of (only for positive),
220
+ * the currently used logging level.
221
+ *
222
+ * @param int $log_level The log level to check. Must be an unsigned whole number.
223
+ */
224
+ function wprss_log_is_level( $log_level, $used_log_level = null )
225
+ {
226
+ $used_log_level = is_null( $used_log_level ) ? wprss_log_get_level() : $used_log_level;
227
+
228
+ if( is_numeric( $log_level ) ) {
229
+ $log_level = intval( $log_level );
230
+ $used_log_level = intval( $used_log_level );
231
+
232
+ return ($log_level > 0 && $used_log_level > 0)
233
+ // Mostly for the case of 0
234
+ ? intval( $log_level ) & intval( $used_log_level )
235
+ : $log_level === $used_log_level;
236
+ }
237
+
238
+ return trim( $log_level ) === trim( $used_log_level );
239
+ }
240
+
241
+ /**
242
+ * Check whether or not messages with the specified logging level should be logged.
243
+ *
244
+ * @param int $log_level The log level to check. Must be an unsigned whole number
245
+ * @return bool True if messages with the specified logging level should be logged; false otherwise.
246
+ */
247
+ function wprss_log_is_logging_level( $log_level )
248
+ {
249
+ $original_used_level = $used_log_level = wprss_log_get_level();
250
+
251
+ // Whether to use the indicated level and below
252
+ $is_below = ( substr( $used_log_level, 0, 1 ) === '-' );
253
+ if ( $is_below ) {
254
+ $used_log_level = substr( $used_log_level, 1 );
255
+ }
256
+
257
+ if( (int)$used_log_level === WPRSS_LOG_LEVEL_NONE ) {
258
+ $is_log_level = WPRSS_LOG_LEVEL_NONE;
259
+ }
260
+ else {
261
+ $is_log_level = $is_below
262
+ ? ((int)$log_level <= (int)$used_log_level && (int)$log_level !== WPRSS_LOG_LEVEL_NONE)
263
+ : wprss_log_is_level( (int)$log_level, $used_log_level );
264
+ }
265
+
266
+ return apply_filters( 'wprss_is_logging_level', $is_log_level, $log_level, $used_log_level, $is_below );
267
+ }
268
+
269
+ /**
270
+ * Get the available log levels.
271
+ *
272
+ * @param bool $levels_only Whether or not only numeric actual levels are to be returned.
273
+ * If false, returns other types as well.
274
+ * @return array An array, where key is level, and value is level's human-readable name.
275
+ */
276
+ function wprss_log_get_levels( $levels_only = true )
277
+ {
278
+ $log_levels = array(
279
+ WPRSS_LOG_LEVEL_NONE => 'None',
280
+ WPRSS_LOG_LEVEL_SYSTEM => 'System',
281
+ WPRSS_LOG_LEVEL_INFO => 'Info',
282
+ WPRSS_LOG_LEVEL_NOTICE => 'Notice',
283
+ WPRSS_LOG_LEVEL_WARNING => 'Warning',
284
+ WPRSS_LOG_LEVEL_ERROR => 'Error'
285
+ );
286
+
287
+ if( !$levels_only ) {
288
+ $log_levels[ WPRSS_LOG_LEVEL_DEFAULT ] = 'Default';
289
+ }
290
+
291
+ return apply_filters( 'wprss_log_levels', $log_levels, $levels_only );
292
+ }
293
+
294
+ /**
295
+ *
296
+ * @param string|int $level Any valid level value.
297
+ * @return string The untranslated label of the specified level, or $default if no such level exists.
298
+ */
299
+ function wprss_log_get_level_label( $level, $default = 'N/A' )
300
+ {
301
+ $levels = wprss_log_get_levels( false );
302
+ return isset( $levels[$level] ) ? $levels[ $level ] : $default;
303
+ }
304
+
305
+ /**
306
+ * Adds a log entry to the log file.
307
+ *
308
+ * @since 3.9.6
309
+ */
310
+ function wprss_log( $message, $src = NULL, $log_level = WPRSS_LOG_LEVEL_ERROR )
311
+ {
312
+ if( !wprss_log_is_logging_level( $log_level ) ) return;
313
+
314
+ if ( $src === NULL ) {
315
+ $callers = debug_backtrace();
316
+ $src = $callers[1]['function'];
317
+ if ( $src === 'wprss_log_obj' ) {
318
+ $src = $callers[2]['function'];
319
+ }
320
+ }
321
+
322
+ $log_level_label = wprss_log_get_level_label( $log_level );
323
+ $date = date( 'd-m-Y H:i:s' );
324
+ $source = 'WPRSS' . ( ( strlen( $src ) > 0 )? " > $src" : '' ) ;
325
+ $str = "[$date] [$log_level_label] $source:\n";
326
+ $str .= "$message\n\n";
327
+ wprss_log_write( $str, FILE_APPEND );
328
+
329
+ add_action( 'shutdown', 'wprss_log_separator' );
330
+ }
331
+
332
+ /**
333
+ * Dumps an object to the log file.
334
+ *
335
+ * @since 3.9.6
336
+ */
337
+ function wprss_log_obj( $message, $obj, $src = '', $log_level = WPRSS_LOG_LEVEL_ERROR )
338
+ {
339
+ wprss_log( "$message: " . print_r( $obj, TRUE ), $src, $log_level );
340
+ }
341
+
342
+ /**
343
+ * Returns the contents of the log file.
344
+ *
345
+ * @since 3.9.6
346
+ */
347
+ function wprss_get_log() {
348
+ if ( !file_exists( wprss_log_file() ) ) {
349
+ wprss_clear_log();
350
+ }
351
+
352
+ $log = wprss_log_read();
353
+
354
+ return $log;
355
+ }
356
+
357
+ /**
358
+ * Downloads the log file.
359
+ *
360
+ * @since 4.7.8
361
+ */
362
+ function wprss_download_log()
363
+ {
364
+ if ( !file_exists( wprss_log_file() ) ) {
365
+ wprss_clear_log();
366
+ }
367
+ else {
368
+ $file = wprss_log_file();
369
+ header( 'Content-Description: File Transfer' );
370
+ header( 'Content-type: text/plain' );
371
+ header( 'Content-Disposition: attachment; filename="error-log.txt"' );
372
+ header( 'Expires: 0' );
373
+ header( 'Cache-Control: must-revalidate' );
374
+ header( 'Pragma: public' );
375
+ header( 'Content-Length: ' . filesize( $file ) );
376
+ readfile( $file );
377
+ exit;
378
+ }
379
+ }
380
+
381
+ /**
382
+ * Adds an empty line at the end of the log file.
383
+ *
384
+ * This function is called on WordPress shutdown, if at least one new line
385
+ * is logged in the log file, to separate logs from different page loads.
386
+ *
387
+ * @since 3.9.6
388
+ */
389
+ function wprss_log_separator()
390
+ {
391
+ wprss_log_write( "\n", FILE_APPEND );
392
+ }
393
+
394
+ /**
395
+ * Adding the default setting value.
396
+ */
397
+ add_filter( 'wprss_default_settings_general', 'wprss_log_default_settings_general' );
398
+ function wprss_log_default_settings_general( $settings )
399
+ {
400
+ /* @todo Add version info */
401
+ $settings[ WPRSS_OPTION_CODE_LOG_LEVEL ] = WPRSS_LOG_LEVEL_DEFAULT;
402
+ return $settings;
403
+ }
404
+
405
+ /**
406
+ * Adding the setting field
407
+ */
408
+ add_filter( 'wprss_settings_array', 'wprss_log_settings_array' );
409
+ function wprss_log_settings_array( $sections )
410
+ {
411
+ $sections['general'][ WPRSS_OPTION_CODE_LOG_LEVEL ] = array(
412
+ 'label' => __( 'Log level threshold', WPRSS_TEXT_DOMAIN ),
413
+ 'callback' => 'wprss_setting_' . WPRSS_OPTION_CODE_LOG_LEVEL . '_callback'
414
+ );
415
+ return $sections;
416
+ }
417
+
418
+ /**
419
+ * Renders the 'log_level' setting field.
420
+ *
421
+ * @param array $field Info about the field
422
+ */
423
+ function wprss_setting_log_level_callback( $field )
424
+ {
425
+ $log_level = wprss_get_general_setting( $field['field_id'] );
426
+
427
+ foreach( wprss_log_get_levels( false ) as $_level => $_label ) {
428
+ $options[ $_level ] = $_label;
429
+ if( is_numeric( $_level ) && ($_level/2 >= 1) ) $options[ (int)$_level * -1 ] = $_label . ' and below';
430
+ }
431
+
432
+ krsort( $options, defined( 'SORT_NATURAL' ) ? SORT_NATURAL : SORT_STRING );
433
+ ?>
434
+ <select id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]">
435
+ <?php
436
+ foreach( $options as $value => $text ) {
437
+ $selected = ( (string)$value === (string)$log_level )? 'selected="selected"' : '';
438
+ ?><option value="<?php echo $value ?>" <?php echo $selected ?>><?php echo __( $text, WPRSS_TEXT_DOMAIN ) ?></option><?php
439
+ }
440
+ ?>
441
+ </select>
442
+ <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
443
+ }
includes/admin-metaboxes.php CHANGED
@@ -113,6 +113,12 @@
113
  'type' => 'checkbox'
114
  );
115
 
 
 
 
 
 
 
116
  // for extensibility, allows more meta fields to be added
117
  return apply_filters( 'wprss_fields', $wprss_meta_fields );
118
  }
@@ -218,6 +224,16 @@
218
  }
219
  break;
220
 
 
 
 
 
 
 
 
 
 
 
221
  // number
222
  case 'number':
223
  ?><input class="wprss-number-roller" type="number" placeholder="<?php _e( 'Default', WPRSS_TEXT_DOMAIN ) ?>" min="0" name="<?php echo $field['id'] ?>" id="<?php echo $field['id'] ?>" value="<?php echo esc_attr( $meta ) ?>" /><?php
@@ -321,7 +337,7 @@
321
  foreach ( $meta_fields as $field ) {
322
  $old = get_post_meta( $post_id, $field[ 'id' ], true );
323
  $new = trim( $_POST[ $field[ 'id' ] ] );
324
- if ( $new && $new != $old ) {
325
  update_post_meta( $post_id, $field[ 'id' ], $new );
326
  } elseif ( '' == $new && $old ) {
327
  delete_post_meta( $post_id, $field[ 'id' ], $old );
113
  'type' => 'checkbox'
114
  );
115
 
116
+ $wprss_meta_fields[ 'source_link' ] = array(
117
+ 'label' => __( 'Link Source', WPRSS_TEXT_DOMAIN ),
118
+ 'id' => $prefix . 'source_link',
119
+ 'type' => 'boolean_fallback'
120
+ );
121
+
122
  // for extensibility, allows more meta fields to be added
123
  return apply_filters( 'wprss_fields', $wprss_meta_fields );
124
  }
224
  }
225
  break;
226
 
227
+ // A select with "On" and "Off" values, and a special option to fall back to General setting
228
+ case 'boolean_fallback':
229
+ $options = wprss_settings_get_feed_source_boolean_options();
230
+ if ($meta === '') {
231
+ $meta = -1;
232
+ }
233
+ echo wprss_settings_render_select($field['id'], $field['id'], $options, $meta);
234
+ echo $help->tooltip( $tooltip_id, $tooltip );
235
+ break;
236
+
237
  // number
238
  case 'number':
239
  ?><input class="wprss-number-roller" type="number" placeholder="<?php _e( 'Default', WPRSS_TEXT_DOMAIN ) ?>" min="0" name="<?php echo $field['id'] ?>" id="<?php echo $field['id'] ?>" value="<?php echo esc_attr( $meta ) ?>" /><?php
337
  foreach ( $meta_fields as $field ) {
338
  $old = get_post_meta( $post_id, $field[ 'id' ], true );
339
  $new = trim( $_POST[ $field[ 'id' ] ] );
340
+ if ( $new !== '' && $new != $old ) {
341
  update_post_meta( $post_id, $field[ 'id' ], $new );
342
  } elseif ( '' == $new && $old ) {
343
  delete_post_meta( $post_id, $field[ 'id' ], $old );
includes/admin-options.php CHANGED
@@ -624,6 +624,55 @@
624
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
625
  }
626
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
627
 
628
  /**
629
  * Set text preceding source
624
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
625
  }
626
 
627
+ /**
628
+ * Renders a <select> HTML tag from its parameters.
629
+ *
630
+ * @since 4.10
631
+ * @return string The HTML of a <select> tag.
632
+ */
633
+ function wprss_settings_render_select($id, $name, $items, $selected = null, $attributes = array())
634
+ {
635
+ ob_start();
636
+ $attributes = array_merge($attributes, array(
637
+ 'id' => $id,
638
+ 'name' => $name,
639
+ ));
640
+
641
+ $attributePairs = $attributes;
642
+ array_walk($attributePairs, function(&$v, $k) { $v = sprintf('%1$s="%2$s"', $k, $v); });
643
+ $attributesString = implode(' ', $attributePairs);
644
+ ?>
645
+ <select <?php echo $attributesString ?>>
646
+ <?php
647
+ foreach( $items as $_key => $_item ) {
648
+ $_key = (string) $_key;
649
+ $_item = (string) $_item;
650
+ $isSelected = $selected == $_key;
651
+ ?><option value="<?php echo $_key ?>"<?php if ($isSelected): ?> selected="selected"<?php endif ?>><?php echo htmlspecialchars($_item) ?></option><?php
652
+ }
653
+ ?>
654
+ </select>
655
+ <?php
656
+ $html = ob_get_clean();
657
+ return $html;
658
+ }
659
+
660
+ /**
661
+ * Gets options that should go in a dropdown which represents a
662
+ * feed-source-specific boolean setting.
663
+ *
664
+ * @since 4.10
665
+ * @return array An array with options.
666
+ */
667
+ function wprss_settings_get_feed_source_boolean_options()
668
+ {
669
+ return array(
670
+ 1 => __('On', WPRSS_TEXT_DOMAIN),
671
+ 0 => __('Off', WPRSS_TEXT_DOMAIN),
672
+ -1 => __('Default', WPRSS_TEXT_DOMAIN),
673
+ );
674
+ }
675
+
676
 
677
  /**
678
  * Set text preceding source
includes/autoload.php CHANGED
@@ -1,26 +1,44 @@
1
  <?php
2
 
 
 
 
3
  if (!function_exists('wprss_autoloader')) {
4
- /**
5
- *
6
- * @return Aventura\Wprss\Core\Loader The loader singleton instance
7
- */
8
- function wprss_autoloader() {
9
- static $loader = null;
10
- $className = 'Aventura\\Wprss\\Core\\Loader';
11
- if (!class_exists($className)){
12
- $dir = dirname(__FILE__);
13
- $classPath = str_replace('\\', DIRECTORY_SEPARATOR, $className);
14
- $classPath = "{$dir}/{$classPath}.php";
15
- require_once($classPath);
16
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
- if ($loader === null) {
19
- $loader = new $className();
20
- /* @var $loader Aventura\Wprss\Core\Loader */
21
- $loader->register();
22
- }
 
23
 
24
- return $loader;
25
- }
26
  }
1
  <?php
2
 
3
+ !defined('WPRSS_CORE_DISABLE_AUTOLOAD') &&
4
+ define('WPRSS_CORE_DISABLE_AUTOLOAD', false);
5
+
6
  if (!function_exists('wprss_autoloader')) {
7
+ /**
8
+ *
9
+ * @return Aventura\Wprss\Core\Loader The loader singleton instance
10
+ */
11
+ function wprss_autoloader() {
12
+ static $loader = null;
13
+ $className = 'Aventura\\Wprss\\Core\\Loader';
14
+
15
+ $composerAutoloader = '/vendor/autoload.php';
16
+ if (!WPRSS_CORE_DISABLE_AUTOLOAD) {
17
+ foreach(array(
18
+ untrailingslashit(WPRSS_DIR) . $composerAutoloader, // Standalone
19
+ realpath(WPRSS_DIR . '/../../..') . $composerAutoloader, // Vanilla WP, or another root package
20
+ ) as $wprssAutoloadPath) {
21
+ if (file_exists($wprssAutoloadPath)) {
22
+ require_once($wprssAutoloadPath);
23
+ break;
24
+ }
25
+ }
26
+ }
27
+
28
+ if (!class_exists($className)) {
29
+ $dir = dirname(__FILE__);
30
+ $classPath = str_replace('\\', DIRECTORY_SEPARATOR, $className);
31
+ $classPath = "{$dir}/{$classPath}.php";
32
+ require_once($classPath);
33
+ }
34
 
35
+ if ($loader === null) {
36
+ $loader = new $className();
37
+ /* @var $loader Aventura\Wprss\Core\Loader */
38
+ !WPRSS_CORE_DISABLE_AUTOLOAD &&
39
+ $loader->register();
40
+ }
41
 
42
+ return $loader;
43
+ }
44
  }
includes/cpt-feeds.php CHANGED
@@ -71,7 +71,7 @@
71
  // Add the post_type query arg
72
  $feed['query'] .= "post_type=$post_type";
73
  // Unparse the URL array into a string
74
- $feed = unparse_url( $feed );
75
  }
76
 
77
  // Get the Post Type Pretty Name
@@ -85,8 +85,8 @@
85
  }
86
 
87
 
88
- if ( !function_exists('unparse_url') ) {
89
- function unparse_url( $parsed_url ) {
90
  $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
91
  $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
92
  $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
71
  // Add the post_type query arg
72
  $feed['query'] .= "post_type=$post_type";
73
  // Unparse the URL array into a string
74
+ $feed = wprss_unparse_url( $feed );
75
  }
76
 
77
  // Get the Post Type Pretty Name
85
  }
86
 
87
 
88
+ if ( !function_exists('wprss_unparse_url') ) {
89
+ function wprss_unparse_url( $parsed_url ) {
90
  $scheme = isset($parsed_url['scheme']) ? $parsed_url['scheme'] . '://' : '';
91
  $host = isset($parsed_url['host']) ? $parsed_url['host'] : '';
92
  $port = isset($parsed_url['port']) ? ':' . $parsed_url['port'] : '';
includes/custom-post-types.php CHANGED
@@ -4,6 +4,8 @@
4
  *
5
  * @package WPRSSAggregator
6
  */
 
 
7
 
8
 
9
  add_action( 'init', 'wprss_register_post_types' );
4
  *
5
  * @package WPRSSAggregator
6
  */
7
+
8
+ define('WPRSS_POST_TYPE_FEED_SOURCE', 'wprss_feed');
9
 
10
 
11
  add_action( 'init', 'wprss_register_post_types' );
includes/feed-access.php CHANGED
@@ -6,15 +6,19 @@
6
  *
7
  * @since 4.7
8
  */
9
- class WPRSS_Feed_Access {
 
10
 
11
- protected static $_instance;
 
12
 
13
- protected $_certificate_file_path;
14
-
15
- const SETTING_KEY_CERTIFICATE_PATH = 'certificate-path';
16
  const SETTING_KEY_FEED_REQUEST_USERAGENT = 'feed_request_useragent';
17
 
 
 
 
 
18
  /**
19
  * @since 4.7
20
  * @return WPRSS_Feed_Access The singleton instance of this class.
@@ -39,10 +43,13 @@ class WPRSS_Feed_Access {
39
  *
40
  * @since 4.7
41
  */
42
- protected function _construct() {
43
- add_action( 'wprss_fetch_feed_before', array( $this, 'set_feed_options' ), 10 );
44
- add_action( 'wprss_settings_array', array( $this, 'add_settings' ) );
45
- add_action( 'wprss_default_settings_general', array( $this, 'add_default_settings' ) );
 
 
 
46
  }
47
 
48
 
@@ -110,15 +117,45 @@ class WPRSS_Feed_Access {
110
  * Get the useragent string that will be sent with feed requests.
111
  *
112
  * @since 4.8.2
 
 
 
 
113
  * @return string The useragent string that will be sent together with feed requests.
114
  * If empty, the value of SIMPLEPIE_USERAGENT will be used.
115
  */
116
- public function get_useragent()
117
  {
118
- $useragent = $this->get_useragent_setting();
119
- return !strlen(trim($useragent))
120
- ? SIMPLEPIE_USERAGENT
 
 
 
 
 
 
 
121
  : $useragent;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
  }
123
 
124
 
@@ -128,12 +165,27 @@ class WPRSS_Feed_Access {
128
  *
129
  * @since 4.7
130
  * @param SimplePie $feed The instance of the object that represents the feed to be fetched.
 
 
131
  * @param string $url The URL, from which the feed is going to be fetched.
132
  */
133
- public function set_feed_options( $feed ) {
134
- $feed->set_file_class( 'WPRSS_SimplePie_File' );
135
- $feed->set_useragent($this->get_useragent());
136
- WPRSS_SimplePie_File::set_default_certificate_file_path( $this->get_certificate_file_path() );
 
 
 
 
 
 
 
 
 
 
 
 
 
137
  }
138
 
139
 
@@ -158,6 +210,26 @@ class WPRSS_Feed_Access {
158
  return $settings;
159
  }
160
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
161
 
162
  /**
163
  * @since 4.7
@@ -201,6 +273,82 @@ class WPRSS_Feed_Access {
201
  <input id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]" type="text" value="<?php echo $value ?>" placeholder="<?php echo __('Default', WPRSS_TEXT_DOMAIN) ?>" />
202
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
203
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
  }
205
 
206
  // Initialize
6
  *
7
  * @since 4.7
8
  */
9
+ class WPRSS_Feed_Access
10
+ {
11
 
12
+ const RESOURCE_CLASS = 'WPRSS_SimplePie_File';
13
+ const D_REDIRECTS = 5;
14
 
15
+ const SETTING_KEY_CERTIFICATE_PATH = 'certificate-path';
 
 
16
  const SETTING_KEY_FEED_REQUEST_USERAGENT = 'feed_request_useragent';
17
 
18
+ protected static $_instance;
19
+
20
+ protected $_certificate_file_path;
21
+
22
  /**
23
  * @since 4.7
24
  * @return WPRSS_Feed_Access The singleton instance of this class.
43
  *
44
  * @since 4.7
45
  */
46
+ protected function _construct()
47
+ {
48
+ $wprss = wprss();
49
+ add_action( 'wprss_fetch_feed_before', array( $this, 'set_feed_options' ), 10, 2 );
50
+ add_action( 'wprss_settings_array', array( $this, 'add_settings' ) );
51
+ add_action( 'wprss_default_settings_general', array( $this, 'add_default_settings' ) );
52
+ $wprss->on('fields', array($this, 'add_feed_source_fields'));
53
  }
54
 
55
 
117
  * Get the useragent string that will be sent with feed requests.
118
  *
119
  * @since 4.8.2
120
+ *
121
+ * @param int|null $feedSourceId The ID of the feed source, which to get the useragent for.
122
+ * Leave `null` to get a useragent independently from any feed source.
123
+ *
124
  * @return string The useragent string that will be sent together with feed requests.
125
  * If empty, the value of SIMPLEPIE_USERAGENT will be used.
126
  */
127
+ public function get_useragent($feedSourceId = null)
128
  {
129
+ $useragent = !is_null($feedSourceId)
130
+ ? get_post_meta($feedSourceId, self::SETTING_KEY_FEED_REQUEST_USERAGENT, true)
131
+ : $this->get_useragent_setting();
132
+
133
+ if (!strlen(trim($useragent))) {
134
+ $useragent = $this->get_useragent_setting();
135
+ }
136
+
137
+ $useragent = !strlen(trim($useragent))
138
+ ? $this->getDefaultUseragent()
139
  : $useragent;
140
+
141
+ wprss()->event('feed_access_useragent', array(
142
+ 'useragent' => &$useragent,
143
+ 'feed_source_id' => $feedSourceId
144
+ ));
145
+
146
+ return $useragent;
147
+ }
148
+
149
+ /**
150
+ * Retrieve the useragent string that will be used by default.
151
+ *
152
+ * @since 4.10
153
+ *
154
+ * @return string The useragent string.
155
+ */
156
+ public function getDefaultUseragent()
157
+ {
158
+ return SIMPLEPIE_USERAGENT;
159
  }
160
 
161
 
165
  *
166
  * @since 4.7
167
  * @param SimplePie $feed The instance of the object that represents the feed to be fetched.
168
+ * @param int $feedSourceId ID of the feed source, which is accessing the feed.
169
+ * Leave `null` to skip setting feed source specific options.
170
  * @param string $url The URL, from which the feed is going to be fetched.
171
  */
172
+ public function set_feed_options($feed, $feedSourceId = null)
173
+ {
174
+ $feed->set_file_class( static::RESOURCE_CLASS );
175
+ $feed->set_useragent($this->get_useragent($feedSourceId));
176
+ WPRSS_SimplePie_File::set_default_certificate_file_path($this->get_certificate_file_path());
177
+
178
+ /*
179
+ * Setting the file resource object for the feed to use.
180
+ * Note: this object will only be used if cache is disabled for
181
+ * the feed. This is why running {@see SimplePie::set_file_class()}
182
+ * is still necessary. Like this, the correct file class will
183
+ * still be used, although the file object set below will
184
+ * have absolutely no effect on the feed retrieval process.
185
+ */
186
+ if (!$feed->file) {
187
+ $feed->file = $this->create_resource_from_feed($feed);
188
+ }
189
  }
190
 
191
 
210
  return $settings;
211
  }
212
 
213
+ /**
214
+ * Adding feed source specific settings.
215
+ *
216
+ * @since 4.10
217
+ *
218
+ * @param array $fields An array containing all existing fields by ID.
219
+ */
220
+ public function add_feed_source_fields($fields)
221
+ {
222
+ $wprss = wprss();
223
+
224
+ $fields[self::SETTING_KEY_FEED_REQUEST_USERAGENT] = array(
225
+ 'id' => self::SETTING_KEY_FEED_REQUEST_USERAGENT,
226
+ 'label' => $wprss->__('Feed Request Useragent'),
227
+ 'placeholder' => $wprss->__('Leave blank to inherit general setting')
228
+ );
229
+
230
+ return $fields;
231
+ }
232
+
233
 
234
  /**
235
  * @since 4.7
273
  <input id="<?php echo $field['field_id'] ?>" name="wprss_settings_general[<?php echo $field['field_id'] ?>]" type="text" value="<?php echo $value ?>" placeholder="<?php echo __('Default', WPRSS_TEXT_DOMAIN) ?>" />
274
  <?php echo wprss_settings_inline_help( $field['field_id'], $field['tooltip'] );
275
  }
276
+
277
+ /**
278
+ * Retrieve default headers that should be used for feed requests.
279
+ *
280
+ * Use the `wprss_feed_default_headers` filter to amend the whole return value.
281
+ * Use the `wprss_feed_default_headers_accept` to amend the types in the "Accept" header.
282
+ *
283
+ * @since 4.10
284
+ * @see array_merge_recursive_distinct()
285
+ * @param array $additionalHeaders Optional headers to merge with the default ones.
286
+ * Merging is done recursively.
287
+ * @return array An array of headers, where keys are header names, and values are header values.
288
+ */
289
+ public function default_headers(array $additionalHeaders = array())
290
+ {
291
+ $defaultHeaders = array(
292
+ 'Accept' => implode(', ', apply_filters('wprss_feed_default_headers_accept', array(
293
+ 'application/atom+xml',
294
+ 'application/rss+xmlm',
295
+ 'application/rdf+xml;q=0.9',
296
+ 'application/xml;q=0.8',
297
+ 'text/xml;q=0.8',
298
+ 'text/html;q=0.7',
299
+ 'unknown/unknown;q=0.1',
300
+ 'application/unknown;q=0.1',
301
+ '*/*;q=0.1')))
302
+ );
303
+
304
+ $headers = array_merge_recursive_distinct($defaultHeaders, $additionalHeaders);
305
+ $headers = apply_filters('wprss_feed_default_headers', $headers);
306
+
307
+ return $headers;
308
+ }
309
+
310
+ /**
311
+ * Creates a new object that is responsible for retrieving a remote resource.
312
+ *
313
+ * @since 4.10
314
+ *
315
+ * @see SimplePie_File::__construct()
316
+ *
317
+ * @param string $url
318
+ * @param int $timeout
319
+ * @param int $redirects
320
+ * @param array $headers If null, {@link default_headers() default headers} will be used.
321
+ * @param string $useragent
322
+ * @param bool $force_fsockopen
323
+ * @return \SimplePie_File
324
+ */
325
+ public function create_resource($url, $timeout = 10, $redirects = 5, $headers = null, $useragent = null, $force_fsockopen = false)
326
+ {
327
+ if (is_null($headers)) {
328
+ $headers = $this->default_headers();
329
+ }
330
+
331
+ if (!class_exists($resourceClass = static::RESOURCE_CLASS)) {
332
+ throw new Exception(sprintf('Could not create resource: resource class "$1$s" does not exist', $resourceClass));
333
+ }
334
+
335
+ return new $resourceClass($url, $timeout, $redirects, $headers, $useragent, $force_fsockopen);
336
+ }
337
+
338
+ /**
339
+ * Creates a new object that is responsible for retrieving a remote resource, using values from a feed.
340
+ *
341
+ * @since 4.10
342
+ *
343
+ * @see wprss_feed_create_resource()
344
+ *
345
+ * @param \SimplePie $feed The feed, based on which to create the resource.
346
+ * @return \SimplePie_File
347
+ */
348
+ public function create_resource_from_feed(SimplePie $feed)
349
+ {
350
+ return $this->create_resource($feed->feed_url, $feed->timeout, static::D_REDIRECTS, null, $feed->useragent, $feed->force_fsockopen);
351
+ }
352
  }
353
 
354
  // Initialize
includes/feed-display.php CHANGED
@@ -62,9 +62,6 @@
62
  ));
63
  $extra_options = apply_filters( 'wprss_template_extra_options', array(), $args);
64
 
65
- // Normalize the source_link option
66
- $source_link = isset( $general_settings['source_link'] )? $general_settings['source_link'] : 0;
67
-
68
  // Declare each item in $args as its own variable
69
  extract( $args, EXTR_SKIP );
70
 
@@ -77,6 +74,13 @@
77
  $source_url = get_post_meta( $feed_source_id, 'wprss_site_url', true );
78
  $timestamp = get_the_time( 'U', $ID );
79
 
 
 
 
 
 
 
 
80
  // Fallback for feeds created with older versions of the plugin
81
  if ( $source_url === '' ) $source_url = get_post_meta( $feed_source_id, 'wprss_url', true );
82
  // convert from Unix timestamp
62
  ));
63
  $extra_options = apply_filters( 'wprss_template_extra_options', array(), $args);
64
 
 
 
 
65
  // Declare each item in $args as its own variable
66
  extract( $args, EXTR_SKIP );
67
 
74
  $source_url = get_post_meta( $feed_source_id, 'wprss_site_url', true );
75
  $timestamp = get_the_time( 'U', $ID );
76
 
77
+ $general_source_link = isset( $general_settings['source_link'] ) ? $general_settings['source_link'] : 0;
78
+ $feed_source_link = get_post_meta( $feed_source_id, 'wprss_source_link', true );
79
+ $source_link = ( $feed_source_link === '' || intval($feed_source_link) < 0 ) // If not explicit value
80
+ ? $general_source_link // Fall back to general setting
81
+ : $feed_source_link; // Otherwise, use value
82
+ $source_link = intval(trim($source_link));
83
+
84
  // Fallback for feeds created with older versions of the plugin
85
  if ( $source_url === '' ) $source_url = get_post_meta( $feed_source_id, 'wprss_url', true );
86
  // convert from Unix timestamp
includes/feed-importing.php CHANGED
@@ -231,7 +231,6 @@
231
  }
232
  }
233
 
234
-
235
  /**
236
  * A clone of the function 'fetch_feed' in wp-includes/feed.php [line #529]
237
  *
@@ -239,63 +238,59 @@
239
  *
240
  * @since 3.5
241
  */
242
- function wprss_fetch_feed( $url, $source = NULL, $param_force_feed = FALSE ) {
243
-
244
- // Trim the URL
245
- $url = trim( $url );
246
-
247
- // Initialize the Feed
248
- $feed = new SimplePie();
249
- // Obselete method calls ?
250
- //$feed->set_cache_class( 'WP_Feed_Cache' );
251
- //$feed->set_file_class( 'WP_SimplePie_File' );
252
- $feed->set_feed_url( $url );
253
- $feed->set_autodiscovery_level( SIMPLEPIE_LOCATOR_ALL );
254
-
255
- // If a feed source was passed
256
- if ( $source !== NULL || $param_force_feed ) {
257
- // Get the force feed option for the feed source
258
- $force_feed = get_post_meta( $source, 'wprss_force_feed', TRUE );
259
- // If turned on, force the feed
260
- if ( $force_feed == 'true' || $param_force_feed ) {
261
- $feed->force_feed( TRUE );
262
- }
263
- }
264
-
265
- // Set timeout limit
266
- $fetch_time_limit = wprss_get_feed_fetch_time_limit();
267
- $feed->set_timeout( $fetch_time_limit );
268
-
269
- //$feed->set_cache_duration( apply_filters( 'wp_feed_cache_transient_lifetime', 12 * HOUR_IN_SECONDS, $url ) );
270
- $feed->enable_cache( FALSE );
271
-
272
- // Reference array action hook, for the feed object and the URL
273
- do_action_ref_array( 'wp_feed_options', array( &$feed, $url ) );
274
-
275
- // Prepare the tags to strip from the feed
276
- $tags_to_strip = apply_filters( 'wprss_feed_tags_to_strip', $feed->strip_htmltags, $source );
277
- // Strip them
278
- $feed->strip_htmltags( $tags_to_strip );
279
-
280
- do_action( 'wprss_fetch_feed_before', $feed );
281
-
282
- // Fetch the feed
283
- $feed->init();
284
- $feed->handle_content_type();
285
-
286
- do_action( 'wprss_fetch_feed_after', $feed );
287
-
288
- // Convert the feed error into a WP_Error, if applicable
289
- if ( $feed->error() ) {
290
- if ( $source !== NULL ) {
291
- $msg = sprintf( __( 'Failed to fetch the RSS feed. Error: %s', WPRSS_TEXT_DOMAIN ), $feed->error() );
292
- update_post_meta( $source, 'wprss_error_last_import', $msg );
293
- }
294
- return new WP_Error( 'simplepie-error', $feed->error() );
295
- }
296
- // If no error, return the feed and remove any error meta
297
- delete_post_meta( $source, "wprss_error_last_import" );
298
- return $feed;
299
  }
300
 
301
 
@@ -465,7 +460,10 @@
465
  foreach ( $items as $item ) {
466
 
467
  // Normalize the URL
468
- $permalink = wprss_normalize_permalink( $item->get_permalink(), $item, $feed_ID );
 
 
 
469
  wprss_log_obj( 'Importing item', $permalink, null, WPRSS_LOG_LEVEL_INFO );
470
  wprss_log_obj( 'Original permalink', $item->get_permalink(), null, WPRSS_LOG_LEVEL_SYSTEM );
471
 
231
  }
232
  }
233
 
 
234
  /**
235
  * A clone of the function 'fetch_feed' in wp-includes/feed.php [line #529]
236
  *
238
  *
239
  * @since 3.5
240
  */
241
+ function wprss_fetch_feed($url, $source = null, $param_force_feed = false)
242
+ {
243
+ // Trim the URL
244
+ $url = trim($url);
245
+
246
+ // Initialize the Feed
247
+ $feed = new SimplePie();
248
+ $feed->set_feed_url($url);
249
+ $feed->set_autodiscovery_level(SIMPLEPIE_LOCATOR_ALL);
250
+
251
+ // If a feed source was passed
252
+ if ($source !== null || $param_force_feed) {
253
+ // Get the force feed option for the feed source
254
+ $force_feed = get_post_meta($source, 'wprss_force_feed', null);
255
+ // If turned on, force the feed
256
+ if ($force_feed == 'true' || $param_force_feed) {
257
+ $feed->force_feed(null);
258
+ }
259
+ }
260
+
261
+ // Set timeout limit
262
+ $fetch_time_limit = wprss_get_feed_fetch_time_limit();
263
+ $feed->set_timeout($fetch_time_limit);
264
+
265
+ $feed->enable_cache(false);
266
+
267
+ // Reference array action hook, for the feed object and the URL
268
+ do_action_ref_array('wp_feed_options', array(&$feed, $url));
269
+
270
+ // Prepare the tags to strip from the feed
271
+ $tags_to_strip = apply_filters('wprss_feed_tags_to_strip', $feed->strip_htmltags, $source);
272
+ // Strip them
273
+ $feed->strip_htmltags($tags_to_strip);
274
+
275
+ do_action('wprss_fetch_feed_before', $feed, $source);
276
+
277
+ // Fetch the feed
278
+ $feed->init();
279
+ $feed->handle_content_type();
280
+
281
+ do_action('wprss_fetch_feed_after', $feed);
282
+
283
+ // Convert the feed error into a WP_Error, if applicable
284
+ if ($feed->error()) {
285
+ if ($source !== null) {
286
+ $msg = sprintf(__('Failed to fetch the RSS feed. Error: %s', WPRSS_TEXT_DOMAIN), $feed->error());
287
+ update_post_meta($source, 'wprss_error_last_import', $msg);
288
+ }
289
+ return new WP_Error('simplepie-error', $feed->error(), array('feed' => $feed));
290
+ }
291
+ // If no error, return the feed and remove any error meta
292
+ delete_post_meta($source, 'wprss_error_last_import');
293
+ return $feed;
 
 
 
 
294
  }
295
 
296
 
460
  foreach ( $items as $item ) {
461
 
462
  // Normalize the URL
463
+ $permalink = $item->get_permalink(); // Link or enclosure URL
464
+ $permalink = htmlspecialchars_decode( $permalink ); // SimplePie encodes HTML special chars
465
+
466
+ $permalink = wprss_normalize_permalink( $permalink, $item, $feed_ID );
467
  wprss_log_obj( 'Importing item', $permalink, null, WPRSS_LOG_LEVEL_INFO );
468
  wprss_log_obj( 'Original permalink', $item->get_permalink(), null, WPRSS_LOG_LEVEL_SYSTEM );
469
 
includes/feed-processing.php CHANGED
@@ -131,7 +131,7 @@
131
  WHERE p.`meta_key` = 'wprss_feed_id' AND p.`meta_value` = '{$feed_ID}'"
132
  );
133
 
134
- return array_flip( $cols );
135
  }
136
 
137
 
@@ -152,7 +152,7 @@
152
  WHERE q.`meta_key` = 'wprss_feed_id' $condition"
153
  );
154
 
155
- return array_flip( $cols );
156
  }
157
 
158
 
131
  WHERE p.`meta_key` = 'wprss_feed_id' AND p.`meta_value` = '{$feed_ID}'"
132
  );
133
 
134
+ return @array_flip($cols);
135
  }
136
 
137
 
152
  WHERE q.`meta_key` = 'wprss_feed_id' $condition"
153
  );
154
 
155
+ return @array_flip($cols);
156
  }
157
 
158
 
includes/image-caching.php CHANGED
@@ -12,6 +12,7 @@ class WPRSS_Image_Cache {
12
  protected $_temp_dir; // System temp dir + 'remote-image-cache'
13
  protected $_current_time;
14
  protected $_ttl = 30; // Time to live, in seconds
 
15
 
16
  protected $_image_class_name = 'WPRSS_Image_Cache_Image';
17
  protected $_images = array();
@@ -161,6 +162,40 @@ class WPRSS_Image_Cache {
161
  }
162
 
163
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  /**
165
  * Converts one of many representations of time into a Unix timestamp.
166
  *
@@ -610,21 +645,25 @@ class WPRSS_Image_Cache {
610
  $path = isset( $path_matches[2][0] ) ? $path_matches[2][0] : null;
611
  $domain = isset( $path_matches[1][0] ) ? $path_matches[1][0] : null;
612
 
613
- $unique_filename = str_replace( '/', '-', $path );
614
-
615
  $base_filename = $extension
616
  ? basename( $url_filename, '.' . $extension )
617
  : basename( $url_filename );
618
 
619
- if ( $hash = self::hash( $url ) )
620
- $base_filename = $base_filename . '-' .$hash;
621
-
622
- if ( !is_null( $extension ) )
623
- $base_filename .= '.' . $extension;
624
 
625
  $path = trailingslashit( substr( $path, 0, strlen( $path ) - strlen( $url_filename ) ) );
626
- $path = trailingslashit( $domain ) . $path;
627
- $unique_filename = $path . $base_filename;
 
 
 
 
 
 
 
 
 
 
628
 
629
  return $unique_filename;
630
  }
12
  protected $_temp_dir; // System temp dir + 'remote-image-cache'
13
  protected $_current_time;
14
  protected $_ttl = 30; // Time to live, in seconds
15
+ protected $_cache_orig_filename_length = 25; // How much of the original filename to preserve in the cache filename, in addition to the hash
16
 
17
  protected $_image_class_name = 'WPRSS_Image_Cache_Image';
18
  protected $_images = array();
162
  }
163
 
164
 
165
+ /**
166
+ * Get the length of the original filename to preserve in cache.
167
+ *
168
+ * This is in addition to the hash. The cache filename will have the
169
+ * following format:
170
+ * [trimmed-orig-filename]-[hash].[orig-extension]
171
+ * The return value determine the length of the `trimmed-orig-filename`
172
+ * segment.
173
+ *
174
+ * @since 4.10
175
+ *
176
+ * @return int The length of the original filename to preserve.
177
+ */
178
+ public function get_cache_orig_filename_length() {
179
+ return $this->_cache_orig_filename_length;
180
+ }
181
+
182
+
183
+ /**
184
+ * Set the length of the original filename that will be preserved in cache.
185
+ *
186
+ * @see get_cache_orig_filename_length()
187
+ *
188
+ * @param int $length The length of the original filename preserved.
189
+ *
190
+ * @return \WPRSS_Image_Cache
191
+ */
192
+ public function set_cache_orig_filename_length($length) {
193
+ $this->_cache_orig_filename_length = intval($length);
194
+
195
+ return $this;
196
+ }
197
+
198
+
199
  /**
200
  * Converts one of many representations of time into a Unix timestamp.
201
  *
645
  $path = isset( $path_matches[2][0] ) ? $path_matches[2][0] : null;
646
  $domain = isset( $path_matches[1][0] ) ? $path_matches[1][0] : null;
647
 
 
 
648
  $base_filename = $extension
649
  ? basename( $url_filename, '.' . $extension )
650
  : basename( $url_filename );
651
 
652
+ $hash = self::hash( $url );
 
 
 
 
653
 
654
  $path = trailingslashit( substr( $path, 0, strlen( $path ) - strlen( $url_filename ) ) );
655
+ if ( $orig_path_length = $this->get_cache_orig_filename_length() ) {
656
+ $base_filename = substr( $base_filename, 0, $orig_path_length );
657
+ }
658
+
659
+ $unique_filename = trailingslashit( $domain ) .
660
+ ($orig_path_length
661
+ ? "$base_filename-"
662
+ : '') .
663
+ $hash .
664
+ (is_null( $extension )
665
+ ? ''
666
+ : ".$extension");
667
 
668
  return $unique_filename;
669
  }
includes/leave-review-notification.php ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * This is a module responsible for facilitating the "Leave a Review" notification.
5
+ *
6
+ * Use the `WPRSS_LEAVE_REVIEW_NOTIFICATION_DELAY` constant to change the amount of time (in seconds)
7
+ * that the notice will be delayed by after first installation date. This date is determined by an option created
8
+ * during plugin activation, if not already present. When retrieving this value, if it does not exist
9
+ * (perhaps because this update was installed after activation happened), it will be deduced from the creation time
10
+ * of the oldest feed source. If no feed sources exist, the time at that moment will be determined as the
11
+ * first activation time from that point onward.
12
+ */
13
+
14
+ // How much time must pass from activation to display notice
15
+ if (!defined('WPRSS_LEAVE_REVIEW_NOTIFICATION_DELAY')) {
16
+ define('WPRSS_LEAVE_REVIEW_NOTIFICATION_DELAY', 60 * 60 * 24 * 7 * 4 * 1); // 1 month
17
+ }
18
+
19
+ // How many active feed sources to display notice
20
+ 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
+ //});
includes/libraries/EDD_licensing/EDD_SL_Plugin_Updater.php CHANGED
File without changes
includes/scripts.php CHANGED
@@ -23,22 +23,43 @@
23
  *
24
  * @since 2.0
25
  */
26
- function wprss_admin_scripts_styles() {
 
 
 
 
 
 
27
 
28
- // Only load scripts if we are on particular pages of the plugin in admin
29
- if ( isset( $_GET['page'] ) && ( $_GET['page'] == 'wprss-aggregator' || $_GET['page'] == 'wprss-aggregator-settings'
30
- || $_GET['page'] == 'wprss-import-export-settings' || $_GET['page'] == 'wprss-debugging' || $_GET['page'] == 'wprss-addons' ) ) {
31
- wp_enqueue_style( 'wprss-styles', WPRSS_CSS . 'admin-styles.css' );
32
- wp_enqueue_style( 'wprss-fa', WPRSS_CSS . 'font-awesome.min.css' );
33
- }
34
 
35
- if ( is_admin() ) {
36
- wp_enqueue_style( 'wprss-admin-3.8-styles', WPRSS_CSS . 'admin-3.8.css' );
 
37
  }
38
 
 
 
 
 
 
 
 
 
 
 
39
  $screen = get_current_screen();
 
 
 
 
 
 
 
 
40
 
41
- // Enqueue scripts for all admin pages
42
  wp_enqueue_script( 'wprss-xdn-class' );
43
  wp_enqueue_script( 'wprss-xdn-lib' );
44
  wp_enqueue_script( 'aventura' );
@@ -46,77 +67,63 @@
46
  wp_enqueue_script( 'wprss-admin-addon-ajax', WPRSS_JS .'admin-addon-ajax.js', array('jquery') );
47
  wp_localize_script( 'wprss-admin-addon-ajax', 'wprss_admin_addon_ajax', array(
48
  'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN )
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
49
  ) );
50
 
51
- wp_enqueue_style( 'wprss-admin-editor-styles', WPRSS_CSS . 'admin-editor.css' );
52
- wp_enqueue_style( 'wprss-admin-tracking-styles', WPRSS_CSS . 'admin-tracking-styles.css' );
53
 
54
- $page = isset( $_GET['page'] )? $_GET['page'] : '';
55
-
56
- if ( ( 'post' === $screen->base || 'edit' === $screen->base || 'wprss-debugging' === $screen->base ) &&
57
- ( 'wprss_feed' === $screen->post_type || 'wprss_feed_item' === $screen->post_type ) ||
58
- $page == 'wprss-aggregator-settings' || $screen->post_type === 'wprss_blacklist' ) {
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
-
62
- // Prepare the URL for removing bulk from blacklist, with a nonce
63
- $blacklist_remove_url = admin_url( 'edit.php?wprss-bulk=1' );
64
- $blacklist_remove_url = wp_nonce_url( $blacklist_remove_url, 'blacklist-remove-selected', 'wprss_blacklist_trash' );
65
- $blacklist_remove_url .= '&wprss-blacklist-remove=';
66
-
67
- wp_enqueue_script( 'wprss-admin-custom', WPRSS_JS .'admin-custom.js', array('jquery','jquery-ui-datepicker','jquery-ui-slider') );
68
- wp_localize_script( 'wprss-admin-custom', 'wprss_admin_custom', array(
69
- 'failed_to_import' => __( 'Failed to import', WPRSS_TEXT_DOMAIN ),
70
- 'items_are_importing' => __( 'Items are importing', WPRSS_TEXT_DOMAIN ),
71
- 'please_wait' => __( 'Please wait ...', WPRSS_TEXT_DOMAIN ),
72
- 'bulk_add' => __( 'Bulk Add', WPRSS_TEXT_DOMAIN ),
73
- 'ok' => __( 'OK', WPRSS_TEXT_DOMAIN ),
74
- 'cancel' => __( 'Cancel', WPRSS_TEXT_DOMAIN ),
75
- 'blacklist_desc' => __( 'The feed items listed here will be disregarded when importing new items from your feed sources.', WPRSS_TEXT_DOMAIN ),
76
- 'blacklist_remove' => __( 'Remove selected from Blacklist', WPRSS_TEXT_DOMAIN ),
77
- 'blacklist_remove_url' => $blacklist_remove_url
78
  ) );
79
-
80
- wp_enqueue_script( 'jquery-ui-timepicker-addon', WPRSS_JS .'jquery-ui-timepicker-addon.js', array('jquery','jquery-ui-datepicker') );
81
- wp_enqueue_style( 'jquery-style', 'http://ajax.googleapis.com/ajax/libs/jqueryui/1.10.4/themes/smoothness/jquery-ui.css' );
82
- if ( 'post' === $screen->base && 'wprss_feed' === $screen->post_type ) {
83
- // Change text on post screen from 'Enter title here' to 'Enter feed name here'
84
- add_filter( 'enter_title_here', 'wprss_change_title_text' );
85
- }
86
- if ( 'wprss_feed' === $screen->post_type ) {
87
- wp_enqueue_script( 'wprss-custom-bulk-actions', WPRSS_JS . 'admin-custom-bulk-actions.js', array( 'jquery' ) );
88
- wp_localize_script( 'wprss-custom-bulk-actions', 'wprss_admin_bulk', array(
89
- 'activate' => __( 'Activate', WPRSS_TEXT_DOMAIN ),
90
- 'pause' => __( 'Pause', WPRSS_TEXT_DOMAIN )
91
- ) );
92
- }
93
- if ( 'wprss_feed_item' === $screen->post_type) {
94
- wp_enqueue_script( 'wprss-custom-bulk-actions-feed-item', WPRSS_JS . 'admin-custom-bulk-actions-feed-item.js', array( 'jquery' ) );
95
- wp_localize_script( 'wprss-custom-bulk-actions-feed-item', 'wprss_admin_bulk_feed_item', array(
96
- 'trash' => __( 'Move to Trash', WPRSS_TEXT_DOMAIN )
97
- ) );
98
- }
99
  }
 
 
 
 
 
 
 
100
  // Load Heartbeat script and set dependancy for Heartbeat to ensure Heartbeat is loaded
101
- if ( 'edit' === $screen->base && $screen->post_type === 'wprss_feed' && apply_filters('wprss_ajax_polling', TRUE) === TRUE ) {
102
  wp_enqueue_script( 'wprss-feed-source-table-heartbeat', WPRSS_JS .'heartbeat.js' );
103
  wp_localize_script( 'wprss-feed-source-table-heartbeat', 'wprss_admin_heartbeat', array(
104
  'ago' => __( 'ago', WPRSS_TEXT_DOMAIN )
105
  ) );
106
  }
107
 
108
- else if ( 'dashboard_page_wprss-welcome' === $screen->base ) {
109
- wp_enqueue_style( 'wprss-admin-styles', WPRSS_CSS . 'admin-styles.css' );
110
- }
111
-
112
- // Creates the wprss_urls object in JS
113
- wp_localize_script( 'wprss-admin-custom', 'wprss_urls',
114
- array(
115
- 'import_export' => admin_url('edit.php?post_type=wprss_feed&page=wprss-import-export-settings')
116
- )
117
- );
118
 
119
- if ( 'wprss_feed_page_wprss-aggregator-settings' === $screen->base ) {
120
  wp_enqueue_script( 'wprss-admin-license-manager', WPRSS_JS . 'admin-license-manager.js' );
121
 
122
  wp_enqueue_script( 'wprss-admin-licensing', WPRSS_JS . 'admin-licensing.js' );
@@ -126,7 +133,7 @@
126
  ) );
127
  }
128
 
129
- if ( 'wprss_feed_page_wprss-help' === $screen->base ) {
130
  wp_enqueue_script( 'wprss-admin-help', WPRSS_JS . 'admin-help.js' );
131
  wp_localize_script( 'wprss-admin-help', 'wprss_admin_help', array(
132
  'sending' => __('Sending...', WPRSS_TEXT_DOMAIN),
@@ -135,8 +142,8 @@
135
  ) );
136
  }
137
 
138
- do_action( 'wprss_admin_scripts_styles' );
139
- } // end wprss_admin_scripts_styles
140
 
141
 
142
  add_action( 'wp_enqueue_scripts', 'wprss_load_scripts' );
23
  *
24
  * @since 2.0
25
  */
26
+ function wprss_admin_scripts_styles()
27
+ {
28
+ $isWpraScreen = wprss_is_wprss_page();
29
+ $screen = get_current_screen();
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) {
40
+ wprss_admin_exclusive_scripts_styles();
41
  }
42
 
43
+ do_action( 'wprss_admin_scripts_styles' );
44
+ } // end wprss_admin_scripts_styles
45
+
46
+ /**
47
+ * Enqueues backend scripts on WPRA-related pages only
48
+ *
49
+ * @since 4.10
50
+ */
51
+ function wprss_admin_exclusive_scripts_styles()
52
+ {
53
  $screen = get_current_screen();
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' );
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' );
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),
142
  ) );
143
  }
144
 
145
+ do_action('wprss_admin_exclusive_scripts_styles');
146
+ }
147
 
148
 
149
  add_action( 'wp_enqueue_scripts', 'wprss_load_scripts' );
includes/update.php CHANGED
@@ -117,7 +117,6 @@
117
  update_option( 'wprss_settings_general', $settings );
118
  }
119
 
120
-
121
  /**
122
  * Initialize settings to default ones if they are not yet set
123
  *
117
  update_option( 'wprss_settings_general', $settings );
118
  }
119
 
 
120
  /**
121
  * Initialize settings to default ones if they are not yet set
122
  *
js/admin-custom.js CHANGED
@@ -34,8 +34,8 @@ function fetch_items_row_action_callback(e){
34
  data: {
35
  'action': 'wprss_fetch_feeds_row_action',
36
  'id': id,
37
- 'wprss_admin_ajax_nonce': link.next().val(), // nonce
38
- 'wprss_admin_ajax_referer': link.next().next().val() // referer
39
  },
40
  success: function( response, status, jqXHR ){
41
  if (response.is_error) {
34
  data: {
35
  'action': 'wprss_fetch_feeds_row_action',
36
  'id': id,
37
+ 'wprss_admin_ajax_nonce': jQuery('#wprss_feed_source_action_nonce').data('value'), // nonce
38
+ 'wprss_admin_ajax_referer': jQuery('#_wp_http_referer').val() // referer
39
  },
40
  success: function( response, status, jqXHR ){
41
  if (response.is_error) {
languages/wprss-es.mo CHANGED
File without changes
languages/wprss-es.po CHANGED
File without changes
readme.txt CHANGED
@@ -3,71 +3,116 @@ 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.5.2
7
- Stable tag: 4.9.1
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
 
11
-
12
  == Description ==
13
 
14
- WP RSS Aggregator is the original and best plugin for importing, merging and displaying RSS and Atom feeds on your WordPress site. It’s the most comprehensive and elegant RSS feed solution for WordPress.
 
 
 
 
 
15
 
16
- With this free core version of WP RSS Aggregator you’ll be able to aggregate as many RSS feeds from as many sources as you'd like. Using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) you can then display the imported feed items from one or more sources directly on your website.
17
 
18
- Have a look at the core version of WP RSS Aggregator below, or [go here to view our introductory videos for the premium add-ons](http://docs.wprssaggregator.com/introductory-videos/).
19
- [youtube http://www.youtube.com/watch?v=fcENPsmJbvc]
 
 
20
 
21
- > ### Highlighted Features ###
22
  > * Set a name for each feed source.
23
  > * Import any number of feed items from multiple RSS Feeds.
24
- > * Display feed items using the [shortcodes](http://docs.wprssaggregator.com/shortcodes/) or by [calling the display function from within your theme](http://docs.wprssaggregator.com/shortcodes/#using-shortcodes-directly-in-templates).
25
- > * Limit the age of the feed items stored in the database.
26
- > * Set the number of feed items per feed source that you want to show and store.
27
- > * Set the pagination for the displayed feed items.
28
- > * Set a general feed import time interval.
29
- > * Schedule feed imports for each individual feed source.
30
- > * Choose whether to show/hide feed sources and dates, and set the date format.
31
- > * Set the links as no-follow or not, or add no follow to the meta tag.
32
- > * Customise the output using various [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters).
33
- > * Set the open link behaviour (lightbox, new window or current window).
34
  > * Opens YouTube, DailyMotion and Vimeo videos directly.
35
- > * Export a custom RSS feed based on your feed sources.
36
- > * Extendable via [action and filter hooks](http://docs.wprssaggregator.com/category/developer-documentation/filters/).
37
- > * Incorporates feed auto-discovery, which lets you add feed sources without knowing the exact URL.
38
- > * Integrated with the Simplepie library that comes with WordPress. This includes RSS 0.91 and RSS 1.0 formats, the popular RSS 2.0 format, Atom etc.
 
 
 
 
 
 
39
 
40
  ### Premium Add-Ons ###
41
- WP RSS Aggregator also has a number of premium add-ons that add more functionality to the core plugin. They provide the means to create auto-blogging websites, display job listings, import YouTube videos and a lot more. Take a look at our [Use Cases](http://www.wprssaggregator.com/use-cases/) and our [Showcase](http://www.wprssaggregator.com/showcase/) for more ideas. Here are the add-ons currently available:
42
-
43
- > * [Feed to Post](http://www.wprssaggregator.com/extension/feed-to-post/) is an advanced importer that lets you import RSS feeds directly into WordPress posts or any other custom post type. You can use it to populate a website in minutes (autoblog). This is the most popular and feature-filled extension.
44
- > * [Keyword Filtering](http://www.wprssaggregator.com/extension/keyword-filtering/) filters the feed items to be imported based on keywords, key phrases or tags, so you only get the items you're interested in.
45
- > * [Excerpts & Thumbnails](http://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.
46
- > * [Categories](http://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).
47
- > * [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) adds connectivity to our Full Text Premium 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/))
48
- > * [WordAi](http://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/))
49
- > * [SpinnerChief](http://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.
50
- > * [Widget](http://www.wprssaggregator.com/extension/widget/) adds a widget to your website that displays 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.
51
-
52
- View a comparison of our three most popular add-ons [here](http://www.wprssaggregator.com/product-comparison/). If you're unsure as to which add-ons you need, we put together [this comprehensive post](http://www.wprssaggregator.com/add-ons-purchase/) to help you out.
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
53
 
54
- There are also two premium bundles available, the [Simple Feeds Bundle](http://www.wprssaggregator.com/extension/simple-feeds-bundle/) and the [Advanced Feeds Bundle](http://www.wprssaggregator.com/extension/advanced-feeds-bundle/). View a quick comparison of these bundles [here](http://www.wprssaggregator.com/bundle-comparison/).
 
 
 
 
 
55
 
56
  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.
57
 
58
- > ### Demo ###
59
- > The core plugin can be seen in use [on our website's demo page](http://www.wprssaggregator.com/demo/). There are also a number of [other demos](http://www.wprssaggregator.com/) available for our premium add-ons.
60
 
61
- > ### Documentation ###
62
- > Our [comprehensive documentation](http://docs.wprssaggregator.com/) provides you with everything you need to install, set up and customize 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.
63
 
64
- > ### Support ###
65
- > The support section for the free version of WP RSS Aggregator can be found [here on the plugin repository](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?replies=4) before opening a new ticket.
66
- >
67
- > For support related to any of the premium add-ons you should open a [premium support ticket](https://www.wprssaggregator.com/contact/).
68
 
69
- ### As featured on ###
 
 
 
 
 
 
 
 
 
 
 
 
 
 
70
  * [WP Mayor](http://www.wpmayor.com/rss-feeds-review-wp-rss-aggregator/)
 
71
  * [LatestWP](http://www.latestwp.com/2015/03/15/wp-rss-aggregator-plugin-review/)
72
  * [WPBeginner](http://www.wpbeginner.com/plugins/how-to-fetch-feeds-in-wordpress-using-wp-rss-aggregator/)
73
  * [WPExplorer](http://www.wpexplorer.com/custom-rss-aggregator-plugin/)
@@ -75,7 +120,6 @@ We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service
75
  * [Torque](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
76
  * [MyWPexpert](http://www.mywpexpert.com/wordpress-rss-aggregator-plugin)
77
  * [Kikolani](http://kikolani.com/create-latest-posts-portfolio-page-wp-rss-aggregator.html)
78
- * [ManageWP Plugin of the Month](http://managewp.com/free-wordpress-plugins-march-2014)
79
  * [Tidy Repo](http://tidyrepo.com/wp-rss-aggregator/)
80
  * [WPEka](http://www.wpeka.com/wp-rss-aggregators-plugin.html)
81
  * [IndexWP](http://www.indexwp.com/wp-rss-aggregator-plugin-review/)
@@ -89,22 +133,42 @@ We also provide a [Feed Creator](http://createfeed.wprssaggregator.com/) service
89
  * Brazilian Portugese - Bruno Calheira
90
  * Dutch - Erick Suiker
91
 
 
 
 
 
 
 
 
92
  == Installation ==
93
 
94
- Follow these instructions to install the core WP RSS Aggregator plugin:
 
 
 
 
 
 
 
 
 
95
 
96
- > 1. Upload the `wp-rss-aggregator` folder to the `/wp-content/plugins/` directory.
97
- > 2. Activate the WP RSS Aggregator plugin from the 'Plugins' section in your dashboard.
98
- > 3. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
99
- > 4. Use the WP RSS Aggregator shortcode in your posts or pages: `[wp-rss-aggregator]`
 
 
100
 
101
- You can easily select the source for your feeds and also insert a limit via [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters) as shown below. To get your feed source ID please refer to the ID column in your feed source listing page.
 
 
102
 
103
- `[wp-rss-aggregator source=”<ID>” limit=”<num>”]`
104
 
105
  An example of a shortcode parameter in use could be:
106
 
107
- `[wp_rss_aggregator link_before='<li class="feed-link">' link_after='</li>']`
108
 
109
  It is advisable to use the 'HTML' view of the editor when inserting shortcodes with parameters.
110
 
@@ -135,15 +199,14 @@ OR
135
  You can either use the shortcode in your posts and pages:
136
  `[wp-rss-aggregator]`
137
 
138
- or you can call the function directly within your theme:
139
  `<?php wprss_display_feed_items(); ?>`
140
 
141
  - - -
142
 
143
  = Is there a limit on the number of feed sources I can use? =
144
 
145
- There is no limit in place for the number of feed sources. Having many (50+) feed sources should not present any problems in itself.
146
-
147
  However, pulling in posts from many sites is bound to put your server under some stress, so you might want to consider using a hosting solution that goes beyond your typical shared host.
148
 
149
  Check out our dedicated page on [WordPress hosting](http://www.wprssaggregator.com/recommended-web-hosts/) recommendations.
@@ -158,58 +221,89 @@ No, our plugin does not currently import from JSON, it only imports from RSS and
158
 
159
  = Why do I get “No feed items found” when I insert the shortcode on a page or post? =
160
 
161
- Try adding a few more feed sources and make sure they are valid by using the RSS Feed Validator.
 
 
162
 
163
- Secondly make sure your WordPress cron system is working well. If not, the feeds cannot be imported. If in doubt you can go to RSS Aggregator > Debugging and hit the red button to re-import all feed items. If the problem persists contact support.
 
 
 
 
 
164
 
165
  - - -
166
 
167
  = Can I store imported feed items as posts? =
168
 
169
- Yes! You can do that with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on. You will not only be able to store items as posts, but also as other custom post types, as well as set the author, auto set tags and categories, import images into the gallery or set featured images, and much more.
 
 
170
 
171
  - - -
172
 
173
  = Some RSS feeds only give a short excerpt. Any way around that? =
174
 
175
- Yes, along with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on we have another add-on called [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) that can get the full content of those feeds that only supply a short excerpt.
 
 
176
 
177
  - - -
178
 
179
  = I’m not sure which premium add-ons are right for me. Can you help me out? =
180
 
181
- Sure! We wrote a [post](http://www.wprssaggregator.com/add-ons-purchase/) just for you. Read about which add-ons you should buy, we explain the different types of usage so you’ll know what to expect when purchasing.
 
182
 
183
- If you need any further help you can [contact our support team](http://www.wprssaggregator.com/contact/).
 
184
 
185
  - - -
186
 
187
  = Where can I find the documentation for the plugin? =
188
 
189
- Our complete documentation with FAQs included can be found on [our dedicated documentation website](http://docs.wprssaggregator.com/).
190
-
191
- - - -
192
-
193
- > ### Got more questions? ###
194
- > You can find the full list of FAQs [in our documentation](https://docs.wprssaggregator.com/category/faqs/).
195
 
196
  == Screenshots ==
197
 
198
- 1. Feed items imported by WP RSS Aggregator displayed on the front-end using the shortcode.
199
 
200
- 2. Feed Items imported by WP RSS Aggregator and displayed with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on installed.
201
 
202
- 3. Adding/Editing a feed source.
203
 
204
- 4. The feed sources.
205
 
206
- 5. The imported feeds items.
207
 
208
- 6. WP RSS Aggregator's Settings page.
209
 
 
210
 
211
  == Changelog ==
212
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
213
  = 4.9.1 (2016-08-01) =
214
  * Changed copyright and other info in plugin header.
215
 
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
 
 
11
  == Description ==
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
+
111
+ Would you like to praise any member of our team for our plugins or support services? [Share the love!](https://wordpress.org/support/plugin/wp-rss-aggregator/reviews/#new-topic-0)
112
+
113
+ ### As featured on: ###
114
  * [WP Mayor](http://www.wpmayor.com/rss-feeds-review-wp-rss-aggregator/)
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/)
120
  * [Torque](http://torquemag.io/wp-rss-aggregator-review-do-more-with-rss-feeds/)
121
  * [MyWPexpert](http://www.mywpexpert.com/wordpress-rss-aggregator-plugin)
122
  * [Kikolani](http://kikolani.com/create-latest-posts-portfolio-page-wp-rss-aggregator.html)
 
123
  * [Tidy Repo](http://tidyrepo.com/wp-rss-aggregator/)
124
  * [WPEka](http://www.wpeka.com/wp-rss-aggregators-plugin.html)
125
  * [IndexWP](http://www.indexwp.com/wp-rss-aggregator-plugin-review/)
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/).
142
+
143
  == Installation ==
144
 
145
+ Follow these instructions to install and set up the core WP RSS Aggregator plugin:
146
+
147
+ > 1. Download the plugin from the “Download” button above.
148
+ > 2. Upload the `wp-rss-aggregator` zip file to your site's `/wp-content/plugins/` directory.
149
+ > 3. Activate the WP RSS Aggregator plugin from the 'Plugins' section in your dashboard.
150
+ > 4. Configure the plugin by going to the `RSS Aggregator` menu item that appears in your dashboard menu.
151
+ > 5. Set up your [feed sources](https://docs.wprssaggregator.com/adding-a-feed-source-importing-as-feed-items/) and [general settings](https://docs.wprssaggregator.com/general-plugin-settings/).
152
+ > 6. Use the WP RSS Aggregator shortcode in your posts and/or pages to display the imported feed items: `[wp-rss-aggregator]`
153
+
154
+ Alternatively, you can find our plugin through your WordPress dashboard:
155
 
156
+ > 1. Go to the Plugins section in your WordPress site's dashboard.
157
+ > 2. Click the "Add New" button.
158
+ > 3. Search for "WP RSS Aggregator".
159
+ > 4. When found, click on the "Install" button, then hit the "Activate" button once it has installed.
160
+ > 5. Set up your [feed sources](https://docs.wprssaggregator.com/adding-a-feed-source-importing-as-feed-items/) and [general settings](https://docs.wprssaggregator.com/general-plugin-settings/).
161
+ > 6. Use the WP RSS Aggregator shortcode in your posts and/or pages to display the imported feed items: `[wp-rss-aggregator]`
162
 
163
+ You can easily select the source for your feeds and also insert a limit via
164
+ [shortcode parameters](http://docs.wprssaggregator.com/shortcodes/#core-parameters) as shown below.
165
+ To get your feed source ID simply hover over the required feed source in the feed source listing page. It will appear beneath the name.
166
 
167
+ `[wp-rss-aggregator source=”ID limit=”num]`
168
 
169
  An example of a shortcode parameter in use could be:
170
 
171
+ `[wp_rss_aggregator link_before='li class="feed-link"' link_after='/li']`
172
 
173
  It is advisable to use the 'HTML' view of the editor when inserting shortcodes with parameters.
174
 
199
  You can either use the shortcode in your posts and pages:
200
  `[wp-rss-aggregator]`
201
 
202
+ Or you can call the function directly within your theme:
203
  `<?php wprss_display_feed_items(); ?>`
204
 
205
  - - -
206
 
207
  = Is there a limit on the number of feed sources I can use? =
208
 
209
+ No, there is no limit for the number of feed sources. Having many (50+) feed sources should not present any problems in itself.
 
210
  However, pulling in posts from many sites is bound to put your server under some stress, so you might want to consider using a hosting solution that goes beyond your typical shared host.
211
 
212
  Check out our dedicated page on [WordPress hosting](http://www.wprssaggregator.com/recommended-web-hosts/) recommendations.
221
 
222
  = Why do I get “No feed items found” when I insert the shortcode on a page or post? =
223
 
224
+ 1. Try adding a few more feed sources and make sure they are valid by using the RSS Feed Validator.
225
+
226
+ 2. Try out the solutions listed on our [Feed Items Not Importing](http://docs.wprssaggregator.com/feed-items-not-importing/) documentation page.
227
 
228
+ 3. It’s important to make sure your WordPress cron system is working well. If not, the feeds cannot be imported.
229
+ If in doubt, you can install the WP Crontrol plugin to check for [bad cron](https://docs.wprssaggregator.com/cron-intervals/#bad-cron),
230
+ or go to RSS Aggregator > Debugging and hit the red button to re-import all feed items.
231
+
232
+ If the problems persist, please [contact our support team](https://wordpress.org/support/plugin/wp-rss-aggregator).
233
+ If you’re using a premium add-on, please use the [premium support channel](https://www.wprssaggregator.com/contact/).
234
 
235
  - - -
236
 
237
  = Can I store imported feed items as posts? =
238
 
239
+ Yes! You can do that with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) premium add-on.
240
+ You will not only be able to store items as posts, but also as any other custom post type. You can also set the author,
241
+ set tags and categories, import images into the gallery or set featured images, and much more.
242
 
243
  - - -
244
 
245
  = Some RSS feeds only give a short excerpt. Any way around that? =
246
 
247
+ Yes, along with the [Feed to Post](http://www.wprssaggregator.com/extensions/feed-to-post) add-on we have another add-on
248
+ called [Full Text RSS Feeds](http://www.wprssaggregator.com/extension/full-text-rss-feeds/) that can get the full content
249
+ of most feeds that only supply a short excerpt. The Full Text RSS Feeds add-on requires Feed to Post and a valid license key to function.
250
 
251
  - - -
252
 
253
  = I’m not sure which premium add-ons are right for me. Can you help me out? =
254
 
255
+ Sure! We wrote a [post](http://www.wprssaggregator.com/add-ons-purchase/) just for you. Read about which add-ons
256
+ you should buy as we explain the different types of usage so you’ll know what to expect when purchasing.
257
 
258
+ If you need any further help you can [contact our support team](http://www.wprssaggregator.com/contact/) or try out our
259
+ [Simple Feeds Bundle demo](http://simple.wprssaggregator.com/) and [Advanced Feeds Bundle demo](http://demo.wprssaggregator.com/).
260
 
261
  - - -
262
 
263
  = Where can I find the documentation for the plugin? =
264
 
265
+ Our complete documentation with FAQs included can be found on our dedicated [documentation website](http://docs.wprssaggregator.com/).
 
 
 
 
 
266
 
267
  == Screenshots ==
268
 
269
+ 1. The default display, using the shortcode, of the Feed items imported by WP RSS Aggregator.
270
 
271
+ 2. A customised display of the Feed Items using some [CSS styling](https://docs.wprssaggregator.com/styling-the-feeds/).
272
 
273
+ 3. Another customised display of the Feed Items using some CSS styling and with the [Excerpts & Thumbnails](http://www.wprssaggregator.com/extensions/excerpts-thumbnails) add-on installed.
274
 
275
+ 4. Adding/Editing a feed source.
276
 
277
+ 5. The list of feed sources.
278
 
279
+ 6. The list of imported feeds items.
280
 
281
+ 7. The complete settings page for the core plugin.
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.
288
+ * Fixed problem with image cache filenames being too long.
289
+ * Fixed problem with permalink URLs sometimes being URL-encoded.
290
+ * Fixed problem with large logs causing OOM errors and breaking Debugging page.
291
+ * Fixed conflict with function `unparse_url()`.
292
+ * Fixed bug with `_getDataOrConst()` not retrieving single value.
293
+ * Fixed future incompatibility with `class-feed.php` for WP 4.7+.
294
+ * Fixed conflicts with many JS scripts by only adding JS on our admin pages.
295
+ * Fixed conflicts with some classes by loading only valid root namespace components.
296
+ * Fixed PHP warning related to retrieving unique titles.
297
+ * Added a per-feed-source "Link Source" option.
298
+ * Added a per-feed-source "Feed Request User Agent" option.
299
+ * The "Add New" button no longer appears for feed items.
300
+ * Added "Leave a Review" notification.
301
+ * Now using Composer!
302
+ * Now using Phing!
303
+ * Added RegEx HTML Encodifier.
304
+ * Added integration with Diagnostics plugin, and tests.
305
+ * Logs are now created in `wp-content/log/wprss`, and are named more descriptively.
306
+
307
  = 4.9.1 (2016-08-01) =
308
  * Changed copyright and other info in plugin header.
309
 
test/diag/Aventura/Wprss/Core/DiagTest/DiagTest.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest;
4
+
5
+ /**
6
+ * Tests basic functionality of WPRADIAG.
7
+ *
8
+ * @since 4.10
9
+ */
10
+ class DiagTest extends \RebelCode\Wprss\Debug\DiagTest\Model\TestCase
11
+ {
12
+ /**
13
+ * Tests whether the WPRADIAG exists and is able to run tests with assertions.
14
+ *
15
+ * @since 4.10
16
+ */
17
+ public function testWpradiagExists()
18
+ {
19
+ $this->assertTrue(true, 'Diagnostic tests cannot be run');
20
+ }
21
+ }
test/diag/Aventura/Wprss/Core/DiagTest/Model/ModelAbstractTest.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest\Model;
4
+
5
+ use RebelCode\Wprss\Debug\Diagtest\Model\TestCase;
6
+
7
+ /**
8
+ * Tests {@see \Aventura\Wprss\Core\Model\ModelAbstract}.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class ModelAbstractTest extends TestCase
13
+ {
14
+ /**
15
+ * Generate a concrete mock class and return a new instance of it.
16
+ *
17
+ * A mock class is a concrete class that extends or implements
18
+ * a given class or interface.
19
+ *
20
+ * @since 4.10
21
+ *
22
+ * @param string $className Name of the class to create the mock for.
23
+ * @param array $constructorArgs Arguments to be passed to the mock's constructor.
24
+ *
25
+ * @return object
26
+ */
27
+ public function createMock($className, $constructorArgs = array())
28
+ {
29
+ if (!class_exists($className)) {
30
+ throw new \RuntimeException(sprintf('Could not create mock for class "%1$s": class does not exist.', $className));
31
+ }
32
+
33
+ $classRef = new \ReflectionClass($className);
34
+ $parentRelationship = $classRef->isInterface()
35
+ ? 'implements'
36
+ : 'extends';
37
+
38
+ $classBasename = explode('\\', $className);
39
+ $classBasename = array_pop($classBasename);
40
+ $mockClassName = sprintf('Mock_%1$s_%2$s', $classBasename, substr(md5($className), 0, 7));
41
+ if (!class_exists($mockClassName)) {
42
+ $classDefinition = <<<CLASS
43
+ class {$mockClassName} {$parentRelationship} {$className}
44
+ {}
45
+ CLASS;
46
+ eval($classDefinition);
47
+ }
48
+
49
+ $ref = new \ReflectionClass($mockClassName);
50
+ $mock = $ref->newInstanceArgs($constructorArgs);
51
+
52
+ return $mock;
53
+ }
54
+
55
+ /**
56
+ * Creates a new instance of the test subject.
57
+ *
58
+ * @since 4.10
59
+ *
60
+ * @return \Aventura\Wprss\Core\Model\ModelAbstract The new test subject instance.
61
+ */
62
+ public function createInstance()
63
+ {
64
+ return $this->createMock('Aventura\\Wprss\\Core\\Model\\ModelAbstract');
65
+ }
66
+
67
+ /**
68
+ * Tests whether a valid instance of the test subject
69
+ *
70
+ * @since 4.10
71
+ */
72
+ public function testCanBeCreated()
73
+ {
74
+ $subject = $this->createInstance();
75
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Model\ModelAbstract, 'Could not create a valid instance of the subject');
76
+ }
77
+
78
+ /**
79
+ * Tests the `_getDataOrConst()` method.
80
+ *
81
+ * @since 4.10
82
+ */
83
+ public function testGetDataOrConst()
84
+ {
85
+ $subject = $this->createInstance();
86
+ $key = 'my_var';
87
+ $value = 'value1';
88
+ $subject->setData($key, $value);
89
+ $ref = new \ReflectionMethod($subject, '_getDataOrConst');
90
+ $ref->setAccessible(true);
91
+ $result = $ref->invoke($subject, $key);
92
+ $this->assertTrue($result === $value, 'A correct data member value could not be retrieved');
93
+ }
94
+ }
test/diag/Aventura/Wprss/Core/DiagTest/Model/Regex/HtmlEncoderTest.php ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest\Model\Regex;
4
+
5
+ use \RebelCode\Wprss\Debug\Diagtest\Model\TestCase;
6
+
7
+ /**
8
+ * Tests {@see \Aventura\Wprss\Core\Model\Regex\HtmlEncoder}.
9
+ *
10
+ * @since 4.10
11
+ */
12
+ class HtmlEncoderTest extends TestCase
13
+ {
14
+ /**
15
+ * Creates an instance of the test subject.
16
+ *
17
+ * @since 4.10
18
+ *
19
+ * @return \Aventura\Wprss\Core\Model\Regex\HtmlEncoder
20
+ */
21
+ public function createInstance()
22
+ {
23
+ $subject = new \Aventura\Wprss\Core\Model\Regex\HtmlEncoder();
24
+
25
+ return $subject;
26
+ }
27
+
28
+ /**
29
+ * Tests whether a valid instance of the test subject can be created.
30
+ *
31
+ * @since 4.10
32
+ */
33
+ public function testCanBeCreated()
34
+ {
35
+ $subject = $this->createInstance();
36
+
37
+ $this->assertTrue($subject instanceof \Aventura\Wprss\Core\Model\Regex\HtmlEncoder, 'A valid instance of the test subject could not be created');
38
+ }
39
+
40
+ /**
41
+ * Tests whether the subject can encodify an expression in the right way.
42
+ *
43
+ * @since 4.10
44
+ */
45
+ public function testEncodify()
46
+ {
47
+ $subject = $this->createInstance();
48
+ $expr = '<div var="([\w\d]*)">';
49
+
50
+ $encodified = $subject->encodify($expr);
51
+ $expected = <<<'EOD'
52
+ (?:\<|&lt;)div var=(?<_sym1>"|'|&#039;|&apos;|&quot;)([\w\d]*)\g{_sym1}(?:\>|&gt;)
53
+ EOD;
54
+
55
+ $this->assertTrue($encodified === $expected, 'Encodifying did not produce correct result');
56
+ }
57
+
58
+ /**
59
+ * Tests whether expressions encodified by the subject match HTML, both regular and with entities.
60
+ *
61
+ * @since 4.10
62
+ */
63
+ public function testVerifyEncodify()
64
+ {
65
+ $subject = $this->createInstance();
66
+ $html = '<div var="val">';
67
+ $expr = '<div var="([\w\d]*)">';
68
+ $encodedHtml = htmlentities($html);
69
+
70
+ $expr = sprintf('!%1$s!', $subject->encodify($expr));
71
+
72
+ $this->assertTrue( preg_match($expr, $html) === 1, 'Encodified HTML did not match original');
73
+ $this->assertTrue( preg_match($expr, $encodedHtml) === 1, 'Encodified HTML did not match encoded original');
74
+ }
75
+
76
+ /**
77
+ * Tests that encodifying preserves character class definitions literally.
78
+ *
79
+ * @since 4.10
80
+ */
81
+ public function testEncodifyCharClasses()
82
+ {
83
+ $subject = $this->createInstance();
84
+ $html = <<<HTML
85
+ <p style="text-align: justify;">
86
+ <img class=" wp-image-38034 alignleft" src="http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel.jpg" alt="" width="184" height="186"
87
+ srcset="http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel.jpg 360w, http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel-110x110.jpg 110w, http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel-230x233.jpg 230w"
88
+ sizes="(max-width: 184px) 100vw, 184px" />
89
+ Kino Gabriel est le commandant du conseil militaire syriaque, qui participe également à l’offensive « colère de l’Euphrate ».
90
+ </p>
91
+ HTML;
92
+ $expr = '<img[^<>]*?src="[^<>]*?abc[^<>]*?"[^<>]*?>';
93
+ $result = $subject->encodify($expr);
94
+ $expected = <<<REGEX
95
+ (?:\<|&lt;)img[^<>]*?src=(?<_sym1>"|'|&#039;|&apos;|&quot;)[^<>]*?abc[^<>]*?\g{_sym1}[^<>]*?(?:\>|&gt;)
96
+ REGEX;
97
+ $this->assertTrue($expected === $result, 'Encodified expression is wrong, perhaps not preserving char classes');
98
+ }
99
+
100
+ /**
101
+ * Tests that an encodified expression containing a character class with HTML special chars can correctly match HTML.
102
+ *
103
+ * @since 4.10
104
+ */
105
+ public function testValidateCharClasses()
106
+ {
107
+ $subject = $this->createInstance();
108
+ $html = <<<HTML
109
+ <p style="text-align: justify;">
110
+ <img class=" wp-image-38034 alignleft" src="http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel.jpg" alt="" width="184" height="186"
111
+ srcset="http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel.jpg 360w, http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel-110x110.jpg 110w, http://www.kedistan.net/wp-content/uploads/2016/12/Kino-Gabriel-230x233.jpg 230w"
112
+ sizes="(max-width: 184px) 100vw, 184px" />
113
+ Kino Gabriel est le commandant du conseil militaire syriaque, qui participe également à l’offensive « colère de l’Euphrate ».
114
+ </p>
115
+ HTML;
116
+ $expr = '<img[^<>]*?srcset="[^<>]*?http://www\\.kedistan\\.net/wp-content/uploads/2016/12/Kino-Gabriel-110x110\\.jpg[^<>]*?"[^<>]*?>';
117
+ $expr = $subject->encodify($expr);
118
+
119
+ $this->assertTrue(preg_match('!' . $expr . '!Us', $html) === 1, 'Encodified expression did not match subject string, perhaps due to char classes being encodified');
120
+ }
121
+ }
test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/SetTest.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest\Model\Set;
4
+
5
+ use RebelCode\Wprss\Debug\Diagtest\Model\TestCase;
6
+ use Aventura\Wprss\Core\Model\Set;
7
+
8
+ /**
9
+ * Tests {@see \Aventura\Wprss\Core\Model\Set\Set}.
10
+ *
11
+ * @since 4.10
12
+ */
13
+ class SetTest extends TestCase
14
+ {
15
+ /**
16
+ * Creates a new instance of the test subject.
17
+ *
18
+ * @since 4.10
19
+ *
20
+ * @return Set\Set The new instance of the test subject.
21
+ */
22
+ public function createInstance()
23
+ {
24
+ $set = new Set\Set();
25
+
26
+ return $set;
27
+ }
28
+
29
+ /**
30
+ * Tests whether a valid instance of the test subject can be created.
31
+ *
32
+ * @since 4.10
33
+ */
34
+ public function testCanBeCreated()
35
+ {
36
+ $subject = $this->createInstance();
37
+
38
+ $this->assertTrue($subject instanceof Set\SetInterface, 'An valid instance of the test subject could not be created');
39
+ }
40
+
41
+ /**
42
+ * Tests whether synonyms can be retrieved correctly.
43
+ *
44
+ * @since 4.10
45
+ */
46
+ public function testManipulateAndRead()
47
+ {
48
+ $subject = $this->createInstance();
49
+
50
+ $items = array('apple', 'banana', 'orange');
51
+ $subject->addMany($items);
52
+ $this->assertTrue($subject->items() == $items, 'Incorrect item set retrieved after adding multiple items');
53
+
54
+ $subject->add('pineapple');
55
+ array_push($items, 'pineapple');
56
+ $this->assertTrue($subject->items() == $items, 'Incorrect item set retrieved after adding an item');
57
+ $this->assertTrue(count($subject) === 4, 'Incorrect item count retrieved');
58
+
59
+ $subject->remove('orange');
60
+ $this->assertTrue(array_values($subject->items()) == array('apple', 'banana', 'pineapple'), 'Incorrect item set retrieved after removing an item');
61
+ $this->assertTrue(count($subject) === 3, 'Incorrect item count retrieved');
62
+
63
+ $this->assertTrue($subject->has('apple'), 'Subject incorrectly determined having an item');
64
+ $this->assertTrue($subject->has('banana'), 'Subject incorrectly determined having an item');
65
+ $this->assertTrue($subject->has('pineapple'), 'Subject incorrectly determined having an item');
66
+ $this->assertFalse($subject->has('orange'), 'Subject incorrectly determined not having an item');
67
+ $this->assertFalse($subject->has('strawberry'), 'Subject incorrectly determined not having an item');
68
+
69
+ $subject->clear();
70
+ $this->assertTrue($subject->items() == array(), 'Incorrect item set retrieved after clearing items');
71
+ $this->assertTrue(count($subject) === 0, 'Incorrect item count retrieved after clearing items');
72
+ }
73
+
74
+ /**
75
+ * Tests that iteration over the subject produces correct results.
76
+ *
77
+ * @since 4.10
78
+ */
79
+ public function testIteration()
80
+ {
81
+ $subject = $this->createInstance();
82
+ $items = array('apple', 'banana', 'strawberry');
83
+
84
+ $subject->addMany($items);
85
+ $itItems = array();
86
+ foreach ($subject as $item) {
87
+ $itItems[] = $item;
88
+ }
89
+
90
+ $this->assertTrue($items == $itItems, 'Iteration over set did not produce desired results');
91
+ }
92
+ }
test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/Synonym/SetTest.php ADDED
@@ -0,0 +1,94 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest\Model\Set\Synonym;
4
+
5
+ use RebelCode\Wprss\Debug\Diagtest\Model\TestCase;
6
+ use Aventura\Wprss\Core\Model\Set\Synonym;
7
+
8
+ /**
9
+ * Tests {@see \Aventura\Wprss\Core\Model\Set\Synonym\Set}.
10
+ *
11
+ * @since 4.10
12
+ */
13
+ class SetTest extends TestCase
14
+ {
15
+ /**
16
+ * Creates a new instance of the test subject.
17
+ *
18
+ * @since 4.10
19
+ *
20
+ * @return Synonym\Set The new instance of the test subject.
21
+ */
22
+ public function createInstance()
23
+ {
24
+ $set = new Synonym\Set();
25
+
26
+ return $set;
27
+ }
28
+
29
+ /**
30
+ * Creates a new synonym set.
31
+ *
32
+ * @since 4.10
33
+ *
34
+ * @param string[] $synonyms An array of synonyms to populate the set with.
35
+ */
36
+ public function createSynonymSet(array $synonyms = array())
37
+ {
38
+ $set = new Synonym\Simple($synonyms);
39
+
40
+ return $set;
41
+ }
42
+
43
+ /**
44
+ * Tests whether a valid instance of the test subject can be created.
45
+ *
46
+ * @since 4.10
47
+ */
48
+ public function testCanBeCreated()
49
+ {
50
+ $subject = $this->createInstance();
51
+
52
+ $this->assertTrue($subject instanceof Synonym\SynonymSetSetInterface, 'An valid instance of the test subject could not be created');
53
+ }
54
+
55
+ /**
56
+ * Tests whether an existing set can be retrieved for a term.
57
+ *
58
+ * @since 4.10
59
+ */
60
+ public function testGetSetForTerm()
61
+ {
62
+ $subject = $this->createInstance();
63
+
64
+ $set1 = $this->createSynonymSet(array('apple', 'banana', 'orange'));
65
+ $set2 = $this->createSynonymSet(array('tomato', 'cucumber', 'radish'));
66
+ $subject->addMany(array($set1, $set2));
67
+
68
+ $this->assertTrue($subject->getSetForTerm('banana') === $set1, 'Incorrect set retrieved for fruit term');
69
+ $this->assertTrue($subject->getSetForTerm('cucumber') === $set2, 'Incorrect set retrieved for vegetable term');
70
+
71
+ $animal = 'cat';
72
+ $animalSet = $subject->getSetForTerm($animal);
73
+ $this->assertTrue(iterator_to_array($animalSet) == array($animal), 'Incorrect set retrieved for animal term');
74
+ }
75
+
76
+ /**
77
+ * Tests whether the subject accepts only strings as its items.
78
+ *
79
+ * @since 4.10
80
+ */
81
+ public function testStringsOnlyAllowed()
82
+ {
83
+ $subject = $this->createInstance();
84
+
85
+ $valid = true;
86
+ try {
87
+ $subject->add(new \stdClass());
88
+ } catch (\RuntimeException $ex) {
89
+ $valid = false;
90
+ }
91
+
92
+ $this->assertFalse($valid, 'A synonym set must only accept strings');
93
+ }
94
+ }
test/diag/Aventura/Wprss/Core/DiagTest/Model/Set/Synonym/SimpleTest.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Aventura\Wprss\Core\DiagTest\Model\Set\Synonym;
4
+
5
+ use \RebelCode\Wprss\Debug\Diagtest\Model\TestCase;
6
+ use Aventura\Wprss\Core\Model\Set\Synonym;
7
+
8
+ /**
9
+ * Tests {@see \Aventura\Wprss\Core\Model\Set\Synonym\Simple}.
10
+ *
11
+ * @since 4.10
12
+ */
13
+ class SimpleTest extends TestCase
14
+ {
15
+ /**
16
+ * Creates a new instance of the test subject.
17
+ *
18
+ * @since 4.10
19
+ *
20
+ * @return Synonym\Simple The new instance of the test subject.
21
+ */
22
+ public function createInstance()
23
+ {
24
+ $set = new Synonym\Simple();
25
+
26
+ return $set;
27
+ }
28
+
29
+ /**
30
+ * Tests whether a valid instance of the test subject can be created.
31
+ *
32
+ * @since 4.10
33
+ */
34
+ public function testCanBeCreated()
35
+ {
36
+ $subject = $this->createInstance();
37
+
38
+ $this->assertTrue($subject instanceof Synonym\SynonymSetInterface, 'An valid instance of the test subject could not be created');
39
+ }
40
+
41
+ /**
42
+ * Tests whether synonyms can be retrieved correctly.
43
+ *
44
+ * @since 4.10
45
+ */
46
+ public function testGetSynonyms()
47
+ {
48
+ $subject = $this->createInstance();
49
+
50
+ $subject->addMany(array('apple', 'banana', 'orange'));
51
+ $this->assertTrue($subject->getSynonyms('banana') == array('apple', 'orange'), 'A correct list of synonyms could not be retrieved');
52
+ }
53
+
54
+ /**
55
+ * Tests whether the subject accepts only strings as its items.
56
+ *
57
+ * @since 4.10
58
+ */
59
+ public function testStringsOnlyAllowed()
60
+ {
61
+ $subject = $this->createInstance();
62
+
63
+ $valid = true;
64
+ try {
65
+ $subject->add(new \stdClass());
66
+ } catch (\RuntimeException $ex) {
67
+ $valid = false;
68
+ }
69
+
70
+ $this->assertFalse($valid, 'A synonym set must only accept strings');
71
+ }
72
+ }
vendor/autoload.php ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload.php @generated by Composer
4
+
5
+ require_once __DIR__ . '/composer/autoload_real.php';
6
+
7
+ return ComposerAutoloaderInit5b1214f1b4db5e953417a3c5488d163a::getLoader();
vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,415 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of Composer.
5
+ *
6
+ * (c) Nils Adermann <naderman@naderman.de>
7
+ * Jordi Boggiano <j.boggiano@seld.be>
8
+ *
9
+ * For the full copyright and license information, please view the LICENSE
10
+ * file that was distributed with this source code.
11
+ */
12
+
13
+ namespace Composer\Autoload;
14
+
15
+ /**
16
+ * ClassLoader implements a PSR-0, PSR-4 and classmap class loader.
17
+ *
18
+ * $loader = new \Composer\Autoload\ClassLoader();
19
+ *
20
+ * // register classes with namespaces
21
+ * $loader->add('Symfony\Component', __DIR__.'/component');
22
+ * $loader->add('Symfony', __DIR__.'/framework');
23
+ *
24
+ * // activate the autoloader
25
+ * $loader->register();
26
+ *
27
+ * // to enable searching the include path (eg. for PEAR packages)
28
+ * $loader->setUseIncludePath(true);
29
+ *
30
+ * In this example, if you try to use a class in the Symfony\Component
31
+ * namespace or one of its children (Symfony\Component\Console for instance),
32
+ * the autoloader will first look for the class under the component/
33
+ * directory, and it will then fallback to the framework/ directory if not
34
+ * found before giving up.
35
+ *
36
+ * This class is loosely based on the Symfony UniversalClassLoader.
37
+ *
38
+ * @author Fabien Potencier <fabien@symfony.com>
39
+ * @author Jordi Boggiano <j.boggiano@seld.be>
40
+ * @see http://www.php-fig.org/psr/psr-0/
41
+ * @see http://www.php-fig.org/psr/psr-4/
42
+ */
43
+ class ClassLoader
44
+ {
45
+ // PSR-4
46
+ private $prefixLengthsPsr4 = array();
47
+ private $prefixDirsPsr4 = array();
48
+ private $fallbackDirsPsr4 = array();
49
+
50
+ // PSR-0
51
+ private $prefixesPsr0 = array();
52
+ private $fallbackDirsPsr0 = array();
53
+
54
+ private $useIncludePath = false;
55
+ private $classMap = array();
56
+ private $classMapAuthoritative = false;
57
+ private $missingClasses = array();
58
+
59
+ public function getPrefixes()
60
+ {
61
+ if (!empty($this->prefixesPsr0)) {
62
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
63
+ }
64
+
65
+ return array();
66
+ }
67
+
68
+ public function getPrefixesPsr4()
69
+ {
70
+ return $this->prefixDirsPsr4;
71
+ }
72
+
73
+ public function getFallbackDirs()
74
+ {
75
+ return $this->fallbackDirsPsr0;
76
+ }
77
+
78
+ public function getFallbackDirsPsr4()
79
+ {
80
+ return $this->fallbackDirsPsr4;
81
+ }
82
+
83
+ public function getClassMap()
84
+ {
85
+ return $this->classMap;
86
+ }
87
+
88
+ /**
89
+ * @param array $classMap Class to filename map
90
+ */
91
+ public function addClassMap(array $classMap)
92
+ {
93
+ if ($this->classMap) {
94
+ $this->classMap = array_merge($this->classMap, $classMap);
95
+ } else {
96
+ $this->classMap = $classMap;
97
+ }
98
+ }
99
+
100
+ /**
101
+ * Registers a set of PSR-0 directories for a given prefix, either
102
+ * appending or prepending to the ones previously set for this prefix.
103
+ *
104
+ * @param string $prefix The prefix
105
+ * @param array|string $paths The PSR-0 root directories
106
+ * @param bool $prepend Whether to prepend the directories
107
+ */
108
+ public function add($prefix, $paths, $prepend = false)
109
+ {
110
+ if (!$prefix) {
111
+ if ($prepend) {
112
+ $this->fallbackDirsPsr0 = array_merge(
113
+ (array) $paths,
114
+ $this->fallbackDirsPsr0
115
+ );
116
+ } else {
117
+ $this->fallbackDirsPsr0 = array_merge(
118
+ $this->fallbackDirsPsr0,
119
+ (array) $paths
120
+ );
121
+ }
122
+
123
+ return;
124
+ }
125
+
126
+ $first = $prefix[0];
127
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
128
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
129
+
130
+ return;
131
+ }
132
+ if ($prepend) {
133
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
134
+ (array) $paths,
135
+ $this->prefixesPsr0[$first][$prefix]
136
+ );
137
+ } else {
138
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
139
+ $this->prefixesPsr0[$first][$prefix],
140
+ (array) $paths
141
+ );
142
+ }
143
+ }
144
+
145
+ /**
146
+ * Registers a set of PSR-4 directories for a given namespace, either
147
+ * appending or prepending to the ones previously set for this namespace.
148
+ *
149
+ * @param string $prefix The prefix/namespace, with trailing '\\'
150
+ * @param array|string $paths The PSR-4 base directories
151
+ * @param bool $prepend Whether to prepend the directories
152
+ *
153
+ * @throws \InvalidArgumentException
154
+ */
155
+ public function addPsr4($prefix, $paths, $prepend = false)
156
+ {
157
+ if (!$prefix) {
158
+ // Register directories for the root namespace.
159
+ if ($prepend) {
160
+ $this->fallbackDirsPsr4 = array_merge(
161
+ (array) $paths,
162
+ $this->fallbackDirsPsr4
163
+ );
164
+ } else {
165
+ $this->fallbackDirsPsr4 = array_merge(
166
+ $this->fallbackDirsPsr4,
167
+ (array) $paths
168
+ );
169
+ }
170
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
171
+ // Register directories for a new namespace.
172
+ $length = strlen($prefix);
173
+ if ('\\' !== $prefix[$length - 1]) {
174
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
175
+ }
176
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
177
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
178
+ } elseif ($prepend) {
179
+ // Prepend directories for an already registered namespace.
180
+ $this->prefixDirsPsr4[$prefix] = array_merge(
181
+ (array) $paths,
182
+ $this->prefixDirsPsr4[$prefix]
183
+ );
184
+ } else {
185
+ // Append directories for an already registered namespace.
186
+ $this->prefixDirsPsr4[$prefix] = array_merge(
187
+ $this->prefixDirsPsr4[$prefix],
188
+ (array) $paths
189
+ );
190
+ }
191
+ }
192
+
193
+ /**
194
+ * Registers a set of PSR-0 directories for a given prefix,
195
+ * replacing any others previously set for this prefix.
196
+ *
197
+ * @param string $prefix The prefix
198
+ * @param array|string $paths The PSR-0 base directories
199
+ */
200
+ public function set($prefix, $paths)
201
+ {
202
+ if (!$prefix) {
203
+ $this->fallbackDirsPsr0 = (array) $paths;
204
+ } else {
205
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
206
+ }
207
+ }
208
+
209
+ /**
210
+ * Registers a set of PSR-4 directories for a given namespace,
211
+ * replacing any others previously set for this namespace.
212
+ *
213
+ * @param string $prefix The prefix/namespace, with trailing '\\'
214
+ * @param array|string $paths The PSR-4 base directories
215
+ *
216
+ * @throws \InvalidArgumentException
217
+ */
218
+ public function setPsr4($prefix, $paths)
219
+ {
220
+ if (!$prefix) {
221
+ $this->fallbackDirsPsr4 = (array) $paths;
222
+ } else {
223
+ $length = strlen($prefix);
224
+ if ('\\' !== $prefix[$length - 1]) {
225
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
226
+ }
227
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
228
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
229
+ }
230
+ }
231
+
232
+ /**
233
+ * Turns on searching the include path for class files.
234
+ *
235
+ * @param bool $useIncludePath
236
+ */
237
+ public function setUseIncludePath($useIncludePath)
238
+ {
239
+ $this->useIncludePath = $useIncludePath;
240
+ }
241
+
242
+ /**
243
+ * Can be used to check if the autoloader uses the include path to check
244
+ * for classes.
245
+ *
246
+ * @return bool
247
+ */
248
+ public function getUseIncludePath()
249
+ {
250
+ return $this->useIncludePath;
251
+ }
252
+
253
+ /**
254
+ * Turns off searching the prefix and fallback directories for classes
255
+ * that have not been registered with the class map.
256
+ *
257
+ * @param bool $classMapAuthoritative
258
+ */
259
+ public function setClassMapAuthoritative($classMapAuthoritative)
260
+ {
261
+ $this->classMapAuthoritative = $classMapAuthoritative;
262
+ }
263
+
264
+ /**
265
+ * Should class lookup fail if not found in the current class map?
266
+ *
267
+ * @return bool
268
+ */
269
+ public function isClassMapAuthoritative()
270
+ {
271
+ return $this->classMapAuthoritative;
272
+ }
273
+
274
+ /**
275
+ * Registers this instance as an autoloader.
276
+ *
277
+ * @param bool $prepend Whether to prepend the autoloader or not
278
+ */
279
+ public function register($prepend = false)
280
+ {
281
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
282
+ }
283
+
284
+ /**
285
+ * Unregisters this instance as an autoloader.
286
+ */
287
+ public function unregister()
288
+ {
289
+ spl_autoload_unregister(array($this, 'loadClass'));
290
+ }
291
+
292
+ /**
293
+ * Loads the given class or interface.
294
+ *
295
+ * @param string $class The name of the class
296
+ * @return bool|null True if loaded, null otherwise
297
+ */
298
+ public function loadClass($class)
299
+ {
300
+ if ($file = $this->findFile($class)) {
301
+ includeFile($file);
302
+
303
+ return true;
304
+ }
305
+ }
306
+
307
+ /**
308
+ * Finds the path to the file where the class is defined.
309
+ *
310
+ * @param string $class The name of the class
311
+ *
312
+ * @return string|false The path if found, false otherwise
313
+ */
314
+ public function findFile($class)
315
+ {
316
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
317
+ if ('\\' == $class[0]) {
318
+ $class = substr($class, 1);
319
+ }
320
+
321
+ // class map lookup
322
+ if (isset($this->classMap[$class])) {
323
+ return $this->classMap[$class];
324
+ }
325
+ if ($this->classMapAuthoritative || isset($this->missingClasses[$class])) {
326
+ return false;
327
+ }
328
+
329
+ $file = $this->findFileWithExtension($class, '.php');
330
+
331
+ // Search for Hack files if we are running on HHVM
332
+ if (false === $file && defined('HHVM_VERSION')) {
333
+ $file = $this->findFileWithExtension($class, '.hh');
334
+ }
335
+
336
+ if (false === $file) {
337
+ // Remember that this class does not exist.
338
+ $this->missingClasses[$class] = true;
339
+ }
340
+
341
+ return $file;
342
+ }
343
+
344
+ private function findFileWithExtension($class, $ext)
345
+ {
346
+ // PSR-4 lookup
347
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
348
+
349
+ $first = $class[0];
350
+ if (isset($this->prefixLengthsPsr4[$first])) {
351
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
352
+ if (0 === strpos($class, $prefix)) {
353
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
354
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
355
+ return $file;
356
+ }
357
+ }
358
+ }
359
+ }
360
+ }
361
+
362
+ // PSR-4 fallback dirs
363
+ foreach ($this->fallbackDirsPsr4 as $dir) {
364
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
365
+ return $file;
366
+ }
367
+ }
368
+
369
+ // PSR-0 lookup
370
+ if (false !== $pos = strrpos($class, '\\')) {
371
+ // namespaced class name
372
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
373
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
374
+ } else {
375
+ // PEAR-like class name
376
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
377
+ }
378
+
379
+ if (isset($this->prefixesPsr0[$first])) {
380
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
381
+ if (0 === strpos($class, $prefix)) {
382
+ foreach ($dirs as $dir) {
383
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
384
+ return $file;
385
+ }
386
+ }
387
+ }
388
+ }
389
+ }
390
+
391
+ // PSR-0 fallback dirs
392
+ foreach ($this->fallbackDirsPsr0 as $dir) {
393
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
394
+ return $file;
395
+ }
396
+ }
397
+
398
+ // PSR-0 include paths.
399
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
400
+ return $file;
401
+ }
402
+
403
+ return false;
404
+ }
405
+ }
406
+
407
+ /**
408
+ * Scope isolated include.
409
+ *
410
+ * Prevents access to $this/self from included files.
411
+ */
412
+ function includeFile($file)
413
+ {
414
+ include $file;
415
+ }
vendor/composer/LICENSE ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ Copyright (c) 2016 Nils Adermann, Jordi Boggiano
3
+
4
+ Permission is hereby granted, free of charge, to any person obtaining a copy
5
+ of this software and associated documentation files (the "Software"), to deal
6
+ in the Software without restriction, including without limitation the rights
7
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8
+ copies of the Software, and to permit persons to whom the Software is furnished
9
+ to do so, subject to the following conditions:
10
+
11
+ The above copyright notice and this permission notice shall be included in all
12
+ copies or substantial portions of the Software.
13
+
14
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20
+ THE SOFTWARE.
21
+
vendor/composer/autoload_classmap.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_classmap.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
vendor/composer/autoload_namespaces.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_namespaces.php @generated by Composer
4
+
5
+ $vendorDir = dirname(dirname(__FILE__));
6
+ $baseDir = dirname($vendorDir);
7
+
8
+ return array(
9
+ );
vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_psr4.php @generated by Composer
4
+
5
+ $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
+ );
vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInit5b1214f1b4db5e953417a3c5488d163a
6
+ {
7
+ private static $loader;
8
+
9
+ public static function loadClassLoader($class)
10
+ {
11
+ if ('Composer\Autoload\ClassLoader' === $class) {
12
+ require __DIR__ . '/ClassLoader.php';
13
+ }
14
+ }
15
+
16
+ public static function getLoader()
17
+ {
18
+ if (null !== self::$loader) {
19
+ return self::$loader;
20
+ }
21
+
22
+ spl_autoload_register(array('ComposerAutoloaderInit5b1214f1b4db5e953417a3c5488d163a', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInit5b1214f1b4db5e953417a3c5488d163a', 'loadClassLoader'));
25
+
26
+ $useStaticLoader = PHP_VERSION_ID >= 50600 && !defined('HHVM_VERSION') && (!function_exists('zend_loader_file_encoded') || !zend_loader_file_encoded());
27
+ if ($useStaticLoader) {
28
+ require_once __DIR__ . '/autoload_static.php';
29
+
30
+ call_user_func(\Composer\Autoload\ComposerStaticInit5b1214f1b4db5e953417a3c5488d163a::getInitializer($loader));
31
+ } else {
32
+ $map = require __DIR__ . '/autoload_namespaces.php';
33
+ foreach ($map as $namespace => $path) {
34
+ $loader->set($namespace, $path);
35
+ }
36
+
37
+ $map = require __DIR__ . '/autoload_psr4.php';
38
+ foreach ($map as $namespace => $path) {
39
+ $loader->setPsr4($namespace, $path);
40
+ }
41
+
42
+ $classMap = require __DIR__ . '/autoload_classmap.php';
43
+ if ($classMap) {
44
+ $loader->addClassMap($classMap);
45
+ }
46
+ }
47
+
48
+ $loader->register(true);
49
+
50
+ return $loader;
51
+ }
52
+ }
vendor/composer/autoload_static.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_static.php @generated by Composer
4
+
5
+ namespace Composer\Autoload;
6
+
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',
26
+ 1 => __DIR__ . '/..' . '/dhii/collections-abstract-base/src',
27
+ 2 => __DIR__ . '/..' . '/dhii/collections-abstract/src',
28
+ ),
29
+ );
30
+
31
+ public static function getInitializer(ClassLoader $loader)
32
+ {
33
+ return \Closure::bind(function () use ($loader) {
34
+ $loader->prefixLengthsPsr4 = ComposerStaticInit5b1214f1b4db5e953417a3c5488d163a::$prefixLengthsPsr4;
35
+ $loader->prefixDirsPsr4 = ComposerStaticInit5b1214f1b4db5e953417a3c5488d163a::$prefixDirsPsr4;
36
+
37
+ }, null, ClassLoader::class);
38
+ }
39
+ }
vendor/composer/installed.json ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "dhii/stats-interface",
4
+ "version": "v0.1.0",
5
+ "version_normalized": "0.1.0.0",
6
+ "source": {
7
+ "type": "git",
8
+ "url": "https://github.com/Dhii/stats-interface.git",
9
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba"
10
+ },
11
+ "dist": {
12
+ "type": "zip",
13
+ "url": "https://api.github.com/repos/Dhii/stats-interface/zipball/36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
14
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
15
+ "shasum": ""
16
+ },
17
+ "require": {
18
+ "php": "^5.3 | ^7.0"
19
+ },
20
+ "require-dev": {
21
+ "dhii/php-cs-fixer-config": "dev-php-5.3"
22
+ },
23
+ "time": "2016-11-10 15:38:37",
24
+ "type": "library",
25
+ "installation-source": "dist",
26
+ "autoload": {
27
+ "psr-4": {
28
+ "Dhii\\Stats\\": "src/"
29
+ }
30
+ },
31
+ "notification-url": "https://packagist.org/downloads/",
32
+ "license": [
33
+ "MIT"
34
+ ],
35
+ "authors": [
36
+ {
37
+ "name": "Dhii Team",
38
+ "email": "development@dhii.co"
39
+ }
40
+ ],
41
+ "description": "Interfaces for stats"
42
+ },
43
+ {
44
+ "name": "dhii/collections-interface",
45
+ "version": "v0.1.2",
46
+ "version_normalized": "0.1.2.0",
47
+ "source": {
48
+ "type": "git",
49
+ "url": "https://github.com/Dhii/collections-interface.git",
50
+ "reference": "a8e9a30366a30d77bc270042a67150b3f8f6d94d"
51
+ },
52
+ "dist": {
53
+ "type": "zip",
54
+ "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/a8e9a30366a30d77bc270042a67150b3f8f6d94d",
55
+ "reference": "a8e9a30366a30d77bc270042a67150b3f8f6d94d",
56
+ "shasum": ""
57
+ },
58
+ "require": {
59
+ "php": "^5.3 | ^7.0"
60
+ },
61
+ "require-dev": {
62
+ "codeclimate/php-test-reporter": "dev-master",
63
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
64
+ "phpunit/phpunit": "^4.8"
65
+ },
66
+ "time": "2016-11-16 14:45:08",
67
+ "type": "library",
68
+ "installation-source": "dist",
69
+ "autoload": {
70
+ "psr-4": {
71
+ "Dhii\\Collection\\": "src/"
72
+ }
73
+ },
74
+ "notification-url": "https://packagist.org/downloads/",
75
+ "license": [
76
+ "MIT"
77
+ ],
78
+ "authors": [
79
+ {
80
+ "name": "Dhii Team",
81
+ "email": "development@dhii.co"
82
+ }
83
+ ],
84
+ "description": "Interfaces for collections"
85
+ },
86
+ {
87
+ "name": "dhii/collections-abstract-base",
88
+ "version": "v0.1.0",
89
+ "version_normalized": "0.1.0.0",
90
+ "source": {
91
+ "type": "git",
92
+ "url": "https://github.com/Dhii/collections-abstract-base.git",
93
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3"
94
+ },
95
+ "dist": {
96
+ "type": "zip",
97
+ "url": "https://api.github.com/repos/Dhii/collections-abstract-base/zipball/0ec0147451a72a13fb327ac6ff747c5e953c56f3",
98
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3",
99
+ "shasum": ""
100
+ },
101
+ "require": {
102
+ "dhii/collections-interface": "^0.1.1"
103
+ },
104
+ "require-dev": {
105
+ "codeclimate/php-test-reporter": "dev-master",
106
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
107
+ "phpunit/phpunit": "^4.8",
108
+ "ptrofimov/xpmock": "^1.1"
109
+ },
110
+ "time": "2016-11-10 15:09:37",
111
+ "type": "library",
112
+ "installation-source": "dist",
113
+ "autoload": {
114
+ "psr-4": {
115
+ "Dhii\\Collection\\": "src/"
116
+ }
117
+ },
118
+ "notification-url": "https://packagist.org/downloads/",
119
+ "license": [
120
+ "MIT"
121
+ ],
122
+ "authors": [
123
+ {
124
+ "name": "Dhii Team",
125
+ "email": "development@dhii.co"
126
+ }
127
+ ],
128
+ "description": "Collection base classes that do not depend on other non-collection packages, on which there is a dependency of other collection packages that depend on this package. This is done to avoid circular reference in the collection toolchain"
129
+ },
130
+ {
131
+ "name": "dhii/stats-abstract",
132
+ "version": "v0.1.0",
133
+ "version_normalized": "0.1.0.0",
134
+ "source": {
135
+ "type": "git",
136
+ "url": "https://github.com/Dhii/stats-abstract.git",
137
+ "reference": "71f6702c3257c71ab3917b6d076d3c3588cc9f49"
138
+ },
139
+ "dist": {
140
+ "type": "zip",
141
+ "url": "https://api.github.com/repos/Dhii/stats-abstract/zipball/71f6702c3257c71ab3917b6d076d3c3588cc9f49",
142
+ "reference": "71f6702c3257c71ab3917b6d076d3c3588cc9f49",
143
+ "shasum": ""
144
+ },
145
+ "require": {
146
+ "dhii/collections-abstract-base": "^0.1.0",
147
+ "dhii/stats-interface": "^0.1.0"
148
+ },
149
+ "require-dev": {
150
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
151
+ "phpunit/phpunit": "^4.8",
152
+ "ptrofimov/xpmock": "^1.1"
153
+ },
154
+ "time": "2016-11-10 18:55:43",
155
+ "type": "library",
156
+ "installation-source": "dist",
157
+ "autoload": {
158
+ "psr-4": {
159
+ "Dhii\\Stats\\": "src/"
160
+ }
161
+ },
162
+ "notification-url": "https://packagist.org/downloads/",
163
+ "license": [
164
+ "MIT"
165
+ ],
166
+ "authors": [
167
+ {
168
+ "name": "Dhii Team",
169
+ "email": "development@dhii.co"
170
+ }
171
+ ],
172
+ "description": "Abstract base for stats"
173
+ },
174
+ {
175
+ "name": "dhii/collections-abstract",
176
+ "version": "v0.1.0",
177
+ "version_normalized": "0.1.0.0",
178
+ "source": {
179
+ "type": "git",
180
+ "url": "https://github.com/Dhii/collections-abstract.git",
181
+ "reference": "7c9141202af4d83b31e75efcbf481fa1cb588ad8"
182
+ },
183
+ "dist": {
184
+ "type": "zip",
185
+ "url": "https://api.github.com/repos/Dhii/collections-abstract/zipball/7c9141202af4d83b31e75efcbf481fa1cb588ad8",
186
+ "reference": "7c9141202af4d83b31e75efcbf481fa1cb588ad8",
187
+ "shasum": ""
188
+ },
189
+ "require": {
190
+ "dhii/collections-abstract-base": "^0.1.0",
191
+ "dhii/collections-interface": "^0.1.1",
192
+ "dhii/stats-abstract": "^0.1.0"
193
+ },
194
+ "require-dev": {
195
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
196
+ "phpunit/phpunit": "4.*",
197
+ "ptrofimov/xpmock": "^1.1"
198
+ },
199
+ "time": "2016-11-10 19:29:24",
200
+ "type": "library",
201
+ "installation-source": "dist",
202
+ "autoload": {
203
+ "psr-4": {
204
+ "Dhii\\Collection\\": "src/"
205
+ }
206
+ },
207
+ "notification-url": "https://packagist.org/downloads/",
208
+ "license": [
209
+ "MIT"
210
+ ],
211
+ "authors": [
212
+ {
213
+ "name": "Dhii Team",
214
+ "email": "development@dhii.co"
215
+ }
216
+ ],
217
+ "description": "A collections library"
218
+ }
219
+ ]
vendor/dhii/collections-abstract-base/.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/collections-abstract-base/.php_cs ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
4
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
5
+ $fixers = $config->getFixers();
6
+
7
+ $toRemove = array();
8
+ foreach ($toRemove as $_fixer) {
9
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
10
+ continue;
11
+ }
12
+
13
+ unset($fixers[$removeIndex]);
14
+ }
15
+
16
+ $toAdd = array();
17
+ foreach ($toAdd as $_fixer) {
18
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
19
+ continue;
20
+ }
21
+
22
+ $fixers[] = $_fixer;
23
+ }
24
+
25
+ $config->fixers($fixers);
26
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
27
+ return $config;
vendor/dhii/collections-abstract-base/.travis.yml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 install
13
+
14
+ script:
15
+ - phpunit
16
+
17
+ after_script:
18
+ - vendor/bin/test-reporter --coverage-report="test/coverage/clover.xml"
19
+
20
+ addons:
21
+ code_climate:
22
+ repo_token: d8aa48cb7625d0b076db7af32c0d0433ba7b93d68ff0749a195c3dcf85771e67
vendor/dhii/collections-abstract-base/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
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.0 - 2016-11-10
8
+ The initial release
vendor/dhii/collections-abstract-base/README.md ADDED
@@ -0,0 +1,10 @@
 
 
 
 
 
 
 
 
 
 
1
+ ## Collections - Abstract Base ##
2
+ [![Build Status](https://travis-ci.org/Dhii/collections-abstract-base.svg?branch=master)](https://travis-ci.org/Dhii/collections-abstract-base)
3
+ [![Code Climate](https://codeclimate.com/github/Dhii/collections-abstract-base/badges/gpa.svg)](https://codeclimate.com/github/Dhii/collections-abstract-base)
4
+ [![Test Coverage](https://codeclimate.com/github/Dhii/collections-abstract-base/badges/coverage.svg)](https://codeclimate.com/github/Dhii/collections-abstract-base/coverage)
5
+
6
+ The abstract base classes for collections.
7
+
8
+ This exists in order not to create a circular reference between generic and
9
+ more specialized collection classes, which would otherwise be inevitable
10
+ due to the unavailability of traits in the target version of PHP.
vendor/dhii/collections-abstract-base/composer.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/collections-abstract-base",
3
+ "description": "Collection base classes that do not depend on other non-collection packages, on which there is a dependency of other collection packages that depend on this package. This is done to avoid circular reference in the collection toolchain",
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
+ "dhii/collections-interface": "^0.1.1"
15
+ },
16
+ "require-dev": {
17
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
18
+ "phpunit/phpunit": "^4.8",
19
+ "ptrofimov/xpmock": "^1.1",
20
+ "codeclimate/php-test-reporter": "dev-master"
21
+ },
22
+ "autoload": {
23
+ "psr-4": {
24
+ "Dhii\\Collection\\": "src/"
25
+ }
26
+ }
27
+ }
vendor/dhii/collections-abstract-base/composer.lock ADDED
@@ -0,0 +1,2015 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "845a0c94f3b04992f2bf9947027c8a6b",
8
+ "content-hash": "398ecb29c294b6a360c1b87e66405f55",
9
+ "packages": [
10
+ {
11
+ "name": "dhii/collections-interface",
12
+ "version": "v0.1.1",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/Dhii/collections-interface.git",
16
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
21
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "php": "^5.3 | ^7.0"
26
+ },
27
+ "require-dev": {
28
+ "codeclimate/php-test-reporter": "dev-master",
29
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
30
+ "phpunit/phpunit": "^4.8"
31
+ },
32
+ "type": "library",
33
+ "autoload": {
34
+ "psr-4": {
35
+ "Dhii\\Collection\\": "src/"
36
+ }
37
+ },
38
+ "notification-url": "https://packagist.org/downloads/",
39
+ "license": [
40
+ "MIT"
41
+ ],
42
+ "authors": [
43
+ {
44
+ "name": "Dhii Team",
45
+ "email": "development@dhii.co"
46
+ }
47
+ ],
48
+ "description": "Interfaces for collections",
49
+ "time": "2016-11-09 19:23:28"
50
+ }
51
+ ],
52
+ "packages-dev": [
53
+ {
54
+ "name": "codeclimate/php-test-reporter",
55
+ "version": "dev-master",
56
+ "source": {
57
+ "type": "git",
58
+ "url": "https://github.com/codeclimate/php-test-reporter.git",
59
+ "reference": "0186c8eb03c677b64b9d23dc0cb5c9475553c7c5"
60
+ },
61
+ "dist": {
62
+ "type": "zip",
63
+ "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/0186c8eb03c677b64b9d23dc0cb5c9475553c7c5",
64
+ "reference": "0186c8eb03c677b64b9d23dc0cb5c9475553c7c5",
65
+ "shasum": ""
66
+ },
67
+ "require": {
68
+ "ext-curl": "*",
69
+ "padraic/phar-updater": "^1.0",
70
+ "php": ">=5.3",
71
+ "psr/log": "^1.0",
72
+ "satooshi/php-coveralls": "^1.0",
73
+ "symfony/console": "^2.0|^3.0"
74
+ },
75
+ "require-dev": {
76
+ "ext-xdebug": "*",
77
+ "phpunit/phpunit": "3.7.*@stable",
78
+ "tm/tooly-composer-script": "^1.0"
79
+ },
80
+ "bin": [
81
+ "composer/bin/test-reporter"
82
+ ],
83
+ "type": "library",
84
+ "extra": {
85
+ "branch-alias": {
86
+ "dev-master": "0.3.x-dev"
87
+ },
88
+ "tools": {
89
+ "box": {
90
+ "url": "https://github.com/box-project/box2/releases/download/2.7.2/box-2.7.2.phar",
91
+ "only-dev": true
92
+ }
93
+ }
94
+ },
95
+ "autoload": {
96
+ "psr-4": {
97
+ "CodeClimate\\PhpTestReporter\\": "src/"
98
+ }
99
+ },
100
+ "notification-url": "https://packagist.org/downloads/",
101
+ "license": [
102
+ "MIT"
103
+ ],
104
+ "authors": [
105
+ {
106
+ "name": "Code Climate",
107
+ "email": "hello@codeclimate.com",
108
+ "homepage": "https://codeclimate.com"
109
+ }
110
+ ],
111
+ "description": "PHP client for reporting test coverage to Code Climate",
112
+ "homepage": "https://github.com/codeclimate/php-test-reporter",
113
+ "keywords": [
114
+ "codeclimate",
115
+ "coverage"
116
+ ],
117
+ "time": "2016-09-22 16:57:58"
118
+ },
119
+ {
120
+ "name": "dhii/php-cs-fixer-config",
121
+ "version": "dev-php-5.3",
122
+ "source": {
123
+ "type": "git",
124
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
125
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
126
+ },
127
+ "dist": {
128
+ "type": "zip",
129
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
130
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
131
+ "shasum": ""
132
+ },
133
+ "require": {
134
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
135
+ "php": "^5.3 | ^7.0"
136
+ },
137
+ "require-dev": {
138
+ "phpunit/phpunit": "^4.8"
139
+ },
140
+ "type": "library",
141
+ "autoload": {
142
+ "psr-4": {
143
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
144
+ }
145
+ },
146
+ "notification-url": "https://packagist.org/downloads/",
147
+ "license": [
148
+ "MIT"
149
+ ],
150
+ "authors": [
151
+ {
152
+ "name": "Dhii Team",
153
+ "email": "development@dhii.co"
154
+ }
155
+ ],
156
+ "description": "A default PHP CS Fixer config implementation",
157
+ "time": "2016-09-03 14:45:03"
158
+ },
159
+ {
160
+ "name": "doctrine/instantiator",
161
+ "version": "dev-master",
162
+ "source": {
163
+ "type": "git",
164
+ "url": "https://github.com/doctrine/instantiator.git",
165
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a"
166
+ },
167
+ "dist": {
168
+ "type": "zip",
169
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a",
170
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a",
171
+ "shasum": ""
172
+ },
173
+ "require": {
174
+ "php": ">=5.3,<8.0-DEV"
175
+ },
176
+ "require-dev": {
177
+ "athletic/athletic": "~0.1.8",
178
+ "ext-pdo": "*",
179
+ "ext-phar": "*",
180
+ "phpunit/phpunit": "~4.0",
181
+ "squizlabs/php_codesniffer": "~2.0"
182
+ },
183
+ "type": "library",
184
+ "extra": {
185
+ "branch-alias": {
186
+ "dev-master": "1.0.x-dev"
187
+ }
188
+ },
189
+ "autoload": {
190
+ "psr-4": {
191
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
192
+ }
193
+ },
194
+ "notification-url": "https://packagist.org/downloads/",
195
+ "license": [
196
+ "MIT"
197
+ ],
198
+ "authors": [
199
+ {
200
+ "name": "Marco Pivetta",
201
+ "email": "ocramius@gmail.com",
202
+ "homepage": "http://ocramius.github.com/"
203
+ }
204
+ ],
205
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
206
+ "homepage": "https://github.com/doctrine/instantiator",
207
+ "keywords": [
208
+ "constructor",
209
+ "instantiate"
210
+ ],
211
+ "time": "2016-03-31 10:24:22"
212
+ },
213
+ {
214
+ "name": "friendsofphp/php-cs-fixer",
215
+ "version": "1.11.x-dev",
216
+ "source": {
217
+ "type": "git",
218
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
219
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
220
+ },
221
+ "dist": {
222
+ "type": "zip",
223
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
224
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
225
+ "shasum": ""
226
+ },
227
+ "require": {
228
+ "ext-tokenizer": "*",
229
+ "php": ">=5.3.6",
230
+ "sebastian/diff": "~1.1",
231
+ "symfony/console": "~2.3|~3.0",
232
+ "symfony/event-dispatcher": "~2.1|~3.0",
233
+ "symfony/filesystem": "~2.1|~3.0",
234
+ "symfony/finder": "~2.1|~3.0",
235
+ "symfony/process": "~2.3|~3.0",
236
+ "symfony/stopwatch": "~2.5|~3.0"
237
+ },
238
+ "conflict": {
239
+ "hhvm": "<3.9"
240
+ },
241
+ "require-dev": {
242
+ "phpunit/phpunit": "^4.5|^5",
243
+ "satooshi/php-coveralls": "^0.7.1"
244
+ },
245
+ "bin": [
246
+ "php-cs-fixer"
247
+ ],
248
+ "type": "application",
249
+ "autoload": {
250
+ "psr-4": {
251
+ "Symfony\\CS\\": "Symfony/CS/"
252
+ }
253
+ },
254
+ "notification-url": "https://packagist.org/downloads/",
255
+ "license": [
256
+ "MIT"
257
+ ],
258
+ "authors": [
259
+ {
260
+ "name": "Dariusz Rumiński",
261
+ "email": "dariusz.ruminski@gmail.com"
262
+ },
263
+ {
264
+ "name": "Fabien Potencier",
265
+ "email": "fabien@symfony.com"
266
+ }
267
+ ],
268
+ "description": "A tool to automatically fix PHP code style",
269
+ "time": "2016-08-16 23:31:05"
270
+ },
271
+ {
272
+ "name": "guzzle/guzzle",
273
+ "version": "dev-master",
274
+ "source": {
275
+ "type": "git",
276
+ "url": "https://github.com/guzzle/guzzle3.git",
277
+ "reference": "f7778ed85e3db90009d79725afd6c3a82dab32fe"
278
+ },
279
+ "dist": {
280
+ "type": "zip",
281
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/f7778ed85e3db90009d79725afd6c3a82dab32fe",
282
+ "reference": "f7778ed85e3db90009d79725afd6c3a82dab32fe",
283
+ "shasum": ""
284
+ },
285
+ "require": {
286
+ "ext-curl": "*",
287
+ "php": ">=5.3.3",
288
+ "symfony/event-dispatcher": "~2.1"
289
+ },
290
+ "replace": {
291
+ "guzzle/batch": "self.version",
292
+ "guzzle/cache": "self.version",
293
+ "guzzle/common": "self.version",
294
+ "guzzle/http": "self.version",
295
+ "guzzle/inflection": "self.version",
296
+ "guzzle/iterator": "self.version",
297
+ "guzzle/log": "self.version",
298
+ "guzzle/parser": "self.version",
299
+ "guzzle/plugin": "self.version",
300
+ "guzzle/plugin-async": "self.version",
301
+ "guzzle/plugin-backoff": "self.version",
302
+ "guzzle/plugin-cache": "self.version",
303
+ "guzzle/plugin-cookie": "self.version",
304
+ "guzzle/plugin-curlauth": "self.version",
305
+ "guzzle/plugin-error-response": "self.version",
306
+ "guzzle/plugin-history": "self.version",
307
+ "guzzle/plugin-log": "self.version",
308
+ "guzzle/plugin-md5": "self.version",
309
+ "guzzle/plugin-mock": "self.version",
310
+ "guzzle/plugin-oauth": "self.version",
311
+ "guzzle/service": "self.version",
312
+ "guzzle/stream": "self.version"
313
+ },
314
+ "require-dev": {
315
+ "doctrine/cache": "~1.3",
316
+ "monolog/monolog": "~1.0",
317
+ "phpunit/phpunit": "3.7.*",
318
+ "psr/log": "~1.0",
319
+ "symfony/class-loader": "~2.1",
320
+ "zendframework/zend-cache": "2.*,<2.3",
321
+ "zendframework/zend-log": "2.*,<2.3"
322
+ },
323
+ "suggest": {
324
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
325
+ },
326
+ "type": "library",
327
+ "extra": {
328
+ "branch-alias": {
329
+ "dev-master": "3.9-dev"
330
+ }
331
+ },
332
+ "autoload": {
333
+ "psr-0": {
334
+ "Guzzle": "src/",
335
+ "Guzzle\\Tests": "tests/"
336
+ }
337
+ },
338
+ "notification-url": "https://packagist.org/downloads/",
339
+ "license": [
340
+ "MIT"
341
+ ],
342
+ "authors": [
343
+ {
344
+ "name": "Michael Dowling",
345
+ "email": "mtdowling@gmail.com",
346
+ "homepage": "https://github.com/mtdowling"
347
+ },
348
+ {
349
+ "name": "Guzzle Community",
350
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
351
+ }
352
+ ],
353
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
354
+ "homepage": "http://guzzlephp.org/",
355
+ "keywords": [
356
+ "client",
357
+ "curl",
358
+ "framework",
359
+ "http",
360
+ "http client",
361
+ "rest",
362
+ "web service"
363
+ ],
364
+ "abandoned": "guzzlehttp/guzzle",
365
+ "time": "2016-10-26 18:22:07"
366
+ },
367
+ {
368
+ "name": "padraic/humbug_get_contents",
369
+ "version": "dev-master",
370
+ "source": {
371
+ "type": "git",
372
+ "url": "https://github.com/padraic/file_get_contents.git",
373
+ "reference": "1bfe28c32ad08093917a527114150d0a155c319b"
374
+ },
375
+ "dist": {
376
+ "type": "zip",
377
+ "url": "https://api.github.com/repos/padraic/file_get_contents/zipball/1bfe28c32ad08093917a527114150d0a155c319b",
378
+ "reference": "1bfe28c32ad08093917a527114150d0a155c319b",
379
+ "shasum": ""
380
+ },
381
+ "require": {
382
+ "php": ">=5.3"
383
+ },
384
+ "require-dev": {
385
+ "phpunit/phpunit": "~4.0"
386
+ },
387
+ "type": "library",
388
+ "extra": {
389
+ "branch-alias": {
390
+ "dev-master": "1.0-dev"
391
+ }
392
+ },
393
+ "autoload": {
394
+ "psr-4": {
395
+ "Humbug\\": "src/Humbug/"
396
+ },
397
+ "files": [
398
+ "src/function.php"
399
+ ]
400
+ },
401
+ "notification-url": "https://packagist.org/downloads/",
402
+ "license": [
403
+ "BSD-3-Clause"
404
+ ],
405
+ "authors": [
406
+ {
407
+ "name": "Pádraic Brady",
408
+ "email": "padraic.brady@gmail.com",
409
+ "homepage": "http://blog.astrumfutura.com"
410
+ }
411
+ ],
412
+ "description": "Secure wrapper for accessing HTTPS resources with file_get_contents for PHP 5.3+",
413
+ "homepage": "https://github.com/padraic/file_get_contents",
414
+ "keywords": [
415
+ "download",
416
+ "file_get_contents",
417
+ "http",
418
+ "https",
419
+ "ssl",
420
+ "tls"
421
+ ],
422
+ "time": "2015-04-24 19:31:03"
423
+ },
424
+ {
425
+ "name": "padraic/phar-updater",
426
+ "version": "dev-master",
427
+ "source": {
428
+ "type": "git",
429
+ "url": "https://github.com/padraic/phar-updater.git",
430
+ "reference": "c17eeb3887dc4269d1b4837dc875d39e9f8149a8"
431
+ },
432
+ "dist": {
433
+ "type": "zip",
434
+ "url": "https://api.github.com/repos/padraic/phar-updater/zipball/c17eeb3887dc4269d1b4837dc875d39e9f8149a8",
435
+ "reference": "c17eeb3887dc4269d1b4837dc875d39e9f8149a8",
436
+ "shasum": ""
437
+ },
438
+ "require": {
439
+ "padraic/humbug_get_contents": "^1.0",
440
+ "php": ">=5.3.3"
441
+ },
442
+ "require-dev": {
443
+ "phpunit/phpunit": "~4.0"
444
+ },
445
+ "type": "library",
446
+ "extra": {
447
+ "branch-alias": {
448
+ "dev-master": "1.0-dev"
449
+ }
450
+ },
451
+ "autoload": {
452
+ "psr-4": {
453
+ "Humbug\\SelfUpdate\\": "src/"
454
+ }
455
+ },
456
+ "notification-url": "https://packagist.org/downloads/",
457
+ "license": [
458
+ "BSD-3-Clause"
459
+ ],
460
+ "authors": [
461
+ {
462
+ "name": "Pádraic Brady",
463
+ "email": "padraic.brady@gmail.com",
464
+ "homepage": "http://blog.astrumfutura.com"
465
+ }
466
+ ],
467
+ "description": "A thing to make PHAR self-updating easy and secure.",
468
+ "keywords": [
469
+ "humbug",
470
+ "phar",
471
+ "self-update",
472
+ "update"
473
+ ],
474
+ "time": "2016-01-05 23:08:01"
475
+ },
476
+ {
477
+ "name": "phpdocumentor/reflection-docblock",
478
+ "version": "2.0.4",
479
+ "source": {
480
+ "type": "git",
481
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
482
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
483
+ },
484
+ "dist": {
485
+ "type": "zip",
486
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
487
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
488
+ "shasum": ""
489
+ },
490
+ "require": {
491
+ "php": ">=5.3.3"
492
+ },
493
+ "require-dev": {
494
+ "phpunit/phpunit": "~4.0"
495
+ },
496
+ "suggest": {
497
+ "dflydev/markdown": "~1.0",
498
+ "erusev/parsedown": "~1.0"
499
+ },
500
+ "type": "library",
501
+ "extra": {
502
+ "branch-alias": {
503
+ "dev-master": "2.0.x-dev"
504
+ }
505
+ },
506
+ "autoload": {
507
+ "psr-0": {
508
+ "phpDocumentor": [
509
+ "src/"
510
+ ]
511
+ }
512
+ },
513
+ "notification-url": "https://packagist.org/downloads/",
514
+ "license": [
515
+ "MIT"
516
+ ],
517
+ "authors": [
518
+ {
519
+ "name": "Mike van Riel",
520
+ "email": "mike.vanriel@naenius.com"
521
+ }
522
+ ],
523
+ "time": "2015-02-03 12:10:50"
524
+ },
525
+ {
526
+ "name": "phpspec/prophecy",
527
+ "version": "dev-master",
528
+ "source": {
529
+ "type": "git",
530
+ "url": "https://github.com/phpspec/prophecy.git",
531
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386"
532
+ },
533
+ "dist": {
534
+ "type": "zip",
535
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/5c324f4951aca87a2de61b7903b75126516b6386",
536
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386",
537
+ "shasum": ""
538
+ },
539
+ "require": {
540
+ "doctrine/instantiator": "^1.0.2",
541
+ "php": "^5.3|^7.0",
542
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
543
+ "sebastian/comparator": "^1.1",
544
+ "sebastian/recursion-context": "^1.0"
545
+ },
546
+ "require-dev": {
547
+ "phpspec/phpspec": "^2.0",
548
+ "phpunit/phpunit": "^4.8 || ^5"
549
+ },
550
+ "type": "library",
551
+ "extra": {
552
+ "branch-alias": {
553
+ "dev-master": "1.6.x-dev"
554
+ }
555
+ },
556
+ "autoload": {
557
+ "psr-0": {
558
+ "Prophecy\\": "src/"
559
+ }
560
+ },
561
+ "notification-url": "https://packagist.org/downloads/",
562
+ "license": [
563
+ "MIT"
564
+ ],
565
+ "authors": [
566
+ {
567
+ "name": "Konstantin Kudryashov",
568
+ "email": "ever.zet@gmail.com",
569
+ "homepage": "http://everzet.com"
570
+ },
571
+ {
572
+ "name": "Marcello Duarte",
573
+ "email": "marcello.duarte@gmail.com"
574
+ }
575
+ ],
576
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
577
+ "homepage": "https://github.com/phpspec/prophecy",
578
+ "keywords": [
579
+ "Double",
580
+ "Dummy",
581
+ "fake",
582
+ "mock",
583
+ "spy",
584
+ "stub"
585
+ ],
586
+ "time": "2016-10-02 13:12:17"
587
+ },
588
+ {
589
+ "name": "phpunit/php-code-coverage",
590
+ "version": "2.2.x-dev",
591
+ "source": {
592
+ "type": "git",
593
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
594
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
595
+ },
596
+ "dist": {
597
+ "type": "zip",
598
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
599
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
600
+ "shasum": ""
601
+ },
602
+ "require": {
603
+ "php": ">=5.3.3",
604
+ "phpunit/php-file-iterator": "~1.3",
605
+ "phpunit/php-text-template": "~1.2",
606
+ "phpunit/php-token-stream": "~1.3",
607
+ "sebastian/environment": "^1.3.2",
608
+ "sebastian/version": "~1.0"
609
+ },
610
+ "require-dev": {
611
+ "ext-xdebug": ">=2.1.4",
612
+ "phpunit/phpunit": "~4"
613
+ },
614
+ "suggest": {
615
+ "ext-dom": "*",
616
+ "ext-xdebug": ">=2.2.1",
617
+ "ext-xmlwriter": "*"
618
+ },
619
+ "type": "library",
620
+ "extra": {
621
+ "branch-alias": {
622
+ "dev-master": "2.2.x-dev"
623
+ }
624
+ },
625
+ "autoload": {
626
+ "classmap": [
627
+ "src/"
628
+ ]
629
+ },
630
+ "notification-url": "https://packagist.org/downloads/",
631
+ "license": [
632
+ "BSD-3-Clause"
633
+ ],
634
+ "authors": [
635
+ {
636
+ "name": "Sebastian Bergmann",
637
+ "email": "sb@sebastian-bergmann.de",
638
+ "role": "lead"
639
+ }
640
+ ],
641
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
642
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
643
+ "keywords": [
644
+ "coverage",
645
+ "testing",
646
+ "xunit"
647
+ ],
648
+ "time": "2015-10-06 15:47:00"
649
+ },
650
+ {
651
+ "name": "phpunit/php-file-iterator",
652
+ "version": "dev-master",
653
+ "source": {
654
+ "type": "git",
655
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
656
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
657
+ },
658
+ "dist": {
659
+ "type": "zip",
660
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
661
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
662
+ "shasum": ""
663
+ },
664
+ "require": {
665
+ "php": ">=5.3.3"
666
+ },
667
+ "type": "library",
668
+ "extra": {
669
+ "branch-alias": {
670
+ "dev-master": "1.4.x-dev"
671
+ }
672
+ },
673
+ "autoload": {
674
+ "classmap": [
675
+ "src/"
676
+ ]
677
+ },
678
+ "notification-url": "https://packagist.org/downloads/",
679
+ "license": [
680
+ "BSD-3-Clause"
681
+ ],
682
+ "authors": [
683
+ {
684
+ "name": "Sebastian Bergmann",
685
+ "email": "sb@sebastian-bergmann.de",
686
+ "role": "lead"
687
+ }
688
+ ],
689
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
690
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
691
+ "keywords": [
692
+ "filesystem",
693
+ "iterator"
694
+ ],
695
+ "time": "2016-10-03 07:40:28"
696
+ },
697
+ {
698
+ "name": "phpunit/php-text-template",
699
+ "version": "1.2.1",
700
+ "source": {
701
+ "type": "git",
702
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
703
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
704
+ },
705
+ "dist": {
706
+ "type": "zip",
707
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
708
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
709
+ "shasum": ""
710
+ },
711
+ "require": {
712
+ "php": ">=5.3.3"
713
+ },
714
+ "type": "library",
715
+ "autoload": {
716
+ "classmap": [
717
+ "src/"
718
+ ]
719
+ },
720
+ "notification-url": "https://packagist.org/downloads/",
721
+ "license": [
722
+ "BSD-3-Clause"
723
+ ],
724
+ "authors": [
725
+ {
726
+ "name": "Sebastian Bergmann",
727
+ "email": "sebastian@phpunit.de",
728
+ "role": "lead"
729
+ }
730
+ ],
731
+ "description": "Simple template engine.",
732
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
733
+ "keywords": [
734
+ "template"
735
+ ],
736
+ "time": "2015-06-21 13:50:34"
737
+ },
738
+ {
739
+ "name": "phpunit/php-timer",
740
+ "version": "1.0.8",
741
+ "source": {
742
+ "type": "git",
743
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
744
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
745
+ },
746
+ "dist": {
747
+ "type": "zip",
748
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
749
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
750
+ "shasum": ""
751
+ },
752
+ "require": {
753
+ "php": ">=5.3.3"
754
+ },
755
+ "require-dev": {
756
+ "phpunit/phpunit": "~4|~5"
757
+ },
758
+ "type": "library",
759
+ "autoload": {
760
+ "classmap": [
761
+ "src/"
762
+ ]
763
+ },
764
+ "notification-url": "https://packagist.org/downloads/",
765
+ "license": [
766
+ "BSD-3-Clause"
767
+ ],
768
+ "authors": [
769
+ {
770
+ "name": "Sebastian Bergmann",
771
+ "email": "sb@sebastian-bergmann.de",
772
+ "role": "lead"
773
+ }
774
+ ],
775
+ "description": "Utility class for timing",
776
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
777
+ "keywords": [
778
+ "timer"
779
+ ],
780
+ "time": "2016-05-12 18:03:57"
781
+ },
782
+ {
783
+ "name": "phpunit/php-token-stream",
784
+ "version": "dev-master",
785
+ "source": {
786
+ "type": "git",
787
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
788
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872"
789
+ },
790
+ "dist": {
791
+ "type": "zip",
792
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/2ef59c57cd196301eeb88865d25916898dd72872",
793
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872",
794
+ "shasum": ""
795
+ },
796
+ "require": {
797
+ "ext-tokenizer": "*",
798
+ "php": ">=5.3.3"
799
+ },
800
+ "require-dev": {
801
+ "phpunit/phpunit": "~4.2"
802
+ },
803
+ "type": "library",
804
+ "extra": {
805
+ "branch-alias": {
806
+ "dev-master": "1.4-dev"
807
+ }
808
+ },
809
+ "autoload": {
810
+ "classmap": [
811
+ "src/"
812
+ ]
813
+ },
814
+ "notification-url": "https://packagist.org/downloads/",
815
+ "license": [
816
+ "BSD-3-Clause"
817
+ ],
818
+ "authors": [
819
+ {
820
+ "name": "Sebastian Bergmann",
821
+ "email": "sebastian@phpunit.de"
822
+ }
823
+ ],
824
+ "description": "Wrapper around PHP's tokenizer extension.",
825
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
826
+ "keywords": [
827
+ "tokenizer"
828
+ ],
829
+ "time": "2016-10-03 07:38:46"
830
+ },
831
+ {
832
+ "name": "phpunit/phpunit",
833
+ "version": "4.8.x-dev",
834
+ "source": {
835
+ "type": "git",
836
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
837
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935"
838
+ },
839
+ "dist": {
840
+ "type": "zip",
841
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b58ff0d8996b56675a3e05dcd563e0a4f244935",
842
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935",
843
+ "shasum": ""
844
+ },
845
+ "require": {
846
+ "ext-dom": "*",
847
+ "ext-json": "*",
848
+ "ext-pcre": "*",
849
+ "ext-reflection": "*",
850
+ "ext-spl": "*",
851
+ "php": ">=5.3.3",
852
+ "phpspec/prophecy": "^1.3.1",
853
+ "phpunit/php-code-coverage": "~2.1",
854
+ "phpunit/php-file-iterator": "~1.4",
855
+ "phpunit/php-text-template": "~1.2",
856
+ "phpunit/php-timer": "^1.0.6",
857
+ "phpunit/phpunit-mock-objects": "~2.3",
858
+ "sebastian/comparator": "~1.1",
859
+ "sebastian/diff": "~1.2",
860
+ "sebastian/environment": "~1.3",
861
+ "sebastian/exporter": "~1.2",
862
+ "sebastian/global-state": "~1.0",
863
+ "sebastian/version": "~1.0",
864
+ "symfony/yaml": "~2.1|~3.0"
865
+ },
866
+ "suggest": {
867
+ "phpunit/php-invoker": "~1.1"
868
+ },
869
+ "bin": [
870
+ "phpunit"
871
+ ],
872
+ "type": "library",
873
+ "extra": {
874
+ "branch-alias": {
875
+ "dev-master": "4.8.x-dev"
876
+ }
877
+ },
878
+ "autoload": {
879
+ "classmap": [
880
+ "src/"
881
+ ]
882
+ },
883
+ "notification-url": "https://packagist.org/downloads/",
884
+ "license": [
885
+ "BSD-3-Clause"
886
+ ],
887
+ "authors": [
888
+ {
889
+ "name": "Sebastian Bergmann",
890
+ "email": "sebastian@phpunit.de",
891
+ "role": "lead"
892
+ }
893
+ ],
894
+ "description": "The PHP Unit Testing framework.",
895
+ "homepage": "https://phpunit.de/",
896
+ "keywords": [
897
+ "phpunit",
898
+ "testing",
899
+ "xunit"
900
+ ],
901
+ "time": "2016-10-03 13:00:58"
902
+ },
903
+ {
904
+ "name": "phpunit/phpunit-mock-objects",
905
+ "version": "2.3.x-dev",
906
+ "source": {
907
+ "type": "git",
908
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
909
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
910
+ },
911
+ "dist": {
912
+ "type": "zip",
913
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
914
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
915
+ "shasum": ""
916
+ },
917
+ "require": {
918
+ "doctrine/instantiator": "^1.0.2",
919
+ "php": ">=5.3.3",
920
+ "phpunit/php-text-template": "~1.2",
921
+ "sebastian/exporter": "~1.2"
922
+ },
923
+ "require-dev": {
924
+ "phpunit/phpunit": "~4.4"
925
+ },
926
+ "suggest": {
927
+ "ext-soap": "*"
928
+ },
929
+ "type": "library",
930
+ "extra": {
931
+ "branch-alias": {
932
+ "dev-master": "2.3.x-dev"
933
+ }
934
+ },
935
+ "autoload": {
936
+ "classmap": [
937
+ "src/"
938
+ ]
939
+ },
940
+ "notification-url": "https://packagist.org/downloads/",
941
+ "license": [
942
+ "BSD-3-Clause"
943
+ ],
944
+ "authors": [
945
+ {
946
+ "name": "Sebastian Bergmann",
947
+ "email": "sb@sebastian-bergmann.de",
948
+ "role": "lead"
949
+ }
950
+ ],
951
+ "description": "Mock Object library for PHPUnit",
952
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
953
+ "keywords": [
954
+ "mock",
955
+ "xunit"
956
+ ],
957
+ "time": "2015-10-02 06:51:40"
958
+ },
959
+ {
960
+ "name": "psr/log",
961
+ "version": "dev-master",
962
+ "source": {
963
+ "type": "git",
964
+ "url": "https://github.com/php-fig/log.git",
965
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
966
+ },
967
+ "dist": {
968
+ "type": "zip",
969
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
970
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
971
+ "shasum": ""
972
+ },
973
+ "require": {
974
+ "php": ">=5.3.0"
975
+ },
976
+ "type": "library",
977
+ "extra": {
978
+ "branch-alias": {
979
+ "dev-master": "1.0.x-dev"
980
+ }
981
+ },
982
+ "autoload": {
983
+ "psr-4": {
984
+ "Psr\\Log\\": "Psr/Log/"
985
+ }
986
+ },
987
+ "notification-url": "https://packagist.org/downloads/",
988
+ "license": [
989
+ "MIT"
990
+ ],
991
+ "authors": [
992
+ {
993
+ "name": "PHP-FIG",
994
+ "homepage": "http://www.php-fig.org/"
995
+ }
996
+ ],
997
+ "description": "Common interface for logging libraries",
998
+ "homepage": "https://github.com/php-fig/log",
999
+ "keywords": [
1000
+ "log",
1001
+ "psr",
1002
+ "psr-3"
1003
+ ],
1004
+ "time": "2016-10-10 12:19:37"
1005
+ },
1006
+ {
1007
+ "name": "ptrofimov/xpmock",
1008
+ "version": "1.1.5",
1009
+ "source": {
1010
+ "type": "git",
1011
+ "url": "https://github.com/ptrofimov/xpmock.git",
1012
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
1013
+ },
1014
+ "dist": {
1015
+ "type": "zip",
1016
+ "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
1017
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
1018
+ "shasum": ""
1019
+ },
1020
+ "require": {
1021
+ "php": ">=5.3.0"
1022
+ },
1023
+ "require-dev": {
1024
+ "phpunit/phpunit": "3.7.*"
1025
+ },
1026
+ "type": "library",
1027
+ "autoload": {
1028
+ "psr-0": {
1029
+ "Xpmock": "src"
1030
+ }
1031
+ },
1032
+ "notification-url": "https://packagist.org/downloads/",
1033
+ "license": [
1034
+ "MIT"
1035
+ ],
1036
+ "description": "PHPUnit: simple syntax to create mock-objects",
1037
+ "time": "2014-01-02 16:42:27"
1038
+ },
1039
+ {
1040
+ "name": "satooshi/php-coveralls",
1041
+ "version": "1.0.x-dev",
1042
+ "source": {
1043
+ "type": "git",
1044
+ "url": "https://github.com/satooshi/php-coveralls.git",
1045
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
1046
+ },
1047
+ "dist": {
1048
+ "type": "zip",
1049
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
1050
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
1051
+ "shasum": ""
1052
+ },
1053
+ "require": {
1054
+ "ext-json": "*",
1055
+ "ext-simplexml": "*",
1056
+ "guzzle/guzzle": "^2.8|^3.0",
1057
+ "php": ">=5.3.3",
1058
+ "psr/log": "^1.0",
1059
+ "symfony/config": "^2.1|^3.0",
1060
+ "symfony/console": "^2.1|^3.0",
1061
+ "symfony/stopwatch": "^2.0|^3.0",
1062
+ "symfony/yaml": "^2.0|^3.0"
1063
+ },
1064
+ "suggest": {
1065
+ "symfony/http-kernel": "Allows Symfony integration"
1066
+ },
1067
+ "bin": [
1068
+ "bin/coveralls"
1069
+ ],
1070
+ "type": "library",
1071
+ "autoload": {
1072
+ "psr-4": {
1073
+ "Satooshi\\": "src/Satooshi/"
1074
+ }
1075
+ },
1076
+ "notification-url": "https://packagist.org/downloads/",
1077
+ "license": [
1078
+ "MIT"
1079
+ ],
1080
+ "authors": [
1081
+ {
1082
+ "name": "Kitamura Satoshi",
1083
+ "email": "with.no.parachute@gmail.com",
1084
+ "homepage": "https://www.facebook.com/satooshi.jp"
1085
+ }
1086
+ ],
1087
+ "description": "PHP client library for Coveralls API",
1088
+ "homepage": "https://github.com/satooshi/php-coveralls",
1089
+ "keywords": [
1090
+ "ci",
1091
+ "coverage",
1092
+ "github",
1093
+ "test"
1094
+ ],
1095
+ "time": "2016-01-20 17:35:46"
1096
+ },
1097
+ {
1098
+ "name": "sebastian/comparator",
1099
+ "version": "dev-master",
1100
+ "source": {
1101
+ "type": "git",
1102
+ "url": "https://github.com/sebastianbergmann/comparator.git",
1103
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f"
1104
+ },
1105
+ "dist": {
1106
+ "type": "zip",
1107
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/21400bd9503c3782f5ee80349117483dcf8cec3f",
1108
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f",
1109
+ "shasum": ""
1110
+ },
1111
+ "require": {
1112
+ "php": ">=5.3.3",
1113
+ "sebastian/diff": "~1.2",
1114
+ "sebastian/exporter": "~1.2"
1115
+ },
1116
+ "require-dev": {
1117
+ "phpunit/phpunit": "~4.4"
1118
+ },
1119
+ "type": "library",
1120
+ "extra": {
1121
+ "branch-alias": {
1122
+ "dev-master": "1.2.x-dev"
1123
+ }
1124
+ },
1125
+ "autoload": {
1126
+ "classmap": [
1127
+ "src/"
1128
+ ]
1129
+ },
1130
+ "notification-url": "https://packagist.org/downloads/",
1131
+ "license": [
1132
+ "BSD-3-Clause"
1133
+ ],
1134
+ "authors": [
1135
+ {
1136
+ "name": "Jeff Welch",
1137
+ "email": "whatthejeff@gmail.com"
1138
+ },
1139
+ {
1140
+ "name": "Volker Dusch",
1141
+ "email": "github@wallbash.com"
1142
+ },
1143
+ {
1144
+ "name": "Bernhard Schussek",
1145
+ "email": "bschussek@2bepublished.at"
1146
+ },
1147
+ {
1148
+ "name": "Sebastian Bergmann",
1149
+ "email": "sebastian@phpunit.de"
1150
+ }
1151
+ ],
1152
+ "description": "Provides the functionality to compare PHP values for equality",
1153
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
1154
+ "keywords": [
1155
+ "comparator",
1156
+ "compare",
1157
+ "equality"
1158
+ ],
1159
+ "time": "2016-10-03 07:45:42"
1160
+ },
1161
+ {
1162
+ "name": "sebastian/diff",
1163
+ "version": "dev-master",
1164
+ "source": {
1165
+ "type": "git",
1166
+ "url": "https://github.com/sebastianbergmann/diff.git",
1167
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
1168
+ },
1169
+ "dist": {
1170
+ "type": "zip",
1171
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
1172
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
1173
+ "shasum": ""
1174
+ },
1175
+ "require": {
1176
+ "php": ">=5.3.3"
1177
+ },
1178
+ "require-dev": {
1179
+ "phpunit/phpunit": "~4.8"
1180
+ },
1181
+ "type": "library",
1182
+ "extra": {
1183
+ "branch-alias": {
1184
+ "dev-master": "1.4-dev"
1185
+ }
1186
+ },
1187
+ "autoload": {
1188
+ "classmap": [
1189
+ "src/"
1190
+ ]
1191
+ },
1192
+ "notification-url": "https://packagist.org/downloads/",
1193
+ "license": [
1194
+ "BSD-3-Clause"
1195
+ ],
1196
+ "authors": [
1197
+ {
1198
+ "name": "Kore Nordmann",
1199
+ "email": "mail@kore-nordmann.de"
1200
+ },
1201
+ {
1202
+ "name": "Sebastian Bergmann",
1203
+ "email": "sebastian@phpunit.de"
1204
+ }
1205
+ ],
1206
+ "description": "Diff implementation",
1207
+ "homepage": "https://github.com/sebastianbergmann/diff",
1208
+ "keywords": [
1209
+ "diff"
1210
+ ],
1211
+ "time": "2016-10-03 07:45:03"
1212
+ },
1213
+ {
1214
+ "name": "sebastian/environment",
1215
+ "version": "1.3.x-dev",
1216
+ "source": {
1217
+ "type": "git",
1218
+ "url": "https://github.com/sebastianbergmann/environment.git",
1219
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1220
+ },
1221
+ "dist": {
1222
+ "type": "zip",
1223
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1224
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1225
+ "shasum": ""
1226
+ },
1227
+ "require": {
1228
+ "php": "^5.3.3 || ^7.0"
1229
+ },
1230
+ "require-dev": {
1231
+ "phpunit/phpunit": "^4.8 || ^5.0"
1232
+ },
1233
+ "type": "library",
1234
+ "extra": {
1235
+ "branch-alias": {
1236
+ "dev-master": "1.3.x-dev"
1237
+ }
1238
+ },
1239
+ "autoload": {
1240
+ "classmap": [
1241
+ "src/"
1242
+ ]
1243
+ },
1244
+ "notification-url": "https://packagist.org/downloads/",
1245
+ "license": [
1246
+ "BSD-3-Clause"
1247
+ ],
1248
+ "authors": [
1249
+ {
1250
+ "name": "Sebastian Bergmann",
1251
+ "email": "sebastian@phpunit.de"
1252
+ }
1253
+ ],
1254
+ "description": "Provides functionality to handle HHVM/PHP environments",
1255
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1256
+ "keywords": [
1257
+ "Xdebug",
1258
+ "environment",
1259
+ "hhvm"
1260
+ ],
1261
+ "time": "2016-08-18 05:49:44"
1262
+ },
1263
+ {
1264
+ "name": "sebastian/exporter",
1265
+ "version": "dev-master",
1266
+ "source": {
1267
+ "type": "git",
1268
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1269
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
1270
+ },
1271
+ "dist": {
1272
+ "type": "zip",
1273
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1274
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1275
+ "shasum": ""
1276
+ },
1277
+ "require": {
1278
+ "php": ">=5.3.3",
1279
+ "sebastian/recursion-context": "~1.0"
1280
+ },
1281
+ "require-dev": {
1282
+ "ext-mbstring": "*",
1283
+ "phpunit/phpunit": "~4.4"
1284
+ },
1285
+ "type": "library",
1286
+ "extra": {
1287
+ "branch-alias": {
1288
+ "dev-master": "1.3.x-dev"
1289
+ }
1290
+ },
1291
+ "autoload": {
1292
+ "classmap": [
1293
+ "src/"
1294
+ ]
1295
+ },
1296
+ "notification-url": "https://packagist.org/downloads/",
1297
+ "license": [
1298
+ "BSD-3-Clause"
1299
+ ],
1300
+ "authors": [
1301
+ {
1302
+ "name": "Jeff Welch",
1303
+ "email": "whatthejeff@gmail.com"
1304
+ },
1305
+ {
1306
+ "name": "Volker Dusch",
1307
+ "email": "github@wallbash.com"
1308
+ },
1309
+ {
1310
+ "name": "Bernhard Schussek",
1311
+ "email": "bschussek@2bepublished.at"
1312
+ },
1313
+ {
1314
+ "name": "Sebastian Bergmann",
1315
+ "email": "sebastian@phpunit.de"
1316
+ },
1317
+ {
1318
+ "name": "Adam Harvey",
1319
+ "email": "aharvey@php.net"
1320
+ }
1321
+ ],
1322
+ "description": "Provides the functionality to export PHP variables for visualization",
1323
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1324
+ "keywords": [
1325
+ "export",
1326
+ "exporter"
1327
+ ],
1328
+ "time": "2016-10-03 07:44:30"
1329
+ },
1330
+ {
1331
+ "name": "sebastian/global-state",
1332
+ "version": "1.1.1",
1333
+ "source": {
1334
+ "type": "git",
1335
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1336
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1337
+ },
1338
+ "dist": {
1339
+ "type": "zip",
1340
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1341
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1342
+ "shasum": ""
1343
+ },
1344
+ "require": {
1345
+ "php": ">=5.3.3"
1346
+ },
1347
+ "require-dev": {
1348
+ "phpunit/phpunit": "~4.2"
1349
+ },
1350
+ "suggest": {
1351
+ "ext-uopz": "*"
1352
+ },
1353
+ "type": "library",
1354
+ "extra": {
1355
+ "branch-alias": {
1356
+ "dev-master": "1.0-dev"
1357
+ }
1358
+ },
1359
+ "autoload": {
1360
+ "classmap": [
1361
+ "src/"
1362
+ ]
1363
+ },
1364
+ "notification-url": "https://packagist.org/downloads/",
1365
+ "license": [
1366
+ "BSD-3-Clause"
1367
+ ],
1368
+ "authors": [
1369
+ {
1370
+ "name": "Sebastian Bergmann",
1371
+ "email": "sebastian@phpunit.de"
1372
+ }
1373
+ ],
1374
+ "description": "Snapshotting of global state",
1375
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1376
+ "keywords": [
1377
+ "global state"
1378
+ ],
1379
+ "time": "2015-10-12 03:26:01"
1380
+ },
1381
+ {
1382
+ "name": "sebastian/recursion-context",
1383
+ "version": "dev-master",
1384
+ "source": {
1385
+ "type": "git",
1386
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1387
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1388
+ },
1389
+ "dist": {
1390
+ "type": "zip",
1391
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1392
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1393
+ "shasum": ""
1394
+ },
1395
+ "require": {
1396
+ "php": ">=5.3.3"
1397
+ },
1398
+ "require-dev": {
1399
+ "phpunit/phpunit": "~4.4"
1400
+ },
1401
+ "type": "library",
1402
+ "extra": {
1403
+ "branch-alias": {
1404
+ "dev-master": "1.0.x-dev"
1405
+ }
1406
+ },
1407
+ "autoload": {
1408
+ "classmap": [
1409
+ "src/"
1410
+ ]
1411
+ },
1412
+ "notification-url": "https://packagist.org/downloads/",
1413
+ "license": [
1414
+ "BSD-3-Clause"
1415
+ ],
1416
+ "authors": [
1417
+ {
1418
+ "name": "Jeff Welch",
1419
+ "email": "whatthejeff@gmail.com"
1420
+ },
1421
+ {
1422
+ "name": "Sebastian Bergmann",
1423
+ "email": "sebastian@phpunit.de"
1424
+ },
1425
+ {
1426
+ "name": "Adam Harvey",
1427
+ "email": "aharvey@php.net"
1428
+ }
1429
+ ],
1430
+ "description": "Provides functionality to recursively process PHP variables",
1431
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1432
+ "time": "2016-10-03 07:41:43"
1433
+ },
1434
+ {
1435
+ "name": "sebastian/version",
1436
+ "version": "1.0.6",
1437
+ "source": {
1438
+ "type": "git",
1439
+ "url": "https://github.com/sebastianbergmann/version.git",
1440
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1441
+ },
1442
+ "dist": {
1443
+ "type": "zip",
1444
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1445
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1446
+ "shasum": ""
1447
+ },
1448
+ "type": "library",
1449
+ "autoload": {
1450
+ "classmap": [
1451
+ "src/"
1452
+ ]
1453
+ },
1454
+ "notification-url": "https://packagist.org/downloads/",
1455
+ "license": [
1456
+ "BSD-3-Clause"
1457
+ ],
1458
+ "authors": [
1459
+ {
1460
+ "name": "Sebastian Bergmann",
1461
+ "email": "sebastian@phpunit.de",
1462
+ "role": "lead"
1463
+ }
1464
+ ],
1465
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1466
+ "homepage": "https://github.com/sebastianbergmann/version",
1467
+ "time": "2015-06-21 13:59:46"
1468
+ },
1469
+ {
1470
+ "name": "symfony/config",
1471
+ "version": "2.8.x-dev",
1472
+ "source": {
1473
+ "type": "git",
1474
+ "url": "https://github.com/symfony/config.git",
1475
+ "reference": "1361bc4e66f97b6202ae83f4190e962c624b5e61"
1476
+ },
1477
+ "dist": {
1478
+ "type": "zip",
1479
+ "url": "https://api.github.com/repos/symfony/config/zipball/1361bc4e66f97b6202ae83f4190e962c624b5e61",
1480
+ "reference": "1361bc4e66f97b6202ae83f4190e962c624b5e61",
1481
+ "shasum": ""
1482
+ },
1483
+ "require": {
1484
+ "php": ">=5.3.9",
1485
+ "symfony/filesystem": "~2.3|~3.0.0"
1486
+ },
1487
+ "suggest": {
1488
+ "symfony/yaml": "To use the yaml reference dumper"
1489
+ },
1490
+ "type": "library",
1491
+ "extra": {
1492
+ "branch-alias": {
1493
+ "dev-master": "2.8-dev"
1494
+ }
1495
+ },
1496
+ "autoload": {
1497
+ "psr-4": {
1498
+ "Symfony\\Component\\Config\\": ""
1499
+ },
1500
+ "exclude-from-classmap": [
1501
+ "/Tests/"
1502
+ ]
1503
+ },
1504
+ "notification-url": "https://packagist.org/downloads/",
1505
+ "license": [
1506
+ "MIT"
1507
+ ],
1508
+ "authors": [
1509
+ {
1510
+ "name": "Fabien Potencier",
1511
+ "email": "fabien@symfony.com"
1512
+ },
1513
+ {
1514
+ "name": "Symfony Community",
1515
+ "homepage": "https://symfony.com/contributors"
1516
+ }
1517
+ ],
1518
+ "description": "Symfony Config Component",
1519
+ "homepage": "https://symfony.com",
1520
+ "time": "2016-11-03 07:52:58"
1521
+ },
1522
+ {
1523
+ "name": "symfony/console",
1524
+ "version": "2.8.x-dev",
1525
+ "source": {
1526
+ "type": "git",
1527
+ "url": "https://github.com/symfony/console.git",
1528
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71"
1529
+ },
1530
+ "dist": {
1531
+ "type": "zip",
1532
+ "url": "https://api.github.com/repos/symfony/console/zipball/ddb26174398f48486ac4231dc4f4cb27c3acba71",
1533
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71",
1534
+ "shasum": ""
1535
+ },
1536
+ "require": {
1537
+ "php": ">=5.3.9",
1538
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
1539
+ "symfony/polyfill-mbstring": "~1.0"
1540
+ },
1541
+ "require-dev": {
1542
+ "psr/log": "~1.0",
1543
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
1544
+ "symfony/process": "~2.1|~3.0.0"
1545
+ },
1546
+ "suggest": {
1547
+ "psr/log": "For using the console logger",
1548
+ "symfony/event-dispatcher": "",
1549
+ "symfony/process": ""
1550
+ },
1551
+ "type": "library",
1552
+ "extra": {
1553
+ "branch-alias": {
1554
+ "dev-master": "2.8-dev"
1555
+ }
1556
+ },
1557
+ "autoload": {
1558
+ "psr-4": {
1559
+ "Symfony\\Component\\Console\\": ""
1560
+ },
1561
+ "exclude-from-classmap": [
1562
+ "/Tests/"
1563
+ ]
1564
+ },
1565
+ "notification-url": "https://packagist.org/downloads/",
1566
+ "license": [
1567
+ "MIT"
1568
+ ],
1569
+ "authors": [
1570
+ {
1571
+ "name": "Fabien Potencier",
1572
+ "email": "fabien@symfony.com"
1573
+ },
1574
+ {
1575
+ "name": "Symfony Community",
1576
+ "homepage": "https://symfony.com/contributors"
1577
+ }
1578
+ ],
1579
+ "description": "Symfony Console Component",
1580
+ "homepage": "https://symfony.com",
1581
+ "time": "2016-11-04 17:49:05"
1582
+ },
1583
+ {
1584
+ "name": "symfony/debug",
1585
+ "version": "2.8.x-dev",
1586
+ "source": {
1587
+ "type": "git",
1588
+ "url": "https://github.com/symfony/debug.git",
1589
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888"
1590
+ },
1591
+ "dist": {
1592
+ "type": "zip",
1593
+ "url": "https://api.github.com/repos/symfony/debug/zipball/d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1594
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1595
+ "shasum": ""
1596
+ },
1597
+ "require": {
1598
+ "php": ">=5.3.9",
1599
+ "psr/log": "~1.0"
1600
+ },
1601
+ "conflict": {
1602
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1603
+ },
1604
+ "require-dev": {
1605
+ "symfony/class-loader": "~2.2|~3.0.0",
1606
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
1607
+ },
1608
+ "type": "library",
1609
+ "extra": {
1610
+ "branch-alias": {
1611
+ "dev-master": "2.8-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": "2016-11-03 07:52:58"
1639
+ },
1640
+ {
1641
+ "name": "symfony/event-dispatcher",
1642
+ "version": "2.8.x-dev",
1643
+ "source": {
1644
+ "type": "git",
1645
+ "url": "https://github.com/symfony/event-dispatcher.git",
1646
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
1647
+ },
1648
+ "dist": {
1649
+ "type": "zip",
1650
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1651
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1652
+ "shasum": ""
1653
+ },
1654
+ "require": {
1655
+ "php": ">=5.3.9"
1656
+ },
1657
+ "require-dev": {
1658
+ "psr/log": "~1.0",
1659
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
1660
+ "symfony/dependency-injection": "~2.6|~3.0.0",
1661
+ "symfony/expression-language": "~2.6|~3.0.0",
1662
+ "symfony/stopwatch": "~2.3|~3.0.0"
1663
+ },
1664
+ "suggest": {
1665
+ "symfony/dependency-injection": "",
1666
+ "symfony/http-kernel": ""
1667
+ },
1668
+ "type": "library",
1669
+ "extra": {
1670
+ "branch-alias": {
1671
+ "dev-master": "2.8-dev"
1672
+ }
1673
+ },
1674
+ "autoload": {
1675
+ "psr-4": {
1676
+ "Symfony\\Component\\EventDispatcher\\": ""
1677
+ },
1678
+ "exclude-from-classmap": [
1679
+ "/Tests/"
1680
+ ]
1681
+ },
1682
+ "notification-url": "https://packagist.org/downloads/",
1683
+ "license": [
1684
+ "MIT"
1685
+ ],
1686
+ "authors": [
1687
+ {
1688
+ "name": "Fabien Potencier",
1689
+ "email": "fabien@symfony.com"
1690
+ },
1691
+ {
1692
+ "name": "Symfony Community",
1693
+ "homepage": "https://symfony.com/contributors"
1694
+ }
1695
+ ],
1696
+ "description": "Symfony EventDispatcher Component",
1697
+ "homepage": "https://symfony.com",
1698
+ "time": "2016-10-13 01:43:15"
1699
+ },
1700
+ {
1701
+ "name": "symfony/filesystem",
1702
+ "version": "2.8.x-dev",
1703
+ "source": {
1704
+ "type": "git",
1705
+ "url": "https://github.com/symfony/filesystem.git",
1706
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898"
1707
+ },
1708
+ "dist": {
1709
+ "type": "zip",
1710
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898",
1711
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898",
1712
+ "shasum": ""
1713
+ },
1714
+ "require": {
1715
+ "php": ">=5.3.9"
1716
+ },
1717
+ "type": "library",
1718
+ "extra": {
1719
+ "branch-alias": {
1720
+ "dev-master": "2.8-dev"
1721
+ }
1722
+ },
1723
+ "autoload": {
1724
+ "psr-4": {
1725
+ "Symfony\\Component\\Filesystem\\": ""
1726
+ },
1727
+ "exclude-from-classmap": [
1728
+ "/Tests/"
1729
+ ]
1730
+ },
1731
+ "notification-url": "https://packagist.org/downloads/",
1732
+ "license": [
1733
+ "MIT"
1734
+ ],
1735
+ "authors": [
1736
+ {
1737
+ "name": "Fabien Potencier",
1738
+ "email": "fabien@symfony.com"
1739
+ },
1740
+ {
1741
+ "name": "Symfony Community",
1742
+ "homepage": "https://symfony.com/contributors"
1743
+ }
1744
+ ],
1745
+ "description": "Symfony Filesystem Component",
1746
+ "homepage": "https://symfony.com",
1747
+ "time": "2016-10-18 04:28:30"
1748
+ },
1749
+ {
1750
+ "name": "symfony/finder",
1751
+ "version": "2.8.x-dev",
1752
+ "source": {
1753
+ "type": "git",
1754
+ "url": "https://github.com/symfony/finder.git",
1755
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd"
1756
+ },
1757
+ "dist": {
1758
+ "type": "zip",
1759
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0023b024363dfc0cd21262e556f25a291fe8d7fd",
1760
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd",
1761
+ "shasum": ""
1762
+ },
1763
+ "require": {
1764
+ "php": ">=5.3.9"
1765
+ },
1766
+ "type": "library",
1767
+ "extra": {
1768
+ "branch-alias": {
1769
+ "dev-master": "2.8-dev"
1770
+ }
1771
+ },
1772
+ "autoload": {
1773
+ "psr-4": {
1774
+ "Symfony\\Component\\Finder\\": ""
1775
+ },
1776
+ "exclude-from-classmap": [
1777
+ "/Tests/"
1778
+ ]
1779
+ },
1780
+ "notification-url": "https://packagist.org/downloads/",
1781
+ "license": [
1782
+ "MIT"
1783
+ ],
1784
+ "authors": [
1785
+ {
1786
+ "name": "Fabien Potencier",
1787
+ "email": "fabien@symfony.com"
1788
+ },
1789
+ {
1790
+ "name": "Symfony Community",
1791
+ "homepage": "https://symfony.com/contributors"
1792
+ }
1793
+ ],
1794
+ "description": "Symfony Finder Component",
1795
+ "homepage": "https://symfony.com",
1796
+ "time": "2016-11-03 07:52:58"
1797
+ },
1798
+ {
1799
+ "name": "symfony/polyfill-mbstring",
1800
+ "version": "dev-master",
1801
+ "source": {
1802
+ "type": "git",
1803
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1804
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c"
1805
+ },
1806
+ "dist": {
1807
+ "type": "zip",
1808
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1809
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1810
+ "shasum": ""
1811
+ },
1812
+ "require": {
1813
+ "php": ">=5.3.3"
1814
+ },
1815
+ "suggest": {
1816
+ "ext-mbstring": "For best performance"
1817
+ },
1818
+ "type": "library",
1819
+ "extra": {
1820
+ "branch-alias": {
1821
+ "dev-master": "1.2-dev"
1822
+ }
1823
+ },
1824
+ "autoload": {
1825
+ "psr-4": {
1826
+ "Symfony\\Polyfill\\Mbstring\\": ""
1827
+ },
1828
+ "files": [
1829
+ "bootstrap.php"
1830
+ ]
1831
+ },
1832
+ "notification-url": "https://packagist.org/downloads/",
1833
+ "license": [
1834
+ "MIT"
1835
+ ],
1836
+ "authors": [
1837
+ {
1838
+ "name": "Nicolas Grekas",
1839
+ "email": "p@tchwork.com"
1840
+ },
1841
+ {
1842
+ "name": "Symfony Community",
1843
+ "homepage": "https://symfony.com/contributors"
1844
+ }
1845
+ ],
1846
+ "description": "Symfony polyfill for the Mbstring extension",
1847
+ "homepage": "https://symfony.com",
1848
+ "keywords": [
1849
+ "compatibility",
1850
+ "mbstring",
1851
+ "polyfill",
1852
+ "portable",
1853
+ "shim"
1854
+ ],
1855
+ "time": "2016-08-30 17:06:17"
1856
+ },
1857
+ {
1858
+ "name": "symfony/process",
1859
+ "version": "2.8.x-dev",
1860
+ "source": {
1861
+ "type": "git",
1862
+ "url": "https://github.com/symfony/process.git",
1863
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
1864
+ },
1865
+ "dist": {
1866
+ "type": "zip",
1867
+ "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1868
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1869
+ "shasum": ""
1870
+ },
1871
+ "require": {
1872
+ "php": ">=5.3.9"
1873
+ },
1874
+ "type": "library",
1875
+ "extra": {
1876
+ "branch-alias": {
1877
+ "dev-master": "2.8-dev"
1878
+ }
1879
+ },
1880
+ "autoload": {
1881
+ "psr-4": {
1882
+ "Symfony\\Component\\Process\\": ""
1883
+ },
1884
+ "exclude-from-classmap": [
1885
+ "/Tests/"
1886
+ ]
1887
+ },
1888
+ "notification-url": "https://packagist.org/downloads/",
1889
+ "license": [
1890
+ "MIT"
1891
+ ],
1892
+ "authors": [
1893
+ {
1894
+ "name": "Fabien Potencier",
1895
+ "email": "fabien@symfony.com"
1896
+ },
1897
+ {
1898
+ "name": "Symfony Community",
1899
+ "homepage": "https://symfony.com/contributors"
1900
+ }
1901
+ ],
1902
+ "description": "Symfony Process Component",
1903
+ "homepage": "https://symfony.com",
1904
+ "time": "2016-09-29 14:03:54"
1905
+ },
1906
+ {
1907
+ "name": "symfony/stopwatch",
1908
+ "version": "2.8.x-dev",
1909
+ "source": {
1910
+ "type": "git",
1911
+ "url": "https://github.com/symfony/stopwatch.git",
1912
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca"
1913
+ },
1914
+ "dist": {
1915
+ "type": "zip",
1916
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
1917
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca",
1918
+ "shasum": ""
1919
+ },
1920
+ "require": {
1921
+ "php": ">=5.3.9"
1922
+ },
1923
+ "type": "library",
1924
+ "extra": {
1925
+ "branch-alias": {
1926
+ "dev-master": "2.8-dev"
1927
+ }
1928
+ },
1929
+ "autoload": {
1930
+ "psr-4": {
1931
+ "Symfony\\Component\\Stopwatch\\": ""
1932
+ },
1933
+ "exclude-from-classmap": [
1934
+ "/Tests/"
1935
+ ]
1936
+ },
1937
+ "notification-url": "https://packagist.org/downloads/",
1938
+ "license": [
1939
+ "MIT"
1940
+ ],
1941
+ "authors": [
1942
+ {
1943
+ "name": "Fabien Potencier",
1944
+ "email": "fabien@symfony.com"
1945
+ },
1946
+ {
1947
+ "name": "Symfony Community",
1948
+ "homepage": "https://symfony.com/contributors"
1949
+ }
1950
+ ],
1951
+ "description": "Symfony Stopwatch Component",
1952
+ "homepage": "https://symfony.com",
1953
+ "time": "2016-06-29 05:29:29"
1954
+ },
1955
+ {
1956
+ "name": "symfony/yaml",
1957
+ "version": "2.8.x-dev",
1958
+ "source": {
1959
+ "type": "git",
1960
+ "url": "https://github.com/symfony/yaml.git",
1961
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb"
1962
+ },
1963
+ "dist": {
1964
+ "type": "zip",
1965
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/58666e4ac3a2d378798f020308b35a75ffbeaafb",
1966
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb",
1967
+ "shasum": ""
1968
+ },
1969
+ "require": {
1970
+ "php": ">=5.3.9"
1971
+ },
1972
+ "type": "library",
1973
+ "extra": {
1974
+ "branch-alias": {
1975
+ "dev-master": "2.8-dev"
1976
+ }
1977
+ },
1978
+ "autoload": {
1979
+ "psr-4": {
1980
+ "Symfony\\Component\\Yaml\\": ""
1981
+ },
1982
+ "exclude-from-classmap": [
1983
+ "/Tests/"
1984
+ ]
1985
+ },
1986
+ "notification-url": "https://packagist.org/downloads/",
1987
+ "license": [
1988
+ "MIT"
1989
+ ],
1990
+ "authors": [
1991
+ {
1992
+ "name": "Fabien Potencier",
1993
+ "email": "fabien@symfony.com"
1994
+ },
1995
+ {
1996
+ "name": "Symfony Community",
1997
+ "homepage": "https://symfony.com/contributors"
1998
+ }
1999
+ ],
2000
+ "description": "Symfony Yaml Component",
2001
+ "homepage": "https://symfony.com",
2002
+ "time": "2016-11-03 07:52:58"
2003
+ }
2004
+ ],
2005
+ "aliases": [],
2006
+ "minimum-stability": "dev",
2007
+ "stability-flags": {
2008
+ "dhii/php-cs-fixer-config": 20,
2009
+ "codeclimate/php-test-reporter": 20
2010
+ },
2011
+ "prefer-stable": false,
2012
+ "prefer-lowest": false,
2013
+ "platform": [],
2014
+ "platform-dev": []
2015
+ }
vendor/dhii/collections-abstract-base/nbproject/project.properties ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ file.reference.collections-abstract-base-vendor=vendor
13
+ file.reference.test-functional=test/functional
14
+ include.path=\
15
+ ${php.global.include.path}:\
16
+ ${file.reference.collections-abstract-base-vendor}
17
+ php.version=PHP_53
18
+ source.encoding=UTF-8
19
+ src.dir=src
20
+ tags.asp=false
21
+ tags.short=false
22
+ test.src.dir=${file.reference.test-functional}
23
+ testing.providers=PhpUnit
24
+ web.root=.
vendor/dhii/collections-abstract-base/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 - collections-abstract-base</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/collections-abstract-base/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/collections-abstract-base/src/AbstractCollection.php ADDED
@@ -0,0 +1,489 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use Exception;
6
+ use RuntimeException;
7
+ use UnexpectedValueException;
8
+
9
+ /**
10
+ * Common functionality for collections.
11
+ *
12
+ * This implementation permits the same value to appear multiple times.
13
+ *
14
+ * @since 0.1.0
15
+ */
16
+ abstract class AbstractCollection extends AbstractHasher implements CollectionInterface
17
+ {
18
+ protected $items;
19
+
20
+ /**
21
+ * Parameter-less constructor.
22
+ *
23
+ * The actual constructor MUST call this method.
24
+ *
25
+ * @since 0.1.0
26
+ */
27
+ protected function _construct()
28
+ {
29
+ $this->items = array();
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ *
35
+ * @since 0.1.0
36
+ */
37
+ public function getItems()
38
+ {
39
+ return $this->_getItems();
40
+ }
41
+
42
+ /**
43
+ * Low-level retrieval of all items.
44
+ *
45
+ * @since 0.1.0
46
+ *
47
+ * @return mixed[]|\Traversable
48
+ */
49
+ protected function _getItems()
50
+ {
51
+ return $this->items;
52
+ }
53
+
54
+ /**
55
+ * Adds items to the collection.
56
+ *
57
+ * @since 0.1.0
58
+ *
59
+ * @param array|\Traversable $items Items to add.
60
+ *
61
+ * @return AbstractCollection This instance.
62
+ */
63
+ protected function _addItems($items)
64
+ {
65
+ foreach ($items as $_key => $_item) {
66
+ $this->_validateItem($_item);
67
+ $this->_addItem($_item);
68
+ }
69
+
70
+ return $this;
71
+ }
72
+
73
+ /**
74
+ * Add an item to the collection.
75
+ *
76
+ * @since 0.1.0
77
+ *
78
+ * @param mixed $item The item to add.
79
+ *
80
+ * @return bool True if item successfully added; false if adding failed.
81
+ */
82
+ protected function _addItem($item)
83
+ {
84
+ $key = $this->_getItemUniqueKey($item);
85
+
86
+ return $this->_arraySet($this->items, $item, $key);
87
+ }
88
+
89
+ /**
90
+ * Sets an item at the specified key in this collection.
91
+ *
92
+ * @since 0.1.0
93
+ *
94
+ * @param string $key The key, at which to set the item
95
+ * @param mixed $item The item to set.
96
+ *
97
+ * @return bool True if item successfully set; false if setting failed.
98
+ */
99
+ protected function _setItem($key, $item)
100
+ {
101
+ return $this->_arraySet($this->items, $item, $key);
102
+ }
103
+
104
+ /**
105
+ * Set the internal items list.
106
+ *
107
+ * The internal list will be replaced with the one given.
108
+ *
109
+ * @since 0.1.0
110
+ *
111
+ * @param array|\Traversable $items The item list to set.
112
+ *
113
+ * @return AbstractCollection This instance.
114
+ */
115
+ protected function _setItems($items)
116
+ {
117
+ $this->_validateItemList($items);
118
+ $this->items = $items;
119
+
120
+ return $this;
121
+ }
122
+
123
+ /**
124
+ * Removes the given item from this collection.
125
+ *
126
+ * @since 0.1.0
127
+ *
128
+ * @param mixed $item The item to remove.
129
+ *
130
+ * @return bool True if removal successful; false if failed.
131
+ */
132
+ protected function _removeItem($item)
133
+ {
134
+ if (($key = $this->_findItem($item, true)) !== false) {
135
+ return $this->_arrayUnset($this->items, $key);
136
+ }
137
+
138
+ return false;
139
+ }
140
+
141
+ /**
142
+ * Checks whether the given item exists in this collection.
143
+ *
144
+ * @since 0.1.0
145
+ *
146
+ * @param mixed $item The item to check for.
147
+ *
148
+ * @return bool True if the given item exists in this collection; false otherwise.
149
+ */
150
+ protected function _hasItem($item)
151
+ {
152
+ return $this->_findItem($item, true) !== false;
153
+ }
154
+
155
+ /**
156
+ * Checks whether an item with the specified key exists in this collection.
157
+ *
158
+ * @since 0.1.0
159
+ *
160
+ * @param int|string $key The key to check for.
161
+ *
162
+ * @return bool True if the key exists in this collection; false otherwise.
163
+ */
164
+ protected function _hasItemKey($key)
165
+ {
166
+ return $this->_arrayKeyExists($this->items, $key);
167
+ }
168
+
169
+ /**
170
+ * Retrieve an item with the specified key from this collection.
171
+ *
172
+ * @since 0.1.0
173
+ *
174
+ * @param string|int $key The key to get an item for.
175
+ * @param mixed $default The value to return if the specified key does not exists.
176
+ *
177
+ * @return mixed|null The item at the specified key, if it exists; otherwise, the default value.
178
+ */
179
+ protected function _getItem($key, $default = null)
180
+ {
181
+ return $this->_arrayGet($this->items, $key, $default);
182
+ }
183
+
184
+ /**
185
+ * Get the key of an item to use for consistency checks.
186
+ *
187
+ * @since 0.1.0
188
+ *
189
+ * @param mixed $item Get the key of an item.
190
+ *
191
+ * @return string|int The key of an item.
192
+ */
193
+ protected function _getItemKey($item)
194
+ {
195
+ return $this->_hash($item);
196
+ }
197
+
198
+ /**
199
+ * Get the index, at which an item exists in this collection.
200
+ *
201
+ * @since 0.1.0
202
+ *
203
+ * @param mixed $item The item to find.
204
+ * @param bool $strict Whether or not the type must also match.
205
+ *
206
+ * @return int|string|false The key, at which the item exists in this collection, if found;
207
+ * false otherwise.
208
+ */
209
+ public function _findItem($item, $strict = false)
210
+ {
211
+ return $this->_arraySearch($this->items, $item, $strict);
212
+ }
213
+
214
+ /**
215
+ * Get a collection-wide unique key for an item.
216
+ *
217
+ * It is not guaranteed to be consistent, e.g. running this several
218
+ * times on the same argument will likely produce different results.
219
+ *
220
+ * @param mixed $item The item, for which to get the key.
221
+ *
222
+ * @return string|int A key that is guaranteed to be different from all other keys in this collection.
223
+ */
224
+ protected function _getItemUniqueKey($item)
225
+ {
226
+ return count($this->items);
227
+ }
228
+
229
+ /**
230
+ * Search a list for a value.
231
+ *
232
+ * @since 0.1.0
233
+ *
234
+ * @param AbstractCollection|array|\Traversable $array The list to search.
235
+ * @param mixed $value The value to search for.
236
+ * @param bool $strict Whether the type must also match.
237
+ *
238
+ * @return int|string|bool The key, at which the value exists in the list, if found;
239
+ * false otherwise.
240
+ */
241
+ protected function _arraySearch(&$array, $value, $strict = false)
242
+ {
243
+ // Regular array matching
244
+ if (is_array($array)) {
245
+ return array_search($value, $array, $strict);
246
+ }
247
+ // Using familiar interface
248
+ if ($array instanceof self) {
249
+ return $array->_findItem($value, $strict);
250
+ }
251
+ // Last resort - iterate and compare
252
+ if ($array instanceof \Traversable) {
253
+ foreach ($array as $_idx => $_value) {
254
+ if ($strict && $value === $_value) {
255
+ return $_idx;
256
+ }
257
+
258
+ if (!$strict && $value == $_value) {
259
+ return $_idx;
260
+ }
261
+ }
262
+
263
+ return false;
264
+ }
265
+
266
+ throw new RuntimeException('Could not search list: the list is not something that can be searched');
267
+ }
268
+
269
+ /**
270
+ * Checks if an item with the specified key exists in a list.
271
+ *
272
+ * @since 0.1.0
273
+ *
274
+ * @param array|\ArrayAccess|AccessibleCollectionInterface $list The list to check.
275
+ * @param string|int $key The key to check for.
276
+ *
277
+ * @throws RuntimeException If list is not something that can have a key checked.
278
+ *
279
+ * @return bool True if an item with the specified key exists the given list; otherwise false.
280
+ */
281
+ protected function _arrayKeyExists(&$list, $key)
282
+ {
283
+ if (is_array($list)) {
284
+ return array_key_exists($key, $list);
285
+ }
286
+
287
+ if ($list instanceof \ArrayAccess) {
288
+ return $list->offsetExists($key);
289
+ }
290
+
291
+ if ($list instanceof AccessibleCollectionInterface) {
292
+ return $list->hasItemKey($key);
293
+ }
294
+
295
+ throw new RuntimeException(sprintf(
296
+ 'Could not check list for key "%1$s": the list is not something that can have an item checked', $key));
297
+ }
298
+
299
+ /**
300
+ * Retrieves an item with the specified key from the given list.
301
+ *
302
+ * @since 0.1.0
303
+ *
304
+ * @param array|\ArrayAccess|AccessibleCollectionInterface $list The list to retrieve from.
305
+ * @param string|int $key The key to retrieve the item for.
306
+ *
307
+ * @throws RuntimeException If list is not something that can have a value retrieved by key.
308
+ *
309
+ * @return mixed|null The item at the specified key.
310
+ */
311
+ protected function _arrayGet(&$list, $key, $default = null)
312
+ {
313
+ if (is_array($list)) {
314
+ return isset($list[$key])
315
+ ? $list[$key]
316
+ : $default;
317
+ }
318
+
319
+ if ($list instanceof \ArrayAccess) {
320
+ return $list->offsetExists($key)
321
+ ? $list->offsetGet($key)
322
+ : $default;
323
+ }
324
+
325
+ if ($list instanceof AccessibleCollectionInterface) {
326
+ return $list->hasItemKey($key)
327
+ ? $list->getItem($key)
328
+ : $default;
329
+ }
330
+
331
+ throw new RuntimeException(sprintf(
332
+ 'Could not get list item for key "%1$s": the list is not something that can have an item retrieved', $key));
333
+ }
334
+
335
+ /**
336
+ * Set an item at the specified key in the given list.
337
+ *
338
+ * @since 0.1.0
339
+ *
340
+ * @param mixed[]|\ArrayAccess|MutableCollectionInterface $list The list, for which to set the value.
341
+ * @param mixed $item The item to set for the specified key.
342
+ * @param string $key The key, for which to set the item.
343
+ *
344
+ * @throws RuntimeException If list is not something that can have a value set.
345
+ *
346
+ * @return bool True if the value has been successfully set; false if setting failed.
347
+ */
348
+ protected function _arraySet(&$list, $item, $key)
349
+ {
350
+ if (is_array($list)) {
351
+ $list[$key] = $item;
352
+
353
+ return true;
354
+ }
355
+
356
+ if ($list instanceof \ArrayAccess) {
357
+ $list->offsetSet($key, $item);
358
+
359
+ return true;
360
+ }
361
+
362
+ if ($list instanceof MutableCollectionInterface) {
363
+ return $list->setItem($item, $key);
364
+ }
365
+
366
+ throw new RuntimeException(sprintf(
367
+ 'Could not set list item for key "%1$s": the list is not something that can have an item set', $key));
368
+ }
369
+
370
+ /**
371
+ * Unset the specified key in the given list.
372
+ *
373
+ * @since 0.1.0
374
+ *
375
+ * @param mixed[]|\ArrayAccess|MutableCollectionInterface $list The list, for which to set the value.
376
+ * @param string $key The key, for which to unset the item.
377
+ *
378
+ * @throws RuntimeException If list is not something that can have a value unset.
379
+ *
380
+ * @return bool True if the value has been successfully unset; false if unsetting failed.
381
+ */
382
+ protected function _arrayUnset(&$array, $key)
383
+ {
384
+ if (is_array($array)) {
385
+ if (isset($array[$key])) {
386
+ unset($array[$key]);
387
+
388
+ return true;
389
+ }
390
+
391
+ return false;
392
+ }
393
+
394
+ if ($array instanceof \ArrayAccess) {
395
+ if ($array->offsetExists($key)) {
396
+ $array->offsetUnset($key);
397
+
398
+ return true;
399
+ }
400
+
401
+ return false;
402
+ }
403
+
404
+ if ($array instanceof MutableCollectionInterface) {
405
+ return $array->removeItemByKey($key);
406
+ }
407
+
408
+ throw new RuntimeException(sprintf(
409
+ 'Could not unset list item for key "%1$s": the list is not something that can have an item unset', $key));
410
+ }
411
+
412
+ /**
413
+ * Normalize an array-ish value to array.
414
+ *
415
+ * @since 0.1.0
416
+ *
417
+ * @param array|AbstractCollection|\Traversable $list The list, which to convert.
418
+ *
419
+ * @throws RuntimeException If list is not something that can have a value unset.
420
+ *
421
+ * @return array The array that resulted from the conversion.
422
+ * If the argument is an array, returns unmodified.
423
+ * If it is an {@see AbstractCollection} and not a {@see \Traversable}, gets its internal items and tries to convert those to array.
424
+ * If it is a {@see \Traversable}, returns the result of {@see iterator_to_array()} on that.
425
+ */
426
+ protected function _arrayConvert(&$list)
427
+ {
428
+ if (is_array($list)) {
429
+ return $list;
430
+ }
431
+
432
+ if ($list instanceof self && !($list instanceof \Traversable)) {
433
+ $items = $list->_getItems();
434
+ return $this->_arrayConvert($items);
435
+ }
436
+
437
+ if ($list instanceof \Traversable) {
438
+ return iterator_to_array($list, true);
439
+ }
440
+
441
+ throw new RuntimeException(sprintf(
442
+ 'Could not convert to array: not something that can be converted'));
443
+ }
444
+
445
+ /**
446
+ * Determines if item is a valid member of the collection.
447
+ *
448
+ * @since 0.1.0
449
+ *
450
+ * @throws \Exception If the item is invalid;
451
+ */
452
+ abstract protected function _validateItem($item);
453
+
454
+ /**
455
+ * Determines if item is a valid member of the collection.
456
+ *
457
+ * @since 0.1.0
458
+ *
459
+ * @param mixed $item The item to evaluate.
460
+ *
461
+ * @return bool True if the item is valid; false otherwise.
462
+ */
463
+ protected function _isValidItem($item)
464
+ {
465
+ try {
466
+ $this->_validateItem($item);
467
+ } catch (Exception $ex) {
468
+ return false;
469
+ }
470
+
471
+ return true;
472
+ }
473
+
474
+ /**
475
+ * Throws an exception if the given value is not a valid item list.
476
+ *
477
+ * @since 0.1.0
478
+ *
479
+ * @param mixed $items An item list.
480
+ *
481
+ * @throws UnexpectedValueException If the list is not a valid item list.
482
+ */
483
+ protected function _validateItemList($items)
484
+ {
485
+ if (!is_array($items) && !($items instanceof \Traversable)) {
486
+ throw new UnexpectedValueException(sprintf('Must be a valid item list'));
487
+ }
488
+ }
489
+ }
vendor/dhii/collections-abstract-base/src/AbstractHasher.php ADDED
@@ -0,0 +1,62 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Generic functionality for hashing.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractHasher
11
+ {
12
+ /**
13
+ * Creates a hash of any value.
14
+ *
15
+ * @since 0.1.0
16
+ * @see _hashScalar()
17
+ * @see _hashNonScalar()
18
+ *
19
+ * @param mixed $value Any value.
20
+ *
21
+ * @return The value's hash.
22
+ */
23
+ protected function _hash($value)
24
+ {
25
+ return is_scalar($value)
26
+ ? $this->_hashScalar($value)
27
+ : $this->_hashNonScalar($value);
28
+ }
29
+
30
+ /**
31
+ * Creates a hash of a scalar value.
32
+ *
33
+ * @since 0.1.0
34
+ * @see sha1()
35
+ *
36
+ * @param int|float|string $value The scalar value to hash.
37
+ *
38
+ * @return string The value's {@link sha1() SHA1} hash.
39
+ */
40
+ protected function _hashScalar($value)
41
+ {
42
+ return sha1($value);
43
+ }
44
+
45
+ /**
46
+ * Creates a hash of a non-scalar value.
47
+ *
48
+ * @since 0.1.0
49
+ *
50
+ * @param object|array $value The non-scalar value to hash.
51
+ *
52
+ * @return string The value's hash. Always same for same object, but
53
+ * different for different identical objects. Same for identical arrays,
54
+ * but different for arrays with same data in a different order.
55
+ */
56
+ protected function _hashNonScalar($value)
57
+ {
58
+ return is_object($value)
59
+ ? $this->_hashScalar(spl_object_hash($value))
60
+ : $this->_hashScalar(serialize($value));
61
+ }
62
+ }
vendor/dhii/collections-abstract-base/src/AbstractIterableCollection.php ADDED
@@ -0,0 +1,286 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use RuntimeException;
6
+ use UnexpectedValueException;
7
+
8
+ /**
9
+ * Common functionality for collections that can be iterated over in a foreach loop.
10
+ *
11
+ * Caches items on rewind, allowing convenient auto-generation of items,
12
+ * while still having performance in the loop.
13
+ *
14
+ * @since 0.1.0
15
+ */
16
+ abstract class AbstractIterableCollection extends AbstractCollection implements \Iterator
17
+ {
18
+ protected $itemIndex = 0;
19
+ protected $cachedItems = null;
20
+
21
+ /**
22
+ * {@inheritdoc}
23
+ *
24
+ * @since 0.1.0
25
+ */
26
+ public function current()
27
+ {
28
+ return $this->_current();
29
+ }
30
+
31
+ /**
32
+ * Retrieves the current element in the iteration.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ protected function _current()
37
+ {
38
+ return $this->_arrayCurrent($this->_getCachedItems());
39
+ }
40
+
41
+ /**
42
+ * {@inheritdoc}
43
+ *
44
+ * @since 0.1.0
45
+ */
46
+ public function key()
47
+ {
48
+ return $this->_key();
49
+ }
50
+
51
+ /**
52
+ * Retrieves the key of the current element in the iteration.
53
+ *
54
+ * @since 0.1.0
55
+ */
56
+ protected function _key()
57
+ {
58
+ return $this->_arrayKey($this->_getCachedItems());
59
+ }
60
+
61
+ /**
62
+ * {@inheritdoc}
63
+ *
64
+ * @since 0.1.0
65
+ */
66
+ public function next()
67
+ {
68
+ $this->_next();
69
+ }
70
+
71
+ /**
72
+ * Advances the internal iteration pointer forward.
73
+ *
74
+ * @since 0.1.0
75
+ */
76
+ protected function _next()
77
+ {
78
+ $this->_arrayNext($this->_getCachedItems());
79
+ }
80
+
81
+ /**
82
+ * {@inheritdoc}
83
+ *
84
+ * @since 0.1.0
85
+ */
86
+ public function rewind()
87
+ {
88
+ $this->_rewind();
89
+ }
90
+
91
+ /**
92
+ * Returns the internal iteration pointer to the beginning.
93
+ *
94
+ * @since 0.1.0
95
+ */
96
+ protected function _rewind()
97
+ {
98
+ $this->_clearItemCache();
99
+ }
100
+
101
+ /**
102
+ * {@inheritdoc}
103
+ *
104
+ * @since 0.1.0
105
+ */
106
+ public function valid()
107
+ {
108
+ return $this->_arrayKey($this->_getCachedItems()) !== null;
109
+ }
110
+
111
+ protected function _count()
112
+ {
113
+ return $this->_arrayCount($this->_getCachedItems());
114
+ }
115
+
116
+ /**
117
+ * Retrieve items that are cached for iteration.
118
+ *
119
+ * If no items are cached, populates the cache first.
120
+ *
121
+ * @since 0.1.0
122
+ *
123
+ * @return array The array of items.
124
+ */
125
+ protected function &_getCachedItems()
126
+ {
127
+ if (is_null($this->cachedItems)) {
128
+ $this->cachedItems = $this->_getItemsForCache();
129
+ $this->_arrayRewind($this->cachedItems);
130
+ }
131
+
132
+ return $this->cachedItems;
133
+ }
134
+
135
+ /**
136
+ * Retrieves items that are prepared to be cached and worked with.
137
+ *
138
+ * @since 0.1.0
139
+ *
140
+ * @return array The array of prepared items.
141
+ */
142
+ protected function _getItemsForCache()
143
+ {
144
+ $items = $this->getItems();
145
+
146
+ return $items;
147
+ }
148
+
149
+ /**
150
+ * Clears and resents the iterable item cache.
151
+ *
152
+ * @since 0.1.0
153
+ *
154
+ * @return AbstractIterableCollection This instance.
155
+ */
156
+ protected function _clearItemCache()
157
+ {
158
+ $this->cachedItems = null;
159
+
160
+ return $this;
161
+ }
162
+
163
+ /**
164
+ * Retrieve the current element from a list.
165
+ *
166
+ * @since 0.1.0
167
+ *
168
+ * @param array|\Traversable $array The list to get the current element of.
169
+ *
170
+ * @return mixed The current element in the list.
171
+ */
172
+ protected function _arrayCurrent(&$array)
173
+ {
174
+ return $array instanceof \Traversable
175
+ ? $this->_getIterator($array)->current()
176
+ : current($array);
177
+ }
178
+
179
+ /**
180
+ * Retrieve the current key from a list.
181
+ *
182
+ * @since 0.1.0
183
+ *
184
+ * @param array|\Traversable $array The list to get the current key of.
185
+ *
186
+ * @return string|int The current key in the list.
187
+ */
188
+ protected function _arrayKey(&$array)
189
+ {
190
+ return $array instanceof \Traversable
191
+ ? $this->_getIterator($array)->key()
192
+ : key($array);
193
+ }
194
+
195
+ /**
196
+ * Move the pointer of the list to the beginning.
197
+ *
198
+ * @since 0.1.0
199
+ *
200
+ * @param array|\Traversable $array The list to rewind.
201
+ *
202
+ * @return mixed|bool The value of the first list item.
203
+ */
204
+ protected function _arrayRewind(&$array)
205
+ {
206
+ return $array instanceof \Traversable
207
+ ? $this->_getIterator($array)->rewind()
208
+ : reset($array);
209
+ }
210
+
211
+ /**
212
+ * Move the pointer of the list forward and return the element there.
213
+ *
214
+ * @since 0.1.0
215
+ *
216
+ * @param array|\Traversable $array The list to move the pointer of.
217
+ *
218
+ * @return mixed|null The element at the next position in the list.
219
+ */
220
+ protected function _arrayNext(&$array)
221
+ {
222
+ return $array instanceof \Traversable
223
+ ? $this->_getIterator($array)->next()
224
+ : next($array);
225
+ }
226
+
227
+ /**
228
+ * Get the amount of all elements in the given list.
229
+ *
230
+ * @since 0.1.0
231
+ *
232
+ * @param array|\Countable|\Traversable $array The list to get the count of
233
+ *
234
+ * @throws RuntimeException If the given list is not something that can be counted.
235
+ *
236
+ * @return int The number of items in the list.
237
+ */
238
+ public function _arrayCount(&$list)
239
+ {
240
+ if (is_array($list)) {
241
+ return count($list);
242
+ }
243
+
244
+ if ($list instanceof \Countable) {
245
+ return $list->count();
246
+ }
247
+
248
+ if ($list instanceof \Traversable) {
249
+ $count = 0;
250
+ $list = $this->_getIterator($list);
251
+ foreach ($list as $_item) {
252
+ ++$count;
253
+ }
254
+
255
+ return $count;
256
+ }
257
+
258
+ throw new RuntimeException(sprintf('Could not count elements: the given list is not someting that can be counted'));
259
+ }
260
+
261
+ /**
262
+ * Retrieve the bottom-most iterator of this iterator.
263
+ *
264
+ * If this is an iterator, gets itself.
265
+ * If this is an {@see \IteratorAggregate}, return its inner-most iterator, recursively.
266
+ *
267
+ *
268
+ * @since 0.1.0
269
+ *
270
+ * @param \Traversable $iterator An iterator.
271
+ *
272
+ * @return \Iterator The final iterator.
273
+ */
274
+ protected function _getIterator(\Traversable $iterator)
275
+ {
276
+ if ($iterator instanceof \Iterator) {
277
+ return $iterator;
278
+ }
279
+
280
+ if (!($iterator instanceof \IteratorAggregate)) {
281
+ throw new UnexpectedValueException(sprintf('Could not retrieve iterator'));
282
+ }
283
+
284
+ $this->_getIterator($iterator->getIterator());
285
+ }
286
+ }
vendor/dhii/collections-abstract-base/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/collections-abstract-base/test/functional/AbstractCollectionTest.php ADDED
@@ -0,0 +1,111 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\FuncTest\AbstractCollectionTest;
4
+
5
+ /**
6
+ * Tests {@see \Dhii\Collection\AbstractCollection}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractCollectionTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return \Dhii\Collection\AbstractCollection The new instance of the subject.
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->mock('Dhii\\Collection\\AbstractCollection')
22
+ ->_validateItem()
23
+ ->new();
24
+
25
+ $reflection = $this->reflect($mock);
26
+ $reflection->_construct();
27
+
28
+ return $mock;
29
+ }
30
+
31
+ /**
32
+ * Tests whether a valid instance of the test subject can be created.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ public function testCanBeCreated()
37
+ {
38
+ $subject = $this->createInstance();
39
+
40
+ $this->assertInstanceOf('Dhii\\Collection\\AbstractCollection', $subject, 'Subject is not of the right type');
41
+ }
42
+
43
+ /**
44
+ * Tests whether the collection reports added items correctly.
45
+ *
46
+ * @since 0.1.0
47
+ */
48
+ public function testCanAdd()
49
+ {
50
+ $subject = $this->createInstance();
51
+ $reflection = $this->reflect($subject);
52
+
53
+ $reflection->_addItem('apple');
54
+ $reflection->_addItem('banana');
55
+
56
+ $items = $reflection->_getItems();
57
+ $this->assertEquals(2, count($items), 'Number of items reported is wrong');
58
+ $this->assertTrue(in_array('apple', $items, true), 'Required element not found among reported items');
59
+ $this->assertTrue(in_array('banana', $items, true), 'Required element not found among reported items');
60
+
61
+ $this->assertTrue($reflection->_hasItem('apple'), 'Collection does not contain required item');
62
+ $this->assertTrue($reflection->_hasItem('banana'), 'Collection does not contain required item');
63
+ }
64
+
65
+ /**
66
+ * Tests whether the collection reports set items correctly.
67
+ *
68
+ * @since 0.1.0
69
+ */
70
+ public function testCanSet()
71
+ {
72
+ $subject = $this->createInstance();
73
+ $reflection = $this->reflect($subject);
74
+
75
+ $reflection->_setItem('one', 'apple');
76
+ $reflection->_setItem('two', 'banana');
77
+
78
+ $items = $reflection->_getItems();
79
+ $this->assertEquals(2, count($items), 'Number of items reported is wrong');
80
+ $this->assertEquals('apple', $items['one'], 'Required element not found at specified key');
81
+ $this->assertEquals('banana', $items['two'], 'Required element not found at specified key');
82
+
83
+ $this->assertTrue($reflection->_hasItem('apple'), 'Collection does not report required item');
84
+ $this->assertTrue($reflection->_hasItem('banana'), 'Collection does not report required item');
85
+
86
+ $this->assertEquals('apple', $reflection->_getItem('one'), 'Collection does not return required item');
87
+ $this->assertEquals('banana', $reflection->_getItem('two'), 'Collection does not return required item');
88
+ $this->assertTrue($reflection->_hasItem('apple'), 'Collection does not contain required item');
89
+ $this->assertTrue($reflection->_hasItem('banana'), 'Collection does not contain required item');
90
+
91
+ $this->assertEquals('one', $reflection->_findItem('apple'), 'Collection does not find item at required index');
92
+ $this->assertEquals('two', $reflection->_findItem('banana'), 'Collection does not find item at required index');
93
+ }
94
+
95
+ public function testCanRemove()
96
+ {
97
+ $subject = $this->createInstance();
98
+ $reflection = $this->reflect($subject);
99
+
100
+ $reflection->_setItem('one', 'apple');
101
+ $reflection->_setItem('two', 'banana');
102
+
103
+ $items = $reflection->_getItems();
104
+ $this->assertEquals(2, count($items), 'Number of items reported before removal is wrong');
105
+
106
+ $this->assertTrue($reflection->_removeItem('apple'), 'Collection reports inability to remove item');
107
+ $items = $reflection->_getItems();
108
+ $this->assertEquals(1, count($items), 'Number of items reported after removal is wrong');
109
+ $this->assertEquals(array('two' => 'banana'), $items, 'The result reported after item removal is wrong');
110
+ }
111
+ }
vendor/dhii/collections-abstract-base/test/functional/AbstractHasherTest.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\FuncTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\AbstractHasher}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractHasherTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\AbstractHasher
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->mock('Dhii\Collection\AbstractHasher')
22
+ ->new();
23
+
24
+ return $mock;
25
+ }
26
+
27
+ /**
28
+ * Tests whether a correct instance of a descendant can be created.
29
+ *
30
+ * @since 0.1.0
31
+ */
32
+ public function testCanBeCreated()
33
+ {
34
+ $subject = $this->createInstance();
35
+
36
+ $this->assertInstanceOf('Dhii\Collection\AbstractHasher', $subject, 'Subject is not a valid hasher.');
37
+ }
38
+
39
+ /**
40
+ * Tests whether or not hashing is done right.
41
+ *
42
+ * @since 0.1.0
43
+ */
44
+ public function testHashing()
45
+ {
46
+ $subject = $this->createInstance();
47
+ $reflection = $this->reflect($subject);
48
+
49
+ $exampleString = 'abcdef123456';
50
+ $stringHash = $reflection->_hash($exampleString);
51
+ $this->assertNotEquals($exampleString, $stringHash, 'String hash is same as string');
52
+ $this->assertInternalType('string', $stringHash, 'String hash is not a string');
53
+
54
+ $exampleObject = new \stdClass();
55
+ $exampleObject->myMember = 'qwerty98765';
56
+ $objectHash = $reflection->_hash($exampleObject);
57
+ $this->assertNotEquals($exampleObject, $objectHash, 'Object hash is same as string');
58
+ $this->assertInternalType('string', $objectHash, 'Object hash is not a string');
59
+ }
60
+ }
vendor/dhii/collections-abstract-base/test/functional/AbstractIterableCollectionTest.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\FuncTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\AbstractIterableCollection}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractIterableCollectionTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\AbstractHasher
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->mock('Dhii\Collection\AbstractIterableCollection')
22
+ ->_validateItem()
23
+ ->new();
24
+
25
+ return $mock;
26
+ }
27
+
28
+ /**
29
+ * Tests whether a correct instance of a descendant can be created.
30
+ *
31
+ * @since 0.1.0
32
+ */
33
+ public function testCanBeCreated()
34
+ {
35
+ $subject = $this->createInstance();
36
+
37
+ $this->assertInstanceOf('Dhii\Collection\CollectionInterface', $subject, 'Subject is not a valid collection.');
38
+ $this->assertInstanceOf('Dhii\Collection\AbstractIterableCollection', $subject, 'Subject is not a valid iterable collection.');
39
+ $this->assertInstanceOf('Iterator', $subject, 'Subject is not a valid iterator.');
40
+ }
41
+
42
+ /**
43
+ * Tests whether or not this collection is actually iterable.
44
+ *
45
+ * @since 0.1.0
46
+ */
47
+ public function testIsIterable()
48
+ {
49
+ $subject = $this->createInstance();
50
+ $reflection = $this->reflect($subject);
51
+
52
+ $items = array(
53
+ 'apple',
54
+ 'orange',
55
+ 'banana'
56
+ );
57
+ $reflection->items = $items;
58
+
59
+ $i = 0;
60
+ foreach ($subject as $_key => $_item) {
61
+ $this->assertSame($items[$i], $_item);
62
+ $i++;
63
+ }
64
+ }
65
+
66
+ /**
67
+ * Tests whether or not this collection is actually iterable when the
68
+ * items are a {@see \Traversable} internally.
69
+ *
70
+ * @since 0.1.0
71
+ */
72
+ public function testIsIterableTraversable()
73
+ {
74
+ $subject = $this->createInstance();
75
+ $reflection = $this->reflect($subject);
76
+
77
+ $items = array(
78
+ 'apple',
79
+ 'orange',
80
+ 'banana'
81
+ );
82
+ $reflection->items = new \ArrayIterator($items);
83
+
84
+ $i = 0;
85
+ foreach ($subject as $_item) {
86
+ $this->assertSame($items[$i], $_item);
87
+ $i++;
88
+ }
89
+ }
90
+
91
+ /**
92
+ * Tests whether or not this collection can count its items.
93
+ *
94
+ * @since 0.1.0
95
+ */
96
+ public function testIsCountable()
97
+ {
98
+ $subject = $this->createInstance();
99
+ $reflection = $this->reflect($subject);
100
+
101
+ $items = array(
102
+ 'apple',
103
+ 'orange',
104
+ 'banana'
105
+ );
106
+ $reflection->items = $items;
107
+
108
+ $this->assertSame(count($items), $reflection->_count(), 'Item count is incorrect');
109
+ }
110
+
111
+ /**
112
+ * Tests whether or not this collection can count its items when they are
113
+ * a {@see \Traversable} internally.
114
+ *
115
+ * @since 0.1.0
116
+ */
117
+ public function testIsCountableTraversable()
118
+ {
119
+ $subject = $this->createInstance();
120
+ $reflection = $this->reflect($subject);
121
+
122
+ $items = array(
123
+ 'apple',
124
+ 'orange',
125
+ 'banana'
126
+ );
127
+ $reflection->items = new \IteratorIterator(new \ArrayIterator($items));
128
+
129
+ $this->assertSame(count($items), $reflection->_count(), 'Item count is incorrect');
130
+ }
131
+ }
vendor/dhii/collections-abstract/.php_cs ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
4
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
5
+ $fixers = $config->getFixers();
6
+
7
+ $toRemove = array('short_array_syntax');
8
+ foreach ($toRemove as $_fixer) {
9
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
10
+ continue;
11
+ }
12
+
13
+ unset($fixers[$removeIndex]);
14
+ }
15
+
16
+ $toAdd = array('long_array_syntax');
17
+ foreach ($toAdd as $_fixer) {
18
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
19
+ continue;
20
+ }
21
+
22
+ $fixers[] = $_fixer;
23
+ }
24
+
25
+ $config->fixers($fixers);
26
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
27
+ return $config;
vendor/dhii/collections-abstract/.travis.yml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 install
13
+
14
+ script:
15
+ - phpunit
vendor/dhii/collections-abstract/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
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.0 - 2016-11-10
8
+ The initial release
vendor/dhii/collections-abstract/composer.json ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/collections-abstract",
3
+ "description": "A collections library",
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
+ "dhii/collections-interface": "^0.1.1",
15
+ "dhii/stats-abstract": "^0.1.0",
16
+ "dhii/collections-abstract-base": "^0.1.0"
17
+ },
18
+ "require-dev": {
19
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
20
+ "phpunit/phpunit": "4.*",
21
+ "ptrofimov/xpmock": "^1.1"
22
+ },
23
+ "autoload": {
24
+ "psr-4": {
25
+ "Dhii\\Collection\\": "src/"
26
+ }
27
+ }
28
+ }
vendor/dhii/collections-abstract/composer.lock ADDED
@@ -0,0 +1,1755 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "ffbb516e9caaae60f4dcd06038c30bae",
8
+ "content-hash": "7b734ffe2650cae1be1f2474f684c1e2",
9
+ "packages": [
10
+ {
11
+ "name": "dhii/collections-abstract-base",
12
+ "version": "v0.1.0",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/Dhii/collections-abstract-base.git",
16
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/Dhii/collections-abstract-base/zipball/0ec0147451a72a13fb327ac6ff747c5e953c56f3",
21
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "dhii/collections-interface": "^0.1.1"
26
+ },
27
+ "require-dev": {
28
+ "codeclimate/php-test-reporter": "dev-master",
29
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
30
+ "phpunit/phpunit": "^4.8",
31
+ "ptrofimov/xpmock": "^1.1"
32
+ },
33
+ "type": "library",
34
+ "autoload": {
35
+ "psr-4": {
36
+ "Dhii\\Collection\\": "src/"
37
+ }
38
+ },
39
+ "notification-url": "https://packagist.org/downloads/",
40
+ "license": [
41
+ "MIT"
42
+ ],
43
+ "authors": [
44
+ {
45
+ "name": "Dhii Team",
46
+ "email": "development@dhii.co"
47
+ }
48
+ ],
49
+ "description": "Collection base classes that do not depend on other non-collection packages, on which there is a dependency of other collection packages that depend on this package. This is done to avoid circular reference in the collection toolchain",
50
+ "time": "2016-11-10 15:09:37"
51
+ },
52
+ {
53
+ "name": "dhii/collections-interface",
54
+ "version": "v0.1.1",
55
+ "source": {
56
+ "type": "git",
57
+ "url": "https://github.com/Dhii/collections-interface.git",
58
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f"
59
+ },
60
+ "dist": {
61
+ "type": "zip",
62
+ "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
63
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
64
+ "shasum": ""
65
+ },
66
+ "require": {
67
+ "php": "^5.3 | ^7.0"
68
+ },
69
+ "require-dev": {
70
+ "codeclimate/php-test-reporter": "dev-master",
71
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
72
+ "phpunit/phpunit": "^4.8"
73
+ },
74
+ "type": "library",
75
+ "autoload": {
76
+ "psr-4": {
77
+ "Dhii\\Collection\\": "src/"
78
+ }
79
+ },
80
+ "notification-url": "https://packagist.org/downloads/",
81
+ "license": [
82
+ "MIT"
83
+ ],
84
+ "authors": [
85
+ {
86
+ "name": "Dhii Team",
87
+ "email": "development@dhii.co"
88
+ }
89
+ ],
90
+ "description": "Interfaces for collections",
91
+ "time": "2016-11-09 19:23:28"
92
+ },
93
+ {
94
+ "name": "dhii/stats-abstract",
95
+ "version": "v0.1.0",
96
+ "source": {
97
+ "type": "git",
98
+ "url": "https://github.com/Dhii/stats-abstract.git",
99
+ "reference": "71f6702c3257c71ab3917b6d076d3c3588cc9f49"
100
+ },
101
+ "dist": {
102
+ "type": "zip",
103
+ "url": "https://api.github.com/repos/Dhii/stats-abstract/zipball/71f6702c3257c71ab3917b6d076d3c3588cc9f49",
104
+ "reference": "71f6702c3257c71ab3917b6d076d3c3588cc9f49",
105
+ "shasum": ""
106
+ },
107
+ "require": {
108
+ "dhii/collections-abstract-base": "^0.1.0",
109
+ "dhii/stats-interface": "^0.1.0"
110
+ },
111
+ "require-dev": {
112
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
113
+ "phpunit/phpunit": "^4.8",
114
+ "ptrofimov/xpmock": "^1.1"
115
+ },
116
+ "type": "library",
117
+ "autoload": {
118
+ "psr-4": {
119
+ "Dhii\\Stats\\": "src/"
120
+ }
121
+ },
122
+ "notification-url": "https://packagist.org/downloads/",
123
+ "license": [
124
+ "MIT"
125
+ ],
126
+ "authors": [
127
+ {
128
+ "name": "Dhii Team",
129
+ "email": "development@dhii.co"
130
+ }
131
+ ],
132
+ "description": "Abstract base for stats",
133
+ "time": "2016-11-10 18:55:43"
134
+ },
135
+ {
136
+ "name": "dhii/stats-interface",
137
+ "version": "v0.1.0",
138
+ "source": {
139
+ "type": "git",
140
+ "url": "https://github.com/Dhii/stats-interface.git",
141
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba"
142
+ },
143
+ "dist": {
144
+ "type": "zip",
145
+ "url": "https://api.github.com/repos/Dhii/stats-interface/zipball/36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
146
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
147
+ "shasum": ""
148
+ },
149
+ "require": {
150
+ "php": "^5.3 | ^7.0"
151
+ },
152
+ "require-dev": {
153
+ "dhii/php-cs-fixer-config": "dev-php-5.3"
154
+ },
155
+ "type": "library",
156
+ "autoload": {
157
+ "psr-4": {
158
+ "Dhii\\Stats\\": "src/"
159
+ }
160
+ },
161
+ "notification-url": "https://packagist.org/downloads/",
162
+ "license": [
163
+ "MIT"
164
+ ],
165
+ "authors": [
166
+ {
167
+ "name": "Dhii Team",
168
+ "email": "development@dhii.co"
169
+ }
170
+ ],
171
+ "description": "Interfaces for stats",
172
+ "time": "2016-11-10 15:38:37"
173
+ }
174
+ ],
175
+ "packages-dev": [
176
+ {
177
+ "name": "dhii/php-cs-fixer-config",
178
+ "version": "dev-php-5.3",
179
+ "source": {
180
+ "type": "git",
181
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
182
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
183
+ },
184
+ "dist": {
185
+ "type": "zip",
186
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
187
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
188
+ "shasum": ""
189
+ },
190
+ "require": {
191
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
192
+ "php": "^5.3 | ^7.0"
193
+ },
194
+ "require-dev": {
195
+ "phpunit/phpunit": "^4.8"
196
+ },
197
+ "type": "library",
198
+ "autoload": {
199
+ "psr-4": {
200
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
201
+ }
202
+ },
203
+ "notification-url": "https://packagist.org/downloads/",
204
+ "license": [
205
+ "MIT"
206
+ ],
207
+ "authors": [
208
+ {
209
+ "name": "Dhii Team",
210
+ "email": "development@dhii.co"
211
+ }
212
+ ],
213
+ "description": "A default PHP CS Fixer config implementation",
214
+ "time": "2016-09-03 14:45:03"
215
+ },
216
+ {
217
+ "name": "doctrine/instantiator",
218
+ "version": "dev-master",
219
+ "source": {
220
+ "type": "git",
221
+ "url": "https://github.com/doctrine/instantiator.git",
222
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a"
223
+ },
224
+ "dist": {
225
+ "type": "zip",
226
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a",
227
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a",
228
+ "shasum": ""
229
+ },
230
+ "require": {
231
+ "php": ">=5.3,<8.0-DEV"
232
+ },
233
+ "require-dev": {
234
+ "athletic/athletic": "~0.1.8",
235
+ "ext-pdo": "*",
236
+ "ext-phar": "*",
237
+ "phpunit/phpunit": "~4.0",
238
+ "squizlabs/php_codesniffer": "~2.0"
239
+ },
240
+ "type": "library",
241
+ "extra": {
242
+ "branch-alias": {
243
+ "dev-master": "1.0.x-dev"
244
+ }
245
+ },
246
+ "autoload": {
247
+ "psr-4": {
248
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
249
+ }
250
+ },
251
+ "notification-url": "https://packagist.org/downloads/",
252
+ "license": [
253
+ "MIT"
254
+ ],
255
+ "authors": [
256
+ {
257
+ "name": "Marco Pivetta",
258
+ "email": "ocramius@gmail.com",
259
+ "homepage": "http://ocramius.github.com/"
260
+ }
261
+ ],
262
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
263
+ "homepage": "https://github.com/doctrine/instantiator",
264
+ "keywords": [
265
+ "constructor",
266
+ "instantiate"
267
+ ],
268
+ "time": "2016-03-31 10:24:22"
269
+ },
270
+ {
271
+ "name": "friendsofphp/php-cs-fixer",
272
+ "version": "1.11.x-dev",
273
+ "source": {
274
+ "type": "git",
275
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
276
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
277
+ },
278
+ "dist": {
279
+ "type": "zip",
280
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
281
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
282
+ "shasum": ""
283
+ },
284
+ "require": {
285
+ "ext-tokenizer": "*",
286
+ "php": ">=5.3.6",
287
+ "sebastian/diff": "~1.1",
288
+ "symfony/console": "~2.3|~3.0",
289
+ "symfony/event-dispatcher": "~2.1|~3.0",
290
+ "symfony/filesystem": "~2.1|~3.0",
291
+ "symfony/finder": "~2.1|~3.0",
292
+ "symfony/process": "~2.3|~3.0",
293
+ "symfony/stopwatch": "~2.5|~3.0"
294
+ },
295
+ "conflict": {
296
+ "hhvm": "<3.9"
297
+ },
298
+ "require-dev": {
299
+ "phpunit/phpunit": "^4.5|^5",
300
+ "satooshi/php-coveralls": "^0.7.1"
301
+ },
302
+ "bin": [
303
+ "php-cs-fixer"
304
+ ],
305
+ "type": "application",
306
+ "autoload": {
307
+ "psr-4": {
308
+ "Symfony\\CS\\": "Symfony/CS/"
309
+ }
310
+ },
311
+ "notification-url": "https://packagist.org/downloads/",
312
+ "license": [
313
+ "MIT"
314
+ ],
315
+ "authors": [
316
+ {
317
+ "name": "Dariusz Rumiński",
318
+ "email": "dariusz.ruminski@gmail.com"
319
+ },
320
+ {
321
+ "name": "Fabien Potencier",
322
+ "email": "fabien@symfony.com"
323
+ }
324
+ ],
325
+ "description": "A tool to automatically fix PHP code style",
326
+ "time": "2016-08-16 23:31:05"
327
+ },
328
+ {
329
+ "name": "phpdocumentor/reflection-docblock",
330
+ "version": "2.0.4",
331
+ "source": {
332
+ "type": "git",
333
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
334
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
335
+ },
336
+ "dist": {
337
+ "type": "zip",
338
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
339
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
340
+ "shasum": ""
341
+ },
342
+ "require": {
343
+ "php": ">=5.3.3"
344
+ },
345
+ "require-dev": {
346
+ "phpunit/phpunit": "~4.0"
347
+ },
348
+ "suggest": {
349
+ "dflydev/markdown": "~1.0",
350
+ "erusev/parsedown": "~1.0"
351
+ },
352
+ "type": "library",
353
+ "extra": {
354
+ "branch-alias": {
355
+ "dev-master": "2.0.x-dev"
356
+ }
357
+ },
358
+ "autoload": {
359
+ "psr-0": {
360
+ "phpDocumentor": [
361
+ "src/"
362
+ ]
363
+ }
364
+ },
365
+ "notification-url": "https://packagist.org/downloads/",
366
+ "license": [
367
+ "MIT"
368
+ ],
369
+ "authors": [
370
+ {
371
+ "name": "Mike van Riel",
372
+ "email": "mike.vanriel@naenius.com"
373
+ }
374
+ ],
375
+ "time": "2015-02-03 12:10:50"
376
+ },
377
+ {
378
+ "name": "phpspec/prophecy",
379
+ "version": "dev-master",
380
+ "source": {
381
+ "type": "git",
382
+ "url": "https://github.com/phpspec/prophecy.git",
383
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386"
384
+ },
385
+ "dist": {
386
+ "type": "zip",
387
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/5c324f4951aca87a2de61b7903b75126516b6386",
388
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386",
389
+ "shasum": ""
390
+ },
391
+ "require": {
392
+ "doctrine/instantiator": "^1.0.2",
393
+ "php": "^5.3|^7.0",
394
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
395
+ "sebastian/comparator": "^1.1",
396
+ "sebastian/recursion-context": "^1.0"
397
+ },
398
+ "require-dev": {
399
+ "phpspec/phpspec": "^2.0",
400
+ "phpunit/phpunit": "^4.8 || ^5"
401
+ },
402
+ "type": "library",
403
+ "extra": {
404
+ "branch-alias": {
405
+ "dev-master": "1.6.x-dev"
406
+ }
407
+ },
408
+ "autoload": {
409
+ "psr-0": {
410
+ "Prophecy\\": "src/"
411
+ }
412
+ },
413
+ "notification-url": "https://packagist.org/downloads/",
414
+ "license": [
415
+ "MIT"
416
+ ],
417
+ "authors": [
418
+ {
419
+ "name": "Konstantin Kudryashov",
420
+ "email": "ever.zet@gmail.com",
421
+ "homepage": "http://everzet.com"
422
+ },
423
+ {
424
+ "name": "Marcello Duarte",
425
+ "email": "marcello.duarte@gmail.com"
426
+ }
427
+ ],
428
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
429
+ "homepage": "https://github.com/phpspec/prophecy",
430
+ "keywords": [
431
+ "Double",
432
+ "Dummy",
433
+ "fake",
434
+ "mock",
435
+ "spy",
436
+ "stub"
437
+ ],
438
+ "time": "2016-10-02 13:12:17"
439
+ },
440
+ {
441
+ "name": "phpunit/php-code-coverage",
442
+ "version": "2.2.x-dev",
443
+ "source": {
444
+ "type": "git",
445
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
446
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
447
+ },
448
+ "dist": {
449
+ "type": "zip",
450
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
451
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
452
+ "shasum": ""
453
+ },
454
+ "require": {
455
+ "php": ">=5.3.3",
456
+ "phpunit/php-file-iterator": "~1.3",
457
+ "phpunit/php-text-template": "~1.2",
458
+ "phpunit/php-token-stream": "~1.3",
459
+ "sebastian/environment": "^1.3.2",
460
+ "sebastian/version": "~1.0"
461
+ },
462
+ "require-dev": {
463
+ "ext-xdebug": ">=2.1.4",
464
+ "phpunit/phpunit": "~4"
465
+ },
466
+ "suggest": {
467
+ "ext-dom": "*",
468
+ "ext-xdebug": ">=2.2.1",
469
+ "ext-xmlwriter": "*"
470
+ },
471
+ "type": "library",
472
+ "extra": {
473
+ "branch-alias": {
474
+ "dev-master": "2.2.x-dev"
475
+ }
476
+ },
477
+ "autoload": {
478
+ "classmap": [
479
+ "src/"
480
+ ]
481
+ },
482
+ "notification-url": "https://packagist.org/downloads/",
483
+ "license": [
484
+ "BSD-3-Clause"
485
+ ],
486
+ "authors": [
487
+ {
488
+ "name": "Sebastian Bergmann",
489
+ "email": "sb@sebastian-bergmann.de",
490
+ "role": "lead"
491
+ }
492
+ ],
493
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
494
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
495
+ "keywords": [
496
+ "coverage",
497
+ "testing",
498
+ "xunit"
499
+ ],
500
+ "time": "2015-10-06 15:47:00"
501
+ },
502
+ {
503
+ "name": "phpunit/php-file-iterator",
504
+ "version": "dev-master",
505
+ "source": {
506
+ "type": "git",
507
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
508
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
509
+ },
510
+ "dist": {
511
+ "type": "zip",
512
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
513
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
514
+ "shasum": ""
515
+ },
516
+ "require": {
517
+ "php": ">=5.3.3"
518
+ },
519
+ "type": "library",
520
+ "extra": {
521
+ "branch-alias": {
522
+ "dev-master": "1.4.x-dev"
523
+ }
524
+ },
525
+ "autoload": {
526
+ "classmap": [
527
+ "src/"
528
+ ]
529
+ },
530
+ "notification-url": "https://packagist.org/downloads/",
531
+ "license": [
532
+ "BSD-3-Clause"
533
+ ],
534
+ "authors": [
535
+ {
536
+ "name": "Sebastian Bergmann",
537
+ "email": "sb@sebastian-bergmann.de",
538
+ "role": "lead"
539
+ }
540
+ ],
541
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
542
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
543
+ "keywords": [
544
+ "filesystem",
545
+ "iterator"
546
+ ],
547
+ "time": "2016-10-03 07:40:28"
548
+ },
549
+ {
550
+ "name": "phpunit/php-text-template",
551
+ "version": "1.2.1",
552
+ "source": {
553
+ "type": "git",
554
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
555
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
556
+ },
557
+ "dist": {
558
+ "type": "zip",
559
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
560
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
561
+ "shasum": ""
562
+ },
563
+ "require": {
564
+ "php": ">=5.3.3"
565
+ },
566
+ "type": "library",
567
+ "autoload": {
568
+ "classmap": [
569
+ "src/"
570
+ ]
571
+ },
572
+ "notification-url": "https://packagist.org/downloads/",
573
+ "license": [
574
+ "BSD-3-Clause"
575
+ ],
576
+ "authors": [
577
+ {
578
+ "name": "Sebastian Bergmann",
579
+ "email": "sebastian@phpunit.de",
580
+ "role": "lead"
581
+ }
582
+ ],
583
+ "description": "Simple template engine.",
584
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
585
+ "keywords": [
586
+ "template"
587
+ ],
588
+ "time": "2015-06-21 13:50:34"
589
+ },
590
+ {
591
+ "name": "phpunit/php-timer",
592
+ "version": "1.0.8",
593
+ "source": {
594
+ "type": "git",
595
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
596
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
597
+ },
598
+ "dist": {
599
+ "type": "zip",
600
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
601
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
602
+ "shasum": ""
603
+ },
604
+ "require": {
605
+ "php": ">=5.3.3"
606
+ },
607
+ "require-dev": {
608
+ "phpunit/phpunit": "~4|~5"
609
+ },
610
+ "type": "library",
611
+ "autoload": {
612
+ "classmap": [
613
+ "src/"
614
+ ]
615
+ },
616
+ "notification-url": "https://packagist.org/downloads/",
617
+ "license": [
618
+ "BSD-3-Clause"
619
+ ],
620
+ "authors": [
621
+ {
622
+ "name": "Sebastian Bergmann",
623
+ "email": "sb@sebastian-bergmann.de",
624
+ "role": "lead"
625
+ }
626
+ ],
627
+ "description": "Utility class for timing",
628
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
629
+ "keywords": [
630
+ "timer"
631
+ ],
632
+ "time": "2016-05-12 18:03:57"
633
+ },
634
+ {
635
+ "name": "phpunit/php-token-stream",
636
+ "version": "dev-master",
637
+ "source": {
638
+ "type": "git",
639
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
640
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872"
641
+ },
642
+ "dist": {
643
+ "type": "zip",
644
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/2ef59c57cd196301eeb88865d25916898dd72872",
645
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872",
646
+ "shasum": ""
647
+ },
648
+ "require": {
649
+ "ext-tokenizer": "*",
650
+ "php": ">=5.3.3"
651
+ },
652
+ "require-dev": {
653
+ "phpunit/phpunit": "~4.2"
654
+ },
655
+ "type": "library",
656
+ "extra": {
657
+ "branch-alias": {
658
+ "dev-master": "1.4-dev"
659
+ }
660
+ },
661
+ "autoload": {
662
+ "classmap": [
663
+ "src/"
664
+ ]
665
+ },
666
+ "notification-url": "https://packagist.org/downloads/",
667
+ "license": [
668
+ "BSD-3-Clause"
669
+ ],
670
+ "authors": [
671
+ {
672
+ "name": "Sebastian Bergmann",
673
+ "email": "sebastian@phpunit.de"
674
+ }
675
+ ],
676
+ "description": "Wrapper around PHP's tokenizer extension.",
677
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
678
+ "keywords": [
679
+ "tokenizer"
680
+ ],
681
+ "time": "2016-10-03 07:38:46"
682
+ },
683
+ {
684
+ "name": "phpunit/phpunit",
685
+ "version": "4.8.x-dev",
686
+ "source": {
687
+ "type": "git",
688
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
689
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935"
690
+ },
691
+ "dist": {
692
+ "type": "zip",
693
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b58ff0d8996b56675a3e05dcd563e0a4f244935",
694
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935",
695
+ "shasum": ""
696
+ },
697
+ "require": {
698
+ "ext-dom": "*",
699
+ "ext-json": "*",
700
+ "ext-pcre": "*",
701
+ "ext-reflection": "*",
702
+ "ext-spl": "*",
703
+ "php": ">=5.3.3",
704
+ "phpspec/prophecy": "^1.3.1",
705
+ "phpunit/php-code-coverage": "~2.1",
706
+ "phpunit/php-file-iterator": "~1.4",
707
+ "phpunit/php-text-template": "~1.2",
708
+ "phpunit/php-timer": "^1.0.6",
709
+ "phpunit/phpunit-mock-objects": "~2.3",
710
+ "sebastian/comparator": "~1.1",
711
+ "sebastian/diff": "~1.2",
712
+ "sebastian/environment": "~1.3",
713
+ "sebastian/exporter": "~1.2",
714
+ "sebastian/global-state": "~1.0",
715
+ "sebastian/version": "~1.0",
716
+ "symfony/yaml": "~2.1|~3.0"
717
+ },
718
+ "suggest": {
719
+ "phpunit/php-invoker": "~1.1"
720
+ },
721
+ "bin": [
722
+ "phpunit"
723
+ ],
724
+ "type": "library",
725
+ "extra": {
726
+ "branch-alias": {
727
+ "dev-master": "4.8.x-dev"
728
+ }
729
+ },
730
+ "autoload": {
731
+ "classmap": [
732
+ "src/"
733
+ ]
734
+ },
735
+ "notification-url": "https://packagist.org/downloads/",
736
+ "license": [
737
+ "BSD-3-Clause"
738
+ ],
739
+ "authors": [
740
+ {
741
+ "name": "Sebastian Bergmann",
742
+ "email": "sebastian@phpunit.de",
743
+ "role": "lead"
744
+ }
745
+ ],
746
+ "description": "The PHP Unit Testing framework.",
747
+ "homepage": "https://phpunit.de/",
748
+ "keywords": [
749
+ "phpunit",
750
+ "testing",
751
+ "xunit"
752
+ ],
753
+ "time": "2016-10-03 13:00:58"
754
+ },
755
+ {
756
+ "name": "phpunit/phpunit-mock-objects",
757
+ "version": "2.3.x-dev",
758
+ "source": {
759
+ "type": "git",
760
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
761
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
762
+ },
763
+ "dist": {
764
+ "type": "zip",
765
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
766
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
767
+ "shasum": ""
768
+ },
769
+ "require": {
770
+ "doctrine/instantiator": "^1.0.2",
771
+ "php": ">=5.3.3",
772
+ "phpunit/php-text-template": "~1.2",
773
+ "sebastian/exporter": "~1.2"
774
+ },
775
+ "require-dev": {
776
+ "phpunit/phpunit": "~4.4"
777
+ },
778
+ "suggest": {
779
+ "ext-soap": "*"
780
+ },
781
+ "type": "library",
782
+ "extra": {
783
+ "branch-alias": {
784
+ "dev-master": "2.3.x-dev"
785
+ }
786
+ },
787
+ "autoload": {
788
+ "classmap": [
789
+ "src/"
790
+ ]
791
+ },
792
+ "notification-url": "https://packagist.org/downloads/",
793
+ "license": [
794
+ "BSD-3-Clause"
795
+ ],
796
+ "authors": [
797
+ {
798
+ "name": "Sebastian Bergmann",
799
+ "email": "sb@sebastian-bergmann.de",
800
+ "role": "lead"
801
+ }
802
+ ],
803
+ "description": "Mock Object library for PHPUnit",
804
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
805
+ "keywords": [
806
+ "mock",
807
+ "xunit"
808
+ ],
809
+ "time": "2015-10-02 06:51:40"
810
+ },
811
+ {
812
+ "name": "psr/log",
813
+ "version": "dev-master",
814
+ "source": {
815
+ "type": "git",
816
+ "url": "https://github.com/php-fig/log.git",
817
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
818
+ },
819
+ "dist": {
820
+ "type": "zip",
821
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
822
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
823
+ "shasum": ""
824
+ },
825
+ "require": {
826
+ "php": ">=5.3.0"
827
+ },
828
+ "type": "library",
829
+ "extra": {
830
+ "branch-alias": {
831
+ "dev-master": "1.0.x-dev"
832
+ }
833
+ },
834
+ "autoload": {
835
+ "psr-4": {
836
+ "Psr\\Log\\": "Psr/Log/"
837
+ }
838
+ },
839
+ "notification-url": "https://packagist.org/downloads/",
840
+ "license": [
841
+ "MIT"
842
+ ],
843
+ "authors": [
844
+ {
845
+ "name": "PHP-FIG",
846
+ "homepage": "http://www.php-fig.org/"
847
+ }
848
+ ],
849
+ "description": "Common interface for logging libraries",
850
+ "homepage": "https://github.com/php-fig/log",
851
+ "keywords": [
852
+ "log",
853
+ "psr",
854
+ "psr-3"
855
+ ],
856
+ "time": "2016-10-10 12:19:37"
857
+ },
858
+ {
859
+ "name": "ptrofimov/xpmock",
860
+ "version": "1.1.5",
861
+ "source": {
862
+ "type": "git",
863
+ "url": "https://github.com/ptrofimov/xpmock.git",
864
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
865
+ },
866
+ "dist": {
867
+ "type": "zip",
868
+ "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
869
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
870
+ "shasum": ""
871
+ },
872
+ "require": {
873
+ "php": ">=5.3.0"
874
+ },
875
+ "require-dev": {
876
+ "phpunit/phpunit": "3.7.*"
877
+ },
878
+ "type": "library",
879
+ "autoload": {
880
+ "psr-0": {
881
+ "Xpmock": "src"
882
+ }
883
+ },
884
+ "notification-url": "https://packagist.org/downloads/",
885
+ "license": [
886
+ "MIT"
887
+ ],
888
+ "description": "PHPUnit: simple syntax to create mock-objects",
889
+ "time": "2014-01-02 16:42:27"
890
+ },
891
+ {
892
+ "name": "sebastian/comparator",
893
+ "version": "dev-master",
894
+ "source": {
895
+ "type": "git",
896
+ "url": "https://github.com/sebastianbergmann/comparator.git",
897
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f"
898
+ },
899
+ "dist": {
900
+ "type": "zip",
901
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/21400bd9503c3782f5ee80349117483dcf8cec3f",
902
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f",
903
+ "shasum": ""
904
+ },
905
+ "require": {
906
+ "php": ">=5.3.3",
907
+ "sebastian/diff": "~1.2",
908
+ "sebastian/exporter": "~1.2"
909
+ },
910
+ "require-dev": {
911
+ "phpunit/phpunit": "~4.4"
912
+ },
913
+ "type": "library",
914
+ "extra": {
915
+ "branch-alias": {
916
+ "dev-master": "1.2.x-dev"
917
+ }
918
+ },
919
+ "autoload": {
920
+ "classmap": [
921
+ "src/"
922
+ ]
923
+ },
924
+ "notification-url": "https://packagist.org/downloads/",
925
+ "license": [
926
+ "BSD-3-Clause"
927
+ ],
928
+ "authors": [
929
+ {
930
+ "name": "Jeff Welch",
931
+ "email": "whatthejeff@gmail.com"
932
+ },
933
+ {
934
+ "name": "Volker Dusch",
935
+ "email": "github@wallbash.com"
936
+ },
937
+ {
938
+ "name": "Bernhard Schussek",
939
+ "email": "bschussek@2bepublished.at"
940
+ },
941
+ {
942
+ "name": "Sebastian Bergmann",
943
+ "email": "sebastian@phpunit.de"
944
+ }
945
+ ],
946
+ "description": "Provides the functionality to compare PHP values for equality",
947
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
948
+ "keywords": [
949
+ "comparator",
950
+ "compare",
951
+ "equality"
952
+ ],
953
+ "time": "2016-10-03 07:45:42"
954
+ },
955
+ {
956
+ "name": "sebastian/diff",
957
+ "version": "dev-master",
958
+ "source": {
959
+ "type": "git",
960
+ "url": "https://github.com/sebastianbergmann/diff.git",
961
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
962
+ },
963
+ "dist": {
964
+ "type": "zip",
965
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
966
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
967
+ "shasum": ""
968
+ },
969
+ "require": {
970
+ "php": ">=5.3.3"
971
+ },
972
+ "require-dev": {
973
+ "phpunit/phpunit": "~4.8"
974
+ },
975
+ "type": "library",
976
+ "extra": {
977
+ "branch-alias": {
978
+ "dev-master": "1.4-dev"
979
+ }
980
+ },
981
+ "autoload": {
982
+ "classmap": [
983
+ "src/"
984
+ ]
985
+ },
986
+ "notification-url": "https://packagist.org/downloads/",
987
+ "license": [
988
+ "BSD-3-Clause"
989
+ ],
990
+ "authors": [
991
+ {
992
+ "name": "Kore Nordmann",
993
+ "email": "mail@kore-nordmann.de"
994
+ },
995
+ {
996
+ "name": "Sebastian Bergmann",
997
+ "email": "sebastian@phpunit.de"
998
+ }
999
+ ],
1000
+ "description": "Diff implementation",
1001
+ "homepage": "https://github.com/sebastianbergmann/diff",
1002
+ "keywords": [
1003
+ "diff"
1004
+ ],
1005
+ "time": "2016-10-03 07:45:03"
1006
+ },
1007
+ {
1008
+ "name": "sebastian/environment",
1009
+ "version": "1.3.x-dev",
1010
+ "source": {
1011
+ "type": "git",
1012
+ "url": "https://github.com/sebastianbergmann/environment.git",
1013
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1014
+ },
1015
+ "dist": {
1016
+ "type": "zip",
1017
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1018
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1019
+ "shasum": ""
1020
+ },
1021
+ "require": {
1022
+ "php": "^5.3.3 || ^7.0"
1023
+ },
1024
+ "require-dev": {
1025
+ "phpunit/phpunit": "^4.8 || ^5.0"
1026
+ },
1027
+ "type": "library",
1028
+ "extra": {
1029
+ "branch-alias": {
1030
+ "dev-master": "1.3.x-dev"
1031
+ }
1032
+ },
1033
+ "autoload": {
1034
+ "classmap": [
1035
+ "src/"
1036
+ ]
1037
+ },
1038
+ "notification-url": "https://packagist.org/downloads/",
1039
+ "license": [
1040
+ "BSD-3-Clause"
1041
+ ],
1042
+ "authors": [
1043
+ {
1044
+ "name": "Sebastian Bergmann",
1045
+ "email": "sebastian@phpunit.de"
1046
+ }
1047
+ ],
1048
+ "description": "Provides functionality to handle HHVM/PHP environments",
1049
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1050
+ "keywords": [
1051
+ "Xdebug",
1052
+ "environment",
1053
+ "hhvm"
1054
+ ],
1055
+ "time": "2016-08-18 05:49:44"
1056
+ },
1057
+ {
1058
+ "name": "sebastian/exporter",
1059
+ "version": "dev-master",
1060
+ "source": {
1061
+ "type": "git",
1062
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1063
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
1064
+ },
1065
+ "dist": {
1066
+ "type": "zip",
1067
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1068
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1069
+ "shasum": ""
1070
+ },
1071
+ "require": {
1072
+ "php": ">=5.3.3",
1073
+ "sebastian/recursion-context": "~1.0"
1074
+ },
1075
+ "require-dev": {
1076
+ "ext-mbstring": "*",
1077
+ "phpunit/phpunit": "~4.4"
1078
+ },
1079
+ "type": "library",
1080
+ "extra": {
1081
+ "branch-alias": {
1082
+ "dev-master": "1.3.x-dev"
1083
+ }
1084
+ },
1085
+ "autoload": {
1086
+ "classmap": [
1087
+ "src/"
1088
+ ]
1089
+ },
1090
+ "notification-url": "https://packagist.org/downloads/",
1091
+ "license": [
1092
+ "BSD-3-Clause"
1093
+ ],
1094
+ "authors": [
1095
+ {
1096
+ "name": "Jeff Welch",
1097
+ "email": "whatthejeff@gmail.com"
1098
+ },
1099
+ {
1100
+ "name": "Volker Dusch",
1101
+ "email": "github@wallbash.com"
1102
+ },
1103
+ {
1104
+ "name": "Bernhard Schussek",
1105
+ "email": "bschussek@2bepublished.at"
1106
+ },
1107
+ {
1108
+ "name": "Sebastian Bergmann",
1109
+ "email": "sebastian@phpunit.de"
1110
+ },
1111
+ {
1112
+ "name": "Adam Harvey",
1113
+ "email": "aharvey@php.net"
1114
+ }
1115
+ ],
1116
+ "description": "Provides the functionality to export PHP variables for visualization",
1117
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1118
+ "keywords": [
1119
+ "export",
1120
+ "exporter"
1121
+ ],
1122
+ "time": "2016-10-03 07:44:30"
1123
+ },
1124
+ {
1125
+ "name": "sebastian/global-state",
1126
+ "version": "1.1.1",
1127
+ "source": {
1128
+ "type": "git",
1129
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1130
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1131
+ },
1132
+ "dist": {
1133
+ "type": "zip",
1134
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1135
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1136
+ "shasum": ""
1137
+ },
1138
+ "require": {
1139
+ "php": ">=5.3.3"
1140
+ },
1141
+ "require-dev": {
1142
+ "phpunit/phpunit": "~4.2"
1143
+ },
1144
+ "suggest": {
1145
+ "ext-uopz": "*"
1146
+ },
1147
+ "type": "library",
1148
+ "extra": {
1149
+ "branch-alias": {
1150
+ "dev-master": "1.0-dev"
1151
+ }
1152
+ },
1153
+ "autoload": {
1154
+ "classmap": [
1155
+ "src/"
1156
+ ]
1157
+ },
1158
+ "notification-url": "https://packagist.org/downloads/",
1159
+ "license": [
1160
+ "BSD-3-Clause"
1161
+ ],
1162
+ "authors": [
1163
+ {
1164
+ "name": "Sebastian Bergmann",
1165
+ "email": "sebastian@phpunit.de"
1166
+ }
1167
+ ],
1168
+ "description": "Snapshotting of global state",
1169
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1170
+ "keywords": [
1171
+ "global state"
1172
+ ],
1173
+ "time": "2015-10-12 03:26:01"
1174
+ },
1175
+ {
1176
+ "name": "sebastian/recursion-context",
1177
+ "version": "dev-master",
1178
+ "source": {
1179
+ "type": "git",
1180
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1181
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1182
+ },
1183
+ "dist": {
1184
+ "type": "zip",
1185
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1186
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1187
+ "shasum": ""
1188
+ },
1189
+ "require": {
1190
+ "php": ">=5.3.3"
1191
+ },
1192
+ "require-dev": {
1193
+ "phpunit/phpunit": "~4.4"
1194
+ },
1195
+ "type": "library",
1196
+ "extra": {
1197
+ "branch-alias": {
1198
+ "dev-master": "1.0.x-dev"
1199
+ }
1200
+ },
1201
+ "autoload": {
1202
+ "classmap": [
1203
+ "src/"
1204
+ ]
1205
+ },
1206
+ "notification-url": "https://packagist.org/downloads/",
1207
+ "license": [
1208
+ "BSD-3-Clause"
1209
+ ],
1210
+ "authors": [
1211
+ {
1212
+ "name": "Jeff Welch",
1213
+ "email": "whatthejeff@gmail.com"
1214
+ },
1215
+ {
1216
+ "name": "Sebastian Bergmann",
1217
+ "email": "sebastian@phpunit.de"
1218
+ },
1219
+ {
1220
+ "name": "Adam Harvey",
1221
+ "email": "aharvey@php.net"
1222
+ }
1223
+ ],
1224
+ "description": "Provides functionality to recursively process PHP variables",
1225
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1226
+ "time": "2016-10-03 07:41:43"
1227
+ },
1228
+ {
1229
+ "name": "sebastian/version",
1230
+ "version": "1.0.6",
1231
+ "source": {
1232
+ "type": "git",
1233
+ "url": "https://github.com/sebastianbergmann/version.git",
1234
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1235
+ },
1236
+ "dist": {
1237
+ "type": "zip",
1238
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1239
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1240
+ "shasum": ""
1241
+ },
1242
+ "type": "library",
1243
+ "autoload": {
1244
+ "classmap": [
1245
+ "src/"
1246
+ ]
1247
+ },
1248
+ "notification-url": "https://packagist.org/downloads/",
1249
+ "license": [
1250
+ "BSD-3-Clause"
1251
+ ],
1252
+ "authors": [
1253
+ {
1254
+ "name": "Sebastian Bergmann",
1255
+ "email": "sebastian@phpunit.de",
1256
+ "role": "lead"
1257
+ }
1258
+ ],
1259
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1260
+ "homepage": "https://github.com/sebastianbergmann/version",
1261
+ "time": "2015-06-21 13:59:46"
1262
+ },
1263
+ {
1264
+ "name": "symfony/console",
1265
+ "version": "2.8.x-dev",
1266
+ "source": {
1267
+ "type": "git",
1268
+ "url": "https://github.com/symfony/console.git",
1269
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71"
1270
+ },
1271
+ "dist": {
1272
+ "type": "zip",
1273
+ "url": "https://api.github.com/repos/symfony/console/zipball/ddb26174398f48486ac4231dc4f4cb27c3acba71",
1274
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71",
1275
+ "shasum": ""
1276
+ },
1277
+ "require": {
1278
+ "php": ">=5.3.9",
1279
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
1280
+ "symfony/polyfill-mbstring": "~1.0"
1281
+ },
1282
+ "require-dev": {
1283
+ "psr/log": "~1.0",
1284
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
1285
+ "symfony/process": "~2.1|~3.0.0"
1286
+ },
1287
+ "suggest": {
1288
+ "psr/log": "For using the console logger",
1289
+ "symfony/event-dispatcher": "",
1290
+ "symfony/process": ""
1291
+ },
1292
+ "type": "library",
1293
+ "extra": {
1294
+ "branch-alias": {
1295
+ "dev-master": "2.8-dev"
1296
+ }
1297
+ },
1298
+ "autoload": {
1299
+ "psr-4": {
1300
+ "Symfony\\Component\\Console\\": ""
1301
+ },
1302
+ "exclude-from-classmap": [
1303
+ "/Tests/"
1304
+ ]
1305
+ },
1306
+ "notification-url": "https://packagist.org/downloads/",
1307
+ "license": [
1308
+ "MIT"
1309
+ ],
1310
+ "authors": [
1311
+ {
1312
+ "name": "Fabien Potencier",
1313
+ "email": "fabien@symfony.com"
1314
+ },
1315
+ {
1316
+ "name": "Symfony Community",
1317
+ "homepage": "https://symfony.com/contributors"
1318
+ }
1319
+ ],
1320
+ "description": "Symfony Console Component",
1321
+ "homepage": "https://symfony.com",
1322
+ "time": "2016-11-04 17:49:05"
1323
+ },
1324
+ {
1325
+ "name": "symfony/debug",
1326
+ "version": "2.8.x-dev",
1327
+ "source": {
1328
+ "type": "git",
1329
+ "url": "https://github.com/symfony/debug.git",
1330
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888"
1331
+ },
1332
+ "dist": {
1333
+ "type": "zip",
1334
+ "url": "https://api.github.com/repos/symfony/debug/zipball/d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1335
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1336
+ "shasum": ""
1337
+ },
1338
+ "require": {
1339
+ "php": ">=5.3.9",
1340
+ "psr/log": "~1.0"
1341
+ },
1342
+ "conflict": {
1343
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1344
+ },
1345
+ "require-dev": {
1346
+ "symfony/class-loader": "~2.2|~3.0.0",
1347
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
1348
+ },
1349
+ "type": "library",
1350
+ "extra": {
1351
+ "branch-alias": {
1352
+ "dev-master": "2.8-dev"
1353
+ }
1354
+ },
1355
+ "autoload": {
1356
+ "psr-4": {
1357
+ "Symfony\\Component\\Debug\\": ""
1358
+ },
1359
+ "exclude-from-classmap": [
1360
+ "/Tests/"
1361
+ ]
1362
+ },
1363
+ "notification-url": "https://packagist.org/downloads/",
1364
+ "license": [
1365
+ "MIT"
1366
+ ],
1367
+ "authors": [
1368
+ {
1369
+ "name": "Fabien Potencier",
1370
+ "email": "fabien@symfony.com"
1371
+ },
1372
+ {
1373
+ "name": "Symfony Community",
1374
+ "homepage": "https://symfony.com/contributors"
1375
+ }
1376
+ ],
1377
+ "description": "Symfony Debug Component",
1378
+ "homepage": "https://symfony.com",
1379
+ "time": "2016-11-03 07:52:58"
1380
+ },
1381
+ {
1382
+ "name": "symfony/event-dispatcher",
1383
+ "version": "2.8.x-dev",
1384
+ "source": {
1385
+ "type": "git",
1386
+ "url": "https://github.com/symfony/event-dispatcher.git",
1387
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
1388
+ },
1389
+ "dist": {
1390
+ "type": "zip",
1391
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1392
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1393
+ "shasum": ""
1394
+ },
1395
+ "require": {
1396
+ "php": ">=5.3.9"
1397
+ },
1398
+ "require-dev": {
1399
+ "psr/log": "~1.0",
1400
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
1401
+ "symfony/dependency-injection": "~2.6|~3.0.0",
1402
+ "symfony/expression-language": "~2.6|~3.0.0",
1403
+ "symfony/stopwatch": "~2.3|~3.0.0"
1404
+ },
1405
+ "suggest": {
1406
+ "symfony/dependency-injection": "",
1407
+ "symfony/http-kernel": ""
1408
+ },
1409
+ "type": "library",
1410
+ "extra": {
1411
+ "branch-alias": {
1412
+ "dev-master": "2.8-dev"
1413
+ }
1414
+ },
1415
+ "autoload": {
1416
+ "psr-4": {
1417
+ "Symfony\\Component\\EventDispatcher\\": ""
1418
+ },
1419
+ "exclude-from-classmap": [
1420
+ "/Tests/"
1421
+ ]
1422
+ },
1423
+ "notification-url": "https://packagist.org/downloads/",
1424
+ "license": [
1425
+ "MIT"
1426
+ ],
1427
+ "authors": [
1428
+ {
1429
+ "name": "Fabien Potencier",
1430
+ "email": "fabien@symfony.com"
1431
+ },
1432
+ {
1433
+ "name": "Symfony Community",
1434
+ "homepage": "https://symfony.com/contributors"
1435
+ }
1436
+ ],
1437
+ "description": "Symfony EventDispatcher Component",
1438
+ "homepage": "https://symfony.com",
1439
+ "time": "2016-10-13 01:43:15"
1440
+ },
1441
+ {
1442
+ "name": "symfony/filesystem",
1443
+ "version": "2.8.x-dev",
1444
+ "source": {
1445
+ "type": "git",
1446
+ "url": "https://github.com/symfony/filesystem.git",
1447
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898"
1448
+ },
1449
+ "dist": {
1450
+ "type": "zip",
1451
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898",
1452
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898",
1453
+ "shasum": ""
1454
+ },
1455
+ "require": {
1456
+ "php": ">=5.3.9"
1457
+ },
1458
+ "type": "library",
1459
+ "extra": {
1460
+ "branch-alias": {
1461
+ "dev-master": "2.8-dev"
1462
+ }
1463
+ },
1464
+ "autoload": {
1465
+ "psr-4": {
1466
+ "Symfony\\Component\\Filesystem\\": ""
1467
+ },
1468
+ "exclude-from-classmap": [
1469
+ "/Tests/"
1470
+ ]
1471
+ },
1472
+ "notification-url": "https://packagist.org/downloads/",
1473
+ "license": [
1474
+ "MIT"
1475
+ ],
1476
+ "authors": [
1477
+ {
1478
+ "name": "Fabien Potencier",
1479
+ "email": "fabien@symfony.com"
1480
+ },
1481
+ {
1482
+ "name": "Symfony Community",
1483
+ "homepage": "https://symfony.com/contributors"
1484
+ }
1485
+ ],
1486
+ "description": "Symfony Filesystem Component",
1487
+ "homepage": "https://symfony.com",
1488
+ "time": "2016-10-18 04:28:30"
1489
+ },
1490
+ {
1491
+ "name": "symfony/finder",
1492
+ "version": "2.8.x-dev",
1493
+ "source": {
1494
+ "type": "git",
1495
+ "url": "https://github.com/symfony/finder.git",
1496
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd"
1497
+ },
1498
+ "dist": {
1499
+ "type": "zip",
1500
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0023b024363dfc0cd21262e556f25a291fe8d7fd",
1501
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd",
1502
+ "shasum": ""
1503
+ },
1504
+ "require": {
1505
+ "php": ">=5.3.9"
1506
+ },
1507
+ "type": "library",
1508
+ "extra": {
1509
+ "branch-alias": {
1510
+ "dev-master": "2.8-dev"
1511
+ }
1512
+ },
1513
+ "autoload": {
1514
+ "psr-4": {
1515
+ "Symfony\\Component\\Finder\\": ""
1516
+ },
1517
+ "exclude-from-classmap": [
1518
+ "/Tests/"
1519
+ ]
1520
+ },
1521
+ "notification-url": "https://packagist.org/downloads/",
1522
+ "license": [
1523
+ "MIT"
1524
+ ],
1525
+ "authors": [
1526
+ {
1527
+ "name": "Fabien Potencier",
1528
+ "email": "fabien@symfony.com"
1529
+ },
1530
+ {
1531
+ "name": "Symfony Community",
1532
+ "homepage": "https://symfony.com/contributors"
1533
+ }
1534
+ ],
1535
+ "description": "Symfony Finder Component",
1536
+ "homepage": "https://symfony.com",
1537
+ "time": "2016-11-03 07:52:58"
1538
+ },
1539
+ {
1540
+ "name": "symfony/polyfill-mbstring",
1541
+ "version": "dev-master",
1542
+ "source": {
1543
+ "type": "git",
1544
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1545
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c"
1546
+ },
1547
+ "dist": {
1548
+ "type": "zip",
1549
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1550
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1551
+ "shasum": ""
1552
+ },
1553
+ "require": {
1554
+ "php": ">=5.3.3"
1555
+ },
1556
+ "suggest": {
1557
+ "ext-mbstring": "For best performance"
1558
+ },
1559
+ "type": "library",
1560
+ "extra": {
1561
+ "branch-alias": {
1562
+ "dev-master": "1.2-dev"
1563
+ }
1564
+ },
1565
+ "autoload": {
1566
+ "psr-4": {
1567
+ "Symfony\\Polyfill\\Mbstring\\": ""
1568
+ },
1569
+ "files": [
1570
+ "bootstrap.php"
1571
+ ]
1572
+ },
1573
+ "notification-url": "https://packagist.org/downloads/",
1574
+ "license": [
1575
+ "MIT"
1576
+ ],
1577
+ "authors": [
1578
+ {
1579
+ "name": "Nicolas Grekas",
1580
+ "email": "p@tchwork.com"
1581
+ },
1582
+ {
1583
+ "name": "Symfony Community",
1584
+ "homepage": "https://symfony.com/contributors"
1585
+ }
1586
+ ],
1587
+ "description": "Symfony polyfill for the Mbstring extension",
1588
+ "homepage": "https://symfony.com",
1589
+ "keywords": [
1590
+ "compatibility",
1591
+ "mbstring",
1592
+ "polyfill",
1593
+ "portable",
1594
+ "shim"
1595
+ ],
1596
+ "time": "2016-08-30 17:06:17"
1597
+ },
1598
+ {
1599
+ "name": "symfony/process",
1600
+ "version": "2.8.x-dev",
1601
+ "source": {
1602
+ "type": "git",
1603
+ "url": "https://github.com/symfony/process.git",
1604
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
1605
+ },
1606
+ "dist": {
1607
+ "type": "zip",
1608
+ "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1609
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1610
+ "shasum": ""
1611
+ },
1612
+ "require": {
1613
+ "php": ">=5.3.9"
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\\Process\\": ""
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 Process Component",
1644
+ "homepage": "https://symfony.com",
1645
+ "time": "2016-09-29 14:03:54"
1646
+ },
1647
+ {
1648
+ "name": "symfony/stopwatch",
1649
+ "version": "2.8.x-dev",
1650
+ "source": {
1651
+ "type": "git",
1652
+ "url": "https://github.com/symfony/stopwatch.git",
1653
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca"
1654
+ },
1655
+ "dist": {
1656
+ "type": "zip",
1657
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
1658
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca",
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\\Stopwatch\\": ""
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 Stopwatch Component",
1693
+ "homepage": "https://symfony.com",
1694
+ "time": "2016-06-29 05:29:29"
1695
+ },
1696
+ {
1697
+ "name": "symfony/yaml",
1698
+ "version": "2.8.x-dev",
1699
+ "source": {
1700
+ "type": "git",
1701
+ "url": "https://github.com/symfony/yaml.git",
1702
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb"
1703
+ },
1704
+ "dist": {
1705
+ "type": "zip",
1706
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/58666e4ac3a2d378798f020308b35a75ffbeaafb",
1707
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb",
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\\Yaml\\": ""
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 Yaml Component",
1742
+ "homepage": "https://symfony.com",
1743
+ "time": "2016-11-03 07:52:58"
1744
+ }
1745
+ ],
1746
+ "aliases": [],
1747
+ "minimum-stability": "dev",
1748
+ "stability-flags": {
1749
+ "dhii/php-cs-fixer-config": 20
1750
+ },
1751
+ "prefer-stable": false,
1752
+ "prefer-lowest": false,
1753
+ "platform": [],
1754
+ "platform-dev": []
1755
+ }
vendor/dhii/collections-abstract/nbproject/project.properties ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ file.reference.collections-abstract-vendor=vendor
13
+ file.reference.test-functional=test/functional
14
+ include.path=\
15
+ ${php.global.include.path}:\
16
+ ${file.reference.collections-abstract-vendor}
17
+ php.version=PHP_53
18
+ source.encoding=UTF-8
19
+ src.dir=src
20
+ tags.asp=false
21
+ tags.short=false
22
+ test.src.dir=${file.reference.test-functional}
23
+ testing.providers=PhpUnit
24
+ web.root=.
vendor/dhii/collections-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 - collections-abstract</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/collections-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/collections-abstract/src/AbstractCallbackCollection.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Common functionality for callback collections.
7
+ *
8
+ * Ready to be extended and instantiated, with minimal or no modifications.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ abstract class AbstractCallbackCollection extends AbstractCallbackCollectionBase implements CallbackIterableInterface
13
+ {
14
+ /**
15
+ * {@inheritdoc}
16
+ *
17
+ * @since 0.1.0
18
+ */
19
+ public function each($callback)
20
+ {
21
+ return $this->_each($callback, $this);
22
+ }
23
+ }
vendor/dhii/collections-abstract/src/AbstractCallbackCollectionBase.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use Dhii\Stats;
6
+
7
+ /**
8
+ * Common functionality for callback collections.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ abstract class AbstractCallbackCollectionBase extends Stats\AbstractAggregatableCollection
13
+ {
14
+ /**
15
+ * Retrieve a callback instance that will apply a callback to each item in the list.
16
+ *
17
+ * See {@see CallbackIterableInterface::each()} for details about the callback.
18
+ *
19
+ * @since 0.1.0
20
+ *
21
+ * @param callable $callback The callback to apply to each item in the list. Default: itself.
22
+ * @param array|\Traversable $items The list of items to iterate over.
23
+ *
24
+ * @return CallbackIteratorInterface The callback iterator that will iterate over the list.
25
+ */
26
+ protected function _each($callback, $items = null)
27
+ {
28
+ if (is_null($items)) {
29
+ $items = $this;
30
+ }
31
+
32
+ return $this->_createCallbackIterator($callback, $items);
33
+ }
34
+
35
+ /**
36
+ * Create a new instance of callback iterator for the specified callback and item list.
37
+ *
38
+ * @since 0.1.0
39
+ *
40
+ * @param callable $callback The callback for the iterator to apply to each item.
41
+ * @param array|\Traversable $items The list of items for the iterator to iterate over.
42
+ *
43
+ * @return CallbackIterator The new callback iterator.
44
+ */
45
+ protected function _createCallbackIterator($callback, $items)
46
+ {
47
+ return new CallbackIterator($items, $callback);
48
+ }
49
+ }
vendor/dhii/collections-abstract/src/AbstractCallbackIterator.php ADDED
@@ -0,0 +1,176 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use UnexpectedValueException;
6
+
7
+ /**
8
+ * Common functionality for callback iterators.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ abstract class AbstractCallbackIterator extends AbstractIterableCollection implements CallbackIteratorInterface
13
+ {
14
+ protected $callback;
15
+ protected $isHalted = false;
16
+
17
+ /**
18
+ * Sets the callback that will be applied to each element of this collection.
19
+ *
20
+ * @since 0.1.0
21
+ *
22
+ * @param callable $callback The callback for this iterator to apply.
23
+ *
24
+ * @return AbstractCallbackIterator This instance.
25
+ */
26
+ protected function _setCallback($callback)
27
+ {
28
+ $this->callback = $callback;
29
+
30
+ return $this;
31
+ }
32
+
33
+ /**
34
+ * {@inheritdoc}
35
+ *
36
+ * @since 0.1.0
37
+ */
38
+ public function getCallback()
39
+ {
40
+ return $this->callback;
41
+ }
42
+
43
+ /**
44
+ * {@inheritdoc}
45
+ *
46
+ * @since 0.1.0
47
+ */
48
+ public function current()
49
+ {
50
+ $item = parent::current();
51
+
52
+ $isContinue = true;
53
+ $item = $this->_applyCallback($this->key(), $item, $isContinue);
54
+
55
+ if (!$isContinue) {
56
+ $this->_halt();
57
+ }
58
+
59
+ return $item;
60
+ }
61
+
62
+ /**
63
+ * Applies the callback to an item, and returns the result.
64
+ *
65
+ * See {@see CallbackIterableInterface::each()} for details about the callback.
66
+ *
67
+ * @since 0.1.0
68
+ *
69
+ * @param string|int $key The key of the current item.
70
+ * @param mixed $item The item to apply the callback to.
71
+ *
72
+ * @return mixed The return value of the callback.
73
+ */
74
+ public function _applyCallback($key, $item, &$isContinue)
75
+ {
76
+ $callback = $this->getCallback();
77
+ $this->_validateCallback($callback);
78
+
79
+ return call_user_func_array($callback, array($key, $item, &$isContinue));
80
+ }
81
+
82
+ /**
83
+ * Determines if a value is a valid callback.
84
+ *
85
+ * @since 0.1.0
86
+ *
87
+ * @param mixed $callback The value to check.
88
+ *
89
+ * @throws \Exception
90
+ */
91
+ protected function _validateCallback($callback)
92
+ {
93
+ if (!is_callable($callback)) {
94
+ throw new UnexpectedValueException(sprintf('Could not apply callback: Callback must be callable'));
95
+ }
96
+ }
97
+
98
+ /**
99
+ * Determines if a value is a valid callback.
100
+ *
101
+ * @since 0.1.0
102
+ *
103
+ * @param mixed $callback The value to check.
104
+ *
105
+ * @return bool True if the callback is valid; false otherwise.
106
+ */
107
+ protected function _isValidCallback($callback)
108
+ {
109
+ try {
110
+ $this->_validateCallback($callback);
111
+ } catch (Exception $ex) {
112
+ return false;
113
+ }
114
+
115
+ return true;
116
+ }
117
+
118
+ /**
119
+ * Stop iteration of the current loop.
120
+ *
121
+ * Because the callback executes outside of the scope of the loop, it is not
122
+ * possible to halt iteration immediately. However, calling this with `true`
123
+ * will cause the next call to `valid()` to return `false`, which signals
124
+ * that the loop should break.
125
+ *
126
+ * @since 0.1.0
127
+ *
128
+ * @param bool $isHalted Whether or not iteration should stop.
129
+ *
130
+ * @return bool True if iteration was halted before the new value took effect;
131
+ * false otherwise.
132
+ */
133
+ protected function _halt($isHalted = true)
134
+ {
135
+ $wasHalted = (bool) $this->isHalted;
136
+ $this->isHalted = (bool) $isHalted;
137
+
138
+ return $wasHalted;
139
+ }
140
+
141
+ /**
142
+ * Check whether or not iteration is stopped.
143
+ *
144
+ * @see _halt()
145
+ * @since 0.1.0
146
+ *
147
+ * @return bool True of iteration is currently halted; false otherwise.
148
+ */
149
+ protected function _isHalted()
150
+ {
151
+ return $this->isHalted;
152
+ }
153
+
154
+ /**
155
+ * {@inheritdoc}
156
+ *
157
+ * @since 0.1.0
158
+ */
159
+ public function rewind()
160
+ {
161
+ $this->_halt(false);
162
+ parent::rewind();
163
+ }
164
+
165
+ /**
166
+ * {@inheritdoc}
167
+ *
168
+ * @since 0.1.0
169
+ */
170
+ public function valid()
171
+ {
172
+ return $this->_isHalted()
173
+ ? false
174
+ : parent::valid();
175
+ }
176
+ }
vendor/dhii/collections-abstract/src/AbstractGenericAccessibleCollection.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Common functionality for generic collections that can have its items retrieved and checked.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ abstract class AbstractGenericAccessibleCollection extends AbstractGenericCollection implements AccessibleCollectionInterface
11
+ {
12
+ /**
13
+ * {@inheritdoc}
14
+ *
15
+ * @since 0.1.0
16
+ */
17
+ public function getItem($key)
18
+ {
19
+ return $this->_getItem($key, null);
20
+ }
21
+
22
+ /**
23
+ * {@inheritdoc}
24
+ *
25
+ * @since 0.1.0
26
+ */
27
+ public function hasItem($item)
28
+ {
29
+ return $this->_hasItem($item);
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ *
35
+ * @since 0.1.0
36
+ */
37
+ public function hasItemKey($key)
38
+ {
39
+ return $this->_hasItemKey($key);
40
+ }
41
+ }
vendor/dhii/collections-abstract/src/AbstractGenericCollection.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * A default implementation of a general purpose collection.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ abstract class AbstractGenericCollection extends AbstractSearchableCollection
11
+ {
12
+ /**
13
+ * @since 0.1.0
14
+ *
15
+ * @param mixed[]|\Traversable $items The items to populate this collection with.
16
+ */
17
+ public function __construct($items = null)
18
+ {
19
+ if (!is_null($items)) {
20
+ $this->_addItems($items);
21
+ }
22
+ }
23
+
24
+ /**
25
+ * {@inheritdoc}
26
+ *
27
+ * @since 0.1.0
28
+ */
29
+ public function _validateItem($item)
30
+ {
31
+ return true;
32
+ }
33
+ }
vendor/dhii/collections-abstract/src/AbstractGenericMutableCollection.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Common functionality for collections that can have its item set changed.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ abstract class AbstractGenericMutableCollection extends AbstractGenericCollection implements MutableCollectionInterface
11
+ {
12
+ /**
13
+ * {@inheritdoc}
14
+ *
15
+ * @since 0.1.0
16
+ */
17
+ public function addItem($item)
18
+ {
19
+ $result = $this->_addItem($item);
20
+ $this->_clearItemCache();
21
+ $this->_resetStats();
22
+
23
+ return $result;
24
+ }
25
+
26
+ /**
27
+ * {@inheritdoc}
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function addItems($items)
32
+ {
33
+ $result = $this->_addItems($items);
34
+ $this->_clearItemCache();
35
+ $this->_resetStats();
36
+
37
+ return $result;
38
+ }
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ *
43
+ * @since 0.1.0
44
+ */
45
+ public function removeItem($item)
46
+ {
47
+ $result = $this->_removeItem($item);
48
+ $this->_clearItemCache();
49
+ $this->_resetStats();
50
+
51
+ return $result;
52
+ }
53
+
54
+ /**
55
+ * {@inheritdoc}
56
+ *
57
+ * @since 0.1.0
58
+ */
59
+ public function removeItemByKey($key)
60
+ {
61
+ $result = $this->_removeItem($item);
62
+
63
+ return $result;
64
+ }
65
+ }
vendor/dhii/collections-abstract/src/AbstractSearchableCollection.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use InvalidArgumentException;
6
+
7
+ /**
8
+ * Common functionality for collection searching.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ abstract class AbstractSearchableCollection extends AbstractCallbackCollection
13
+ {
14
+ /**
15
+ * Search the items of a collection according to arbitrary criteria.
16
+ *
17
+ * @since 0.1.0
18
+ *
19
+ * @param callable $eval See {@see SearchableCollectionInterface::search()} for details on the callback.
20
+ * @param object[]|\Traversable
21
+ *
22
+ * @throws InvalidArgumentException If the evaluator is not callable.
23
+ *
24
+ * @return object[]|\Traversable
25
+ */
26
+ protected function _search($eval, $items = null)
27
+ {
28
+ if (is_null($items)) {
29
+ $items = $this;
30
+ }
31
+ $results = array();
32
+ foreach ($this->_each($eval, $items) as $_key => $_item) {
33
+ if ($this->_isValidSearchResult($_item)) {
34
+ $results[] = $_item;
35
+ }
36
+ }
37
+
38
+ return $this->_createSearchResultsIterator($results);
39
+ }
40
+
41
+ /**
42
+ * Creates an iterator of set of items that are are result of a search.
43
+ *
44
+ * @since 0.1.0
45
+ *
46
+ * @param mixed[] The array of items.
47
+ *
48
+ * @return AbstractSearchableCollection The new collection that contains search results.
49
+ */
50
+ protected function _createSearchResultsIterator($results)
51
+ {
52
+ $class = get_class($this);
53
+ $instance = new $class();
54
+ /* @var $instance AbstractSearchableCollection */
55
+ $instance->_setItems($results);
56
+
57
+ return $instance;
58
+ }
59
+
60
+ /**
61
+ * Determines whether an item is a valid search item.
62
+ *
63
+ * @since 0.1.0
64
+ *
65
+ * @param mixed $item The item to validate.
66
+ *
67
+ * @return bool True if item is a valid search result item; false otherwise.
68
+ */
69
+ protected function _isValidSearchResult($item)
70
+ {
71
+ return $this->_isValidItem($item);
72
+ }
73
+ }
vendor/dhii/collections-abstract/src/AppendIterator.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * A standards-compliant implementation of {@see \AppendIterator} that does
7
+ * not promise to be writable.
8
+ *
9
+ * @since 0.1.0
10
+ */
11
+ class AppendIterator extends \AppendIterator implements SequenceIteratorIteratorInterface
12
+ {
13
+ }
vendor/dhii/collections-abstract/src/CallbackIterator.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * A default implementation of a callback iterator.
7
+ *
8
+ * Can have values of any type, and of different types.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ class CallbackIterator extends AbstractCallbackIterator
13
+ {
14
+ /**
15
+ * @since 0.1.0
16
+ *
17
+ * @param mixed[]|\Traversable $items A list of items to iterate over.
18
+ * @param callable $callback
19
+ */
20
+ public function __construct($items, $callback)
21
+ {
22
+ $this->_setItems($items);
23
+ $this->_setCallback($callback);
24
+ }
25
+
26
+ /**
27
+ * Allows any items through.
28
+ *
29
+ * @since 0.1.0
30
+ *
31
+ * @return bool Always true.
32
+ */
33
+ protected function _validateItem($item)
34
+ {
35
+ // Nothing needs to happen in order to indicate that an item is valid.
36
+ }
37
+ }
vendor/dhii/collections-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/collections-abstract/test/functional/AbstractCallbackCollectionBaseTest.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\FuncTest;
4
+
5
+ /**
6
+ * Tests {@see \Dhii\Collection\AbstractCallbackCollection}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractCallbackCollectionBaseTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return \Dhii\Collection\AbstractCallbackCollection The new instance of the test subject.
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $instance = $this->mock('Dhii\\Collection\\AbstractCallbackCollectionBase')
22
+ ->_validateItem()
23
+ ->new();
24
+
25
+ $reflection = $this->reflect($instance);
26
+ $reflection->_construct();
27
+
28
+ return $instance;
29
+ }
30
+
31
+ /**
32
+ * Tests whether a valid instance of the test subejct can be created.
33
+ *
34
+ * @since 0.1.0
35
+ */
36
+ public function testCanBeCreated()
37
+ {
38
+ $subject = $this->createInstance();
39
+
40
+ $this->assertInstanceOf('Dhii\\Collection\\AbstractCallbackCollectionBase', $subject, 'Subject is not of the required type');
41
+ }
42
+
43
+ /**
44
+ * Tests whether the each() method runs as required.
45
+ *
46
+ * @since 0.1.0
47
+ */
48
+ public function testEach()
49
+ {
50
+ $me = $this;
51
+ $subject = $this->createInstance();
52
+ $reflection = $this->reflect($subject);
53
+
54
+ $reflection->_addItem('apple');
55
+ $reflection->_addItem('banana');
56
+ $reflection->_addItem('orange');
57
+ $items = $reflection->_getItems();
58
+
59
+ $iterations = 0;
60
+ $iterator = $reflection->_each(
61
+ /* In the `use` statement, the `$iterations` variable is byref to bypass early binding:
62
+ * http://stackoverflow.com/q/8403908#comment37564320_8403958
63
+ */
64
+ function($key, $item, &$isContinue) use ($me, &$iterations, $items) {
65
+ $iterations++;
66
+ if ($iterations === 2) {
67
+ // This tests whether breaking out of the loop works from the callback
68
+ $isContinue = false;
69
+ }
70
+
71
+ $me->assertContains($item, $items, 'The current item is not in the collection');
72
+ }
73
+ );
74
+
75
+ foreach ($iterator as $_item) {
76
+ // Callback only runs on each iteration.
77
+ }
78
+
79
+ $this->assertEquals(2, $iterations, 'The callback has not been invoked the required number of times');
80
+ }
81
+ }
vendor/dhii/collections-abstract/test/functional/AbstractCallbackIteratorTest.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\FuncTest;
4
+
5
+ /**
6
+ * Testing {@see \Dhii\Collection\AbstractCallbackIterator}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractCallbackIteratorTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return \Dhii\Collection\AbstractCallbackIterator The new instance of the test subject.
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->mock('Dhii\\Collection\\AbstractCallbackIterator')
22
+ ->_validateItem()
23
+ ->new();
24
+
25
+ return $mock;
26
+ }
27
+
28
+ /**
29
+ * Tests whether a valid instance of the test subject can be created.
30
+ *
31
+ * @since 0.1.0
32
+ */
33
+ public function testCanBeCreated()
34
+ {
35
+ $subject = $this->createInstance();
36
+ $reflection = $this->reflect($subject);
37
+
38
+ $this->assertInstanceOf('Dhii\\Collection\\AbstractCallbackIterator', $subject, 'The subject is not of a required type');
39
+ }
40
+ }
vendor/dhii/collections-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/collections-interface/.php_cs ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
4
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
5
+ $fixers = $config->getFixers();
6
+
7
+ $toRemove = array('short_array_syntax');
8
+ foreach ($toRemove as $_fixer) {
9
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
10
+ continue;
11
+ }
12
+
13
+ unset($fixers[$removeIndex]);
14
+ }
15
+
16
+ $toAdd = array('long_array_syntax');
17
+ foreach ($toAdd as $_fixer) {
18
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
19
+ continue;
20
+ }
21
+
22
+ $fixers[] = $_fixer;
23
+ }
24
+
25
+ $config->fixers($fixers);
26
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
27
+ return $config;
vendor/dhii/collections-interface/.travis.yml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 install
13
+
14
+ script:
15
+ - phpunit
16
+
17
+ after_script:
18
+ - vendor/bin/test-reporter --coverage-report="test/coverage/clover.xml"
19
+
20
+ addons:
21
+ code_climate:
22
+ repo_token: 0042feaf6b9021bdff3717889ab22b493d2bf4051404f12d273fd8d9d1fee500
vendor/dhii/collections-interface/CHANGELOG.md ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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.0 - 2016-11-09
8
+ The initial release
9
+
10
+ ## 0.1.1 - 2016-11-09
11
+ Immediately released to fix absense of release data.
12
+
13
+ ### Added
14
+ - Change log;
15
+ - Next version placeholders replaced with version number.
16
+
17
+ ## 0.1.2 - 2016-11-16
18
+ Adding some new functionality. This can be depended on, but will be split into
19
+ more granular interfaces in the future.
20
+
21
+ ### Added
22
+ - `SetInterface` interface, which exposes all functionality of a standard interface.
23
+
24
+ ## Fixed
25
+ - Next version placeholders in tests releasesd in version 0.1.0.
vendor/dhii/collections-interface/composer.json ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/collections-interface",
3
+ "description": "Interfaces for collections",
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
+ },
16
+ "require-dev": {
17
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
18
+ "phpunit/phpunit": "^4.8",
19
+ "codeclimate/php-test-reporter": "dev-master"
20
+ },
21
+ "autoload": {
22
+ "psr-4": {
23
+ "Dhii\\Collection\\": "src/"
24
+ }
25
+ },
26
+ "autoload-dev": {
27
+ "psr-4": {
28
+ "Dhii\\Collection\\UnitTest\\": "test/unit",
29
+ "Dhii\\Collection\\FuncTest\\": "test/functional"
30
+ }
31
+ }
32
+ }
vendor/dhii/collections-interface/composer.lock ADDED
@@ -0,0 +1,1941 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "394923ba9b30e037e8d6df6dda41cefd",
8
+ "content-hash": "1e9adb9153dc287a6a738831bc8ec6b1",
9
+ "packages": [],
10
+ "packages-dev": [
11
+ {
12
+ "name": "codeclimate/php-test-reporter",
13
+ "version": "dev-master",
14
+ "source": {
15
+ "type": "git",
16
+ "url": "https://github.com/codeclimate/php-test-reporter.git",
17
+ "reference": "0186c8eb03c677b64b9d23dc0cb5c9475553c7c5"
18
+ },
19
+ "dist": {
20
+ "type": "zip",
21
+ "url": "https://api.github.com/repos/codeclimate/php-test-reporter/zipball/0186c8eb03c677b64b9d23dc0cb5c9475553c7c5",
22
+ "reference": "0186c8eb03c677b64b9d23dc0cb5c9475553c7c5",
23
+ "shasum": ""
24
+ },
25
+ "require": {
26
+ "ext-curl": "*",
27
+ "padraic/phar-updater": "^1.0",
28
+ "php": ">=5.3",
29
+ "psr/log": "^1.0",
30
+ "satooshi/php-coveralls": "^1.0",
31
+ "symfony/console": "^2.0|^3.0"
32
+ },
33
+ "require-dev": {
34
+ "ext-xdebug": "*",
35
+ "phpunit/phpunit": "3.7.*@stable",
36
+ "tm/tooly-composer-script": "^1.0"
37
+ },
38
+ "bin": [
39
+ "composer/bin/test-reporter"
40
+ ],
41
+ "type": "library",
42
+ "extra": {
43
+ "branch-alias": {
44
+ "dev-master": "0.3.x-dev"
45
+ },
46
+ "tools": {
47
+ "box": {
48
+ "url": "https://github.com/box-project/box2/releases/download/2.7.2/box-2.7.2.phar",
49
+ "only-dev": true
50
+ }
51
+ }
52
+ },
53
+ "autoload": {
54
+ "psr-4": {
55
+ "CodeClimate\\PhpTestReporter\\": "src/"
56
+ }
57
+ },
58
+ "notification-url": "https://packagist.org/downloads/",
59
+ "license": [
60
+ "MIT"
61
+ ],
62
+ "authors": [
63
+ {
64
+ "name": "Code Climate",
65
+ "email": "hello@codeclimate.com",
66
+ "homepage": "https://codeclimate.com"
67
+ }
68
+ ],
69
+ "description": "PHP client for reporting test coverage to Code Climate",
70
+ "homepage": "https://github.com/codeclimate/php-test-reporter",
71
+ "keywords": [
72
+ "codeclimate",
73
+ "coverage"
74
+ ],
75
+ "time": "2016-09-22 16:57:58"
76
+ },
77
+ {
78
+ "name": "dhii/php-cs-fixer-config",
79
+ "version": "dev-php-5.3",
80
+ "source": {
81
+ "type": "git",
82
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
83
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
84
+ },
85
+ "dist": {
86
+ "type": "zip",
87
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
88
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
89
+ "shasum": ""
90
+ },
91
+ "require": {
92
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
93
+ "php": "^5.3 | ^7.0"
94
+ },
95
+ "require-dev": {
96
+ "phpunit/phpunit": "^4.8"
97
+ },
98
+ "type": "library",
99
+ "autoload": {
100
+ "psr-4": {
101
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
102
+ }
103
+ },
104
+ "notification-url": "https://packagist.org/downloads/",
105
+ "license": [
106
+ "MIT"
107
+ ],
108
+ "authors": [
109
+ {
110
+ "name": "Dhii Team",
111
+ "email": "development@dhii.co"
112
+ }
113
+ ],
114
+ "description": "A default PHP CS Fixer config implementation",
115
+ "time": "2016-09-03 14:45:03"
116
+ },
117
+ {
118
+ "name": "doctrine/instantiator",
119
+ "version": "dev-master",
120
+ "source": {
121
+ "type": "git",
122
+ "url": "https://github.com/doctrine/instantiator.git",
123
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a"
124
+ },
125
+ "dist": {
126
+ "type": "zip",
127
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a",
128
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a",
129
+ "shasum": ""
130
+ },
131
+ "require": {
132
+ "php": ">=5.3,<8.0-DEV"
133
+ },
134
+ "require-dev": {
135
+ "athletic/athletic": "~0.1.8",
136
+ "ext-pdo": "*",
137
+ "ext-phar": "*",
138
+ "phpunit/phpunit": "~4.0",
139
+ "squizlabs/php_codesniffer": "~2.0"
140
+ },
141
+ "type": "library",
142
+ "extra": {
143
+ "branch-alias": {
144
+ "dev-master": "1.0.x-dev"
145
+ }
146
+ },
147
+ "autoload": {
148
+ "psr-4": {
149
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
150
+ }
151
+ },
152
+ "notification-url": "https://packagist.org/downloads/",
153
+ "license": [
154
+ "MIT"
155
+ ],
156
+ "authors": [
157
+ {
158
+ "name": "Marco Pivetta",
159
+ "email": "ocramius@gmail.com",
160
+ "homepage": "http://ocramius.github.com/"
161
+ }
162
+ ],
163
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
164
+ "homepage": "https://github.com/doctrine/instantiator",
165
+ "keywords": [
166
+ "constructor",
167
+ "instantiate"
168
+ ],
169
+ "time": "2016-03-31 10:24:22"
170
+ },
171
+ {
172
+ "name": "friendsofphp/php-cs-fixer",
173
+ "version": "1.11.x-dev",
174
+ "source": {
175
+ "type": "git",
176
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
177
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
178
+ },
179
+ "dist": {
180
+ "type": "zip",
181
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
182
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
183
+ "shasum": ""
184
+ },
185
+ "require": {
186
+ "ext-tokenizer": "*",
187
+ "php": ">=5.3.6",
188
+ "sebastian/diff": "~1.1",
189
+ "symfony/console": "~2.3|~3.0",
190
+ "symfony/event-dispatcher": "~2.1|~3.0",
191
+ "symfony/filesystem": "~2.1|~3.0",
192
+ "symfony/finder": "~2.1|~3.0",
193
+ "symfony/process": "~2.3|~3.0",
194
+ "symfony/stopwatch": "~2.5|~3.0"
195
+ },
196
+ "conflict": {
197
+ "hhvm": "<3.9"
198
+ },
199
+ "require-dev": {
200
+ "phpunit/phpunit": "^4.5|^5",
201
+ "satooshi/php-coveralls": "^0.7.1"
202
+ },
203
+ "bin": [
204
+ "php-cs-fixer"
205
+ ],
206
+ "type": "application",
207
+ "autoload": {
208
+ "psr-4": {
209
+ "Symfony\\CS\\": "Symfony/CS/"
210
+ }
211
+ },
212
+ "notification-url": "https://packagist.org/downloads/",
213
+ "license": [
214
+ "MIT"
215
+ ],
216
+ "authors": [
217
+ {
218
+ "name": "Dariusz Rumiński",
219
+ "email": "dariusz.ruminski@gmail.com"
220
+ },
221
+ {
222
+ "name": "Fabien Potencier",
223
+ "email": "fabien@symfony.com"
224
+ }
225
+ ],
226
+ "description": "A tool to automatically fix PHP code style",
227
+ "time": "2016-08-16 23:31:05"
228
+ },
229
+ {
230
+ "name": "guzzle/guzzle",
231
+ "version": "dev-master",
232
+ "source": {
233
+ "type": "git",
234
+ "url": "https://github.com/guzzle/guzzle3.git",
235
+ "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02"
236
+ },
237
+ "dist": {
238
+ "type": "zip",
239
+ "url": "https://api.github.com/repos/guzzle/guzzle3/zipball/b3f5050cb6270c7a728a0b74ac2de50a262b3e02",
240
+ "reference": "b3f5050cb6270c7a728a0b74ac2de50a262b3e02",
241
+ "shasum": ""
242
+ },
243
+ "require": {
244
+ "ext-curl": "*",
245
+ "php": ">=5.3.3",
246
+ "symfony/event-dispatcher": "~2.1"
247
+ },
248
+ "replace": {
249
+ "guzzle/batch": "self.version",
250
+ "guzzle/cache": "self.version",
251
+ "guzzle/common": "self.version",
252
+ "guzzle/http": "self.version",
253
+ "guzzle/inflection": "self.version",
254
+ "guzzle/iterator": "self.version",
255
+ "guzzle/log": "self.version",
256
+ "guzzle/parser": "self.version",
257
+ "guzzle/plugin": "self.version",
258
+ "guzzle/plugin-async": "self.version",
259
+ "guzzle/plugin-backoff": "self.version",
260
+ "guzzle/plugin-cache": "self.version",
261
+ "guzzle/plugin-cookie": "self.version",
262
+ "guzzle/plugin-curlauth": "self.version",
263
+ "guzzle/plugin-error-response": "self.version",
264
+ "guzzle/plugin-history": "self.version",
265
+ "guzzle/plugin-log": "self.version",
266
+ "guzzle/plugin-md5": "self.version",
267
+ "guzzle/plugin-mock": "self.version",
268
+ "guzzle/plugin-oauth": "self.version",
269
+ "guzzle/service": "self.version",
270
+ "guzzle/stream": "self.version"
271
+ },
272
+ "require-dev": {
273
+ "doctrine/cache": "~1.3",
274
+ "monolog/monolog": "~1.0",
275
+ "phpunit/phpunit": "3.7.*",
276
+ "psr/log": "~1.0",
277
+ "symfony/class-loader": "~2.1",
278
+ "zendframework/zend-cache": "2.*,<2.3",
279
+ "zendframework/zend-log": "2.*,<2.3"
280
+ },
281
+ "suggest": {
282
+ "guzzlehttp/guzzle": "Guzzle 5 has moved to a new package name. The package you have installed, Guzzle 3, is deprecated."
283
+ },
284
+ "type": "library",
285
+ "extra": {
286
+ "branch-alias": {
287
+ "dev-master": "3.9-dev"
288
+ }
289
+ },
290
+ "autoload": {
291
+ "psr-0": {
292
+ "Guzzle": "src/",
293
+ "Guzzle\\Tests": "tests/"
294
+ }
295
+ },
296
+ "notification-url": "https://packagist.org/downloads/",
297
+ "license": [
298
+ "MIT"
299
+ ],
300
+ "authors": [
301
+ {
302
+ "name": "Michael Dowling",
303
+ "email": "mtdowling@gmail.com",
304
+ "homepage": "https://github.com/mtdowling"
305
+ },
306
+ {
307
+ "name": "Guzzle Community",
308
+ "homepage": "https://github.com/guzzle/guzzle/contributors"
309
+ }
310
+ ],
311
+ "description": "PHP HTTP client. This library is deprecated in favor of https://packagist.org/packages/guzzlehttp/guzzle",
312
+ "homepage": "http://guzzlephp.org/",
313
+ "keywords": [
314
+ "client",
315
+ "curl",
316
+ "framework",
317
+ "http",
318
+ "http client",
319
+ "rest",
320
+ "web service"
321
+ ],
322
+ "abandoned": "guzzlehttp/guzzle",
323
+ "time": "2015-04-29 17:06:53"
324
+ },
325
+ {
326
+ "name": "padraic/humbug_get_contents",
327
+ "version": "dev-master",
328
+ "source": {
329
+ "type": "git",
330
+ "url": "https://github.com/padraic/file_get_contents.git",
331
+ "reference": "1bfe28c32ad08093917a527114150d0a155c319b"
332
+ },
333
+ "dist": {
334
+ "type": "zip",
335
+ "url": "https://api.github.com/repos/padraic/file_get_contents/zipball/1bfe28c32ad08093917a527114150d0a155c319b",
336
+ "reference": "1bfe28c32ad08093917a527114150d0a155c319b",
337
+ "shasum": ""
338
+ },
339
+ "require": {
340
+ "php": ">=5.3"
341
+ },
342
+ "require-dev": {
343
+ "phpunit/phpunit": "~4.0"
344
+ },
345
+ "type": "library",
346
+ "extra": {
347
+ "branch-alias": {
348
+ "dev-master": "1.0-dev"
349
+ }
350
+ },
351
+ "autoload": {
352
+ "psr-4": {
353
+ "Humbug\\": "src/Humbug/"
354
+ },
355
+ "files": [
356
+ "src/function.php"
357
+ ]
358
+ },
359
+ "notification-url": "https://packagist.org/downloads/",
360
+ "license": [
361
+ "BSD-3-Clause"
362
+ ],
363
+ "authors": [
364
+ {
365
+ "name": "Pádraic Brady",
366
+ "email": "padraic.brady@gmail.com",
367
+ "homepage": "http://blog.astrumfutura.com"
368
+ }
369
+ ],
370
+ "description": "Secure wrapper for accessing HTTPS resources with file_get_contents for PHP 5.3+",
371
+ "homepage": "https://github.com/padraic/file_get_contents",
372
+ "keywords": [
373
+ "download",
374
+ "file_get_contents",
375
+ "http",
376
+ "https",
377
+ "ssl",
378
+ "tls"
379
+ ],
380
+ "time": "2015-04-24 19:31:03"
381
+ },
382
+ {
383
+ "name": "padraic/phar-updater",
384
+ "version": "dev-master",
385
+ "source": {
386
+ "type": "git",
387
+ "url": "https://github.com/padraic/phar-updater.git",
388
+ "reference": "c17eeb3887dc4269d1b4837dc875d39e9f8149a8"
389
+ },
390
+ "dist": {
391
+ "type": "zip",
392
+ "url": "https://api.github.com/repos/padraic/phar-updater/zipball/c17eeb3887dc4269d1b4837dc875d39e9f8149a8",
393
+ "reference": "c17eeb3887dc4269d1b4837dc875d39e9f8149a8",
394
+ "shasum": ""
395
+ },
396
+ "require": {
397
+ "padraic/humbug_get_contents": "^1.0",
398
+ "php": ">=5.3.3"
399
+ },
400
+ "require-dev": {
401
+ "phpunit/phpunit": "~4.0"
402
+ },
403
+ "type": "library",
404
+ "extra": {
405
+ "branch-alias": {
406
+ "dev-master": "1.0-dev"
407
+ }
408
+ },
409
+ "autoload": {
410
+ "psr-4": {
411
+ "Humbug\\SelfUpdate\\": "src/"
412
+ }
413
+ },
414
+ "notification-url": "https://packagist.org/downloads/",
415
+ "license": [
416
+ "BSD-3-Clause"
417
+ ],
418
+ "authors": [
419
+ {
420
+ "name": "Pádraic Brady",
421
+ "email": "padraic.brady@gmail.com",
422
+ "homepage": "http://blog.astrumfutura.com"
423
+ }
424
+ ],
425
+ "description": "A thing to make PHAR self-updating easy and secure.",
426
+ "keywords": [
427
+ "humbug",
428
+ "phar",
429
+ "self-update",
430
+ "update"
431
+ ],
432
+ "time": "2016-01-05 23:08:01"
433
+ },
434
+ {
435
+ "name": "phpdocumentor/reflection-docblock",
436
+ "version": "2.0.4",
437
+ "source": {
438
+ "type": "git",
439
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
440
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
441
+ },
442
+ "dist": {
443
+ "type": "zip",
444
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
445
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
446
+ "shasum": ""
447
+ },
448
+ "require": {
449
+ "php": ">=5.3.3"
450
+ },
451
+ "require-dev": {
452
+ "phpunit/phpunit": "~4.0"
453
+ },
454
+ "suggest": {
455
+ "dflydev/markdown": "~1.0",
456
+ "erusev/parsedown": "~1.0"
457
+ },
458
+ "type": "library",
459
+ "extra": {
460
+ "branch-alias": {
461
+ "dev-master": "2.0.x-dev"
462
+ }
463
+ },
464
+ "autoload": {
465
+ "psr-0": {
466
+ "phpDocumentor": [
467
+ "src/"
468
+ ]
469
+ }
470
+ },
471
+ "notification-url": "https://packagist.org/downloads/",
472
+ "license": [
473
+ "MIT"
474
+ ],
475
+ "authors": [
476
+ {
477
+ "name": "Mike van Riel",
478
+ "email": "mike.vanriel@naenius.com"
479
+ }
480
+ ],
481
+ "time": "2015-02-03 12:10:50"
482
+ },
483
+ {
484
+ "name": "phpspec/prophecy",
485
+ "version": "dev-master",
486
+ "source": {
487
+ "type": "git",
488
+ "url": "https://github.com/phpspec/prophecy.git",
489
+ "reference": "d3be8294e4729abcf8e6e207f25cdcb299cd1c88"
490
+ },
491
+ "dist": {
492
+ "type": "zip",
493
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/d3be8294e4729abcf8e6e207f25cdcb299cd1c88",
494
+ "reference": "d3be8294e4729abcf8e6e207f25cdcb299cd1c88",
495
+ "shasum": ""
496
+ },
497
+ "require": {
498
+ "doctrine/instantiator": "^1.0.2",
499
+ "php": "^5.3|^7.0",
500
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
501
+ "sebastian/comparator": "^1.1",
502
+ "sebastian/recursion-context": "^1.0"
503
+ },
504
+ "require-dev": {
505
+ "phpspec/phpspec": "^2.0"
506
+ },
507
+ "type": "library",
508
+ "extra": {
509
+ "branch-alias": {
510
+ "dev-master": "1.6.x-dev"
511
+ }
512
+ },
513
+ "autoload": {
514
+ "psr-0": {
515
+ "Prophecy\\": "src/"
516
+ }
517
+ },
518
+ "notification-url": "https://packagist.org/downloads/",
519
+ "license": [
520
+ "MIT"
521
+ ],
522
+ "authors": [
523
+ {
524
+ "name": "Konstantin Kudryashov",
525
+ "email": "ever.zet@gmail.com",
526
+ "homepage": "http://everzet.com"
527
+ },
528
+ {
529
+ "name": "Marcello Duarte",
530
+ "email": "marcello.duarte@gmail.com"
531
+ }
532
+ ],
533
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
534
+ "homepage": "https://github.com/phpspec/prophecy",
535
+ "keywords": [
536
+ "Double",
537
+ "Dummy",
538
+ "fake",
539
+ "mock",
540
+ "spy",
541
+ "stub"
542
+ ],
543
+ "time": "2016-09-21 19:41:08"
544
+ },
545
+ {
546
+ "name": "phpunit/php-code-coverage",
547
+ "version": "2.2.x-dev",
548
+ "source": {
549
+ "type": "git",
550
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
551
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
552
+ },
553
+ "dist": {
554
+ "type": "zip",
555
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
556
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
557
+ "shasum": ""
558
+ },
559
+ "require": {
560
+ "php": ">=5.3.3",
561
+ "phpunit/php-file-iterator": "~1.3",
562
+ "phpunit/php-text-template": "~1.2",
563
+ "phpunit/php-token-stream": "~1.3",
564
+ "sebastian/environment": "^1.3.2",
565
+ "sebastian/version": "~1.0"
566
+ },
567
+ "require-dev": {
568
+ "ext-xdebug": ">=2.1.4",
569
+ "phpunit/phpunit": "~4"
570
+ },
571
+ "suggest": {
572
+ "ext-dom": "*",
573
+ "ext-xdebug": ">=2.2.1",
574
+ "ext-xmlwriter": "*"
575
+ },
576
+ "type": "library",
577
+ "extra": {
578
+ "branch-alias": {
579
+ "dev-master": "2.2.x-dev"
580
+ }
581
+ },
582
+ "autoload": {
583
+ "classmap": [
584
+ "src/"
585
+ ]
586
+ },
587
+ "notification-url": "https://packagist.org/downloads/",
588
+ "license": [
589
+ "BSD-3-Clause"
590
+ ],
591
+ "authors": [
592
+ {
593
+ "name": "Sebastian Bergmann",
594
+ "email": "sb@sebastian-bergmann.de",
595
+ "role": "lead"
596
+ }
597
+ ],
598
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
599
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
600
+ "keywords": [
601
+ "coverage",
602
+ "testing",
603
+ "xunit"
604
+ ],
605
+ "time": "2015-10-06 15:47:00"
606
+ },
607
+ {
608
+ "name": "phpunit/php-file-iterator",
609
+ "version": "dev-master",
610
+ "source": {
611
+ "type": "git",
612
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
613
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0"
614
+ },
615
+ "dist": {
616
+ "type": "zip",
617
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
618
+ "reference": "6150bf2c35d3fc379e50c7602b75caceaa39dbf0",
619
+ "shasum": ""
620
+ },
621
+ "require": {
622
+ "php": ">=5.3.3"
623
+ },
624
+ "type": "library",
625
+ "extra": {
626
+ "branch-alias": {
627
+ "dev-master": "1.4.x-dev"
628
+ }
629
+ },
630
+ "autoload": {
631
+ "classmap": [
632
+ "src/"
633
+ ]
634
+ },
635
+ "notification-url": "https://packagist.org/downloads/",
636
+ "license": [
637
+ "BSD-3-Clause"
638
+ ],
639
+ "authors": [
640
+ {
641
+ "name": "Sebastian Bergmann",
642
+ "email": "sb@sebastian-bergmann.de",
643
+ "role": "lead"
644
+ }
645
+ ],
646
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
647
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
648
+ "keywords": [
649
+ "filesystem",
650
+ "iterator"
651
+ ],
652
+ "time": "2015-06-21 13:08:43"
653
+ },
654
+ {
655
+ "name": "phpunit/php-text-template",
656
+ "version": "1.2.1",
657
+ "source": {
658
+ "type": "git",
659
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
660
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
661
+ },
662
+ "dist": {
663
+ "type": "zip",
664
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
665
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
666
+ "shasum": ""
667
+ },
668
+ "require": {
669
+ "php": ">=5.3.3"
670
+ },
671
+ "type": "library",
672
+ "autoload": {
673
+ "classmap": [
674
+ "src/"
675
+ ]
676
+ },
677
+ "notification-url": "https://packagist.org/downloads/",
678
+ "license": [
679
+ "BSD-3-Clause"
680
+ ],
681
+ "authors": [
682
+ {
683
+ "name": "Sebastian Bergmann",
684
+ "email": "sebastian@phpunit.de",
685
+ "role": "lead"
686
+ }
687
+ ],
688
+ "description": "Simple template engine.",
689
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
690
+ "keywords": [
691
+ "template"
692
+ ],
693
+ "time": "2015-06-21 13:50:34"
694
+ },
695
+ {
696
+ "name": "phpunit/php-timer",
697
+ "version": "1.0.8",
698
+ "source": {
699
+ "type": "git",
700
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
701
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
702
+ },
703
+ "dist": {
704
+ "type": "zip",
705
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
706
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
707
+ "shasum": ""
708
+ },
709
+ "require": {
710
+ "php": ">=5.3.3"
711
+ },
712
+ "require-dev": {
713
+ "phpunit/phpunit": "~4|~5"
714
+ },
715
+ "type": "library",
716
+ "autoload": {
717
+ "classmap": [
718
+ "src/"
719
+ ]
720
+ },
721
+ "notification-url": "https://packagist.org/downloads/",
722
+ "license": [
723
+ "BSD-3-Clause"
724
+ ],
725
+ "authors": [
726
+ {
727
+ "name": "Sebastian Bergmann",
728
+ "email": "sb@sebastian-bergmann.de",
729
+ "role": "lead"
730
+ }
731
+ ],
732
+ "description": "Utility class for timing",
733
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
734
+ "keywords": [
735
+ "timer"
736
+ ],
737
+ "time": "2016-05-12 18:03:57"
738
+ },
739
+ {
740
+ "name": "phpunit/php-token-stream",
741
+ "version": "dev-master",
742
+ "source": {
743
+ "type": "git",
744
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
745
+ "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644"
746
+ },
747
+ "dist": {
748
+ "type": "zip",
749
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/cab6c6fefee93d7b7c3a01292a0fe0884ea66644",
750
+ "reference": "cab6c6fefee93d7b7c3a01292a0fe0884ea66644",
751
+ "shasum": ""
752
+ },
753
+ "require": {
754
+ "ext-tokenizer": "*",
755
+ "php": ">=5.3.3"
756
+ },
757
+ "require-dev": {
758
+ "phpunit/phpunit": "~4.2"
759
+ },
760
+ "type": "library",
761
+ "extra": {
762
+ "branch-alias": {
763
+ "dev-master": "1.4-dev"
764
+ }
765
+ },
766
+ "autoload": {
767
+ "classmap": [
768
+ "src/"
769
+ ]
770
+ },
771
+ "notification-url": "https://packagist.org/downloads/",
772
+ "license": [
773
+ "BSD-3-Clause"
774
+ ],
775
+ "authors": [
776
+ {
777
+ "name": "Sebastian Bergmann",
778
+ "email": "sebastian@phpunit.de"
779
+ }
780
+ ],
781
+ "description": "Wrapper around PHP's tokenizer extension.",
782
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
783
+ "keywords": [
784
+ "tokenizer"
785
+ ],
786
+ "time": "2015-09-23 14:46:55"
787
+ },
788
+ {
789
+ "name": "phpunit/phpunit",
790
+ "version": "4.8.x-dev",
791
+ "source": {
792
+ "type": "git",
793
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
794
+ "reference": "d99e588e3cbab28db86f8da22e22c72d8cc38543"
795
+ },
796
+ "dist": {
797
+ "type": "zip",
798
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d99e588e3cbab28db86f8da22e22c72d8cc38543",
799
+ "reference": "d99e588e3cbab28db86f8da22e22c72d8cc38543",
800
+ "shasum": ""
801
+ },
802
+ "require": {
803
+ "ext-dom": "*",
804
+ "ext-json": "*",
805
+ "ext-pcre": "*",
806
+ "ext-reflection": "*",
807
+ "ext-spl": "*",
808
+ "php": ">=5.3.3",
809
+ "phpspec/prophecy": "^1.3.1",
810
+ "phpunit/php-code-coverage": "~2.1",
811
+ "phpunit/php-file-iterator": "~1.4",
812
+ "phpunit/php-text-template": "~1.2",
813
+ "phpunit/php-timer": "^1.0.6",
814
+ "phpunit/phpunit-mock-objects": "~2.3",
815
+ "sebastian/comparator": "~1.1",
816
+ "sebastian/diff": "~1.2",
817
+ "sebastian/environment": "~1.3",
818
+ "sebastian/exporter": "~1.2",
819
+ "sebastian/global-state": "~1.0",
820
+ "sebastian/version": "~1.0",
821
+ "symfony/yaml": "~2.1|~3.0"
822
+ },
823
+ "suggest": {
824
+ "phpunit/php-invoker": "~1.1"
825
+ },
826
+ "bin": [
827
+ "phpunit"
828
+ ],
829
+ "type": "library",
830
+ "extra": {
831
+ "branch-alias": {
832
+ "dev-master": "4.8.x-dev"
833
+ }
834
+ },
835
+ "autoload": {
836
+ "classmap": [
837
+ "src/"
838
+ ]
839
+ },
840
+ "notification-url": "https://packagist.org/downloads/",
841
+ "license": [
842
+ "BSD-3-Clause"
843
+ ],
844
+ "authors": [
845
+ {
846
+ "name": "Sebastian Bergmann",
847
+ "email": "sebastian@phpunit.de",
848
+ "role": "lead"
849
+ }
850
+ ],
851
+ "description": "The PHP Unit Testing framework.",
852
+ "homepage": "https://phpunit.de/",
853
+ "keywords": [
854
+ "phpunit",
855
+ "testing",
856
+ "xunit"
857
+ ],
858
+ "time": "2016-09-22 17:37:27"
859
+ },
860
+ {
861
+ "name": "phpunit/phpunit-mock-objects",
862
+ "version": "2.3.x-dev",
863
+ "source": {
864
+ "type": "git",
865
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
866
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
867
+ },
868
+ "dist": {
869
+ "type": "zip",
870
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
871
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
872
+ "shasum": ""
873
+ },
874
+ "require": {
875
+ "doctrine/instantiator": "^1.0.2",
876
+ "php": ">=5.3.3",
877
+ "phpunit/php-text-template": "~1.2",
878
+ "sebastian/exporter": "~1.2"
879
+ },
880
+ "require-dev": {
881
+ "phpunit/phpunit": "~4.4"
882
+ },
883
+ "suggest": {
884
+ "ext-soap": "*"
885
+ },
886
+ "type": "library",
887
+ "extra": {
888
+ "branch-alias": {
889
+ "dev-master": "2.3.x-dev"
890
+ }
891
+ },
892
+ "autoload": {
893
+ "classmap": [
894
+ "src/"
895
+ ]
896
+ },
897
+ "notification-url": "https://packagist.org/downloads/",
898
+ "license": [
899
+ "BSD-3-Clause"
900
+ ],
901
+ "authors": [
902
+ {
903
+ "name": "Sebastian Bergmann",
904
+ "email": "sb@sebastian-bergmann.de",
905
+ "role": "lead"
906
+ }
907
+ ],
908
+ "description": "Mock Object library for PHPUnit",
909
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
910
+ "keywords": [
911
+ "mock",
912
+ "xunit"
913
+ ],
914
+ "time": "2015-10-02 06:51:40"
915
+ },
916
+ {
917
+ "name": "psr/log",
918
+ "version": "dev-master",
919
+ "source": {
920
+ "type": "git",
921
+ "url": "https://github.com/php-fig/log.git",
922
+ "reference": "5277094ed527a1c4477177d102fe4c53551953e0"
923
+ },
924
+ "dist": {
925
+ "type": "zip",
926
+ "url": "https://api.github.com/repos/php-fig/log/zipball/5277094ed527a1c4477177d102fe4c53551953e0",
927
+ "reference": "5277094ed527a1c4477177d102fe4c53551953e0",
928
+ "shasum": ""
929
+ },
930
+ "require": {
931
+ "php": ">=5.3.0"
932
+ },
933
+ "type": "library",
934
+ "extra": {
935
+ "branch-alias": {
936
+ "dev-master": "1.0.x-dev"
937
+ }
938
+ },
939
+ "autoload": {
940
+ "psr-4": {
941
+ "Psr\\Log\\": "Psr/Log/"
942
+ }
943
+ },
944
+ "notification-url": "https://packagist.org/downloads/",
945
+ "license": [
946
+ "MIT"
947
+ ],
948
+ "authors": [
949
+ {
950
+ "name": "PHP-FIG",
951
+ "homepage": "http://www.php-fig.org/"
952
+ }
953
+ ],
954
+ "description": "Common interface for logging libraries",
955
+ "homepage": "https://github.com/php-fig/log",
956
+ "keywords": [
957
+ "log",
958
+ "psr",
959
+ "psr-3"
960
+ ],
961
+ "time": "2016-09-19 16:02:08"
962
+ },
963
+ {
964
+ "name": "satooshi/php-coveralls",
965
+ "version": "1.0.x-dev",
966
+ "source": {
967
+ "type": "git",
968
+ "url": "https://github.com/satooshi/php-coveralls.git",
969
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c"
970
+ },
971
+ "dist": {
972
+ "type": "zip",
973
+ "url": "https://api.github.com/repos/satooshi/php-coveralls/zipball/da51d304fe8622bf9a6da39a8446e7afd432115c",
974
+ "reference": "da51d304fe8622bf9a6da39a8446e7afd432115c",
975
+ "shasum": ""
976
+ },
977
+ "require": {
978
+ "ext-json": "*",
979
+ "ext-simplexml": "*",
980
+ "guzzle/guzzle": "^2.8|^3.0",
981
+ "php": ">=5.3.3",
982
+ "psr/log": "^1.0",
983
+ "symfony/config": "^2.1|^3.0",
984
+ "symfony/console": "^2.1|^3.0",
985
+ "symfony/stopwatch": "^2.0|^3.0",
986
+ "symfony/yaml": "^2.0|^3.0"
987
+ },
988
+ "suggest": {
989
+ "symfony/http-kernel": "Allows Symfony integration"
990
+ },
991
+ "bin": [
992
+ "bin/coveralls"
993
+ ],
994
+ "type": "library",
995
+ "autoload": {
996
+ "psr-4": {
997
+ "Satooshi\\": "src/Satooshi/"
998
+ }
999
+ },
1000
+ "notification-url": "https://packagist.org/downloads/",
1001
+ "license": [
1002
+ "MIT"
1003
+ ],
1004
+ "authors": [
1005
+ {
1006
+ "name": "Kitamura Satoshi",
1007
+ "email": "with.no.parachute@gmail.com",
1008
+ "homepage": "https://www.facebook.com/satooshi.jp"
1009
+ }
1010
+ ],
1011
+ "description": "PHP client library for Coveralls API",
1012
+ "homepage": "https://github.com/satooshi/php-coveralls",
1013
+ "keywords": [
1014
+ "ci",
1015
+ "coverage",
1016
+ "github",
1017
+ "test"
1018
+ ],
1019
+ "time": "2016-01-20 17:35:46"
1020
+ },
1021
+ {
1022
+ "name": "sebastian/comparator",
1023
+ "version": "dev-master",
1024
+ "source": {
1025
+ "type": "git",
1026
+ "url": "https://github.com/sebastianbergmann/comparator.git",
1027
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22"
1028
+ },
1029
+ "dist": {
1030
+ "type": "zip",
1031
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/937efb279bd37a375bcadf584dec0726f84dbf22",
1032
+ "reference": "937efb279bd37a375bcadf584dec0726f84dbf22",
1033
+ "shasum": ""
1034
+ },
1035
+ "require": {
1036
+ "php": ">=5.3.3",
1037
+ "sebastian/diff": "~1.2",
1038
+ "sebastian/exporter": "~1.2"
1039
+ },
1040
+ "require-dev": {
1041
+ "phpunit/phpunit": "~4.4"
1042
+ },
1043
+ "type": "library",
1044
+ "extra": {
1045
+ "branch-alias": {
1046
+ "dev-master": "1.2.x-dev"
1047
+ }
1048
+ },
1049
+ "autoload": {
1050
+ "classmap": [
1051
+ "src/"
1052
+ ]
1053
+ },
1054
+ "notification-url": "https://packagist.org/downloads/",
1055
+ "license": [
1056
+ "BSD-3-Clause"
1057
+ ],
1058
+ "authors": [
1059
+ {
1060
+ "name": "Jeff Welch",
1061
+ "email": "whatthejeff@gmail.com"
1062
+ },
1063
+ {
1064
+ "name": "Volker Dusch",
1065
+ "email": "github@wallbash.com"
1066
+ },
1067
+ {
1068
+ "name": "Bernhard Schussek",
1069
+ "email": "bschussek@2bepublished.at"
1070
+ },
1071
+ {
1072
+ "name": "Sebastian Bergmann",
1073
+ "email": "sebastian@phpunit.de"
1074
+ }
1075
+ ],
1076
+ "description": "Provides the functionality to compare PHP values for equality",
1077
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
1078
+ "keywords": [
1079
+ "comparator",
1080
+ "compare",
1081
+ "equality"
1082
+ ],
1083
+ "time": "2015-07-26 15:48:44"
1084
+ },
1085
+ {
1086
+ "name": "sebastian/diff",
1087
+ "version": "dev-master",
1088
+ "source": {
1089
+ "type": "git",
1090
+ "url": "https://github.com/sebastianbergmann/diff.git",
1091
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e"
1092
+ },
1093
+ "dist": {
1094
+ "type": "zip",
1095
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/13edfd8706462032c2f52b4b862974dd46b71c9e",
1096
+ "reference": "13edfd8706462032c2f52b4b862974dd46b71c9e",
1097
+ "shasum": ""
1098
+ },
1099
+ "require": {
1100
+ "php": ">=5.3.3"
1101
+ },
1102
+ "require-dev": {
1103
+ "phpunit/phpunit": "~4.8"
1104
+ },
1105
+ "type": "library",
1106
+ "extra": {
1107
+ "branch-alias": {
1108
+ "dev-master": "1.4-dev"
1109
+ }
1110
+ },
1111
+ "autoload": {
1112
+ "classmap": [
1113
+ "src/"
1114
+ ]
1115
+ },
1116
+ "notification-url": "https://packagist.org/downloads/",
1117
+ "license": [
1118
+ "BSD-3-Clause"
1119
+ ],
1120
+ "authors": [
1121
+ {
1122
+ "name": "Kore Nordmann",
1123
+ "email": "mail@kore-nordmann.de"
1124
+ },
1125
+ {
1126
+ "name": "Sebastian Bergmann",
1127
+ "email": "sebastian@phpunit.de"
1128
+ }
1129
+ ],
1130
+ "description": "Diff implementation",
1131
+ "homepage": "https://github.com/sebastianbergmann/diff",
1132
+ "keywords": [
1133
+ "diff"
1134
+ ],
1135
+ "time": "2015-12-08 07:14:41"
1136
+ },
1137
+ {
1138
+ "name": "sebastian/environment",
1139
+ "version": "1.3.x-dev",
1140
+ "source": {
1141
+ "type": "git",
1142
+ "url": "https://github.com/sebastianbergmann/environment.git",
1143
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
1144
+ },
1145
+ "dist": {
1146
+ "type": "zip",
1147
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1148
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
1149
+ "shasum": ""
1150
+ },
1151
+ "require": {
1152
+ "php": "^5.3.3 || ^7.0"
1153
+ },
1154
+ "require-dev": {
1155
+ "phpunit/phpunit": "^4.8 || ^5.0"
1156
+ },
1157
+ "type": "library",
1158
+ "extra": {
1159
+ "branch-alias": {
1160
+ "dev-master": "1.3.x-dev"
1161
+ }
1162
+ },
1163
+ "autoload": {
1164
+ "classmap": [
1165
+ "src/"
1166
+ ]
1167
+ },
1168
+ "notification-url": "https://packagist.org/downloads/",
1169
+ "license": [
1170
+ "BSD-3-Clause"
1171
+ ],
1172
+ "authors": [
1173
+ {
1174
+ "name": "Sebastian Bergmann",
1175
+ "email": "sebastian@phpunit.de"
1176
+ }
1177
+ ],
1178
+ "description": "Provides functionality to handle HHVM/PHP environments",
1179
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1180
+ "keywords": [
1181
+ "Xdebug",
1182
+ "environment",
1183
+ "hhvm"
1184
+ ],
1185
+ "time": "2016-08-18 05:49:44"
1186
+ },
1187
+ {
1188
+ "name": "sebastian/exporter",
1189
+ "version": "dev-master",
1190
+ "source": {
1191
+ "type": "git",
1192
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1193
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4"
1194
+ },
1195
+ "dist": {
1196
+ "type": "zip",
1197
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/42c4c2eec485ee3e159ec9884f95b431287edde4",
1198
+ "reference": "42c4c2eec485ee3e159ec9884f95b431287edde4",
1199
+ "shasum": ""
1200
+ },
1201
+ "require": {
1202
+ "php": ">=5.3.3",
1203
+ "sebastian/recursion-context": "~1.0"
1204
+ },
1205
+ "require-dev": {
1206
+ "ext-mbstring": "*",
1207
+ "phpunit/phpunit": "~4.4"
1208
+ },
1209
+ "type": "library",
1210
+ "extra": {
1211
+ "branch-alias": {
1212
+ "dev-master": "1.3.x-dev"
1213
+ }
1214
+ },
1215
+ "autoload": {
1216
+ "classmap": [
1217
+ "src/"
1218
+ ]
1219
+ },
1220
+ "notification-url": "https://packagist.org/downloads/",
1221
+ "license": [
1222
+ "BSD-3-Clause"
1223
+ ],
1224
+ "authors": [
1225
+ {
1226
+ "name": "Jeff Welch",
1227
+ "email": "whatthejeff@gmail.com"
1228
+ },
1229
+ {
1230
+ "name": "Volker Dusch",
1231
+ "email": "github@wallbash.com"
1232
+ },
1233
+ {
1234
+ "name": "Bernhard Schussek",
1235
+ "email": "bschussek@2bepublished.at"
1236
+ },
1237
+ {
1238
+ "name": "Sebastian Bergmann",
1239
+ "email": "sebastian@phpunit.de"
1240
+ },
1241
+ {
1242
+ "name": "Adam Harvey",
1243
+ "email": "aharvey@php.net"
1244
+ }
1245
+ ],
1246
+ "description": "Provides the functionality to export PHP variables for visualization",
1247
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1248
+ "keywords": [
1249
+ "export",
1250
+ "exporter"
1251
+ ],
1252
+ "time": "2016-06-17 09:04:28"
1253
+ },
1254
+ {
1255
+ "name": "sebastian/global-state",
1256
+ "version": "1.1.1",
1257
+ "source": {
1258
+ "type": "git",
1259
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1260
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1261
+ },
1262
+ "dist": {
1263
+ "type": "zip",
1264
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1265
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1266
+ "shasum": ""
1267
+ },
1268
+ "require": {
1269
+ "php": ">=5.3.3"
1270
+ },
1271
+ "require-dev": {
1272
+ "phpunit/phpunit": "~4.2"
1273
+ },
1274
+ "suggest": {
1275
+ "ext-uopz": "*"
1276
+ },
1277
+ "type": "library",
1278
+ "extra": {
1279
+ "branch-alias": {
1280
+ "dev-master": "1.0-dev"
1281
+ }
1282
+ },
1283
+ "autoload": {
1284
+ "classmap": [
1285
+ "src/"
1286
+ ]
1287
+ },
1288
+ "notification-url": "https://packagist.org/downloads/",
1289
+ "license": [
1290
+ "BSD-3-Clause"
1291
+ ],
1292
+ "authors": [
1293
+ {
1294
+ "name": "Sebastian Bergmann",
1295
+ "email": "sebastian@phpunit.de"
1296
+ }
1297
+ ],
1298
+ "description": "Snapshotting of global state",
1299
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1300
+ "keywords": [
1301
+ "global state"
1302
+ ],
1303
+ "time": "2015-10-12 03:26:01"
1304
+ },
1305
+ {
1306
+ "name": "sebastian/recursion-context",
1307
+ "version": "dev-master",
1308
+ "source": {
1309
+ "type": "git",
1310
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1311
+ "reference": "7ff5b1b3dcc55b8ab8ae61ef99d4730940856ee7"
1312
+ },
1313
+ "dist": {
1314
+ "type": "zip",
1315
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/7ff5b1b3dcc55b8ab8ae61ef99d4730940856ee7",
1316
+ "reference": "7ff5b1b3dcc55b8ab8ae61ef99d4730940856ee7",
1317
+ "shasum": ""
1318
+ },
1319
+ "require": {
1320
+ "php": ">=5.3.3"
1321
+ },
1322
+ "require-dev": {
1323
+ "phpunit/phpunit": "~4.4"
1324
+ },
1325
+ "type": "library",
1326
+ "extra": {
1327
+ "branch-alias": {
1328
+ "dev-master": "1.0.x-dev"
1329
+ }
1330
+ },
1331
+ "autoload": {
1332
+ "classmap": [
1333
+ "src/"
1334
+ ]
1335
+ },
1336
+ "notification-url": "https://packagist.org/downloads/",
1337
+ "license": [
1338
+ "BSD-3-Clause"
1339
+ ],
1340
+ "authors": [
1341
+ {
1342
+ "name": "Jeff Welch",
1343
+ "email": "whatthejeff@gmail.com"
1344
+ },
1345
+ {
1346
+ "name": "Sebastian Bergmann",
1347
+ "email": "sebastian@phpunit.de"
1348
+ },
1349
+ {
1350
+ "name": "Adam Harvey",
1351
+ "email": "aharvey@php.net"
1352
+ }
1353
+ ],
1354
+ "description": "Provides functionality to recursively process PHP variables",
1355
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1356
+ "time": "2016-01-28 05:39:29"
1357
+ },
1358
+ {
1359
+ "name": "sebastian/version",
1360
+ "version": "1.0.6",
1361
+ "source": {
1362
+ "type": "git",
1363
+ "url": "https://github.com/sebastianbergmann/version.git",
1364
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1365
+ },
1366
+ "dist": {
1367
+ "type": "zip",
1368
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1369
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1370
+ "shasum": ""
1371
+ },
1372
+ "type": "library",
1373
+ "autoload": {
1374
+ "classmap": [
1375
+ "src/"
1376
+ ]
1377
+ },
1378
+ "notification-url": "https://packagist.org/downloads/",
1379
+ "license": [
1380
+ "BSD-3-Clause"
1381
+ ],
1382
+ "authors": [
1383
+ {
1384
+ "name": "Sebastian Bergmann",
1385
+ "email": "sebastian@phpunit.de",
1386
+ "role": "lead"
1387
+ }
1388
+ ],
1389
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1390
+ "homepage": "https://github.com/sebastianbergmann/version",
1391
+ "time": "2015-06-21 13:59:46"
1392
+ },
1393
+ {
1394
+ "name": "symfony/config",
1395
+ "version": "2.8.x-dev",
1396
+ "source": {
1397
+ "type": "git",
1398
+ "url": "https://github.com/symfony/config.git",
1399
+ "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde"
1400
+ },
1401
+ "dist": {
1402
+ "type": "zip",
1403
+ "url": "https://api.github.com/repos/symfony/config/zipball/f8b1922bbda9d2ac86aecd649399040bce849fde",
1404
+ "reference": "f8b1922bbda9d2ac86aecd649399040bce849fde",
1405
+ "shasum": ""
1406
+ },
1407
+ "require": {
1408
+ "php": ">=5.3.9",
1409
+ "symfony/filesystem": "~2.3|~3.0.0"
1410
+ },
1411
+ "suggest": {
1412
+ "symfony/yaml": "To use the yaml reference dumper"
1413
+ },
1414
+ "type": "library",
1415
+ "extra": {
1416
+ "branch-alias": {
1417
+ "dev-master": "2.8-dev"
1418
+ }
1419
+ },
1420
+ "autoload": {
1421
+ "psr-4": {
1422
+ "Symfony\\Component\\Config\\": ""
1423
+ },
1424
+ "exclude-from-classmap": [
1425
+ "/Tests/"
1426
+ ]
1427
+ },
1428
+ "notification-url": "https://packagist.org/downloads/",
1429
+ "license": [
1430
+ "MIT"
1431
+ ],
1432
+ "authors": [
1433
+ {
1434
+ "name": "Fabien Potencier",
1435
+ "email": "fabien@symfony.com"
1436
+ },
1437
+ {
1438
+ "name": "Symfony Community",
1439
+ "homepage": "https://symfony.com/contributors"
1440
+ }
1441
+ ],
1442
+ "description": "Symfony Config Component",
1443
+ "homepage": "https://symfony.com",
1444
+ "time": "2016-09-14 20:31:12"
1445
+ },
1446
+ {
1447
+ "name": "symfony/console",
1448
+ "version": "2.8.x-dev",
1449
+ "source": {
1450
+ "type": "git",
1451
+ "url": "https://github.com/symfony/console.git",
1452
+ "reference": "b5fe20d60be1d9876f31228fcfff742b794806ad"
1453
+ },
1454
+ "dist": {
1455
+ "type": "zip",
1456
+ "url": "https://api.github.com/repos/symfony/console/zipball/b5fe20d60be1d9876f31228fcfff742b794806ad",
1457
+ "reference": "b5fe20d60be1d9876f31228fcfff742b794806ad",
1458
+ "shasum": ""
1459
+ },
1460
+ "require": {
1461
+ "php": ">=5.3.9",
1462
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
1463
+ "symfony/polyfill-mbstring": "~1.0"
1464
+ },
1465
+ "require-dev": {
1466
+ "psr/log": "~1.0",
1467
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
1468
+ "symfony/process": "~2.1|~3.0.0"
1469
+ },
1470
+ "suggest": {
1471
+ "psr/log": "For using the console logger",
1472
+ "symfony/event-dispatcher": "",
1473
+ "symfony/process": ""
1474
+ },
1475
+ "type": "library",
1476
+ "extra": {
1477
+ "branch-alias": {
1478
+ "dev-master": "2.8-dev"
1479
+ }
1480
+ },
1481
+ "autoload": {
1482
+ "psr-4": {
1483
+ "Symfony\\Component\\Console\\": ""
1484
+ },
1485
+ "exclude-from-classmap": [
1486
+ "/Tests/"
1487
+ ]
1488
+ },
1489
+ "notification-url": "https://packagist.org/downloads/",
1490
+ "license": [
1491
+ "MIT"
1492
+ ],
1493
+ "authors": [
1494
+ {
1495
+ "name": "Fabien Potencier",
1496
+ "email": "fabien@symfony.com"
1497
+ },
1498
+ {
1499
+ "name": "Symfony Community",
1500
+ "homepage": "https://symfony.com/contributors"
1501
+ }
1502
+ ],
1503
+ "description": "Symfony Console Component",
1504
+ "homepage": "https://symfony.com",
1505
+ "time": "2016-09-19 20:28:05"
1506
+ },
1507
+ {
1508
+ "name": "symfony/debug",
1509
+ "version": "2.8.x-dev",
1510
+ "source": {
1511
+ "type": "git",
1512
+ "url": "https://github.com/symfony/debug.git",
1513
+ "reference": "8c29235936a47473af16fb91c7c4b7b193c5693c"
1514
+ },
1515
+ "dist": {
1516
+ "type": "zip",
1517
+ "url": "https://api.github.com/repos/symfony/debug/zipball/8c29235936a47473af16fb91c7c4b7b193c5693c",
1518
+ "reference": "8c29235936a47473af16fb91c7c4b7b193c5693c",
1519
+ "shasum": ""
1520
+ },
1521
+ "require": {
1522
+ "php": ">=5.3.9",
1523
+ "psr/log": "~1.0"
1524
+ },
1525
+ "conflict": {
1526
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1527
+ },
1528
+ "require-dev": {
1529
+ "symfony/class-loader": "~2.2|~3.0.0",
1530
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
1531
+ },
1532
+ "type": "library",
1533
+ "extra": {
1534
+ "branch-alias": {
1535
+ "dev-master": "2.8-dev"
1536
+ }
1537
+ },
1538
+ "autoload": {
1539
+ "psr-4": {
1540
+ "Symfony\\Component\\Debug\\": ""
1541
+ },
1542
+ "exclude-from-classmap": [
1543
+ "/Tests/"
1544
+ ]
1545
+ },
1546
+ "notification-url": "https://packagist.org/downloads/",
1547
+ "license": [
1548
+ "MIT"
1549
+ ],
1550
+ "authors": [
1551
+ {
1552
+ "name": "Fabien Potencier",
1553
+ "email": "fabien@symfony.com"
1554
+ },
1555
+ {
1556
+ "name": "Symfony Community",
1557
+ "homepage": "https://symfony.com/contributors"
1558
+ }
1559
+ ],
1560
+ "description": "Symfony Debug Component",
1561
+ "homepage": "https://symfony.com",
1562
+ "time": "2016-09-06 10:55:00"
1563
+ },
1564
+ {
1565
+ "name": "symfony/event-dispatcher",
1566
+ "version": "2.8.x-dev",
1567
+ "source": {
1568
+ "type": "git",
1569
+ "url": "https://github.com/symfony/event-dispatcher.git",
1570
+ "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8"
1571
+ },
1572
+ "dist": {
1573
+ "type": "zip",
1574
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/889983a79a043dfda68f38c38b6dba092dd49cd8",
1575
+ "reference": "889983a79a043dfda68f38c38b6dba092dd49cd8",
1576
+ "shasum": ""
1577
+ },
1578
+ "require": {
1579
+ "php": ">=5.3.9"
1580
+ },
1581
+ "require-dev": {
1582
+ "psr/log": "~1.0",
1583
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
1584
+ "symfony/dependency-injection": "~2.6|~3.0.0",
1585
+ "symfony/expression-language": "~2.6|~3.0.0",
1586
+ "symfony/stopwatch": "~2.3|~3.0.0"
1587
+ },
1588
+ "suggest": {
1589
+ "symfony/dependency-injection": "",
1590
+ "symfony/http-kernel": ""
1591
+ },
1592
+ "type": "library",
1593
+ "extra": {
1594
+ "branch-alias": {
1595
+ "dev-master": "2.8-dev"
1596
+ }
1597
+ },
1598
+ "autoload": {
1599
+ "psr-4": {
1600
+ "Symfony\\Component\\EventDispatcher\\": ""
1601
+ },
1602
+ "exclude-from-classmap": [
1603
+ "/Tests/"
1604
+ ]
1605
+ },
1606
+ "notification-url": "https://packagist.org/downloads/",
1607
+ "license": [
1608
+ "MIT"
1609
+ ],
1610
+ "authors": [
1611
+ {
1612
+ "name": "Fabien Potencier",
1613
+ "email": "fabien@symfony.com"
1614
+ },
1615
+ {
1616
+ "name": "Symfony Community",
1617
+ "homepage": "https://symfony.com/contributors"
1618
+ }
1619
+ ],
1620
+ "description": "Symfony EventDispatcher Component",
1621
+ "homepage": "https://symfony.com",
1622
+ "time": "2016-07-28 16:56:28"
1623
+ },
1624
+ {
1625
+ "name": "symfony/filesystem",
1626
+ "version": "2.8.x-dev",
1627
+ "source": {
1628
+ "type": "git",
1629
+ "url": "https://github.com/symfony/filesystem.git",
1630
+ "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf"
1631
+ },
1632
+ "dist": {
1633
+ "type": "zip",
1634
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/44b499521defddf2eae17a18c811bbdae4f98bdf",
1635
+ "reference": "44b499521defddf2eae17a18c811bbdae4f98bdf",
1636
+ "shasum": ""
1637
+ },
1638
+ "require": {
1639
+ "php": ">=5.3.9"
1640
+ },
1641
+ "type": "library",
1642
+ "extra": {
1643
+ "branch-alias": {
1644
+ "dev-master": "2.8-dev"
1645
+ }
1646
+ },
1647
+ "autoload": {
1648
+ "psr-4": {
1649
+ "Symfony\\Component\\Filesystem\\": ""
1650
+ },
1651
+ "exclude-from-classmap": [
1652
+ "/Tests/"
1653
+ ]
1654
+ },
1655
+ "notification-url": "https://packagist.org/downloads/",
1656
+ "license": [
1657
+ "MIT"
1658
+ ],
1659
+ "authors": [
1660
+ {
1661
+ "name": "Fabien Potencier",
1662
+ "email": "fabien@symfony.com"
1663
+ },
1664
+ {
1665
+ "name": "Symfony Community",
1666
+ "homepage": "https://symfony.com/contributors"
1667
+ }
1668
+ ],
1669
+ "description": "Symfony Filesystem Component",
1670
+ "homepage": "https://symfony.com",
1671
+ "time": "2016-09-06 10:55:00"
1672
+ },
1673
+ {
1674
+ "name": "symfony/finder",
1675
+ "version": "2.8.x-dev",
1676
+ "source": {
1677
+ "type": "git",
1678
+ "url": "https://github.com/symfony/finder.git",
1679
+ "reference": "edb9822044c046705c1a103e3b275296ae30f252"
1680
+ },
1681
+ "dist": {
1682
+ "type": "zip",
1683
+ "url": "https://api.github.com/repos/symfony/finder/zipball/edb9822044c046705c1a103e3b275296ae30f252",
1684
+ "reference": "edb9822044c046705c1a103e3b275296ae30f252",
1685
+ "shasum": ""
1686
+ },
1687
+ "require": {
1688
+ "php": ">=5.3.9"
1689
+ },
1690
+ "type": "library",
1691
+ "extra": {
1692
+ "branch-alias": {
1693
+ "dev-master": "2.8-dev"
1694
+ }
1695
+ },
1696
+ "autoload": {
1697
+ "psr-4": {
1698
+ "Symfony\\Component\\Finder\\": ""
1699
+ },
1700
+ "exclude-from-classmap": [
1701
+ "/Tests/"
1702
+ ]
1703
+ },
1704
+ "notification-url": "https://packagist.org/downloads/",
1705
+ "license": [
1706
+ "MIT"
1707
+ ],
1708
+ "authors": [
1709
+ {
1710
+ "name": "Fabien Potencier",
1711
+ "email": "fabien@symfony.com"
1712
+ },
1713
+ {
1714
+ "name": "Symfony Community",
1715
+ "homepage": "https://symfony.com/contributors"
1716
+ }
1717
+ ],
1718
+ "description": "Symfony Finder Component",
1719
+ "homepage": "https://symfony.com",
1720
+ "time": "2016-09-14 22:47:13"
1721
+ },
1722
+ {
1723
+ "name": "symfony/polyfill-mbstring",
1724
+ "version": "dev-master",
1725
+ "source": {
1726
+ "type": "git",
1727
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1728
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c"
1729
+ },
1730
+ "dist": {
1731
+ "type": "zip",
1732
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1733
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1734
+ "shasum": ""
1735
+ },
1736
+ "require": {
1737
+ "php": ">=5.3.3"
1738
+ },
1739
+ "suggest": {
1740
+ "ext-mbstring": "For best performance"
1741
+ },
1742
+ "type": "library",
1743
+ "extra": {
1744
+ "branch-alias": {
1745
+ "dev-master": "1.2-dev"
1746
+ }
1747
+ },
1748
+ "autoload": {
1749
+ "psr-4": {
1750
+ "Symfony\\Polyfill\\Mbstring\\": ""
1751
+ },
1752
+ "files": [
1753
+ "bootstrap.php"
1754
+ ]
1755
+ },
1756
+ "notification-url": "https://packagist.org/downloads/",
1757
+ "license": [
1758
+ "MIT"
1759
+ ],
1760
+ "authors": [
1761
+ {
1762
+ "name": "Nicolas Grekas",
1763
+ "email": "p@tchwork.com"
1764
+ },
1765
+ {
1766
+ "name": "Symfony Community",
1767
+ "homepage": "https://symfony.com/contributors"
1768
+ }
1769
+ ],
1770
+ "description": "Symfony polyfill for the Mbstring extension",
1771
+ "homepage": "https://symfony.com",
1772
+ "keywords": [
1773
+ "compatibility",
1774
+ "mbstring",
1775
+ "polyfill",
1776
+ "portable",
1777
+ "shim"
1778
+ ],
1779
+ "time": "2016-08-30 17:06:17"
1780
+ },
1781
+ {
1782
+ "name": "symfony/process",
1783
+ "version": "2.8.x-dev",
1784
+ "source": {
1785
+ "type": "git",
1786
+ "url": "https://github.com/symfony/process.git",
1787
+ "reference": "05a03ed27073638658cab9405d99a67dd1014987"
1788
+ },
1789
+ "dist": {
1790
+ "type": "zip",
1791
+ "url": "https://api.github.com/repos/symfony/process/zipball/05a03ed27073638658cab9405d99a67dd1014987",
1792
+ "reference": "05a03ed27073638658cab9405d99a67dd1014987",
1793
+ "shasum": ""
1794
+ },
1795
+ "require": {
1796
+ "php": ">=5.3.9"
1797
+ },
1798
+ "type": "library",
1799
+ "extra": {
1800
+ "branch-alias": {
1801
+ "dev-master": "2.8-dev"
1802
+ }
1803
+ },
1804
+ "autoload": {
1805
+ "psr-4": {
1806
+ "Symfony\\Component\\Process\\": ""
1807
+ },
1808
+ "exclude-from-classmap": [
1809
+ "/Tests/"
1810
+ ]
1811
+ },
1812
+ "notification-url": "https://packagist.org/downloads/",
1813
+ "license": [
1814
+ "MIT"
1815
+ ],
1816
+ "authors": [
1817
+ {
1818
+ "name": "Fabien Potencier",
1819
+ "email": "fabien@symfony.com"
1820
+ },
1821
+ {
1822
+ "name": "Symfony Community",
1823
+ "homepage": "https://symfony.com/contributors"
1824
+ }
1825
+ ],
1826
+ "description": "Symfony Process Component",
1827
+ "homepage": "https://symfony.com",
1828
+ "time": "2016-09-06 10:55:00"
1829
+ },
1830
+ {
1831
+ "name": "symfony/stopwatch",
1832
+ "version": "2.8.x-dev",
1833
+ "source": {
1834
+ "type": "git",
1835
+ "url": "https://github.com/symfony/stopwatch.git",
1836
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca"
1837
+ },
1838
+ "dist": {
1839
+ "type": "zip",
1840
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
1841
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca",
1842
+ "shasum": ""
1843
+ },
1844
+ "require": {
1845
+ "php": ">=5.3.9"
1846
+ },
1847
+ "type": "library",
1848
+ "extra": {
1849
+ "branch-alias": {
1850
+ "dev-master": "2.8-dev"
1851
+ }
1852
+ },
1853
+ "autoload": {
1854
+ "psr-4": {
1855
+ "Symfony\\Component\\Stopwatch\\": ""
1856
+ },
1857
+ "exclude-from-classmap": [
1858
+ "/Tests/"
1859
+ ]
1860
+ },
1861
+ "notification-url": "https://packagist.org/downloads/",
1862
+ "license": [
1863
+ "MIT"
1864
+ ],
1865
+ "authors": [
1866
+ {
1867
+ "name": "Fabien Potencier",
1868
+ "email": "fabien@symfony.com"
1869
+ },
1870
+ {
1871
+ "name": "Symfony Community",
1872
+ "homepage": "https://symfony.com/contributors"
1873
+ }
1874
+ ],
1875
+ "description": "Symfony Stopwatch Component",
1876
+ "homepage": "https://symfony.com",
1877
+ "time": "2016-06-29 05:29:29"
1878
+ },
1879
+ {
1880
+ "name": "symfony/yaml",
1881
+ "version": "2.8.x-dev",
1882
+ "source": {
1883
+ "type": "git",
1884
+ "url": "https://github.com/symfony/yaml.git",
1885
+ "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c"
1886
+ },
1887
+ "dist": {
1888
+ "type": "zip",
1889
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/e7540734bad981fe59f8ef14b6fc194ae9df8d9c",
1890
+ "reference": "e7540734bad981fe59f8ef14b6fc194ae9df8d9c",
1891
+ "shasum": ""
1892
+ },
1893
+ "require": {
1894
+ "php": ">=5.3.9"
1895
+ },
1896
+ "type": "library",
1897
+ "extra": {
1898
+ "branch-alias": {
1899
+ "dev-master": "2.8-dev"
1900
+ }
1901
+ },
1902
+ "autoload": {
1903
+ "psr-4": {
1904
+ "Symfony\\Component\\Yaml\\": ""
1905
+ },
1906
+ "exclude-from-classmap": [
1907
+ "/Tests/"
1908
+ ]
1909
+ },
1910
+ "notification-url": "https://packagist.org/downloads/",
1911
+ "license": [
1912
+ "MIT"
1913
+ ],
1914
+ "authors": [
1915
+ {
1916
+ "name": "Fabien Potencier",
1917
+ "email": "fabien@symfony.com"
1918
+ },
1919
+ {
1920
+ "name": "Symfony Community",
1921
+ "homepage": "https://symfony.com/contributors"
1922
+ }
1923
+ ],
1924
+ "description": "Symfony Yaml Component",
1925
+ "homepage": "https://symfony.com",
1926
+ "time": "2016-09-02 01:57:56"
1927
+ }
1928
+ ],
1929
+ "aliases": [],
1930
+ "minimum-stability": "dev",
1931
+ "stability-flags": {
1932
+ "dhii/php-cs-fixer-config": 20,
1933
+ "codeclimate/php-test-reporter": 20
1934
+ },
1935
+ "prefer-stable": false,
1936
+ "prefer-lowest": false,
1937
+ "platform": {
1938
+ "php": "^5.3 | ^7.0"
1939
+ },
1940
+ "platform-dev": []
1941
+ }
vendor/dhii/collections-interface/nbproject/project.properties ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ file.reference.collections-interface-vendor=vendor
13
+ file.reference.test-unit=test/unit
14
+ include.path=\
15
+ ${php.global.include.path}:\
16
+ ${file.reference.collections-interface-vendor}
17
+ php.version=PHP_53
18
+ source.encoding=UTF-8
19
+ src.dir=src
20
+ tags.asp=false
21
+ tags.short=false
22
+ test.src.dir=${file.reference.test-unit}
23
+ testing.providers=PhpUnit
24
+ web.root=.
vendor/dhii/collections-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 - collections-interface</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/collections-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/collections-interface/src/AccessibleCollectionInterface.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Something that can act as a collection, the individual items of which can be accessed.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ interface AccessibleCollectionInterface
11
+ {
12
+ /**
13
+ * Checks whether this collection contains the given item.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @param mixed $item The item to check for.
18
+ *
19
+ * @return bool True if the given item exists in this collection; false otherwise.
20
+ */
21
+ public function hasItem($item);
22
+
23
+ /**
24
+ * Checks whether this collection contains an item with the given key.
25
+ *
26
+ * @since 0.1.0
27
+ *
28
+ * @param string|int $key The key to check for.
29
+ *
30
+ * @return bool True if an item witht he specified key exists in this collcetion; false otherwise.
31
+ */
32
+ public function hasItemKey($key);
33
+
34
+ /**
35
+ * Retrieves an item with the specified key.
36
+ *
37
+ * @since 0.1.0
38
+ *
39
+ * @param string|int $key The key of the item to retrieve.
40
+ *
41
+ * @return mixed The item, if key is found; null otherwise.
42
+ */
43
+ public function getItem($key);
44
+ }
vendor/dhii/collections-interface/src/CallbackIterableInterface.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use UnexpectedValueException;
6
+
7
+ /**
8
+ * Something that can iterate over its items using a callback.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ interface CallbackIterableInterface
13
+ {
14
+ /**
15
+ * Do something with each element of the collection.
16
+ *
17
+ * @since 0.1.0
18
+ *
19
+ * @param callable $callback The callback to apply to each element of the collection.
20
+ * See {@see CallbackIteratorInterface::getCallback()} for callback specification.
21
+ * @param mixed[]|\Traversable A list of items. Default: this collection's items.
22
+ *
23
+ * @throws UnexpectedValueException If the callback is not callable.
24
+ *
25
+ * @return CallbackIterator The iterator that will apply the callback to each element.
26
+ */
27
+ public function each($callback);
28
+ }
vendor/dhii/collections-interface/src/CallbackIteratorInterface.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use Iterator;
6
+
7
+ /**
8
+ * Something that can act as a callback iterator.
9
+ *
10
+ * A callback iterator is something that returns items processed by a callback.
11
+ *
12
+ * @since 0.1.0
13
+ */
14
+ interface CallbackIteratorInterface extends Iterator
15
+ {
16
+ /**
17
+ * Retrieves the callback that this iterator will apply to each element.
18
+ *
19
+ * The callback will be called with 2 parameters:
20
+ * 1. The key of the current item;
21
+ * 2. The current item;
22
+ * 3. The reference to the $isContinue pointer, which, if set to false, will cause the loop to terminate.
23
+ *
24
+ * @since 0.1.0
25
+ *
26
+ * @return callable The callback of this iterator.
27
+ */
28
+ public function getCallback();
29
+
30
+ /**
31
+ * Return the current element after applying the callback to it.
32
+ *
33
+ * @see getCallback()
34
+ * @since 0.1.0
35
+ */
36
+ public function current();
37
+ }
vendor/dhii/collections-interface/src/CollectionInterface.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Something that can act like a collection.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ interface CollectionInterface
11
+ {
12
+ /**
13
+ * Retrieve the items of the collection.
14
+ *
15
+ * This method may return an array. However, this is not a reliable way to convert a collection
16
+ * to an array. For that purpose, use {@see iterator_to_array()}.
17
+ *
18
+ * @since 0.1.0
19
+ *
20
+ * @return mixed[]|\Traversable The list of items, by original key.
21
+ */
22
+ public function getItems();
23
+ }
vendor/dhii/collections-interface/src/MutableCollectionInterface.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Something that can act as a collection which can have its item set changed.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ interface MutableCollectionInterface
11
+ {
12
+ /**
13
+ * Adds an item to this collection.
14
+ *
15
+ * @param mixed $item An item to add to the collection.
16
+ *
17
+ * @since 0.1.0
18
+ *
19
+ * @return bool True if item has been added; false otherwise.
20
+ */
21
+ public function addItem($item);
22
+
23
+ /**
24
+ * Adds multiple items to this collection.
25
+ *
26
+ * @param mixed[]|\Traversable $items A list of items to add.
27
+ *
28
+ * @since 0.1.0
29
+ *
30
+ * @return bool True if items have been added; false otherwise.
31
+ */
32
+ public function addItems($items);
33
+
34
+ /**
35
+ * Removes an item from the collection.
36
+ *
37
+ * @param mixed $item The item to remove from the collection.
38
+ *
39
+ * @since 0.1.0
40
+ *
41
+ * @return bool True if item has been removed; false otherwise.
42
+ */
43
+ public function removeitem($item);
44
+
45
+ /**
46
+ * Removes an item with the specified key from the collection.
47
+ *
48
+ * @param string|int $key The key of an item to remove.
49
+ *
50
+ * @since 0.1.0
51
+ *
52
+ * @return bool True if item has been removed; false otherwise.
53
+ */
54
+ public function removeItemByKey($key);
55
+ }
vendor/dhii/collections-interface/src/SearchableCollectionInterface.php ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Something that can act as a searchable collection.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ interface SearchableCollectionInterface
11
+ {
12
+ /**
13
+ * Search this collection for items using custom criteria.
14
+ *
15
+ * @param callable $eval A callable that evaluates an item to determine whether it matches a criteria.
16
+ * This callable must return the item passed as the second argument, the validity of which will be evaluated by {@see _isValidItem()}, if it is a match.
17
+ * The third argument is a boolean value passed by reference which, if set to false, will prevent any further evaluation, and cause the search to stop.
18
+ * The first argument is the key of the item being evaluated.
19
+ * @param array|\Traversable $items
20
+ *
21
+ * @return mixed[]|\Traversable A list of items which represents the search result.
22
+ */
23
+ public function search($eval);
24
+ }
vendor/dhii/collections-interface/src/SequenceIteratorIteratorInterface.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ use OuterIterator;
6
+
7
+ /**
8
+ * Something that can act as an iterator which iterates sequentially over elemnts in other aggregators.
9
+ *
10
+ * Based on {@see \AppendIterator}. However, does not require a public {@link \AppendIterator::append() append()}
11
+ * method, thus allowing iteration over a read-only list of iterators.
12
+ *
13
+ * @since 0.1.0
14
+ */
15
+ interface SequenceIteratorIteratorInterface extends OuterIterator
16
+ {
17
+ /**
18
+ * @see \AppendIterator::getArrayIterator()
19
+ * @since 0.1.0
20
+ */
21
+ public function getArrayIterator();
22
+
23
+ /**
24
+ * @see \AppendIterator::getIteratorIndex()
25
+ * @since 0.1.0
26
+ */
27
+ public function getIteratorIndex();
28
+ }
vendor/dhii/collections-interface/src/SetInterface.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection;
4
+
5
+ /**
6
+ * Something that can behave as a set with complete functionality.
7
+ *
8
+ * @since 0.1.2
9
+ */
10
+ interface SetInterface extends \Countable
11
+ {
12
+ /**
13
+ * Adds an item.
14
+ *
15
+ * @param mixed $item An item to add.
16
+ *
17
+ * @since 0.1.2
18
+ *
19
+ * @return bool True if item has been added; false otherwise.
20
+ */
21
+ public function add($item);
22
+
23
+ /**
24
+ * Adds multiple items.
25
+ *
26
+ * @param mixed[]|\Traversable $values A list of items to add.
27
+ *
28
+ * @since 0.1.2
29
+ *
30
+ * @return bool True if items have been added; false otherwise.
31
+ */
32
+ public function addMany($values);
33
+
34
+ /**
35
+ * Removes an item.
36
+ *
37
+ * @param mixed $item The item to remove.
38
+ *
39
+ * @since 0.1.2
40
+ *
41
+ * @return bool True if item has been removed; false otherwise.
42
+ */
43
+ public function remove($item);
44
+
45
+ /**
46
+ * Removes multiple items.
47
+ *
48
+ * @since 0.1.2
49
+ *
50
+ * @param mixed[]|\Traversable $items The items to remove
51
+ */
52
+ public function removeMany($items);
53
+
54
+ /**
55
+ * Checks whether this instance contains an item with the given key.
56
+ *
57
+ * @since 0.1.2
58
+ *
59
+ * @param string|int $key The key to check for.
60
+ *
61
+ * @return bool True if an item witht he specified key exists in this instance; false otherwise.
62
+ */
63
+ public function has($key);
64
+
65
+ /**
66
+ * Clears all items of this collection.
67
+ *
68
+ * @since 0.1.2
69
+ */
70
+ public function clear();
71
+
72
+ /**
73
+ * Retrieve the items of the collection.
74
+ *
75
+ * This method may return an array. However, this is not a reliable way to convert a collection
76
+ * to an array. For that purpose, use {@see iterator_to_array()}.
77
+ *
78
+ * @since 0.1.2
79
+ *
80
+ * @return mixed[]|\Traversable The list of items, by original key.
81
+ */
82
+ public function items();
83
+ }
vendor/dhii/collections-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/collections-interface/test/unit/AccessibleCollectionInterfaceTest.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\AccessibleCollectionInterfaceTest}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AccessibleCollectionInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\AccessibleCollectionInterfaceTest
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\AccessibleCollectionInterfaceTest');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\AccessibleCollectionInterfaceTest', $subject, 'Could not create an implementing instance');
36
+ }
37
+ }
vendor/dhii/collections-interface/test/unit/CallbackIterableInterfaceTest.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\CallbackIterableInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class CallbackIterableInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\CallbackIterableInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\CallbackIterableInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\CallbackIterableInterface', $subject, 'Could not create an implementing instance');
36
+ }
37
+ }
vendor/dhii/collections-interface/test/unit/CallbackIteratorInterfaceTest.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\CallbackIteratorInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class CallbackIteratorInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\CallbackIteratorInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\CallbackIteratorInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\CallbackIteratorInterface', $subject, 'Could not create an implementing instance');
36
+ $this->assertInstanceOf('Iterator', $subject, 'Subject does not implement required interface');
37
+ }
38
+ }
vendor/dhii/collections-interface/test/unit/CollectionInterfaceTest.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\CollectionInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class CollectionInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\CollectionInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\CollectionInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\CollectionInterface', $subject, 'Could not create an implementing instance');
36
+ }
37
+ }
vendor/dhii/collections-interface/test/unit/MutableCollectionInterfaceTest.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\MutableCollectionInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class MutableCollectionInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\MutableCollectionInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\MutableCollectionInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\MutableCollectionInterface', $subject, 'Could not create an implementing instance');
36
+ }
37
+ }
vendor/dhii/collections-interface/test/unit/SearchableCollectionInterfaceTest.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\SearchableCollectionInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class SearchableCollectionInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\SearchableCollectionInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\SearchableCollectionInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\SearchableCollectionInterface', $subject, 'Could not create an implementing instance');
36
+ }
37
+ }
vendor/dhii/collections-interface/test/unit/SequenceIteratorIteratorInterfaceTest.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\SequenceIteratorIteratorInterface}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class SequenceIteratorIteratorInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.0
16
+ *
17
+ * @return Dhii\Collection\SequenceIteratorIteratorInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMock('Dhii\\Collection\\SequenceIteratorIteratorInterface');
22
+
23
+ return $mock;
24
+ }
25
+
26
+ /**
27
+ * Tests whether a correct instance of a descendant can be created.
28
+ *
29
+ * @since 0.1.0
30
+ */
31
+ public function testCanBeCreated()
32
+ {
33
+ $subject = $this->createInstance();
34
+
35
+ $this->assertInstanceOf('Dhii\\Collection\\SequenceIteratorIteratorInterface', $subject, 'Could not create an implementing instance');
36
+ $this->assertInstanceOf('OuterIterator', $subject, 'Subject does not implement required interface');
37
+ }
38
+ }
vendor/dhii/collections-interface/test/unit/SetInterfaceTest.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Collection\UnitTest;
4
+
5
+ /**
6
+ * Tests {@see Dhii\Collection\SetInterface}.
7
+ *
8
+ * @since 0.1.1
9
+ */
10
+ class SetInterfaceTest extends \PHPUnit_Framework_TestCase
11
+ {
12
+ /**
13
+ * Creates a new instance of the test subject.
14
+ *
15
+ * @since 0.1.1
16
+ *
17
+ * @return \Dhii\Collection\SetInterface
18
+ */
19
+ public function createInstance()
20
+ {
21
+ $mock = $this->getMockBuilder('Dhii\\Collection\\SetInterface')
22
+ ->getMockForAbstractClass();
23
+
24
+ return $mock;
25
+ }
26
+
27
+ /**
28
+ * Tests whether a valid instance of the test subject can be created.
29
+ *
30
+ * @since 0.1.1
31
+ */
32
+ public function testCanBeCreated()
33
+ {
34
+ $subject = $this->createInstance();
35
+
36
+ $this->assertInstanceOf('Dhii\\Collection\\SetInterface', $subject, 'A valid instance of the test subject could not be created');
37
+ $this->assertInstanceOf('Countable', $subject, 'A valid instance of the test subject could not be created');
38
+ }
39
+ }
vendor/dhii/stats-abstract/.php_cs ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
4
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
5
+ $fixers = $config->getFixers();
6
+
7
+ $toRemove = array('short_array_syntax');
8
+ foreach ($toRemove as $_fixer) {
9
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
10
+ continue;
11
+ }
12
+
13
+ unset($fixers[$removeIndex]);
14
+ }
15
+
16
+ $toAdd = array('long_array_syntax');
17
+ foreach ($toAdd as $_fixer) {
18
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
19
+ continue;
20
+ }
21
+
22
+ $fixers[] = $_fixer;
23
+ }
24
+
25
+ $config->fixers($fixers);
26
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
27
+ return $config;
vendor/dhii/stats-abstract/.travis.yml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 install
13
+
14
+ script:
15
+ - phpunit
vendor/dhii/stats-abstract/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
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.0 - 2016-11-10
8
+ The initial release
vendor/dhii/stats-abstract/composer.json ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/stats-abstract",
3
+ "description": "Abstract base for stats",
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
+ "dhii/stats-interface": "^0.1.0",
15
+ "dhii/collections-abstract-base": "^0.1.0"
16
+ },
17
+ "require-dev": {
18
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
19
+ "phpunit/phpunit": "^4.8",
20
+ "ptrofimov/xpmock": "^1.1"
21
+ },
22
+ "autoload": {
23
+ "psr-4": {
24
+ "Dhii\\Stats\\": "src/"
25
+ }
26
+ }
27
+ }
vendor/dhii/stats-abstract/composer.lock ADDED
@@ -0,0 +1,1713 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "f0084852930ea26e6cb21cbbb7d38d1c",
8
+ "content-hash": "120c1703c5fd5fc931362ebb3fd7b0be",
9
+ "packages": [
10
+ {
11
+ "name": "dhii/collections-abstract-base",
12
+ "version": "v0.1.0",
13
+ "source": {
14
+ "type": "git",
15
+ "url": "https://github.com/Dhii/collections-abstract-base.git",
16
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3"
17
+ },
18
+ "dist": {
19
+ "type": "zip",
20
+ "url": "https://api.github.com/repos/Dhii/collections-abstract-base/zipball/0ec0147451a72a13fb327ac6ff747c5e953c56f3",
21
+ "reference": "0ec0147451a72a13fb327ac6ff747c5e953c56f3",
22
+ "shasum": ""
23
+ },
24
+ "require": {
25
+ "dhii/collections-interface": "^0.1.1"
26
+ },
27
+ "require-dev": {
28
+ "codeclimate/php-test-reporter": "dev-master",
29
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
30
+ "phpunit/phpunit": "^4.8",
31
+ "ptrofimov/xpmock": "^1.1"
32
+ },
33
+ "type": "library",
34
+ "autoload": {
35
+ "psr-4": {
36
+ "Dhii\\Collection\\": "src/"
37
+ }
38
+ },
39
+ "notification-url": "https://packagist.org/downloads/",
40
+ "license": [
41
+ "MIT"
42
+ ],
43
+ "authors": [
44
+ {
45
+ "name": "Dhii Team",
46
+ "email": "development@dhii.co"
47
+ }
48
+ ],
49
+ "description": "Collection base classes that do not depend on other non-collection packages, on which there is a dependency of other collection packages that depend on this package. This is done to avoid circular reference in the collection toolchain",
50
+ "time": "2016-11-10 15:09:37"
51
+ },
52
+ {
53
+ "name": "dhii/collections-interface",
54
+ "version": "v0.1.1",
55
+ "source": {
56
+ "type": "git",
57
+ "url": "https://github.com/Dhii/collections-interface.git",
58
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f"
59
+ },
60
+ "dist": {
61
+ "type": "zip",
62
+ "url": "https://api.github.com/repos/Dhii/collections-interface/zipball/1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
63
+ "reference": "1d8c785cdf8b63334b35f9a2d663b82e56d06e4f",
64
+ "shasum": ""
65
+ },
66
+ "require": {
67
+ "php": "^5.3 | ^7.0"
68
+ },
69
+ "require-dev": {
70
+ "codeclimate/php-test-reporter": "dev-master",
71
+ "dhii/php-cs-fixer-config": "dev-php-5.3",
72
+ "phpunit/phpunit": "^4.8"
73
+ },
74
+ "type": "library",
75
+ "autoload": {
76
+ "psr-4": {
77
+ "Dhii\\Collection\\": "src/"
78
+ }
79
+ },
80
+ "notification-url": "https://packagist.org/downloads/",
81
+ "license": [
82
+ "MIT"
83
+ ],
84
+ "authors": [
85
+ {
86
+ "name": "Dhii Team",
87
+ "email": "development@dhii.co"
88
+ }
89
+ ],
90
+ "description": "Interfaces for collections",
91
+ "time": "2016-11-09 19:23:28"
92
+ },
93
+ {
94
+ "name": "dhii/stats-interface",
95
+ "version": "v0.1.0",
96
+ "source": {
97
+ "type": "git",
98
+ "url": "https://github.com/Dhii/stats-interface.git",
99
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba"
100
+ },
101
+ "dist": {
102
+ "type": "zip",
103
+ "url": "https://api.github.com/repos/Dhii/stats-interface/zipball/36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
104
+ "reference": "36d09a8b8a3b8058214dae6eefb8ecdd98e0f0ba",
105
+ "shasum": ""
106
+ },
107
+ "require": {
108
+ "php": "^5.3 | ^7.0"
109
+ },
110
+ "require-dev": {
111
+ "dhii/php-cs-fixer-config": "dev-php-5.3"
112
+ },
113
+ "type": "library",
114
+ "autoload": {
115
+ "psr-4": {
116
+ "Dhii\\Stats\\": "src/"
117
+ }
118
+ },
119
+ "notification-url": "https://packagist.org/downloads/",
120
+ "license": [
121
+ "MIT"
122
+ ],
123
+ "authors": [
124
+ {
125
+ "name": "Dhii Team",
126
+ "email": "development@dhii.co"
127
+ }
128
+ ],
129
+ "description": "Interfaces for stats",
130
+ "time": "2016-11-10 15:38:37"
131
+ }
132
+ ],
133
+ "packages-dev": [
134
+ {
135
+ "name": "dhii/php-cs-fixer-config",
136
+ "version": "dev-php-5.3",
137
+ "source": {
138
+ "type": "git",
139
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
140
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
141
+ },
142
+ "dist": {
143
+ "type": "zip",
144
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
145
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
146
+ "shasum": ""
147
+ },
148
+ "require": {
149
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
150
+ "php": "^5.3 | ^7.0"
151
+ },
152
+ "require-dev": {
153
+ "phpunit/phpunit": "^4.8"
154
+ },
155
+ "type": "library",
156
+ "autoload": {
157
+ "psr-4": {
158
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
159
+ }
160
+ },
161
+ "notification-url": "https://packagist.org/downloads/",
162
+ "license": [
163
+ "MIT"
164
+ ],
165
+ "authors": [
166
+ {
167
+ "name": "Dhii Team",
168
+ "email": "development@dhii.co"
169
+ }
170
+ ],
171
+ "description": "A default PHP CS Fixer config implementation",
172
+ "time": "2016-09-03 14:45:03"
173
+ },
174
+ {
175
+ "name": "doctrine/instantiator",
176
+ "version": "dev-master",
177
+ "source": {
178
+ "type": "git",
179
+ "url": "https://github.com/doctrine/instantiator.git",
180
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a"
181
+ },
182
+ "dist": {
183
+ "type": "zip",
184
+ "url": "https://api.github.com/repos/doctrine/instantiator/zipball/416fb8ad1d095a87f1d21bc40711843cd122fd4a",
185
+ "reference": "416fb8ad1d095a87f1d21bc40711843cd122fd4a",
186
+ "shasum": ""
187
+ },
188
+ "require": {
189
+ "php": ">=5.3,<8.0-DEV"
190
+ },
191
+ "require-dev": {
192
+ "athletic/athletic": "~0.1.8",
193
+ "ext-pdo": "*",
194
+ "ext-phar": "*",
195
+ "phpunit/phpunit": "~4.0",
196
+ "squizlabs/php_codesniffer": "~2.0"
197
+ },
198
+ "type": "library",
199
+ "extra": {
200
+ "branch-alias": {
201
+ "dev-master": "1.0.x-dev"
202
+ }
203
+ },
204
+ "autoload": {
205
+ "psr-4": {
206
+ "Doctrine\\Instantiator\\": "src/Doctrine/Instantiator/"
207
+ }
208
+ },
209
+ "notification-url": "https://packagist.org/downloads/",
210
+ "license": [
211
+ "MIT"
212
+ ],
213
+ "authors": [
214
+ {
215
+ "name": "Marco Pivetta",
216
+ "email": "ocramius@gmail.com",
217
+ "homepage": "http://ocramius.github.com/"
218
+ }
219
+ ],
220
+ "description": "A small, lightweight utility to instantiate objects in PHP without invoking their constructors",
221
+ "homepage": "https://github.com/doctrine/instantiator",
222
+ "keywords": [
223
+ "constructor",
224
+ "instantiate"
225
+ ],
226
+ "time": "2016-03-31 10:24:22"
227
+ },
228
+ {
229
+ "name": "friendsofphp/php-cs-fixer",
230
+ "version": "1.11.x-dev",
231
+ "source": {
232
+ "type": "git",
233
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
234
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
235
+ },
236
+ "dist": {
237
+ "type": "zip",
238
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
239
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
240
+ "shasum": ""
241
+ },
242
+ "require": {
243
+ "ext-tokenizer": "*",
244
+ "php": ">=5.3.6",
245
+ "sebastian/diff": "~1.1",
246
+ "symfony/console": "~2.3|~3.0",
247
+ "symfony/event-dispatcher": "~2.1|~3.0",
248
+ "symfony/filesystem": "~2.1|~3.0",
249
+ "symfony/finder": "~2.1|~3.0",
250
+ "symfony/process": "~2.3|~3.0",
251
+ "symfony/stopwatch": "~2.5|~3.0"
252
+ },
253
+ "conflict": {
254
+ "hhvm": "<3.9"
255
+ },
256
+ "require-dev": {
257
+ "phpunit/phpunit": "^4.5|^5",
258
+ "satooshi/php-coveralls": "^0.7.1"
259
+ },
260
+ "bin": [
261
+ "php-cs-fixer"
262
+ ],
263
+ "type": "application",
264
+ "autoload": {
265
+ "psr-4": {
266
+ "Symfony\\CS\\": "Symfony/CS/"
267
+ }
268
+ },
269
+ "notification-url": "https://packagist.org/downloads/",
270
+ "license": [
271
+ "MIT"
272
+ ],
273
+ "authors": [
274
+ {
275
+ "name": "Dariusz Rumiński",
276
+ "email": "dariusz.ruminski@gmail.com"
277
+ },
278
+ {
279
+ "name": "Fabien Potencier",
280
+ "email": "fabien@symfony.com"
281
+ }
282
+ ],
283
+ "description": "A tool to automatically fix PHP code style",
284
+ "time": "2016-08-16 23:31:05"
285
+ },
286
+ {
287
+ "name": "phpdocumentor/reflection-docblock",
288
+ "version": "2.0.4",
289
+ "source": {
290
+ "type": "git",
291
+ "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git",
292
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8"
293
+ },
294
+ "dist": {
295
+ "type": "zip",
296
+ "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/d68dbdc53dc358a816f00b300704702b2eaff7b8",
297
+ "reference": "d68dbdc53dc358a816f00b300704702b2eaff7b8",
298
+ "shasum": ""
299
+ },
300
+ "require": {
301
+ "php": ">=5.3.3"
302
+ },
303
+ "require-dev": {
304
+ "phpunit/phpunit": "~4.0"
305
+ },
306
+ "suggest": {
307
+ "dflydev/markdown": "~1.0",
308
+ "erusev/parsedown": "~1.0"
309
+ },
310
+ "type": "library",
311
+ "extra": {
312
+ "branch-alias": {
313
+ "dev-master": "2.0.x-dev"
314
+ }
315
+ },
316
+ "autoload": {
317
+ "psr-0": {
318
+ "phpDocumentor": [
319
+ "src/"
320
+ ]
321
+ }
322
+ },
323
+ "notification-url": "https://packagist.org/downloads/",
324
+ "license": [
325
+ "MIT"
326
+ ],
327
+ "authors": [
328
+ {
329
+ "name": "Mike van Riel",
330
+ "email": "mike.vanriel@naenius.com"
331
+ }
332
+ ],
333
+ "time": "2015-02-03 12:10:50"
334
+ },
335
+ {
336
+ "name": "phpspec/prophecy",
337
+ "version": "dev-master",
338
+ "source": {
339
+ "type": "git",
340
+ "url": "https://github.com/phpspec/prophecy.git",
341
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386"
342
+ },
343
+ "dist": {
344
+ "type": "zip",
345
+ "url": "https://api.github.com/repos/phpspec/prophecy/zipball/5c324f4951aca87a2de61b7903b75126516b6386",
346
+ "reference": "5c324f4951aca87a2de61b7903b75126516b6386",
347
+ "shasum": ""
348
+ },
349
+ "require": {
350
+ "doctrine/instantiator": "^1.0.2",
351
+ "php": "^5.3|^7.0",
352
+ "phpdocumentor/reflection-docblock": "^2.0|^3.0.2",
353
+ "sebastian/comparator": "^1.1",
354
+ "sebastian/recursion-context": "^1.0"
355
+ },
356
+ "require-dev": {
357
+ "phpspec/phpspec": "^2.0",
358
+ "phpunit/phpunit": "^4.8 || ^5"
359
+ },
360
+ "type": "library",
361
+ "extra": {
362
+ "branch-alias": {
363
+ "dev-master": "1.6.x-dev"
364
+ }
365
+ },
366
+ "autoload": {
367
+ "psr-0": {
368
+ "Prophecy\\": "src/"
369
+ }
370
+ },
371
+ "notification-url": "https://packagist.org/downloads/",
372
+ "license": [
373
+ "MIT"
374
+ ],
375
+ "authors": [
376
+ {
377
+ "name": "Konstantin Kudryashov",
378
+ "email": "ever.zet@gmail.com",
379
+ "homepage": "http://everzet.com"
380
+ },
381
+ {
382
+ "name": "Marcello Duarte",
383
+ "email": "marcello.duarte@gmail.com"
384
+ }
385
+ ],
386
+ "description": "Highly opinionated mocking framework for PHP 5.3+",
387
+ "homepage": "https://github.com/phpspec/prophecy",
388
+ "keywords": [
389
+ "Double",
390
+ "Dummy",
391
+ "fake",
392
+ "mock",
393
+ "spy",
394
+ "stub"
395
+ ],
396
+ "time": "2016-10-02 13:12:17"
397
+ },
398
+ {
399
+ "name": "phpunit/php-code-coverage",
400
+ "version": "2.2.x-dev",
401
+ "source": {
402
+ "type": "git",
403
+ "url": "https://github.com/sebastianbergmann/php-code-coverage.git",
404
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979"
405
+ },
406
+ "dist": {
407
+ "type": "zip",
408
+ "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/eabf68b476ac7d0f73793aada060f1c1a9bf8979",
409
+ "reference": "eabf68b476ac7d0f73793aada060f1c1a9bf8979",
410
+ "shasum": ""
411
+ },
412
+ "require": {
413
+ "php": ">=5.3.3",
414
+ "phpunit/php-file-iterator": "~1.3",
415
+ "phpunit/php-text-template": "~1.2",
416
+ "phpunit/php-token-stream": "~1.3",
417
+ "sebastian/environment": "^1.3.2",
418
+ "sebastian/version": "~1.0"
419
+ },
420
+ "require-dev": {
421
+ "ext-xdebug": ">=2.1.4",
422
+ "phpunit/phpunit": "~4"
423
+ },
424
+ "suggest": {
425
+ "ext-dom": "*",
426
+ "ext-xdebug": ">=2.2.1",
427
+ "ext-xmlwriter": "*"
428
+ },
429
+ "type": "library",
430
+ "extra": {
431
+ "branch-alias": {
432
+ "dev-master": "2.2.x-dev"
433
+ }
434
+ },
435
+ "autoload": {
436
+ "classmap": [
437
+ "src/"
438
+ ]
439
+ },
440
+ "notification-url": "https://packagist.org/downloads/",
441
+ "license": [
442
+ "BSD-3-Clause"
443
+ ],
444
+ "authors": [
445
+ {
446
+ "name": "Sebastian Bergmann",
447
+ "email": "sb@sebastian-bergmann.de",
448
+ "role": "lead"
449
+ }
450
+ ],
451
+ "description": "Library that provides collection, processing, and rendering functionality for PHP code coverage information.",
452
+ "homepage": "https://github.com/sebastianbergmann/php-code-coverage",
453
+ "keywords": [
454
+ "coverage",
455
+ "testing",
456
+ "xunit"
457
+ ],
458
+ "time": "2015-10-06 15:47:00"
459
+ },
460
+ {
461
+ "name": "phpunit/php-file-iterator",
462
+ "version": "dev-master",
463
+ "source": {
464
+ "type": "git",
465
+ "url": "https://github.com/sebastianbergmann/php-file-iterator.git",
466
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5"
467
+ },
468
+ "dist": {
469
+ "type": "zip",
470
+ "url": "https://api.github.com/repos/sebastianbergmann/php-file-iterator/zipball/3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
471
+ "reference": "3cc8f69b3028d0f96a9078e6295d86e9bf019be5",
472
+ "shasum": ""
473
+ },
474
+ "require": {
475
+ "php": ">=5.3.3"
476
+ },
477
+ "type": "library",
478
+ "extra": {
479
+ "branch-alias": {
480
+ "dev-master": "1.4.x-dev"
481
+ }
482
+ },
483
+ "autoload": {
484
+ "classmap": [
485
+ "src/"
486
+ ]
487
+ },
488
+ "notification-url": "https://packagist.org/downloads/",
489
+ "license": [
490
+ "BSD-3-Clause"
491
+ ],
492
+ "authors": [
493
+ {
494
+ "name": "Sebastian Bergmann",
495
+ "email": "sb@sebastian-bergmann.de",
496
+ "role": "lead"
497
+ }
498
+ ],
499
+ "description": "FilterIterator implementation that filters files based on a list of suffixes.",
500
+ "homepage": "https://github.com/sebastianbergmann/php-file-iterator/",
501
+ "keywords": [
502
+ "filesystem",
503
+ "iterator"
504
+ ],
505
+ "time": "2016-10-03 07:40:28"
506
+ },
507
+ {
508
+ "name": "phpunit/php-text-template",
509
+ "version": "1.2.1",
510
+ "source": {
511
+ "type": "git",
512
+ "url": "https://github.com/sebastianbergmann/php-text-template.git",
513
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686"
514
+ },
515
+ "dist": {
516
+ "type": "zip",
517
+ "url": "https://api.github.com/repos/sebastianbergmann/php-text-template/zipball/31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
518
+ "reference": "31f8b717e51d9a2afca6c9f046f5d69fc27c8686",
519
+ "shasum": ""
520
+ },
521
+ "require": {
522
+ "php": ">=5.3.3"
523
+ },
524
+ "type": "library",
525
+ "autoload": {
526
+ "classmap": [
527
+ "src/"
528
+ ]
529
+ },
530
+ "notification-url": "https://packagist.org/downloads/",
531
+ "license": [
532
+ "BSD-3-Clause"
533
+ ],
534
+ "authors": [
535
+ {
536
+ "name": "Sebastian Bergmann",
537
+ "email": "sebastian@phpunit.de",
538
+ "role": "lead"
539
+ }
540
+ ],
541
+ "description": "Simple template engine.",
542
+ "homepage": "https://github.com/sebastianbergmann/php-text-template/",
543
+ "keywords": [
544
+ "template"
545
+ ],
546
+ "time": "2015-06-21 13:50:34"
547
+ },
548
+ {
549
+ "name": "phpunit/php-timer",
550
+ "version": "1.0.8",
551
+ "source": {
552
+ "type": "git",
553
+ "url": "https://github.com/sebastianbergmann/php-timer.git",
554
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260"
555
+ },
556
+ "dist": {
557
+ "type": "zip",
558
+ "url": "https://api.github.com/repos/sebastianbergmann/php-timer/zipball/38e9124049cf1a164f1e4537caf19c99bf1eb260",
559
+ "reference": "38e9124049cf1a164f1e4537caf19c99bf1eb260",
560
+ "shasum": ""
561
+ },
562
+ "require": {
563
+ "php": ">=5.3.3"
564
+ },
565
+ "require-dev": {
566
+ "phpunit/phpunit": "~4|~5"
567
+ },
568
+ "type": "library",
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": "Utility class for timing",
586
+ "homepage": "https://github.com/sebastianbergmann/php-timer/",
587
+ "keywords": [
588
+ "timer"
589
+ ],
590
+ "time": "2016-05-12 18:03:57"
591
+ },
592
+ {
593
+ "name": "phpunit/php-token-stream",
594
+ "version": "dev-master",
595
+ "source": {
596
+ "type": "git",
597
+ "url": "https://github.com/sebastianbergmann/php-token-stream.git",
598
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872"
599
+ },
600
+ "dist": {
601
+ "type": "zip",
602
+ "url": "https://api.github.com/repos/sebastianbergmann/php-token-stream/zipball/2ef59c57cd196301eeb88865d25916898dd72872",
603
+ "reference": "2ef59c57cd196301eeb88865d25916898dd72872",
604
+ "shasum": ""
605
+ },
606
+ "require": {
607
+ "ext-tokenizer": "*",
608
+ "php": ">=5.3.3"
609
+ },
610
+ "require-dev": {
611
+ "phpunit/phpunit": "~4.2"
612
+ },
613
+ "type": "library",
614
+ "extra": {
615
+ "branch-alias": {
616
+ "dev-master": "1.4-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": "sebastian@phpunit.de"
632
+ }
633
+ ],
634
+ "description": "Wrapper around PHP's tokenizer extension.",
635
+ "homepage": "https://github.com/sebastianbergmann/php-token-stream/",
636
+ "keywords": [
637
+ "tokenizer"
638
+ ],
639
+ "time": "2016-10-03 07:38:46"
640
+ },
641
+ {
642
+ "name": "phpunit/phpunit",
643
+ "version": "4.8.x-dev",
644
+ "source": {
645
+ "type": "git",
646
+ "url": "https://github.com/sebastianbergmann/phpunit.git",
647
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935"
648
+ },
649
+ "dist": {
650
+ "type": "zip",
651
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/7b58ff0d8996b56675a3e05dcd563e0a4f244935",
652
+ "reference": "7b58ff0d8996b56675a3e05dcd563e0a4f244935",
653
+ "shasum": ""
654
+ },
655
+ "require": {
656
+ "ext-dom": "*",
657
+ "ext-json": "*",
658
+ "ext-pcre": "*",
659
+ "ext-reflection": "*",
660
+ "ext-spl": "*",
661
+ "php": ">=5.3.3",
662
+ "phpspec/prophecy": "^1.3.1",
663
+ "phpunit/php-code-coverage": "~2.1",
664
+ "phpunit/php-file-iterator": "~1.4",
665
+ "phpunit/php-text-template": "~1.2",
666
+ "phpunit/php-timer": "^1.0.6",
667
+ "phpunit/phpunit-mock-objects": "~2.3",
668
+ "sebastian/comparator": "~1.1",
669
+ "sebastian/diff": "~1.2",
670
+ "sebastian/environment": "~1.3",
671
+ "sebastian/exporter": "~1.2",
672
+ "sebastian/global-state": "~1.0",
673
+ "sebastian/version": "~1.0",
674
+ "symfony/yaml": "~2.1|~3.0"
675
+ },
676
+ "suggest": {
677
+ "phpunit/php-invoker": "~1.1"
678
+ },
679
+ "bin": [
680
+ "phpunit"
681
+ ],
682
+ "type": "library",
683
+ "extra": {
684
+ "branch-alias": {
685
+ "dev-master": "4.8.x-dev"
686
+ }
687
+ },
688
+ "autoload": {
689
+ "classmap": [
690
+ "src/"
691
+ ]
692
+ },
693
+ "notification-url": "https://packagist.org/downloads/",
694
+ "license": [
695
+ "BSD-3-Clause"
696
+ ],
697
+ "authors": [
698
+ {
699
+ "name": "Sebastian Bergmann",
700
+ "email": "sebastian@phpunit.de",
701
+ "role": "lead"
702
+ }
703
+ ],
704
+ "description": "The PHP Unit Testing framework.",
705
+ "homepage": "https://phpunit.de/",
706
+ "keywords": [
707
+ "phpunit",
708
+ "testing",
709
+ "xunit"
710
+ ],
711
+ "time": "2016-10-03 13:00:58"
712
+ },
713
+ {
714
+ "name": "phpunit/phpunit-mock-objects",
715
+ "version": "2.3.x-dev",
716
+ "source": {
717
+ "type": "git",
718
+ "url": "https://github.com/sebastianbergmann/phpunit-mock-objects.git",
719
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983"
720
+ },
721
+ "dist": {
722
+ "type": "zip",
723
+ "url": "https://api.github.com/repos/sebastianbergmann/phpunit-mock-objects/zipball/ac8e7a3db35738d56ee9a76e78a4e03d97628983",
724
+ "reference": "ac8e7a3db35738d56ee9a76e78a4e03d97628983",
725
+ "shasum": ""
726
+ },
727
+ "require": {
728
+ "doctrine/instantiator": "^1.0.2",
729
+ "php": ">=5.3.3",
730
+ "phpunit/php-text-template": "~1.2",
731
+ "sebastian/exporter": "~1.2"
732
+ },
733
+ "require-dev": {
734
+ "phpunit/phpunit": "~4.4"
735
+ },
736
+ "suggest": {
737
+ "ext-soap": "*"
738
+ },
739
+ "type": "library",
740
+ "extra": {
741
+ "branch-alias": {
742
+ "dev-master": "2.3.x-dev"
743
+ }
744
+ },
745
+ "autoload": {
746
+ "classmap": [
747
+ "src/"
748
+ ]
749
+ },
750
+ "notification-url": "https://packagist.org/downloads/",
751
+ "license": [
752
+ "BSD-3-Clause"
753
+ ],
754
+ "authors": [
755
+ {
756
+ "name": "Sebastian Bergmann",
757
+ "email": "sb@sebastian-bergmann.de",
758
+ "role": "lead"
759
+ }
760
+ ],
761
+ "description": "Mock Object library for PHPUnit",
762
+ "homepage": "https://github.com/sebastianbergmann/phpunit-mock-objects/",
763
+ "keywords": [
764
+ "mock",
765
+ "xunit"
766
+ ],
767
+ "time": "2015-10-02 06:51:40"
768
+ },
769
+ {
770
+ "name": "psr/log",
771
+ "version": "dev-master",
772
+ "source": {
773
+ "type": "git",
774
+ "url": "https://github.com/php-fig/log.git",
775
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
776
+ },
777
+ "dist": {
778
+ "type": "zip",
779
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
780
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
781
+ "shasum": ""
782
+ },
783
+ "require": {
784
+ "php": ">=5.3.0"
785
+ },
786
+ "type": "library",
787
+ "extra": {
788
+ "branch-alias": {
789
+ "dev-master": "1.0.x-dev"
790
+ }
791
+ },
792
+ "autoload": {
793
+ "psr-4": {
794
+ "Psr\\Log\\": "Psr/Log/"
795
+ }
796
+ },
797
+ "notification-url": "https://packagist.org/downloads/",
798
+ "license": [
799
+ "MIT"
800
+ ],
801
+ "authors": [
802
+ {
803
+ "name": "PHP-FIG",
804
+ "homepage": "http://www.php-fig.org/"
805
+ }
806
+ ],
807
+ "description": "Common interface for logging libraries",
808
+ "homepage": "https://github.com/php-fig/log",
809
+ "keywords": [
810
+ "log",
811
+ "psr",
812
+ "psr-3"
813
+ ],
814
+ "time": "2016-10-10 12:19:37"
815
+ },
816
+ {
817
+ "name": "ptrofimov/xpmock",
818
+ "version": "1.1.5",
819
+ "source": {
820
+ "type": "git",
821
+ "url": "https://github.com/ptrofimov/xpmock.git",
822
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e"
823
+ },
824
+ "dist": {
825
+ "type": "zip",
826
+ "url": "https://api.github.com/repos/ptrofimov/xpmock/zipball/5b95ace33624b66bf4e854071b8856722fde515e",
827
+ "reference": "5b95ace33624b66bf4e854071b8856722fde515e",
828
+ "shasum": ""
829
+ },
830
+ "require": {
831
+ "php": ">=5.3.0"
832
+ },
833
+ "require-dev": {
834
+ "phpunit/phpunit": "3.7.*"
835
+ },
836
+ "type": "library",
837
+ "autoload": {
838
+ "psr-0": {
839
+ "Xpmock": "src"
840
+ }
841
+ },
842
+ "notification-url": "https://packagist.org/downloads/",
843
+ "license": [
844
+ "MIT"
845
+ ],
846
+ "description": "PHPUnit: simple syntax to create mock-objects",
847
+ "time": "2014-01-02 16:42:27"
848
+ },
849
+ {
850
+ "name": "sebastian/comparator",
851
+ "version": "dev-master",
852
+ "source": {
853
+ "type": "git",
854
+ "url": "https://github.com/sebastianbergmann/comparator.git",
855
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f"
856
+ },
857
+ "dist": {
858
+ "type": "zip",
859
+ "url": "https://api.github.com/repos/sebastianbergmann/comparator/zipball/21400bd9503c3782f5ee80349117483dcf8cec3f",
860
+ "reference": "21400bd9503c3782f5ee80349117483dcf8cec3f",
861
+ "shasum": ""
862
+ },
863
+ "require": {
864
+ "php": ">=5.3.3",
865
+ "sebastian/diff": "~1.2",
866
+ "sebastian/exporter": "~1.2"
867
+ },
868
+ "require-dev": {
869
+ "phpunit/phpunit": "~4.4"
870
+ },
871
+ "type": "library",
872
+ "extra": {
873
+ "branch-alias": {
874
+ "dev-master": "1.2.x-dev"
875
+ }
876
+ },
877
+ "autoload": {
878
+ "classmap": [
879
+ "src/"
880
+ ]
881
+ },
882
+ "notification-url": "https://packagist.org/downloads/",
883
+ "license": [
884
+ "BSD-3-Clause"
885
+ ],
886
+ "authors": [
887
+ {
888
+ "name": "Jeff Welch",
889
+ "email": "whatthejeff@gmail.com"
890
+ },
891
+ {
892
+ "name": "Volker Dusch",
893
+ "email": "github@wallbash.com"
894
+ },
895
+ {
896
+ "name": "Bernhard Schussek",
897
+ "email": "bschussek@2bepublished.at"
898
+ },
899
+ {
900
+ "name": "Sebastian Bergmann",
901
+ "email": "sebastian@phpunit.de"
902
+ }
903
+ ],
904
+ "description": "Provides the functionality to compare PHP values for equality",
905
+ "homepage": "http://www.github.com/sebastianbergmann/comparator",
906
+ "keywords": [
907
+ "comparator",
908
+ "compare",
909
+ "equality"
910
+ ],
911
+ "time": "2016-10-03 07:45:42"
912
+ },
913
+ {
914
+ "name": "sebastian/diff",
915
+ "version": "dev-master",
916
+ "source": {
917
+ "type": "git",
918
+ "url": "https://github.com/sebastianbergmann/diff.git",
919
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
920
+ },
921
+ "dist": {
922
+ "type": "zip",
923
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
924
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
925
+ "shasum": ""
926
+ },
927
+ "require": {
928
+ "php": ">=5.3.3"
929
+ },
930
+ "require-dev": {
931
+ "phpunit/phpunit": "~4.8"
932
+ },
933
+ "type": "library",
934
+ "extra": {
935
+ "branch-alias": {
936
+ "dev-master": "1.4-dev"
937
+ }
938
+ },
939
+ "autoload": {
940
+ "classmap": [
941
+ "src/"
942
+ ]
943
+ },
944
+ "notification-url": "https://packagist.org/downloads/",
945
+ "license": [
946
+ "BSD-3-Clause"
947
+ ],
948
+ "authors": [
949
+ {
950
+ "name": "Kore Nordmann",
951
+ "email": "mail@kore-nordmann.de"
952
+ },
953
+ {
954
+ "name": "Sebastian Bergmann",
955
+ "email": "sebastian@phpunit.de"
956
+ }
957
+ ],
958
+ "description": "Diff implementation",
959
+ "homepage": "https://github.com/sebastianbergmann/diff",
960
+ "keywords": [
961
+ "diff"
962
+ ],
963
+ "time": "2016-10-03 07:45:03"
964
+ },
965
+ {
966
+ "name": "sebastian/environment",
967
+ "version": "1.3.x-dev",
968
+ "source": {
969
+ "type": "git",
970
+ "url": "https://github.com/sebastianbergmann/environment.git",
971
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea"
972
+ },
973
+ "dist": {
974
+ "type": "zip",
975
+ "url": "https://api.github.com/repos/sebastianbergmann/environment/zipball/be2c607e43ce4c89ecd60e75c6a85c126e754aea",
976
+ "reference": "be2c607e43ce4c89ecd60e75c6a85c126e754aea",
977
+ "shasum": ""
978
+ },
979
+ "require": {
980
+ "php": "^5.3.3 || ^7.0"
981
+ },
982
+ "require-dev": {
983
+ "phpunit/phpunit": "^4.8 || ^5.0"
984
+ },
985
+ "type": "library",
986
+ "extra": {
987
+ "branch-alias": {
988
+ "dev-master": "1.3.x-dev"
989
+ }
990
+ },
991
+ "autoload": {
992
+ "classmap": [
993
+ "src/"
994
+ ]
995
+ },
996
+ "notification-url": "https://packagist.org/downloads/",
997
+ "license": [
998
+ "BSD-3-Clause"
999
+ ],
1000
+ "authors": [
1001
+ {
1002
+ "name": "Sebastian Bergmann",
1003
+ "email": "sebastian@phpunit.de"
1004
+ }
1005
+ ],
1006
+ "description": "Provides functionality to handle HHVM/PHP environments",
1007
+ "homepage": "http://www.github.com/sebastianbergmann/environment",
1008
+ "keywords": [
1009
+ "Xdebug",
1010
+ "environment",
1011
+ "hhvm"
1012
+ ],
1013
+ "time": "2016-08-18 05:49:44"
1014
+ },
1015
+ {
1016
+ "name": "sebastian/exporter",
1017
+ "version": "dev-master",
1018
+ "source": {
1019
+ "type": "git",
1020
+ "url": "https://github.com/sebastianbergmann/exporter.git",
1021
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d"
1022
+ },
1023
+ "dist": {
1024
+ "type": "zip",
1025
+ "url": "https://api.github.com/repos/sebastianbergmann/exporter/zipball/7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1026
+ "reference": "7dfcd2418aacbdb5e123fb23ac735acfdd6c588d",
1027
+ "shasum": ""
1028
+ },
1029
+ "require": {
1030
+ "php": ">=5.3.3",
1031
+ "sebastian/recursion-context": "~1.0"
1032
+ },
1033
+ "require-dev": {
1034
+ "ext-mbstring": "*",
1035
+ "phpunit/phpunit": "~4.4"
1036
+ },
1037
+ "type": "library",
1038
+ "extra": {
1039
+ "branch-alias": {
1040
+ "dev-master": "1.3.x-dev"
1041
+ }
1042
+ },
1043
+ "autoload": {
1044
+ "classmap": [
1045
+ "src/"
1046
+ ]
1047
+ },
1048
+ "notification-url": "https://packagist.org/downloads/",
1049
+ "license": [
1050
+ "BSD-3-Clause"
1051
+ ],
1052
+ "authors": [
1053
+ {
1054
+ "name": "Jeff Welch",
1055
+ "email": "whatthejeff@gmail.com"
1056
+ },
1057
+ {
1058
+ "name": "Volker Dusch",
1059
+ "email": "github@wallbash.com"
1060
+ },
1061
+ {
1062
+ "name": "Bernhard Schussek",
1063
+ "email": "bschussek@2bepublished.at"
1064
+ },
1065
+ {
1066
+ "name": "Sebastian Bergmann",
1067
+ "email": "sebastian@phpunit.de"
1068
+ },
1069
+ {
1070
+ "name": "Adam Harvey",
1071
+ "email": "aharvey@php.net"
1072
+ }
1073
+ ],
1074
+ "description": "Provides the functionality to export PHP variables for visualization",
1075
+ "homepage": "http://www.github.com/sebastianbergmann/exporter",
1076
+ "keywords": [
1077
+ "export",
1078
+ "exporter"
1079
+ ],
1080
+ "time": "2016-10-03 07:44:30"
1081
+ },
1082
+ {
1083
+ "name": "sebastian/global-state",
1084
+ "version": "1.1.1",
1085
+ "source": {
1086
+ "type": "git",
1087
+ "url": "https://github.com/sebastianbergmann/global-state.git",
1088
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4"
1089
+ },
1090
+ "dist": {
1091
+ "type": "zip",
1092
+ "url": "https://api.github.com/repos/sebastianbergmann/global-state/zipball/bc37d50fea7d017d3d340f230811c9f1d7280af4",
1093
+ "reference": "bc37d50fea7d017d3d340f230811c9f1d7280af4",
1094
+ "shasum": ""
1095
+ },
1096
+ "require": {
1097
+ "php": ">=5.3.3"
1098
+ },
1099
+ "require-dev": {
1100
+ "phpunit/phpunit": "~4.2"
1101
+ },
1102
+ "suggest": {
1103
+ "ext-uopz": "*"
1104
+ },
1105
+ "type": "library",
1106
+ "extra": {
1107
+ "branch-alias": {
1108
+ "dev-master": "1.0-dev"
1109
+ }
1110
+ },
1111
+ "autoload": {
1112
+ "classmap": [
1113
+ "src/"
1114
+ ]
1115
+ },
1116
+ "notification-url": "https://packagist.org/downloads/",
1117
+ "license": [
1118
+ "BSD-3-Clause"
1119
+ ],
1120
+ "authors": [
1121
+ {
1122
+ "name": "Sebastian Bergmann",
1123
+ "email": "sebastian@phpunit.de"
1124
+ }
1125
+ ],
1126
+ "description": "Snapshotting of global state",
1127
+ "homepage": "http://www.github.com/sebastianbergmann/global-state",
1128
+ "keywords": [
1129
+ "global state"
1130
+ ],
1131
+ "time": "2015-10-12 03:26:01"
1132
+ },
1133
+ {
1134
+ "name": "sebastian/recursion-context",
1135
+ "version": "dev-master",
1136
+ "source": {
1137
+ "type": "git",
1138
+ "url": "https://github.com/sebastianbergmann/recursion-context.git",
1139
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7"
1140
+ },
1141
+ "dist": {
1142
+ "type": "zip",
1143
+ "url": "https://api.github.com/repos/sebastianbergmann/recursion-context/zipball/b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1144
+ "reference": "b19cc3298482a335a95f3016d2f8a6950f0fbcd7",
1145
+ "shasum": ""
1146
+ },
1147
+ "require": {
1148
+ "php": ">=5.3.3"
1149
+ },
1150
+ "require-dev": {
1151
+ "phpunit/phpunit": "~4.4"
1152
+ },
1153
+ "type": "library",
1154
+ "extra": {
1155
+ "branch-alias": {
1156
+ "dev-master": "1.0.x-dev"
1157
+ }
1158
+ },
1159
+ "autoload": {
1160
+ "classmap": [
1161
+ "src/"
1162
+ ]
1163
+ },
1164
+ "notification-url": "https://packagist.org/downloads/",
1165
+ "license": [
1166
+ "BSD-3-Clause"
1167
+ ],
1168
+ "authors": [
1169
+ {
1170
+ "name": "Jeff Welch",
1171
+ "email": "whatthejeff@gmail.com"
1172
+ },
1173
+ {
1174
+ "name": "Sebastian Bergmann",
1175
+ "email": "sebastian@phpunit.de"
1176
+ },
1177
+ {
1178
+ "name": "Adam Harvey",
1179
+ "email": "aharvey@php.net"
1180
+ }
1181
+ ],
1182
+ "description": "Provides functionality to recursively process PHP variables",
1183
+ "homepage": "http://www.github.com/sebastianbergmann/recursion-context",
1184
+ "time": "2016-10-03 07:41:43"
1185
+ },
1186
+ {
1187
+ "name": "sebastian/version",
1188
+ "version": "1.0.6",
1189
+ "source": {
1190
+ "type": "git",
1191
+ "url": "https://github.com/sebastianbergmann/version.git",
1192
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6"
1193
+ },
1194
+ "dist": {
1195
+ "type": "zip",
1196
+ "url": "https://api.github.com/repos/sebastianbergmann/version/zipball/58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1197
+ "reference": "58b3a85e7999757d6ad81c787a1fbf5ff6c628c6",
1198
+ "shasum": ""
1199
+ },
1200
+ "type": "library",
1201
+ "autoload": {
1202
+ "classmap": [
1203
+ "src/"
1204
+ ]
1205
+ },
1206
+ "notification-url": "https://packagist.org/downloads/",
1207
+ "license": [
1208
+ "BSD-3-Clause"
1209
+ ],
1210
+ "authors": [
1211
+ {
1212
+ "name": "Sebastian Bergmann",
1213
+ "email": "sebastian@phpunit.de",
1214
+ "role": "lead"
1215
+ }
1216
+ ],
1217
+ "description": "Library that helps with managing the version number of Git-hosted PHP projects",
1218
+ "homepage": "https://github.com/sebastianbergmann/version",
1219
+ "time": "2015-06-21 13:59:46"
1220
+ },
1221
+ {
1222
+ "name": "symfony/console",
1223
+ "version": "2.8.x-dev",
1224
+ "source": {
1225
+ "type": "git",
1226
+ "url": "https://github.com/symfony/console.git",
1227
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71"
1228
+ },
1229
+ "dist": {
1230
+ "type": "zip",
1231
+ "url": "https://api.github.com/repos/symfony/console/zipball/ddb26174398f48486ac4231dc4f4cb27c3acba71",
1232
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71",
1233
+ "shasum": ""
1234
+ },
1235
+ "require": {
1236
+ "php": ">=5.3.9",
1237
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
1238
+ "symfony/polyfill-mbstring": "~1.0"
1239
+ },
1240
+ "require-dev": {
1241
+ "psr/log": "~1.0",
1242
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
1243
+ "symfony/process": "~2.1|~3.0.0"
1244
+ },
1245
+ "suggest": {
1246
+ "psr/log": "For using the console logger",
1247
+ "symfony/event-dispatcher": "",
1248
+ "symfony/process": ""
1249
+ },
1250
+ "type": "library",
1251
+ "extra": {
1252
+ "branch-alias": {
1253
+ "dev-master": "2.8-dev"
1254
+ }
1255
+ },
1256
+ "autoload": {
1257
+ "psr-4": {
1258
+ "Symfony\\Component\\Console\\": ""
1259
+ },
1260
+ "exclude-from-classmap": [
1261
+ "/Tests/"
1262
+ ]
1263
+ },
1264
+ "notification-url": "https://packagist.org/downloads/",
1265
+ "license": [
1266
+ "MIT"
1267
+ ],
1268
+ "authors": [
1269
+ {
1270
+ "name": "Fabien Potencier",
1271
+ "email": "fabien@symfony.com"
1272
+ },
1273
+ {
1274
+ "name": "Symfony Community",
1275
+ "homepage": "https://symfony.com/contributors"
1276
+ }
1277
+ ],
1278
+ "description": "Symfony Console Component",
1279
+ "homepage": "https://symfony.com",
1280
+ "time": "2016-11-04 17:49:05"
1281
+ },
1282
+ {
1283
+ "name": "symfony/debug",
1284
+ "version": "2.8.x-dev",
1285
+ "source": {
1286
+ "type": "git",
1287
+ "url": "https://github.com/symfony/debug.git",
1288
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888"
1289
+ },
1290
+ "dist": {
1291
+ "type": "zip",
1292
+ "url": "https://api.github.com/repos/symfony/debug/zipball/d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1293
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
1294
+ "shasum": ""
1295
+ },
1296
+ "require": {
1297
+ "php": ">=5.3.9",
1298
+ "psr/log": "~1.0"
1299
+ },
1300
+ "conflict": {
1301
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
1302
+ },
1303
+ "require-dev": {
1304
+ "symfony/class-loader": "~2.2|~3.0.0",
1305
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
1306
+ },
1307
+ "type": "library",
1308
+ "extra": {
1309
+ "branch-alias": {
1310
+ "dev-master": "2.8-dev"
1311
+ }
1312
+ },
1313
+ "autoload": {
1314
+ "psr-4": {
1315
+ "Symfony\\Component\\Debug\\": ""
1316
+ },
1317
+ "exclude-from-classmap": [
1318
+ "/Tests/"
1319
+ ]
1320
+ },
1321
+ "notification-url": "https://packagist.org/downloads/",
1322
+ "license": [
1323
+ "MIT"
1324
+ ],
1325
+ "authors": [
1326
+ {
1327
+ "name": "Fabien Potencier",
1328
+ "email": "fabien@symfony.com"
1329
+ },
1330
+ {
1331
+ "name": "Symfony Community",
1332
+ "homepage": "https://symfony.com/contributors"
1333
+ }
1334
+ ],
1335
+ "description": "Symfony Debug Component",
1336
+ "homepage": "https://symfony.com",
1337
+ "time": "2016-11-03 07:52:58"
1338
+ },
1339
+ {
1340
+ "name": "symfony/event-dispatcher",
1341
+ "version": "2.8.x-dev",
1342
+ "source": {
1343
+ "type": "git",
1344
+ "url": "https://github.com/symfony/event-dispatcher.git",
1345
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
1346
+ },
1347
+ "dist": {
1348
+ "type": "zip",
1349
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1350
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
1351
+ "shasum": ""
1352
+ },
1353
+ "require": {
1354
+ "php": ">=5.3.9"
1355
+ },
1356
+ "require-dev": {
1357
+ "psr/log": "~1.0",
1358
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
1359
+ "symfony/dependency-injection": "~2.6|~3.0.0",
1360
+ "symfony/expression-language": "~2.6|~3.0.0",
1361
+ "symfony/stopwatch": "~2.3|~3.0.0"
1362
+ },
1363
+ "suggest": {
1364
+ "symfony/dependency-injection": "",
1365
+ "symfony/http-kernel": ""
1366
+ },
1367
+ "type": "library",
1368
+ "extra": {
1369
+ "branch-alias": {
1370
+ "dev-master": "2.8-dev"
1371
+ }
1372
+ },
1373
+ "autoload": {
1374
+ "psr-4": {
1375
+ "Symfony\\Component\\EventDispatcher\\": ""
1376
+ },
1377
+ "exclude-from-classmap": [
1378
+ "/Tests/"
1379
+ ]
1380
+ },
1381
+ "notification-url": "https://packagist.org/downloads/",
1382
+ "license": [
1383
+ "MIT"
1384
+ ],
1385
+ "authors": [
1386
+ {
1387
+ "name": "Fabien Potencier",
1388
+ "email": "fabien@symfony.com"
1389
+ },
1390
+ {
1391
+ "name": "Symfony Community",
1392
+ "homepage": "https://symfony.com/contributors"
1393
+ }
1394
+ ],
1395
+ "description": "Symfony EventDispatcher Component",
1396
+ "homepage": "https://symfony.com",
1397
+ "time": "2016-10-13 01:43:15"
1398
+ },
1399
+ {
1400
+ "name": "symfony/filesystem",
1401
+ "version": "2.8.x-dev",
1402
+ "source": {
1403
+ "type": "git",
1404
+ "url": "https://github.com/symfony/filesystem.git",
1405
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898"
1406
+ },
1407
+ "dist": {
1408
+ "type": "zip",
1409
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898",
1410
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898",
1411
+ "shasum": ""
1412
+ },
1413
+ "require": {
1414
+ "php": ">=5.3.9"
1415
+ },
1416
+ "type": "library",
1417
+ "extra": {
1418
+ "branch-alias": {
1419
+ "dev-master": "2.8-dev"
1420
+ }
1421
+ },
1422
+ "autoload": {
1423
+ "psr-4": {
1424
+ "Symfony\\Component\\Filesystem\\": ""
1425
+ },
1426
+ "exclude-from-classmap": [
1427
+ "/Tests/"
1428
+ ]
1429
+ },
1430
+ "notification-url": "https://packagist.org/downloads/",
1431
+ "license": [
1432
+ "MIT"
1433
+ ],
1434
+ "authors": [
1435
+ {
1436
+ "name": "Fabien Potencier",
1437
+ "email": "fabien@symfony.com"
1438
+ },
1439
+ {
1440
+ "name": "Symfony Community",
1441
+ "homepage": "https://symfony.com/contributors"
1442
+ }
1443
+ ],
1444
+ "description": "Symfony Filesystem Component",
1445
+ "homepage": "https://symfony.com",
1446
+ "time": "2016-10-18 04:28:30"
1447
+ },
1448
+ {
1449
+ "name": "symfony/finder",
1450
+ "version": "2.8.x-dev",
1451
+ "source": {
1452
+ "type": "git",
1453
+ "url": "https://github.com/symfony/finder.git",
1454
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd"
1455
+ },
1456
+ "dist": {
1457
+ "type": "zip",
1458
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0023b024363dfc0cd21262e556f25a291fe8d7fd",
1459
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd",
1460
+ "shasum": ""
1461
+ },
1462
+ "require": {
1463
+ "php": ">=5.3.9"
1464
+ },
1465
+ "type": "library",
1466
+ "extra": {
1467
+ "branch-alias": {
1468
+ "dev-master": "2.8-dev"
1469
+ }
1470
+ },
1471
+ "autoload": {
1472
+ "psr-4": {
1473
+ "Symfony\\Component\\Finder\\": ""
1474
+ },
1475
+ "exclude-from-classmap": [
1476
+ "/Tests/"
1477
+ ]
1478
+ },
1479
+ "notification-url": "https://packagist.org/downloads/",
1480
+ "license": [
1481
+ "MIT"
1482
+ ],
1483
+ "authors": [
1484
+ {
1485
+ "name": "Fabien Potencier",
1486
+ "email": "fabien@symfony.com"
1487
+ },
1488
+ {
1489
+ "name": "Symfony Community",
1490
+ "homepage": "https://symfony.com/contributors"
1491
+ }
1492
+ ],
1493
+ "description": "Symfony Finder Component",
1494
+ "homepage": "https://symfony.com",
1495
+ "time": "2016-11-03 07:52:58"
1496
+ },
1497
+ {
1498
+ "name": "symfony/polyfill-mbstring",
1499
+ "version": "dev-master",
1500
+ "source": {
1501
+ "type": "git",
1502
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
1503
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c"
1504
+ },
1505
+ "dist": {
1506
+ "type": "zip",
1507
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1508
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
1509
+ "shasum": ""
1510
+ },
1511
+ "require": {
1512
+ "php": ">=5.3.3"
1513
+ },
1514
+ "suggest": {
1515
+ "ext-mbstring": "For best performance"
1516
+ },
1517
+ "type": "library",
1518
+ "extra": {
1519
+ "branch-alias": {
1520
+ "dev-master": "1.2-dev"
1521
+ }
1522
+ },
1523
+ "autoload": {
1524
+ "psr-4": {
1525
+ "Symfony\\Polyfill\\Mbstring\\": ""
1526
+ },
1527
+ "files": [
1528
+ "bootstrap.php"
1529
+ ]
1530
+ },
1531
+ "notification-url": "https://packagist.org/downloads/",
1532
+ "license": [
1533
+ "MIT"
1534
+ ],
1535
+ "authors": [
1536
+ {
1537
+ "name": "Nicolas Grekas",
1538
+ "email": "p@tchwork.com"
1539
+ },
1540
+ {
1541
+ "name": "Symfony Community",
1542
+ "homepage": "https://symfony.com/contributors"
1543
+ }
1544
+ ],
1545
+ "description": "Symfony polyfill for the Mbstring extension",
1546
+ "homepage": "https://symfony.com",
1547
+ "keywords": [
1548
+ "compatibility",
1549
+ "mbstring",
1550
+ "polyfill",
1551
+ "portable",
1552
+ "shim"
1553
+ ],
1554
+ "time": "2016-08-30 17:06:17"
1555
+ },
1556
+ {
1557
+ "name": "symfony/process",
1558
+ "version": "2.8.x-dev",
1559
+ "source": {
1560
+ "type": "git",
1561
+ "url": "https://github.com/symfony/process.git",
1562
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
1563
+ },
1564
+ "dist": {
1565
+ "type": "zip",
1566
+ "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1567
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
1568
+ "shasum": ""
1569
+ },
1570
+ "require": {
1571
+ "php": ">=5.3.9"
1572
+ },
1573
+ "type": "library",
1574
+ "extra": {
1575
+ "branch-alias": {
1576
+ "dev-master": "2.8-dev"
1577
+ }
1578
+ },
1579
+ "autoload": {
1580
+ "psr-4": {
1581
+ "Symfony\\Component\\Process\\": ""
1582
+ },
1583
+ "exclude-from-classmap": [
1584
+ "/Tests/"
1585
+ ]
1586
+ },
1587
+ "notification-url": "https://packagist.org/downloads/",
1588
+ "license": [
1589
+ "MIT"
1590
+ ],
1591
+ "authors": [
1592
+ {
1593
+ "name": "Fabien Potencier",
1594
+ "email": "fabien@symfony.com"
1595
+ },
1596
+ {
1597
+ "name": "Symfony Community",
1598
+ "homepage": "https://symfony.com/contributors"
1599
+ }
1600
+ ],
1601
+ "description": "Symfony Process Component",
1602
+ "homepage": "https://symfony.com",
1603
+ "time": "2016-09-29 14:03:54"
1604
+ },
1605
+ {
1606
+ "name": "symfony/stopwatch",
1607
+ "version": "2.8.x-dev",
1608
+ "source": {
1609
+ "type": "git",
1610
+ "url": "https://github.com/symfony/stopwatch.git",
1611
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca"
1612
+ },
1613
+ "dist": {
1614
+ "type": "zip",
1615
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
1616
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca",
1617
+ "shasum": ""
1618
+ },
1619
+ "require": {
1620
+ "php": ">=5.3.9"
1621
+ },
1622
+ "type": "library",
1623
+ "extra": {
1624
+ "branch-alias": {
1625
+ "dev-master": "2.8-dev"
1626
+ }
1627
+ },
1628
+ "autoload": {
1629
+ "psr-4": {
1630
+ "Symfony\\Component\\Stopwatch\\": ""
1631
+ },
1632
+ "exclude-from-classmap": [
1633
+ "/Tests/"
1634
+ ]
1635
+ },
1636
+ "notification-url": "https://packagist.org/downloads/",
1637
+ "license": [
1638
+ "MIT"
1639
+ ],
1640
+ "authors": [
1641
+ {
1642
+ "name": "Fabien Potencier",
1643
+ "email": "fabien@symfony.com"
1644
+ },
1645
+ {
1646
+ "name": "Symfony Community",
1647
+ "homepage": "https://symfony.com/contributors"
1648
+ }
1649
+ ],
1650
+ "description": "Symfony Stopwatch Component",
1651
+ "homepage": "https://symfony.com",
1652
+ "time": "2016-06-29 05:29:29"
1653
+ },
1654
+ {
1655
+ "name": "symfony/yaml",
1656
+ "version": "2.8.x-dev",
1657
+ "source": {
1658
+ "type": "git",
1659
+ "url": "https://github.com/symfony/yaml.git",
1660
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb"
1661
+ },
1662
+ "dist": {
1663
+ "type": "zip",
1664
+ "url": "https://api.github.com/repos/symfony/yaml/zipball/58666e4ac3a2d378798f020308b35a75ffbeaafb",
1665
+ "reference": "58666e4ac3a2d378798f020308b35a75ffbeaafb",
1666
+ "shasum": ""
1667
+ },
1668
+ "require": {
1669
+ "php": ">=5.3.9"
1670
+ },
1671
+ "type": "library",
1672
+ "extra": {
1673
+ "branch-alias": {
1674
+ "dev-master": "2.8-dev"
1675
+ }
1676
+ },
1677
+ "autoload": {
1678
+ "psr-4": {
1679
+ "Symfony\\Component\\Yaml\\": ""
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 Yaml Component",
1700
+ "homepage": "https://symfony.com",
1701
+ "time": "2016-11-03 07:52:58"
1702
+ }
1703
+ ],
1704
+ "aliases": [],
1705
+ "minimum-stability": "dev",
1706
+ "stability-flags": {
1707
+ "dhii/php-cs-fixer-config": 20
1708
+ },
1709
+ "prefer-stable": false,
1710
+ "prefer-lowest": false,
1711
+ "platform": [],
1712
+ "platform-dev": []
1713
+ }
vendor/dhii/stats-abstract/nbproject/project.properties ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ file.reference.stats-abstract-vendor=vendor
13
+ file.reference.test-functional=test/functional
14
+ include.path=\
15
+ ${php.global.include.path}:\
16
+ ${file.reference.stats-abstract-vendor}
17
+ php.version=PHP_53
18
+ source.encoding=UTF-8
19
+ src.dir=src
20
+ tags.asp=false
21
+ tags.short=false
22
+ test.src.dir=${file.reference.test-functional}
23
+ testing.providers=PhpUnit
24
+ web.root=.
vendor/dhii/stats-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 - stats-abstract</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/stats-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/stats-abstract/src/AbstractAggregatableCollection.php ADDED
@@ -0,0 +1,156 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Stats;
4
+
5
+ use Dhii\Collection;
6
+
7
+ /**
8
+ * Common functionality for collections that can be aggregated.
9
+ *
10
+ * Aggregation is the process of producing totals from the elements of a collection.
11
+ *
12
+ * @since 0.1.0
13
+ */
14
+ abstract class AbstractAggregatableCollection extends Collection\AbstractIterableCollection
15
+ {
16
+ protected $stats;
17
+ protected $statAggregator;
18
+
19
+ /**
20
+ * Retrieve the instance of the stat aggregator which will aggregate stats for this instance.
21
+ *
22
+ * @since 0.1.0
23
+ *
24
+ * @return AggregatorInterface
25
+ */
26
+ protected function _getStatAggregator()
27
+ {
28
+ return $this->statAggregator;
29
+ }
30
+
31
+ /**
32
+ * Sets the stats aggregator to be used by this instance for calculating totals.
33
+ *
34
+ * @since 0.1.0
35
+ *
36
+ * @param AggregatorInterface $aggregator The stats aggregator for this instance to use.
37
+ *
38
+ * @return AbstractResultSet This instance.
39
+ */
40
+ protected function _setStatAggregator(AggregatorInterface $aggregator)
41
+ {
42
+ $this->statAggregator = $aggregator;
43
+
44
+ return $this;
45
+ }
46
+
47
+ /**
48
+ * Low-level retrieval of stat values.
49
+ *
50
+ * Operates on raw values, no cache is generated.
51
+ *
52
+ * @since 0.1.0
53
+ *
54
+ * @param string|null $code The code of the stat, the value for which to retrieve.
55
+ * If null, retrieve all stats.
56
+ *
57
+ * @return mixed[]|mixed|null If a code is supplied, retrieves the stat value for that code, or null if no stat with that code.
58
+ * Otherwise, a map of all stat codes to their values, or null if no stats have been aggregated.
59
+ */
60
+ protected function _getStatsValue($code = null)
61
+ {
62
+ if (is_null($code)) {
63
+ return $this->stats;
64
+ }
65
+
66
+ return isset($this->stats[$code])
67
+ ? $this->stats[$code]
68
+ : null;
69
+ }
70
+
71
+ /**
72
+ * Low-level assignment of stat values.
73
+ *
74
+ * Assigns all values in one go, or one at a time.
75
+ *
76
+ * @since 0.1.0
77
+ *
78
+ * @param mixed[]|string $stats An map of stat names to stat values, or a stat code.
79
+ * @param mixed $value If a stat code is specified, its value will be set to this.
80
+ *
81
+ * @return AbstractAggregatableCollection This instance.
82
+ */
83
+ protected function _setStatsValue($stats, $value = null)
84
+ {
85
+ if (is_array($stats)) {
86
+ $this->stats = $stats;
87
+
88
+ return $this;
89
+ }
90
+
91
+ if (!is_array($this->stats)) {
92
+ $this->stats = array();
93
+ }
94
+
95
+ $this->stats[$stats] = $value;
96
+
97
+ return $this;
98
+ }
99
+
100
+ /**
101
+ * Clears stat cache.
102
+ *
103
+ * After this, retrieval of a stat value will trigger generation of cache.
104
+ *
105
+ * @since 0.1.0
106
+ *
107
+ * @return AbstractAggregatableCollection This instance.
108
+ */
109
+ protected function _resetStats()
110
+ {
111
+ $this->stats = null;
112
+
113
+ return $this;
114
+ }
115
+
116
+ /**
117
+ * Retrieve codes for stats that should be aggregated from this collection's items.
118
+ *
119
+ * @since 0.1.0
120
+ *
121
+ * @return string[] An array of stat codes.
122
+ */
123
+ protected function _getAggregatableStatCodes()
124
+ {
125
+ return array();
126
+ }
127
+
128
+ /**
129
+ * Get one or all stat values.
130
+ *
131
+ * If no cached values available, triggers their generation.
132
+ *
133
+ * @since 0.1.0
134
+ *
135
+ * @param string|null $code The code, for which to retrieve the stat value.
136
+ * If null, all stats will be retrieved.
137
+ *
138
+ * @return mixed[]|mixed A stat value, or a map of stat codes to values.
139
+ */
140
+ protected function _getStats($code = null)
141
+ {
142
+ if (is_null($this->stats)) {
143
+ $this->stats = $this->_getStatAggregator()->aggregate(
144
+ $this->_getAggregatableStatCodes(),
145
+ $this->_getCachedItems());
146
+ }
147
+
148
+ if (is_null($code)) {
149
+ return $this->stats;
150
+ }
151
+
152
+ return isset($this->stats[$code])
153
+ ? $this->stats[$code]
154
+ : null;
155
+ }
156
+ }
vendor/dhii/stats-abstract/src/AbstractAggregator.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Stats;
4
+
5
+ use RuntimeException;
6
+
7
+ /**
8
+ * Common functionality for stats aggregators.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ abstract class AbstractAggregator implements AggregatorInterface
13
+ {
14
+ /**
15
+ * {@inheritdoc}
16
+ *
17
+ * @since 0.1.0
18
+ *
19
+ * @param mixed[] $totals Current totals. Totals will only be aggregated for codes contained here.
20
+ * This allows adding new totals to existing ones.
21
+ * For totals that don't yet exist, it's possible to specify them as values. Example:
22
+ * `array('existing_total' => 123, 'other_new_total')`
23
+ * @param mixed[]|\Traversable $items The items, which to aggregate from.
24
+ *
25
+ * @return mixed[] The new totals.
26
+ */
27
+ public function aggregate($totals, $items)
28
+ {
29
+ $totals = $this->_normalizeTotals($totals);
30
+ $calculators = $this->_getCalculators();
31
+ $stats = $this->_aggregateStats($totals, $items, $calculators);
32
+
33
+ return $stats;
34
+ }
35
+
36
+ /**
37
+ * Normalizes totals.
38
+ *
39
+ * If the given totals contain numeric keys, the result will have the values of those keys as keys.
40
+ * Null values will be added where stats are missing.
41
+ *
42
+ * Example:
43
+ * `array('my_stat' => 123, 'other_stat');`
44
+ * becomes
45
+ * `array('my_stat' => 123, 'other_stat' => null)`
46
+ *
47
+ * @since 0.1.0
48
+ *
49
+ * @param mixed[] $totals The totals to normalize.
50
+ *
51
+ * @return mixed[] An array where keys are stat names and values are stat values.
52
+ */
53
+ protected function _normalizeTotals($totals)
54
+ {
55
+ $newTotals = array();
56
+ foreach ($totals as $_stat => $_total) {
57
+ if (is_numeric($_stat)) {
58
+ $_stat = $_total;
59
+ }
60
+
61
+ $newTotals[$_stat] = isset($totals[$_stat])
62
+ ? $totals[$_stat]
63
+ : null;
64
+ }
65
+
66
+ return $newTotals;
67
+ }
68
+
69
+ /**
70
+ * Aggregates stats by applying appropriate calculators to all items.
71
+ *
72
+ * @since 0.1.0
73
+ *
74
+ * @param mixed[] $totals Existing totals map, where key is stat name, and value is stat value.
75
+ * @param mixed[]|\Traversable $items A list of items to aggregate stats from.
76
+ * @param callable[] $calculators A map of calculators, where key is stat name, and value is a callable calculator.
77
+ *
78
+ * @throws RuntimeException If an aggregator is missing for a stat.
79
+ *
80
+ * @return mixed[] Aggregated stats.
81
+ */
82
+ protected function _aggregateStats($totals, $items, $calculators)
83
+ {
84
+ foreach ($items as $_item) {
85
+ foreach ($totals as $_stat => $_total) {
86
+ if (!isset($calculators[$_stat])) {
87
+ throw new RuntimeException(sprintf('Could not aggregate stat: No aggregator defined for stat "%1$s"', $_stat));
88
+ }
89
+
90
+ $totals[$_stat] = $this->_aggregateStat($totals, $_stat, $_item, $calculators[$_stat]);
91
+ }
92
+ }
93
+
94
+ return $totals;
95
+ }
96
+
97
+ /**
98
+ * Retrieve a map of available calculators.
99
+ *
100
+ * @since 0.1.0
101
+ *
102
+ * @return callable[] A map of calculators, where key is stat code, and value is a callable calculator.
103
+ */
104
+ protected function _getCalculators()
105
+ {
106
+ return array();
107
+ }
108
+
109
+ /**
110
+ * Aggregate a specific stat using an aggregator.
111
+ *
112
+ * @since 0.1.0
113
+ *
114
+ * @param mixed[] $totals Current totals. Keys are stat names, values are stat values.
115
+ * @param string $stat The code of the stat to aggregate.
116
+ * @param object|array $source The source of the stat, e.g. something from where to aggregate.
117
+ * @param callable $calculator The callable calculator that would deduce the new stat.
118
+ *
119
+ * @return mixed[] New stat value.
120
+ */
121
+ protected function _aggregateStat($totals, $stat, $source, $calculator)
122
+ {
123
+ return $this->_applyCalculator($totals, $stat, $source, $calculator);
124
+ }
125
+
126
+ /**
127
+ * Apply a stat aggregator to a set of totals.
128
+ *
129
+ * @since 0.1.0
130
+ *
131
+ * @param mixed[] $totals Current totals. Keys are stat names, values are stat values.
132
+ * @param string $stat The code of the stat to aggregate.
133
+ * @param object|array $source The source of the stat, e.g. something from where to aggregate.
134
+ * @param callable $calculator The callable calculator that would deduce the new stat.
135
+ *
136
+ * @return mixed[] New stat value.
137
+ */
138
+ protected function _applyCalculator($totals, $stat, $source, $calculator)
139
+ {
140
+ if (!is_callable($calculator)) {
141
+ throw new UnexpectedValueException(sprintf('Could not apply calculator for stat "%1$s": must be callable', $stat));
142
+ }
143
+
144
+ if (!isset($totals[$stat])) {
145
+ $totals[$stat] = 0;
146
+ }
147
+
148
+ return call_user_func_array($calculator, array($totals, $stat, $source));
149
+ }
150
+ }
vendor/dhii/stats-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/stats-abstract/test/functional/AbstractAggregatorTest.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Stats\FuncTest;
4
+
5
+ /**
6
+ * Tests {@see \Dhii\Stats\AbstractAggregator}.
7
+ *
8
+ * @since 0.1.0
9
+ */
10
+ class AbstractAggregatorTest extends \Xpmock\TestCase
11
+ {
12
+ /**
13
+ * @since 0.1.0
14
+ *
15
+ * @return \Dhii\Stats\AbstractAggregator
16
+ */
17
+ public function createInstance()
18
+ {
19
+ $mock = $this->mock('Dhii\\Stats\\AbstractAggregator')
20
+ ->_getCalculators(array(
21
+ 'count' => function($totals, $code, $source) {
22
+ return $totals[$code] + 1;
23
+ }
24
+ ))
25
+ ->new();
26
+
27
+ return $mock;
28
+ }
29
+
30
+ /**
31
+ * Tests that the aggregation of stats happens according to defined rules.
32
+ *
33
+ * @since 0.1.0
34
+ */
35
+ public function testAggregation()
36
+ {
37
+ $subject = $this->createInstance();
38
+ $data = array(
39
+ 'apple',
40
+ 'banana',
41
+ 'orange'
42
+ );
43
+
44
+ $result = $subject->aggregate(array('count'), $data);
45
+
46
+ $this->assertEquals(array('count' => 3), $result, 'Aggregated totals are incorrect');
47
+ }
48
+ }
vendor/dhii/stats-interface/.php_cs ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once __DIR__.DIRECTORY_SEPARATOR.'vendor/autoload.php';
4
+ $config = Dhii\Configuration\PHPCSFixer\Config::create();
5
+ $fixers = $config->getFixers();
6
+
7
+ $toRemove = array('short_array_syntax');
8
+ foreach ($toRemove as $_fixer) {
9
+ if (($removeIndex = array_search($_fixer, $fixers)) === false) {
10
+ continue;
11
+ }
12
+
13
+ unset($fixers[$removeIndex]);
14
+ }
15
+
16
+ $toAdd = array('long_array_syntax');
17
+ foreach ($toAdd as $_fixer) {
18
+ if (($removeIndex = array_search($_fixer, $fixers)) !== false) {
19
+ continue;
20
+ }
21
+
22
+ $fixers[] = $_fixer;
23
+ }
24
+
25
+ $config->fixers($fixers);
26
+ $config->getFinder()->in(__DIR__.DIRECTORY_SEPARATOR.'src');
27
+ return $config;
vendor/dhii/stats-interface/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
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.0 - 2016-11-10
8
+ The initial release
vendor/dhii/stats-interface/composer.json ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "dhii/stats-interface",
3
+ "description": "Interfaces for stats",
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
+ },
16
+ "require-dev": {
17
+ "dhii/php-cs-fixer-config": "dev-php-5.3"
18
+ },
19
+ "autoload": {
20
+ "psr-4": {
21
+ "Dhii\\Stats\\": "src/"
22
+ }
23
+ }
24
+ }
vendor/dhii/stats-interface/composer.lock ADDED
@@ -0,0 +1,653 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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": "e2a55f7fcdba19696c5b4928509dd6fe",
8
+ "content-hash": "7dd54334388df547c560f1c73a586b24",
9
+ "packages": [],
10
+ "packages-dev": [
11
+ {
12
+ "name": "dhii/php-cs-fixer-config",
13
+ "version": "dev-php-5.3",
14
+ "source": {
15
+ "type": "git",
16
+ "url": "https://github.com/Dhii/php-cs-fixer-config.git",
17
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca"
18
+ },
19
+ "dist": {
20
+ "type": "zip",
21
+ "url": "https://api.github.com/repos/Dhii/php-cs-fixer-config/zipball/ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
22
+ "reference": "ee3cc6c906a1aa4dca2bcbfcfef684dbd1ebb8ca",
23
+ "shasum": ""
24
+ },
25
+ "require": {
26
+ "friendsofphp/php-cs-fixer": ">=1.11 <1.12",
27
+ "php": "^5.3 | ^7.0"
28
+ },
29
+ "require-dev": {
30
+ "phpunit/phpunit": "^4.8"
31
+ },
32
+ "type": "library",
33
+ "autoload": {
34
+ "psr-4": {
35
+ "Dhii\\Configuration\\PHPCSFixer\\": "src/"
36
+ }
37
+ },
38
+ "notification-url": "https://packagist.org/downloads/",
39
+ "license": [
40
+ "MIT"
41
+ ],
42
+ "authors": [
43
+ {
44
+ "name": "Dhii Team",
45
+ "email": "development@dhii.co"
46
+ }
47
+ ],
48
+ "description": "A default PHP CS Fixer config implementation",
49
+ "time": "2016-09-03 14:45:03"
50
+ },
51
+ {
52
+ "name": "friendsofphp/php-cs-fixer",
53
+ "version": "1.11.x-dev",
54
+ "source": {
55
+ "type": "git",
56
+ "url": "https://github.com/FriendsOfPHP/PHP-CS-Fixer.git",
57
+ "reference": "117137e9970054d022b7656209f094dab852b90c"
58
+ },
59
+ "dist": {
60
+ "type": "zip",
61
+ "url": "https://api.github.com/repos/FriendsOfPHP/PHP-CS-Fixer/zipball/117137e9970054d022b7656209f094dab852b90c",
62
+ "reference": "117137e9970054d022b7656209f094dab852b90c",
63
+ "shasum": ""
64
+ },
65
+ "require": {
66
+ "ext-tokenizer": "*",
67
+ "php": ">=5.3.6",
68
+ "sebastian/diff": "~1.1",
69
+ "symfony/console": "~2.3|~3.0",
70
+ "symfony/event-dispatcher": "~2.1|~3.0",
71
+ "symfony/filesystem": "~2.1|~3.0",
72
+ "symfony/finder": "~2.1|~3.0",
73
+ "symfony/process": "~2.3|~3.0",
74
+ "symfony/stopwatch": "~2.5|~3.0"
75
+ },
76
+ "conflict": {
77
+ "hhvm": "<3.9"
78
+ },
79
+ "require-dev": {
80
+ "phpunit/phpunit": "^4.5|^5",
81
+ "satooshi/php-coveralls": "^0.7.1"
82
+ },
83
+ "bin": [
84
+ "php-cs-fixer"
85
+ ],
86
+ "type": "application",
87
+ "autoload": {
88
+ "psr-4": {
89
+ "Symfony\\CS\\": "Symfony/CS/"
90
+ }
91
+ },
92
+ "notification-url": "https://packagist.org/downloads/",
93
+ "license": [
94
+ "MIT"
95
+ ],
96
+ "authors": [
97
+ {
98
+ "name": "Dariusz Rumiński",
99
+ "email": "dariusz.ruminski@gmail.com"
100
+ },
101
+ {
102
+ "name": "Fabien Potencier",
103
+ "email": "fabien@symfony.com"
104
+ }
105
+ ],
106
+ "description": "A tool to automatically fix PHP code style",
107
+ "time": "2016-08-16 23:31:05"
108
+ },
109
+ {
110
+ "name": "psr/log",
111
+ "version": "dev-master",
112
+ "source": {
113
+ "type": "git",
114
+ "url": "https://github.com/php-fig/log.git",
115
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d"
116
+ },
117
+ "dist": {
118
+ "type": "zip",
119
+ "url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
120
+ "reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d",
121
+ "shasum": ""
122
+ },
123
+ "require": {
124
+ "php": ">=5.3.0"
125
+ },
126
+ "type": "library",
127
+ "extra": {
128
+ "branch-alias": {
129
+ "dev-master": "1.0.x-dev"
130
+ }
131
+ },
132
+ "autoload": {
133
+ "psr-4": {
134
+ "Psr\\Log\\": "Psr/Log/"
135
+ }
136
+ },
137
+ "notification-url": "https://packagist.org/downloads/",
138
+ "license": [
139
+ "MIT"
140
+ ],
141
+ "authors": [
142
+ {
143
+ "name": "PHP-FIG",
144
+ "homepage": "http://www.php-fig.org/"
145
+ }
146
+ ],
147
+ "description": "Common interface for logging libraries",
148
+ "homepage": "https://github.com/php-fig/log",
149
+ "keywords": [
150
+ "log",
151
+ "psr",
152
+ "psr-3"
153
+ ],
154
+ "time": "2016-10-10 12:19:37"
155
+ },
156
+ {
157
+ "name": "sebastian/diff",
158
+ "version": "dev-master",
159
+ "source": {
160
+ "type": "git",
161
+ "url": "https://github.com/sebastianbergmann/diff.git",
162
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a"
163
+ },
164
+ "dist": {
165
+ "type": "zip",
166
+ "url": "https://api.github.com/repos/sebastianbergmann/diff/zipball/d0814318784b7756fb932116acd19ee3b0cbe67a",
167
+ "reference": "d0814318784b7756fb932116acd19ee3b0cbe67a",
168
+ "shasum": ""
169
+ },
170
+ "require": {
171
+ "php": ">=5.3.3"
172
+ },
173
+ "require-dev": {
174
+ "phpunit/phpunit": "~4.8"
175
+ },
176
+ "type": "library",
177
+ "extra": {
178
+ "branch-alias": {
179
+ "dev-master": "1.4-dev"
180
+ }
181
+ },
182
+ "autoload": {
183
+ "classmap": [
184
+ "src/"
185
+ ]
186
+ },
187
+ "notification-url": "https://packagist.org/downloads/",
188
+ "license": [
189
+ "BSD-3-Clause"
190
+ ],
191
+ "authors": [
192
+ {
193
+ "name": "Kore Nordmann",
194
+ "email": "mail@kore-nordmann.de"
195
+ },
196
+ {
197
+ "name": "Sebastian Bergmann",
198
+ "email": "sebastian@phpunit.de"
199
+ }
200
+ ],
201
+ "description": "Diff implementation",
202
+ "homepage": "https://github.com/sebastianbergmann/diff",
203
+ "keywords": [
204
+ "diff"
205
+ ],
206
+ "time": "2016-10-03 07:45:03"
207
+ },
208
+ {
209
+ "name": "symfony/console",
210
+ "version": "2.8.x-dev",
211
+ "source": {
212
+ "type": "git",
213
+ "url": "https://github.com/symfony/console.git",
214
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71"
215
+ },
216
+ "dist": {
217
+ "type": "zip",
218
+ "url": "https://api.github.com/repos/symfony/console/zipball/ddb26174398f48486ac4231dc4f4cb27c3acba71",
219
+ "reference": "ddb26174398f48486ac4231dc4f4cb27c3acba71",
220
+ "shasum": ""
221
+ },
222
+ "require": {
223
+ "php": ">=5.3.9",
224
+ "symfony/debug": "~2.7,>=2.7.2|~3.0.0",
225
+ "symfony/polyfill-mbstring": "~1.0"
226
+ },
227
+ "require-dev": {
228
+ "psr/log": "~1.0",
229
+ "symfony/event-dispatcher": "~2.1|~3.0.0",
230
+ "symfony/process": "~2.1|~3.0.0"
231
+ },
232
+ "suggest": {
233
+ "psr/log": "For using the console logger",
234
+ "symfony/event-dispatcher": "",
235
+ "symfony/process": ""
236
+ },
237
+ "type": "library",
238
+ "extra": {
239
+ "branch-alias": {
240
+ "dev-master": "2.8-dev"
241
+ }
242
+ },
243
+ "autoload": {
244
+ "psr-4": {
245
+ "Symfony\\Component\\Console\\": ""
246
+ },
247
+ "exclude-from-classmap": [
248
+ "/Tests/"
249
+ ]
250
+ },
251
+ "notification-url": "https://packagist.org/downloads/",
252
+ "license": [
253
+ "MIT"
254
+ ],
255
+ "authors": [
256
+ {
257
+ "name": "Fabien Potencier",
258
+ "email": "fabien@symfony.com"
259
+ },
260
+ {
261
+ "name": "Symfony Community",
262
+ "homepage": "https://symfony.com/contributors"
263
+ }
264
+ ],
265
+ "description": "Symfony Console Component",
266
+ "homepage": "https://symfony.com",
267
+ "time": "2016-11-04 17:49:05"
268
+ },
269
+ {
270
+ "name": "symfony/debug",
271
+ "version": "2.8.x-dev",
272
+ "source": {
273
+ "type": "git",
274
+ "url": "https://github.com/symfony/debug.git",
275
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888"
276
+ },
277
+ "dist": {
278
+ "type": "zip",
279
+ "url": "https://api.github.com/repos/symfony/debug/zipball/d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
280
+ "reference": "d99867cf7b8a0b08e4ad6e1f130268bcb6a64888",
281
+ "shasum": ""
282
+ },
283
+ "require": {
284
+ "php": ">=5.3.9",
285
+ "psr/log": "~1.0"
286
+ },
287
+ "conflict": {
288
+ "symfony/http-kernel": ">=2.3,<2.3.24|~2.4.0|>=2.5,<2.5.9|>=2.6,<2.6.2"
289
+ },
290
+ "require-dev": {
291
+ "symfony/class-loader": "~2.2|~3.0.0",
292
+ "symfony/http-kernel": "~2.3.24|~2.5.9|~2.6,>=2.6.2|~3.0.0"
293
+ },
294
+ "type": "library",
295
+ "extra": {
296
+ "branch-alias": {
297
+ "dev-master": "2.8-dev"
298
+ }
299
+ },
300
+ "autoload": {
301
+ "psr-4": {
302
+ "Symfony\\Component\\Debug\\": ""
303
+ },
304
+ "exclude-from-classmap": [
305
+ "/Tests/"
306
+ ]
307
+ },
308
+ "notification-url": "https://packagist.org/downloads/",
309
+ "license": [
310
+ "MIT"
311
+ ],
312
+ "authors": [
313
+ {
314
+ "name": "Fabien Potencier",
315
+ "email": "fabien@symfony.com"
316
+ },
317
+ {
318
+ "name": "Symfony Community",
319
+ "homepage": "https://symfony.com/contributors"
320
+ }
321
+ ],
322
+ "description": "Symfony Debug Component",
323
+ "homepage": "https://symfony.com",
324
+ "time": "2016-11-03 07:52:58"
325
+ },
326
+ {
327
+ "name": "symfony/event-dispatcher",
328
+ "version": "2.8.x-dev",
329
+ "source": {
330
+ "type": "git",
331
+ "url": "https://github.com/symfony/event-dispatcher.git",
332
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934"
333
+ },
334
+ "dist": {
335
+ "type": "zip",
336
+ "url": "https://api.github.com/repos/symfony/event-dispatcher/zipball/25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
337
+ "reference": "25c576abd4e0f212e678fe8b2bd9a9a98c7ea934",
338
+ "shasum": ""
339
+ },
340
+ "require": {
341
+ "php": ">=5.3.9"
342
+ },
343
+ "require-dev": {
344
+ "psr/log": "~1.0",
345
+ "symfony/config": "~2.0,>=2.0.5|~3.0.0",
346
+ "symfony/dependency-injection": "~2.6|~3.0.0",
347
+ "symfony/expression-language": "~2.6|~3.0.0",
348
+ "symfony/stopwatch": "~2.3|~3.0.0"
349
+ },
350
+ "suggest": {
351
+ "symfony/dependency-injection": "",
352
+ "symfony/http-kernel": ""
353
+ },
354
+ "type": "library",
355
+ "extra": {
356
+ "branch-alias": {
357
+ "dev-master": "2.8-dev"
358
+ }
359
+ },
360
+ "autoload": {
361
+ "psr-4": {
362
+ "Symfony\\Component\\EventDispatcher\\": ""
363
+ },
364
+ "exclude-from-classmap": [
365
+ "/Tests/"
366
+ ]
367
+ },
368
+ "notification-url": "https://packagist.org/downloads/",
369
+ "license": [
370
+ "MIT"
371
+ ],
372
+ "authors": [
373
+ {
374
+ "name": "Fabien Potencier",
375
+ "email": "fabien@symfony.com"
376
+ },
377
+ {
378
+ "name": "Symfony Community",
379
+ "homepage": "https://symfony.com/contributors"
380
+ }
381
+ ],
382
+ "description": "Symfony EventDispatcher Component",
383
+ "homepage": "https://symfony.com",
384
+ "time": "2016-10-13 01:43:15"
385
+ },
386
+ {
387
+ "name": "symfony/filesystem",
388
+ "version": "2.8.x-dev",
389
+ "source": {
390
+ "type": "git",
391
+ "url": "https://github.com/symfony/filesystem.git",
392
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898"
393
+ },
394
+ "dist": {
395
+ "type": "zip",
396
+ "url": "https://api.github.com/repos/symfony/filesystem/zipball/a3784111af9f95f102b6411548376e1ae7c93898",
397
+ "reference": "a3784111af9f95f102b6411548376e1ae7c93898",
398
+ "shasum": ""
399
+ },
400
+ "require": {
401
+ "php": ">=5.3.9"
402
+ },
403
+ "type": "library",
404
+ "extra": {
405
+ "branch-alias": {
406
+ "dev-master": "2.8-dev"
407
+ }
408
+ },
409
+ "autoload": {
410
+ "psr-4": {
411
+ "Symfony\\Component\\Filesystem\\": ""
412
+ },
413
+ "exclude-from-classmap": [
414
+ "/Tests/"
415
+ ]
416
+ },
417
+ "notification-url": "https://packagist.org/downloads/",
418
+ "license": [
419
+ "MIT"
420
+ ],
421
+ "authors": [
422
+ {
423
+ "name": "Fabien Potencier",
424
+ "email": "fabien@symfony.com"
425
+ },
426
+ {
427
+ "name": "Symfony Community",
428
+ "homepage": "https://symfony.com/contributors"
429
+ }
430
+ ],
431
+ "description": "Symfony Filesystem Component",
432
+ "homepage": "https://symfony.com",
433
+ "time": "2016-10-18 04:28:30"
434
+ },
435
+ {
436
+ "name": "symfony/finder",
437
+ "version": "2.8.x-dev",
438
+ "source": {
439
+ "type": "git",
440
+ "url": "https://github.com/symfony/finder.git",
441
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd"
442
+ },
443
+ "dist": {
444
+ "type": "zip",
445
+ "url": "https://api.github.com/repos/symfony/finder/zipball/0023b024363dfc0cd21262e556f25a291fe8d7fd",
446
+ "reference": "0023b024363dfc0cd21262e556f25a291fe8d7fd",
447
+ "shasum": ""
448
+ },
449
+ "require": {
450
+ "php": ">=5.3.9"
451
+ },
452
+ "type": "library",
453
+ "extra": {
454
+ "branch-alias": {
455
+ "dev-master": "2.8-dev"
456
+ }
457
+ },
458
+ "autoload": {
459
+ "psr-4": {
460
+ "Symfony\\Component\\Finder\\": ""
461
+ },
462
+ "exclude-from-classmap": [
463
+ "/Tests/"
464
+ ]
465
+ },
466
+ "notification-url": "https://packagist.org/downloads/",
467
+ "license": [
468
+ "MIT"
469
+ ],
470
+ "authors": [
471
+ {
472
+ "name": "Fabien Potencier",
473
+ "email": "fabien@symfony.com"
474
+ },
475
+ {
476
+ "name": "Symfony Community",
477
+ "homepage": "https://symfony.com/contributors"
478
+ }
479
+ ],
480
+ "description": "Symfony Finder Component",
481
+ "homepage": "https://symfony.com",
482
+ "time": "2016-11-03 07:52:58"
483
+ },
484
+ {
485
+ "name": "symfony/polyfill-mbstring",
486
+ "version": "dev-master",
487
+ "source": {
488
+ "type": "git",
489
+ "url": "https://github.com/symfony/polyfill-mbstring.git",
490
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c"
491
+ },
492
+ "dist": {
493
+ "type": "zip",
494
+ "url": "https://api.github.com/repos/symfony/polyfill-mbstring/zipball/53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
495
+ "reference": "53ad9faffe141fbe8f98cd6a7fd9a5e84513f56c",
496
+ "shasum": ""
497
+ },
498
+ "require": {
499
+ "php": ">=5.3.3"
500
+ },
501
+ "suggest": {
502
+ "ext-mbstring": "For best performance"
503
+ },
504
+ "type": "library",
505
+ "extra": {
506
+ "branch-alias": {
507
+ "dev-master": "1.2-dev"
508
+ }
509
+ },
510
+ "autoload": {
511
+ "psr-4": {
512
+ "Symfony\\Polyfill\\Mbstring\\": ""
513
+ },
514
+ "files": [
515
+ "bootstrap.php"
516
+ ]
517
+ },
518
+ "notification-url": "https://packagist.org/downloads/",
519
+ "license": [
520
+ "MIT"
521
+ ],
522
+ "authors": [
523
+ {
524
+ "name": "Nicolas Grekas",
525
+ "email": "p@tchwork.com"
526
+ },
527
+ {
528
+ "name": "Symfony Community",
529
+ "homepage": "https://symfony.com/contributors"
530
+ }
531
+ ],
532
+ "description": "Symfony polyfill for the Mbstring extension",
533
+ "homepage": "https://symfony.com",
534
+ "keywords": [
535
+ "compatibility",
536
+ "mbstring",
537
+ "polyfill",
538
+ "portable",
539
+ "shim"
540
+ ],
541
+ "time": "2016-08-30 17:06:17"
542
+ },
543
+ {
544
+ "name": "symfony/process",
545
+ "version": "2.8.x-dev",
546
+ "source": {
547
+ "type": "git",
548
+ "url": "https://github.com/symfony/process.git",
549
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f"
550
+ },
551
+ "dist": {
552
+ "type": "zip",
553
+ "url": "https://api.github.com/repos/symfony/process/zipball/024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
554
+ "reference": "024de37f8a6b9e5e8244d9eb3fcf3e467dd2a93f",
555
+ "shasum": ""
556
+ },
557
+ "require": {
558
+ "php": ">=5.3.9"
559
+ },
560
+ "type": "library",
561
+ "extra": {
562
+ "branch-alias": {
563
+ "dev-master": "2.8-dev"
564
+ }
565
+ },
566
+ "autoload": {
567
+ "psr-4": {
568
+ "Symfony\\Component\\Process\\": ""
569
+ },
570
+ "exclude-from-classmap": [
571
+ "/Tests/"
572
+ ]
573
+ },
574
+ "notification-url": "https://packagist.org/downloads/",
575
+ "license": [
576
+ "MIT"
577
+ ],
578
+ "authors": [
579
+ {
580
+ "name": "Fabien Potencier",
581
+ "email": "fabien@symfony.com"
582
+ },
583
+ {
584
+ "name": "Symfony Community",
585
+ "homepage": "https://symfony.com/contributors"
586
+ }
587
+ ],
588
+ "description": "Symfony Process Component",
589
+ "homepage": "https://symfony.com",
590
+ "time": "2016-09-29 14:03:54"
591
+ },
592
+ {
593
+ "name": "symfony/stopwatch",
594
+ "version": "2.8.x-dev",
595
+ "source": {
596
+ "type": "git",
597
+ "url": "https://github.com/symfony/stopwatch.git",
598
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca"
599
+ },
600
+ "dist": {
601
+ "type": "zip",
602
+ "url": "https://api.github.com/repos/symfony/stopwatch/zipball/35bae476693150728b0eb51647faac82faf9aaca",
603
+ "reference": "35bae476693150728b0eb51647faac82faf9aaca",
604
+ "shasum": ""
605
+ },
606
+ "require": {
607
+ "php": ">=5.3.9"
608
+ },
609
+ "type": "library",
610
+ "extra": {
611
+ "branch-alias": {
612
+ "dev-master": "2.8-dev"
613
+ }
614
+ },
615
+ "autoload": {
616
+ "psr-4": {
617
+ "Symfony\\Component\\Stopwatch\\": ""
618
+ },
619
+ "exclude-from-classmap": [
620
+ "/Tests/"
621
+ ]
622
+ },
623
+ "notification-url": "https://packagist.org/downloads/",
624
+ "license": [
625
+ "MIT"
626
+ ],
627
+ "authors": [
628
+ {
629
+ "name": "Fabien Potencier",
630
+ "email": "fabien@symfony.com"
631
+ },
632
+ {
633
+ "name": "Symfony Community",
634
+ "homepage": "https://symfony.com/contributors"
635
+ }
636
+ ],
637
+ "description": "Symfony Stopwatch Component",
638
+ "homepage": "https://symfony.com",
639
+ "time": "2016-06-29 05:29:29"
640
+ }
641
+ ],
642
+ "aliases": [],
643
+ "minimum-stability": "dev",
644
+ "stability-flags": {
645
+ "dhii/php-cs-fixer-config": 20
646
+ },
647
+ "prefer-stable": false,
648
+ "prefer-lowest": false,
649
+ "platform": {
650
+ "php": "^5.3 | ^7.0"
651
+ },
652
+ "platform-dev": []
653
+ }
vendor/dhii/stats-interface/nbproject/project.properties ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
1
+ include.path=${php.global.include.path}
2
+ php.version=PHP_53
3
+ source.encoding=UTF-8
4
+ src.dir=src
5
+ tags.asp=false
6
+ tags.short=false
7
+ web.root=.
vendor/dhii/stats-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 - stats-interface</name>
7
+ </data>
8
+ </configuration>
9
+ </project>
vendor/dhii/stats-interface/src/AggregatorInterface.php ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace Dhii\Stats;
4
+
5
+ /**
6
+ * Something that can act as a stats aggregator.
7
+ *
8
+ * A stats aggregator is something that calculates totals based on individual values.
9
+ *
10
+ * @since 0.1.0
11
+ */
12
+ interface AggregatorInterface
13
+ {
14
+ /**
15
+ * Aggregates stats from a set of items.
16
+ *
17
+ * @since 0.1.0
18
+ *
19
+ * @param mixed[] $totals Existing totals.
20
+ * @param mixed[]|\Traversable $items A list of items to aggregate the totals from.
21
+ *
22
+ * @return mixed[] The new totals.
23
+ */
24
+ public function aggregate($totals, $items);
25
+ }
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.9.1
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.9.1
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.9.1', true );
48
 
49
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
50
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
@@ -90,7 +90,8 @@
90
 
91
  // Set the constant path to the plugin's log file.
92
  if( !defined( 'WPRSS_LOG_FILE' ) )
93
- define( 'WPRSS_LOG_FILE', WPRSS_DIR . 'log', true );
 
94
  if( !defined( 'WPRSS_LOG_FILE_EXT' ) )
95
  define( 'WPRSS_LOG_FILE_EXT', '.txt', true );
96
 
@@ -110,6 +111,12 @@
110
  if ( !defined( 'WPRSS_ITEM_IMPORT_TIME_LIMIT' ) ) {
111
  define( 'WPRSS_ITEM_IMPORT_TIME_LIMIT', 15, TRUE );
112
  }
 
 
 
 
 
 
113
 
114
  /**
115
  * Load required files.
@@ -119,6 +126,23 @@
119
  require_once ( WPRSS_INC . 'autoload.php' );
120
  // Adding autoload paths
121
  wprss_autoloader()->add('Aventura\\Wprss\\Core', WPRSS_INC);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
122
 
123
  /* Load install, upgrade and migration code. */
124
  require_once ( WPRSS_INC . 'update.php' );
@@ -232,7 +256,7 @@
232
  require_once ( WPRSS_INC . 'admin-help-settings.php' );
233
 
234
  /* SimplePie */
235
- require_once ( ABSPATH . WPINC . '/class-feed.php' );
236
 
237
  /* Access to feed */
238
  require_once ( WPRSS_INC . 'feed-access.php' );
@@ -240,6 +264,9 @@
240
  /* Load the fallbacks for mbstring */
241
  require_once ( WPRSS_INC . 'fallback-mbstring.php' );
242
 
 
 
 
243
  // Initializes licensing
244
  add_action( 'plugins_loaded', 'wprss_licensing' );
245
 
@@ -248,7 +275,7 @@
248
 
249
 
250
  /**
251
- * Returns the Spinnerchief Addon class singleton instance.
252
  *
253
  * @since 4.8.1
254
  * @return Aventura\Wprss\Core\Plugin
@@ -261,7 +288,7 @@
261
  if (is_null($plugin)) {
262
  static $timesCalled = 0;
263
  if ($timesCalled) {
264
- throw new Exception('WP RSS Aggregator has been initialized recursively');
265
  }
266
  $timesCalled++;
267
 
@@ -284,14 +311,13 @@
284
 
285
  $plugin = call_user_func_array(array($factoryClassName, 'create'), array(array(
286
  'basename' => __FILE__,
287
- 'name' => 'WP RSS Aggregator'
288
  )));
289
  }
290
 
291
  return $plugin;
292
  }
293
 
294
- require_once(WPRSS_INC . 'functions.php');
295
  try {
296
  $instance = wprss();
297
  } catch (Exception $e) {
@@ -330,7 +356,7 @@
330
 
331
  'target' => '#wpadminbar',
332
  'options' => array(
333
- 'content' => '<h3>' . __( 'Help improve WP RSS Aggregator', WPRSS_TEXT_DOMAIN ) . '</h3>' . '<p>' . __( 'You\'ve just installed WP RSS Aggregator. Please helps us improve it by allowing us to gather anonymous usage stats so we know which configurations, plugins and themes to test with.', WPRSS_TEXT_DOMAIN ) . '</p>',
334
  'position' => array(
335
  'edge' => 'top',
336
  'align' => 'center',
@@ -463,9 +489,9 @@
463
  wprss_admin_notice_add(array(
464
  'id' => 'wp_version_warning',
465
  'content' => sprintf( __(
466
- '<p><strong>WP RSS Aggregator requires WordPress to be of version %1$s or higher.</strong></br>'
467
- . 'Older versions of WordPress are no longer supported by WP RSS Aggregator. Please upgrade your WordPress core to continue benefiting from WP RSS Aggregator support services.</p>',
468
- WPRSS_TEXT_DOMAIN ), WPRSS_WP_MIN_VERSION ),
469
  'notice_type' => 'error'
470
  ));
471
 
@@ -481,9 +507,9 @@
481
  wprss_admin_notice_add(array(
482
  'id' => 'php_version_change_warning',
483
  'content' => sprintf( __(
484
- '<p><strong>WP RSS Aggregator is moving to PHP %1$s</strong></br>'
485
  . 'The next release of your favourite aggregator will not support PHP 5.2. <a href="http://www.wprssaggregator.com/wp-rss-aggregator-to-require-php-5-3/" target="_blank">Read why here</a></p>',
486
- WPRSS_TEXT_DOMAIN ), $minVersion ),
487
  'notice_type' => 'error',
488
  'condition' => 'wprss_is_wprss_page'
489
  ));
@@ -500,7 +526,7 @@
500
  /* Prevents activation of plugin if compatible version of WordPress not found */
501
  if ( !wprss_wp_min_version_satisfied() ) {
502
  deactivate_plugins ( basename( __FILE__ )); // Deactivate plugin
503
- wp_die( sprintf ( __( 'This plugin requires WordPress version %1$s or higher.' ), WPRSS_WP_MIN_VERSION ), 'WP RSS Aggregator', array( 'back_link' => true ) );
504
  }
505
  wprss_settings_initialize();
506
  flush_rewrite_rules();
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
 
31
  /**
32
  * @package WPRSSAggregator
33
+ * @version 4.10
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.10', true );
48
 
49
  if( !defined( 'WPRSS_WP_MIN_VERSION' ) )
50
  define( 'WPRSS_WP_MIN_VERSION', '4.0', true );
90
 
91
  // Set the constant path to the plugin's log file.
92
  if( !defined( 'WPRSS_LOG_FILE' ) )
93
+ define( 'WPRSS_LOG_FILE', WP_CONTENT_DIR . '/log/wprss/log', true );
94
+
95
  if( !defined( 'WPRSS_LOG_FILE_EXT' ) )
96
  define( 'WPRSS_LOG_FILE_EXT', '.txt', true );
97
 
111
  if ( !defined( 'WPRSS_ITEM_IMPORT_TIME_LIMIT' ) ) {
112
  define( 'WPRSS_ITEM_IMPORT_TIME_LIMIT', 15, TRUE );
113
  }
114
+ // Where to take the diagnostic tests from
115
+ if ( !defined( 'WPRACORE_DIAG_TESTS_DIR' ) ) {
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.
126
  require_once ( WPRSS_INC . 'autoload.php' );
127
  // Adding autoload paths
128
  wprss_autoloader()->add('Aventura\\Wprss\\Core', WPRSS_INC);
129
+ wprss_autoloader()->add('Aventura\\Wprss\\Core\\DiagTest', WPRACORE_DIAG_TESTS_DIR);
130
+ // Add tests
131
+ add_filter('wprss_diag_tester_sources', function ($event) {
132
+ $sources = $event->getData('sources');
133
+
134
+ $locator = new \Dhii\SimpleTest\Locator\FilePathLocator();
135
+ $locator->addPath(new \RecursiveDirectoryIterator(WPRACORE_DIAG_TESTS_DIR, 1));
136
+ $testSource = new \RebelCode\Wprss\Debug\DiagTest\Model\TestSource($locator->locate(), wprss()->getCode(), WPRSS_CORE_PLUGIN_NAME);
137
+
138
+ $sources[$testSource->getCode()] = $testSource;
139
+ $event->setData('sources', $sources);
140
+
141
+ return $event;
142
+ });
143
+
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' );
256
  require_once ( WPRSS_INC . 'admin-help-settings.php' );
257
 
258
  /* SimplePie */
259
+ require_once ( ABSPATH . WPINC . '/class-simplepie.php' );
260
 
261
  /* Access to feed */
262
  require_once ( WPRSS_INC . 'feed-access.php' );
264
  /* Load the fallbacks for mbstring */
265
  require_once ( WPRSS_INC . 'fallback-mbstring.php' );
266
 
267
+ /* The "Leave a Review" notification module */
268
+ require_once ( WPRSS_INC . 'leave-review-notification.php' );
269
+
270
  // Initializes licensing
271
  add_action( 'plugins_loaded', 'wprss_licensing' );
272
 
275
 
276
 
277
  /**
278
+ * Returns the Core plugin singleton instance.
279
  *
280
  * @since 4.8.1
281
  * @return Aventura\Wprss\Core\Plugin
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
 
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 {
322
  $instance = wprss();
323
  } catch (Exception $e) {
356
 
357
  'target' => '#wpadminbar',
358
  'options' => array(
359
+ 'content' => '<h3>' . sprintf( __( 'Help improve %1$s', WPRSS_TEXT_DOMAIN ), WPRSS_CORE_PLUGIN_NAME ) . '</h3>' . '<p>' . sprintf( __( 'You\'ve just installed %1$s. Please helps us improve it by allowing us to gather anonymous usage stats so we know which configurations, plugins and themes to test with.', WPRSS_TEXT_DOMAIN ), WPRSS_CORE_PLUGIN_NAME ) . '</p>',
360
  'position' => array(
361
  'edge' => 'top',
362
  'align' => 'center',
489
  wprss_admin_notice_add(array(
490
  'id' => 'wp_version_warning',
491
  'content' => sprintf( __(
492
+ '<p><strong>%2$s requires WordPress to be of version %1$s or higher.</strong></br>'
493
+ . 'Older versions of WordPress are no longer supported by %2$s. Please upgrade your WordPress core to continue benefiting from %2$s support services.</p>',
494
+ WPRSS_TEXT_DOMAIN ), WPRSS_WP_MIN_VERSION, WPRSS_CORE_PLUGIN_NAME ),
495
  'notice_type' => 'error'
496
  ));
497
 
507
  wprss_admin_notice_add(array(
508
  'id' => 'php_version_change_warning',
509
  'content' => sprintf( __(
510
+ '<p><strong>%2$s is moving to PHP %1$s</strong></br>'
511
  . 'The next release of your favourite aggregator will not support PHP 5.2. <a href="http://www.wprssaggregator.com/wp-rss-aggregator-to-require-php-5-3/" target="_blank">Read why here</a></p>',
512
+ WPRSS_TEXT_DOMAIN ), $minVersion, WPRSS_CORE_PLUGIN_NAME ),
513
  'notice_type' => 'error',
514
  'condition' => 'wprss_is_wprss_page'
515
  ));
526
  /* Prevents activation of plugin if compatible version of WordPress not found */
527
  if ( !wprss_wp_min_version_satisfied() ) {
528
  deactivate_plugins ( basename( __FILE__ )); // Deactivate plugin
529
+ wp_die( sprintf ( __( '%2$s requires WordPress version %1$s or higher.' ), WPRSS_WP_MIN_VERSION, WPRSS_CORE_PLUGIN_NAME ), WPRSS_CORE_PLUGIN_NAME, array( 'back_link' => true ) );
530
  }
531
  wprss_settings_initialize();
532
  flush_rewrite_rules();