BackUpWordPress - Version 3.2.0

Version Description

= 3.1.3 =

  • Fixes backwards compatibility for add-ons and avoids a Fatal Error. Please upgrade straight to this version before upgrading your add-ons.

= 3.0.4 =

  • Fixes a few minor bugs. Immediate update is recommended.

= 3.0.2 =

  • Important: we have dropped support for PHP 5.2, you will not be able to activate BackUpWordPress on a server running PHP versions older than PHP 5.3.29

= 3.0.1 =

  • This is a critical update. Fixes a bug in the core backup library. Please update immediately.
Download this release

Release Info

Developer pauldewouters
Plugin Icon 128x128 BackUpWordPress
Version 3.2.0
Comparing to
See all releases

Code changes from version 3.1.4 to 3.2.0

Files changed (114) hide show
  1. History.md +0 -2028
  2. admin/actions.php +18 -41
  3. admin/backups.php +1 -1
  4. admin/menu.php +30 -13
  5. admin/schedule-form-excludes.php +185 -162
  6. admin/schedule-form.php +6 -4
  7. admin/schedule-sentence.php +8 -2
  8. assets/hmbkp.js +5 -12
  9. assets/hmbkp.min.js +1 -1
  10. backupwordpress.php +10 -386
  11. changelog +0 -2024
  12. classes/class-backup.php +200 -77
  13. classes/class-plugin.php +407 -0
  14. classes/class-schedule.php +61 -124
  15. classes/class-schedules.php +1 -1
  16. classes/class-setup.php +15 -2
  17. functions/core.php +54 -0
  18. functions/interface.php +4 -6
  19. languages/backupwordpress.pot +176 -156
  20. readme.txt +74 -1
  21. uninstall.php +2 -7
  22. vendor/autoload.php +7 -0
  23. vendor/composer/ClassLoader.php +386 -0
  24. vendor/composer/autoload_classmap.php +9 -0
  25. vendor/composer/autoload_namespaces.php +10 -0
  26. vendor/composer/autoload_psr4.php +9 -0
  27. vendor/composer/autoload_real.php +50 -0
  28. vendor/composer/installed.json +51 -0
  29. vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php +236 -0
  30. vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php +327 -0
  31. vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php +144 -0
  32. vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php +103 -0
  33. vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php +104 -0
  34. vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php +98 -0
  35. vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md +34 -0
  36. vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php +98 -0
  37. vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php +53 -0
  38. vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php +81 -0
  39. vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php +19 -0
  40. vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php +46 -0
  41. vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php +23 -0
  42. vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php +19 -0
  43. vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php +45 -0
  44. vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php +146 -0
  45. vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php +157 -0
  46. vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php +321 -0
  47. vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php +60 -0
  48. vendor/symfony/finder/Symfony/Component/Finder/Finder.php +840 -0
  49. vendor/symfony/finder/Symfony/Component/Finder/Glob.php +103 -0
  50. vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php +63 -0
  51. vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php +60 -0
  52. vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php +47 -0
  53. vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php +55 -0
  54. vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php +131 -0
  55. vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php +55 -0
  56. vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php +76 -0
  57. vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php +67 -0
  58. vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php +49 -0
  59. vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php +66 -0
  60. vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php +74 -0
  61. vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php +126 -0
  62. vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php +59 -0
  63. vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php +82 -0
  64. vendor/symfony/finder/Symfony/Component/Finder/LICENSE +19 -0
  65. vendor/symfony/finder/Symfony/Component/Finder/README.md +53 -0
  66. vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php +294 -0
  67. vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php +97 -0
  68. vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php +77 -0
  69. vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php +64 -0
  70. vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php +63 -0
  71. vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php +107 -0
  72. vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php +68 -0
  73. vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php +47 -0
  74. vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php +143 -0
  75. vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php +57 -0
  76. vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php +45 -0
  77. vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php +57 -0
  78. vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php +44 -0
  79. vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php +869 -0
  80. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat +0 -0
  81. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat +0 -0
  82. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat +0 -0
  83. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy +0 -0
  84. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy +0 -0
  85. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy +0 -0
  86. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt +2 -0
  87. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt +2 -0
  88. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt +2 -0
  89. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a +0 -0
  90. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon +0 -0
  91. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon +0 -0
  92. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat +0 -0
  93. vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt +0 -0
  94. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php +46 -0
  95. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php +72 -0
  96. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php +80 -0
  97. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php +64 -0
  98. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php +66 -0
  99. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php +72 -0
  100. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php +86 -0
  101. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php +54 -0
  102. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php +50 -0
  103. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php +55 -0
  104. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php +98 -0
  105. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php +21 -0
  106. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php +134 -0
  107. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php +67 -0
  108. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php +83 -0
  109. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php +109 -0
  110. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php +83 -0
  111. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php +68 -0
  112. vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php +169 -0
  113. vendor/symfony/finder/Symfony/Component/Finder/composer.json +31 -0
  114. vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist +28 -0
History.md DELETED
@@ -1,2028 +0,0 @@
1
-
2
- n.n.n / 2015-02-24
3
- ==================
4
-
5
- * Merge pull request #728 from humanmade/issue-728
6
- * Merge pull request #739 from humanmade/upgrade-options
7
- * Bump version
8
- * strtolower is redundant
9
- * Upgrade routine
10
- * Use the Service name as the setting name
11
- * Cleear settings for schedule settings
12
- * Fixes bug in displaying settings error notices
13
- * Update version number
14
- * Merge pull request #726 from humanmade/fix-fatal-error-missing-class-addons
15
- * Leave bare minimum to avoid fatal error
16
- * remove old main plugin class
17
- * remove deprecated notice
18
- * Throw a deprecated warning
19
- * Add BWP class
20
- * Bump version
21
- * Introduces a deprecated.php file
22
-
23
- n.n.n / 2015-02-03
24
- ==================
25
-
26
- * Merge pull request #687 from humanmade/fixup-setup-class
27
- * Merge pull request #724 from humanmade/simplify-bwp-file-timestamp
28
- * Simplify the file name timestamp
29
- * Fix class file name
30
- * Merge pull request #723 from humanmade/willmot-slack-notifications
31
- * Add missing transients to uninstall routine
32
- * switch Travis notifications to Slack instead of Hipchat
33
- * Do not delete backups on uninstall
34
- * wrap in parenthesis
35
- * Fix include paths after moving uninstall to own file herpderp
36
- * Update BackUp class include
37
- * Merge branch 'master' into fixup-setup-class
38
- * Merge pull request #719 from humanmade/iis-fixes
39
- * Merge pull request #720 from humanmade/refactor-fixes
40
- * Add all cases to switch
41
- * Pass scanned files sizes through conform_dir()
42
- * Fix some classes and requires
43
- * Merge branch 'master' into fixup-setup-class
44
- * Merge branch 'master' into fixup-setup-class
45
- * Merge pull request #684 from humanmade/issue-684
46
- * Fix namespaces
47
- * Remove unnecessary wildcard from regex
48
- * Merge branch 'master' into issue-684
49
- * Merge pull request #667 from humanmade/crazy-refactor
50
- * Remove some duplication
51
- * Formatting
52
- * Fix Class name
53
- * Merge branch 'master' into crazy-refactor
54
- * Blank line
55
- * Uses a DirectoryIterator to delete files
56
- * Merge pull request #683 from humanmade/change-singleton-implementation
57
- * Merge branch 'master' into crazy-refactor
58
- * Remove tests for now
59
- * Fix stable tag number
60
- * Revert to using uninstall.php
61
- * Add tests for uninstall and deactivate
62
- * Remove double lie break
63
- * Remove double line break
64
- * Remove phpdocumentor
65
- * We still need to require some scripts...
66
- * We dont need to check for this constant in the hook callback
67
- * Use get_col to directly have an array of schedule option names
68
- * Remove namespacing
69
- * Remove debugging
70
- * Make the uninstall, activation and deactivation hooks work
71
- * Change the singleton implementation to not use the static() function
72
- * Merge pull request #682 from duritong/fix_path_argument
73
- * path argument interfers with wp-cli path argument.
74
- * Fix some scrutinizer issues, mostly major ones
75
- * Consistent default name for database dumps
76
- * Major 5.3 re-factoring fun
77
- * Merge hm-backup into backupwordpress
78
- * Minor code formatting
79
- * else if should be elseif
80
- * Update the WP_CLI command to fix some issues
81
- * Add support for copying and updating an existing backups
82
- b3ffe16 (HEAD, origin/master, master) Merge pull request #670 from humanmade/fix-668
83
- ad7e0fa Correct $response1 variable
84
- 89c87e8 (tag: 3.1-alpha) Merge pull request #475 from humanmade/issue-475
85
- d0e6d0c Merge pull request #652 from humanmade/issue-652
86
- 804c472 (origin/issue-652, issue-652) Suppress warnings from filesystem functions
87
- 9861f06 Remove debugging function
88
- 6601346 Merge branch 'master' into issue-652
89
- 65808bb (origin/issue-475, issue-475) Fix a French string
90
- ca35ba3 Format the intercom data better
91
- c8cd859 Load Intercom in the admin footer
92
- 34c3af0 Fix some HTML issues
93
- b896803 Fix tests
94
- 4c3fade Add a function that returns a given option value
95
- 071a23a Return Unknown if no average exists or invalid
96
- 4e6ca12 Add a start parameter to function
97
- 6d8047a Pass in the start time as a parameter
98
- 0410b01 Add some unit tests
99
- 740583a Make strings translatable
100
- 9861f70 Escape values
101
- 61a0441 Adds a function to track backup duration and anpther to display it
102
- adb7b8a Adds Average Backup Duration Info
103
- e9a4088 Improve display of arrays
104
- 1ee8c69 Fixes open_basedir warnings
105
- 8de17c3 Replace spaces with tabs for indentation
106
- 082a038 Merge pull request #664 from humanmade/wp-cron-test-improvements
107
- cc8e46e (wp-cron-test-improvements) Improve the reliability of the wp-cron test
108
- 8bf18c5 Merge pull request #639 from humanmade/issue-639
109
- 5ad724e Merge pull request #588 from humanmade/issue-588
110
- b87396b (issue-639) Do not start schedule if backups are not possible
111
- 069553b (origin/issue-588, issue-588) Merge branch 'master' into issue-588
112
- 876b955 Pop in the directory sizes
113
- f6d99f6 No need to return the whole array
114
- 81fc305 Merge pull request #640 from humanmade/issue-640
115
- c11b1b5 Merge pull request #605 from humanmade/issue-605
116
- 809528e Adapt heartbeat pulse
117
- bdb1142 Update Javascript
118
- 0f4f758 A few adjustments based on peer review feedback.
119
- 315ff75 Update constant name
120
- 195189b Load the default translations so that activation error message is in user language
121
- cb6fbe5 Fix a few translatable strings
122
- 8c52f3a Update French translations
123
- 2f1a3a5 Re-uglify Intercom js
124
- 727579e Use provided callback argument to determine current screen
125
- 036998c remove deprecated code
126
- 34cfdc9 Merge branch 'master' into issue-605
127
- 6951b7e Merge pull request #612 from humanmade/hmbkp-path
128
- 5c48e64 Remove PHPDoc build process
129
- f3e9fc3 Merge branch 'master' into hmbkp-path
130
- 6457232 Merge branch 'master' into issue-605
131
- c134e41 Ignore IDE project files
132
- c127848 Merge pull request #651 from humanmade/remove_memory_limit_define
133
- 16213e9 Only show notices on BWP admin page
134
- 4945ce9 Merge pull request #649 from humanmade/improved_notices
135
- b2a228c Fix class name
136
- 3ffb704 Formating
137
- d128ae5 Make function public for now
138
- a491cfc Get an instance of BWP to load functions
139
- 45af4c4 Fix conditional
140
- 9675432 Fix conditional
141
- 6769d23 Show admin notice if fails to meet requirements
142
- bd56ea0 Remove unneeded function
143
- 7d7b515 Fix references
144
- b4a9a0e Refactor main class after addition of the Setup class
145
- 0e6febe Introduce a setup class
146
- 26cb5ab Update tests
147
- 8cc3a85 Determine if we need to run a cleanup routine
148
- 71fca9c Introduce a custom hook for addons
149
- ca5fbc7 Refactor main plugin file into a singleton class
150
- bf5be41 Bring activation and deactivation into main plugin class
151
- ae82d2c Ignore IDE project files
152
- 5cf0843 Merge pull request #648 from humanmade/issue-648-sprtbtnfix
153
- 93cc9ce css changes to fix support button alignment
154
- 0165a6c Merge pull request #644 from humanmade/issue-644
155
- ea4854b Merge pull request #650 from humanmade/fix_nojs_backup
156
- 46d3601 Merge pull request #642 from humanmade/fix-missing-i18n
157
- 2fa87b0 Merge branch 'master' into hmbkp-path
158
- bdada67 Fixes issue preventing backups from running without JS
159
- b901112 Remove back compat memory limit define
160
- b3fb80e Refactot HMBKP_Notices to support non-persistant notices
161
- e9cac5f Minor refactor for PHP minimum requirements notice
162
- 65b89ff Clear previous backup notices when running a new backup
163
- 25ce583 Fix issues with custom paths
164
- eaf520b Fixup some issues in merge_existing_paths
165
- ca6b691 Improved singleton pattern
166
- f679be5 Display errors in network admin
167
- b30722e Change to text input so multiple email address are supported
168
- 6100176 Removes HTML tag from string
169
- fe62548 Merge pull request #643 from humanmade/fix-conditional
170
- 9743f32 code is of type string
171
- d4e8765 Remove unneeded code
172
- 070dd9e Account for new schedule
173
- 27f9e77 Make upsell sentence translatable
174
- 97aa688 Regenerate minified
175
- 6bb46f7 Fix a few linting issue
176
- 2b1ef2d Extract to a function
177
- 6401221 JSHint config
178
- 0bf6248 fix return type
179
- d5170dd Return true if transient exists
180
- 6a0a704 Check if constant is defined
181
- 198f40a Request the site size fvia heartbeat send
182
- b4ee172 Pass site size through heartbeat
183
- 4155280 Only calculate if necessary
184
- 939ccdb Remove phpunit and naming checks
185
- c2a199e (tag: v3.0.4) Remove naming checks as we do this with phpcs
186
- 8cc1f65 Bump version to 3.0.4
187
- 65f5095 Don't run phpunit on Scrutinizer
188
- e5bc0dc Merge pull request #624 from humanmade/issue-624
189
- 95873c5 Merge pull request #629 from humanmade/issue-629
190
- fc495bd Merge pull request #633 from humanmade/fix-help-tabs-display
191
- 823107e Merge pull request #634 from humanmade/issue-634
192
- 6eece13 Merge pull request #636 from humanmade/fix-admin-scripts
193
- 7a56b46 Only build docs on master
194
- 868ae6b Wait for tests
195
- 42838dc Try using a hardcoded string
196
- 6ab00bc Simplify the backup count display
197
- 6b4684e Enqueue scripts properly
198
- 17b0610 Change how we check directory_sizes
199
- 31baca0 Disable php_cpd
200
- 7b9f9cb Merge branch 'master' into fix-help-tabs-display
201
- 1e01d21 Fix typo
202
- d98e143 Merge branch 'master' into issue-629
203
- 5438c20 Add BackUpWordPress test case class
204
- b03582c Move class to separate file
205
- 2102a88 Account for various testing environments
206
- 2c1469a Use HTTPS in tests setup
207
- 0766c37 Add required functions
208
- 8b9a4d8 Remove deprecated property
209
- 20bf107 Simplify writing status to file and throw Exception on failure
210
- 48d45e2 Spacing
211
- 710fbc0 Group help tab display functions
212
- 8ad56ee Remove deprecated function
213
- 9358318 call hmbkp_path directly
214
- 0f96866 Merge pull request #628 from humanmade/wpml-compat
215
- b27e2f2 expected actual
216
- 23d3e78 Update POT file
217
- cca1f0b Make strings ready for translation
218
- 0d0f270 Run test suites separately
219
- 69812bb Reorganize tests
220
- 43d20c4 Get the singleton instead of instantiating
221
- b3aa187 Do not delete backups folder between tests
222
- a771a02 Expected then Actual
223
- e52bb77 Fix order of arguments in assertions
224
- 50fe291 No need for this var
225
- a8a8659 Add BackUpWordPress test case class
226
- dcbac12 Move class to separate file
227
- 4e88297 Account for various testing environments
228
- c1e3158 Use HTTPS in tests setup
229
- b9ce28c Merge branch 'master' into hmbkp-path
230
- 1e093b6 Update dependencies in composer.lock
231
- 40faa7c (tag: v3.0.3) Fix code coverage config
232
- 486d6c7 Fix code coverage config
233
- 04e4d9d Fix class name
234
- 889572d Merge branch 'master' into hmbkp-path
235
- 748f132 Remove asterisk from pattern
236
- d91cfe7 Fix asterisk
237
- a5d6af5 Rename translation files
238
- d67f3d6 Bump plugin version to 3.0.3
239
- 4bdb26f bump version
240
- 3e3aa0d refresh readme
241
- 0e15823 Regenerate readme
242
- 40d72ce Refresh POT file
243
- 5afe400 Latest hm backup
244
- c81b561 Merge pull request #621 from humanmade/fix-time-dependent-tests
245
- e96e73b Merge branch 'master' into hmbkp-path
246
- 91ed195 Merge pull request #623 from humanmade/issue-623
247
- 11dcfa0 Merge pull request #620 from humanmade/issue-620
248
- 07bcd59 Merge branch 'master' into hmbkp-path
249
- 6702908 Merge pull request #597 from humanmade/issue-597
250
- 69daeef Add French translations
251
- 4396c41 Update textdomain
252
- abd3585 Fix deleted function
253
- 1bdf3ff Use HM_Backup function to determine if shell_exec is enabled
254
- d0c7d70 Merge branch 'master' into issue-620
255
- b894d52 Check if file is readable first
256
- 025c581 Fix how we kick off Task
257
- be92693 Merge pull request #625 from humanmade/issue-625
258
- 1bc3eb7 Remove unused var
259
- db0ec01 Call recursive filescanner on admin page load
260
- 99cbe70 Update package.json
261
- 804d727 Update the POT file task params
262
- f10bf82 Replace hmbkp with backupwordpress as textdomain
263
- 80aae82 Exclude folders
264
- a490f77 Add Grunt task options
265
- c73afab Checkout hmbkp-path branch
266
- 9d163c1 Make function public
267
- 32e7b12 Merge branch 'master' into hmbkp-path
268
- 32a36a4 Comments and formatting
269
- af7c0c3 Fix scrutinizer issues
270
- 909332a Remove hard line returns
271
- c603734 Display placeholder if exec fails
272
- 9869c23 Add 30 second time diff allowance
273
- 845b9fe Use $TRAVIS_BUILD_DIR
274
- d163ee6 we do this in travis.yml
275
- 9e4fda4 Regenerate github account info
276
- 5722e0c Update command to reflect function rename
277
- bcc100e Update tests to reflect function name change
278
- 1853d7b Rename function
279
- 1fe371a Filter tests to run
280
- 6892c2c Fix group flags
281
- 8b1f65c Return true on success, false on failure
282
- 012866b Unit tests php ini configs
283
- 960d5b0 Add unit tests for hmbkp_is_function_available
284
- dddd1f8 Check if exec is available before using it
285
- aaf06c1 Introduce a function to determine if a function was disabled in the PHP config
286
- d3ac584 Merge branch 'master' into issue-597
287
- 225aea9 (tag: v3.0.2, origin/gh-pages) Merge pull request #610 from humanmade/phpdocs
288
- bee261b (phpdocs) Change composer flags
289
- 6b354f1 Need to call bash to run script
290
- b69921c Display debug info
291
- f3e0391 Merge branch 'master' into phpdocs
292
- 14a67f2 Ignore PHP Docs and Vendor during build
293
- dd37733 Rename hmbkp pot file
294
- a223cc1 Changelog
295
- 128e6ab Update readme
296
- 5c8308c Update translatable strings
297
- a9a30d0 Regenerate CSS
298
- 01fd58a Bump version
299
- 4cc2f99 Add github user info
300
- f43e036 Regenerate encrypted notification key for Hipchat
301
- 245b460 Regenerate composer lock file
302
- aeeb8b2 Merge branch 'master' into phpdocs
303
- 14912a5 Merge pull request #600 from humanmade/issue-600
304
- e8f2993 Merge pull request #347 from humanmade/issue-347
305
- 5d89edd Calculate site size on page load
306
- f45f1ab Pull out logic into own function
307
- bdc0572 Add parenthesis to require_once
308
- d8158a9 Remove disk space info
309
- a358977 Merge branch 'master' into issue-347
310
- ea2687e Merge pull request #614 from humanmade/remove-custom-webhook
311
- 9483558 Merge branch 'master' into remove-custom-webhook
312
- 621e73b Merge branch 'master' into issue-600
313
- 54eda33 Merge pull request #611 from humanmade/fix_unit_tests
314
- aae1791 Attempt to fix build
315
- 431df76 Merge branch 'master' into fix_unit_tests
316
- 7ae6772 define WP_TESTS_DIR
317
- bca3838 Make sure current_action fnction is loaded
318
- e004fe0 Remove extra slashes and semicolons
319
- 4f35f2a Use Travis env var
320
- 5126fb4 Last try
321
- 8bd5d53 Try Travis var unquoted sigh
322
- 4145a4a Actually load the HMBKP_Path class
323
- 4e32368 Merge branch 'master' into hmbkp-path
324
- 16fb29c Remove the custom webhook service
325
- a595864 Better default WP_TESTS_DIR
326
- c6583bd move trailingslash calls out of the loop for performance
327
- 272d663 Stop excluding duplicate backup directories
328
- b4de446 Update wp-cli to use hmbkp_path
329
- 0286823 Introduce a HMBKP_Path class to replace hmbkp_path();
330
- 56b7aee Minor code cleanup
331
- aeabc8c Merge pull request #599 from humanmade/issue-599
332
- b816d56 Correct path for hm-backup so it's tests are run
333
- ac40ab7 try this
334
- 4ac18e0 other syntax
335
- db7873f Try just a subfolder
336
- 0ab3771 try another thing
337
- ca4dfed test
338
- 7a35636 debugging travis
339
- 563e16d Try using travis var
340
- c702657 Warp var in quotes
341
- 27833f0 Fix invalid command
342
- 00db4f7 Use env var
343
- cd4042f Add list of ignored folders
344
- 6c6348a Update composer lock file
345
- 064653f Set required version to dev-master
346
- c99feb1 Fix deprecated call
347
- 5cef443 Don't test PHP 5.2
348
- 36279c1 Rename script
349
- 4bb9cea Install composer requirements
350
- d29dc96 add composer.lock
351
- e707f13 Use scrutinizer code coverage
352
- 02c1cd6 Merge pull request #609 from waffle-iron/master
353
- 99084c6 Ignore vendor
354
- f80d6ca Add composer
355
- da54899 Add custom documentation script builder
356
- 68e5a49 Add PHPdoc tasks
357
- a9510b5 add waffle.io badge
358
- 16bf682 Use up to date commands for coverage
359
- aadcac6 Add code rating
360
- 4be70a3 Don't test 5.2
361
- dced064 Update readme.md
362
- 496dfab excluded_dirs is deprecated
363
- 277134b Update scrutinizer config
364
- 6ff23df Add composer config and dev dependencies
365
- 93d76ec Make PHPUnit generate an XML for coveralls
366
- b19656e Add scrutinizer config
367
- de04025 Ignore vendor dir
368
- b480376 Add a link to Help page
369
- 288b562 Move to activation hook
370
- 863fd4c Bump up required WP version
371
- a42df0e Escape all the things
372
- 86dee22 Save errors to a notices option
373
- 275727b Reload page on errors
374
- 6cc016b Remove script
375
- 25fa141 Remove unneeded class
376
- 9fb9d09 Merge branch 'nice-errors' into issue-600
377
- 16f9a71 Check PHP version on plugins loaded
378
- cb50705 Check PHP version on activate
379
- ca0bdcb Merge branch 'master' into issue-599
380
- ad7545a Merge pull request #522 from humanmade/issue-522
381
- f3c1926 Merge branch 'master' into nice-errors
382
- cd9f659 Update readme
383
- 7e56616 Set required version to 5.3.2
384
- a1e232a Update tests
385
- f5b647d Merge branch 'master' into issue-522
386
- c3a4120 Merge pull request #567 from humanmade/issue-567
387
- 63828db Merge branch 'master' into issue-522
388
- fc8dc0f Merge pull request #559 from humanmade/issue-559
389
- ab910df Merge branch 'master' into issue-522
390
- 53dd5ec Merge branch 'master' into nice-errors
391
- 96463b5 Allow for a 30 second delta in asserting schedule time
392
- 28f3fee Merge pull request #603 from joshk/patch-1
393
- b2e6b4d Use the new build env on Travis
394
- 7003ac1 Restrict plugin to be network only
395
- ddc10dc Fix admin URL logic
396
- 80bac40 Merge pull request #571 from humanmade/codesniffs
397
- 7d372a7 Formatting
398
- 1554f59 Merge branch 'master' into codesniffs
399
- a3360a5 Merge branch 'master' into nice-errors
400
- 3588d85 Update readme changelog
401
- 8ee1642 Bump version
402
- aa02f24 Ignoe history log
403
- f441eec Merge branch 'master' into nice-errors
404
- a33db27 remove uneeded images
405
- 1bc5460 latest hm-backup
406
- ed1cf87 latest hm-backup
407
- a9d5bf3 Latest hm backup
408
- ac9daea Added known errors and nice messages
409
- d5ab157 Fix the support button splitting on 2 lines when too many tabs
410
- 74f7298 Spaces
411
- 4866fb7 Merge branch 'master' into nice-errors
412
- 19a7c14 Typos in v 3.0 changelog
413
- 8011d69 Specify POT filename in grunt task
414
- feac2fa Update POT file
415
- e86b19c Markdown readme
416
- 8452647 Regenerate readme
417
- b6ed354 Add plugin headers
418
- 5f0ced8 Fix semicolon
419
- 7d94870 Merge branch 'master' of github.com:humanmade/backupwordpress
420
- 572479e Refactor the recursive filesize scanner
421
- 611fe90 correct text domain
422
- 028a406 Merge pull request #556 from humanmade/issue-556
423
- d252312 Merge pull request #580 from humanmade/issue-580
424
- f45eb75 Merge pull request #584 from humanmade/update-backdrop
425
- 6a5053b See if this fixes tests
426
- b9bf7f6 Remove unneede statements
427
- ab6d058 Use correct action hook
428
- b4f9c9e Fix display notices
429
- 6ba1774 Set notices
430
- cdf4b01 Formatting
431
- c31db46 Merge branch 'master' into nice-errors
432
- 104c0ea reload the excludes filelist in the correct place when someone excludes a file
433
- 6a78aa9 Latest backdrop
434
- 1507855 Regenerate minified CSS
435
- c6f6b19 Regenerate minified JS
436
- f141d82 Fix cancel backup action
437
- b18075d WordPress Coding Standards
438
- 1bf78f3 Exit early if incompatible version of WordPress
439
- 0371f2d Update translations
440
- 7d10add Update changelog
441
- 9135ff1 Merge pull request #573 from humanmade/design
442
- 834e55f Load minified CSS
443
- 026d280 Formatting
444
- fd7f6f3 Biweekly wording
445
- 2baaa0f More Yoda conditions
446
- 9373e66 Spaces
447
- 61672e1 Comma after last array element
448
- 2fd458e Yoda conditions
449
- f61f8cb Add missing period
450
- 27d076c use nonce_url instead of manually adding the nonce query param
451
- 309a57c close the settings form when done
452
- f2cefe0 Design changes as per ticket
453
- b965549 Start tracking langauge in server info
454
- e2e1484 Right align the primary button in the enable support modal
455
- b9302b2 Re-factor the directory filesize code to use a single array instead of thoussands of transients
456
- fd5e4b7 Remove the warning that would show if you were using anything other than the latest stable, it's no longer needed now that the FAQ is local
457
- 2ec7406 switch to using a single transient to store directory filesize data
458
- e7668ab Merge pull request #552 from humanmade/issue-552
459
- ecf868b Merge pull request #562 from humanmade/enhancement/issue-562
460
- 66dfebe Add an anchor link
461
- c10a760 Add error message
462
- d9f2f64 Rename function
463
- 205355d Prefix GET params
464
- 4424535 Update exclude rule action
465
- a40fb52 Adds function for building admin action urls
466
- 0bb6d12 fix vertical scroll
467
- 1349691 Adds some functions to manage settings form submission errors
468
- cd5ca41 Rename nonce and action
469
- bf5eeb4 fetch errors to display
470
- 1461319 Form submission handling for BWP and add-ons settings
471
- 2e753d6 Use a new function that persists form submission errors to a transient
472
- 1379329 None check
473
- 8f8e84c Pass the nonce around in the ajax request
474
- dd220c9 Enable support action links
475
- db63646 Check nonces
476
- 689cf4e Modify action URLs to use the admin_post hook
477
- b3926bf Remove unneeded code
478
- be579ff New line at end
479
- 0b8a892 Use admin_post hook
480
- 784733f Merge pull request #502 from humanmade/stream-integration
481
- e9d20dc Merge pull request #554 from humanmade/fix-display-schedule-time
482
- 6a3ac22 Display schedule start time in local timezone
483
- 4f20f32 (tag: 3.0.0-beta) Update change log
484
- 6342aad Remove duplicate file
485
- f9ba00d update read me.md
486
- 010159a Update translatable strings POT file
487
- 8e93e09 Bump version
488
- ca037bd Bump nom version
489
- f6b3e6b Update min WP version and tested up to
490
- 73ba64d Bump version
491
- f37c3dc Merge pull request #482 from humanmade/re-design
492
- 61f644d fix some more issues with time
493
- 7727c51 try fixing the time
494
- d3c93b8 exclude tests dir from test backup
495
- 075023c PHP 5.2 compatible time mock
496
- 5fb1475 fix tests bootstrap
497
- 743f9b1 Update tests shell script
498
- 7aeb0f9 Update tests config
499
- fcaa5e6 Use HTTPS URL
500
- 64d38aa Merge branch 'master' into re-design
501
- 7da213c Merge pull request #536 from humanmade/fix-transients
502
- 8eb71c9 Update tests shell script
503
- ad16c2c Update tests config
504
- d435898 Make it clear we want one week
505
- f538a4b Display our notices - still WIP
506
- b136062 Add a class to track common errors and their nice message
507
- 7331c01 Add a notices class.
508
- 5e6e858 Reload the page to display notices
509
- 480e56a Set our notices option in the database with the backup errors.
510
- 16d08a5 Handle the dismiss action for backup errors
511
- afe325c Include the notices and errors classes
512
- fa4a7a1 Add a singleton to handle known errors thrown by backups
513
- 29c5795 Add remaining disk space
514
- e97f76b accidently used dash instead of underscore
515
- 4e76cf8 namespaced option and added option to uninstall.php
516
- 628486c basic show/hide of premium upsell
517
- ee76b21 Merge branch 'fix-transients' into nice-errors
518
- 3e8060b Merge branch 're-design' into nice-errors
519
- 2eaa37e Merge branch 'master' into nice-errors
520
- 07e61d1 Set BWP WPR web hook url to live url
521
- b870d0f BWP webhooks - 2nd iteration
522
- 1b4ce2a Fix incorrect transient expiry
523
- 13526d8 Add an action hook that gives access to consumers to the backup progress
524
- 0f82eb7 Merge pull request #406 from humanmade/issue-406
525
- 14bb5fc Show the spinner in the tab if a schedule other than the current is running
526
- 7ad8cdb Snip snip
527
- 5cf3737 Bring back the some javascript enhancements
528
- bb41a2b Switch to the PHP 5.2 compatible version of Backdrop
529
- f9bbe62 Finish up support
530
- fb1a135 Brace up single line if's and foreach's
531
- 613100a Only load minified scripts and styles if WP_DEBUG isn't on
532
- d656ee5 Load the minified css and js files by default
533
- 1fea51c Remove the combined css files as we only have one now. Stop loading colorbox.
534
- 0922885 Remove colorbox
535
- 259476d Merge branch 'master' into re-design
536
- cc3bf2d Merge branch 'master' into re-design
537
- 332c84f Improvements
538
- bb112ea More improvements
539
- f33e735 Latest BackUpWordpress
540
- 43d1f7b Don't die when directly running a backup on page load
541
- a03b0ab Re-factor the backup filesize calculation
542
- 4c1f49a make capability filterable
543
- a8b4cbc use core capabilities instead of custom
544
- 0715c88 Switch to Backdrop
545
- b250577 Merge pull request #486 from humanmade/feature/486-exclude-directories-default
546
- 94125e6 Fix typo in prefix
547
- ee06cd5 Merge pull request #523 from humanmade/build-tasks
548
- 03c2ff7 Hook function onto admin_post
549
- b3d776f Update delete link
550
- 72be8d2 Bookmark current admin page for redirect
551
- 44243ca Add custom capabilities and role
552
- 60815cd Exclude BackUpWP by default
553
- 0c97e6f Merge branch 'master' into feature/486-exclude-directories-default
554
- e569fbb add fake endpoint
555
- 9cf9a82 Configure WP Remote webhook on instantiation
556
- c170405 Inject the schedule to the constructor
557
- 33d8e59 JSON encode body
558
- 0d903b7 Sanitize URL
559
- 2952179 Encrypt the header with WPR key
560
- a0e3ca3 Ignore the build folder
561
- 75e492d Add more build excludes
562
- d3a8ceb minify JS
563
- cd15331 generate markdown readme
564
- 0126061 minify css
565
- 737d1c2 combine css
566
- 17f8975 regenerate readme
567
- 1eeed38 Make links consistent for the grunt task
568
- 8a6d52f Convert URLS to markdown
569
- f04f804 Update lang files
570
- 06eb230 Add colorbox as bower dependency
571
- 1d4066a remove colorbox folder
572
- 402129b Remove colorbox submodule
573
- 2015eb2 Change how we include FAQ
574
- 8b72677 Add readme partials
575
- 87e4cbf Add package.json
576
- f70a6fd Add Gruntfile
577
- f5253b6 Add bower.json
578
- 8d9760a JSHint rules
579
- 89975f7 remove from ignore
580
- 452320d Update ignore list
581
- 0e59aa8 Add bower config
582
- f16e93a Add FAQ strings
583
- 344d9ba Return the cached directory size early if we have it
584
- bac6613 Re-factor the file browser scanner
585
- 3fbcb3f correct sprintf usage
586
- ba52842 Handle saving service forms
587
- 9aa9396 Merge branch 're-design' of github.com:humanmade/backupwordpress into re-design
588
- c32babc Codeing standards
589
- b882cd9 Move the error check outside of the foreach
590
- 38633d8 Remove uneeded $is_tab_visible
591
- b515c6c Only show excludes for backups which include files
592
- 918c984 Show destinations in the list of schedule links
593
- 6e3a449 Merge pull request #514 from humanmade/issue-514
594
- dc33eac Fix property name
595
- 12f791b Fix property name
596
- aa90eaa Return errors
597
- 631b382 Add the remote post action
598
- 5b01a1e Start on the remote post
599
- cd03423 Display and validate settings
600
- 0e3ab94 Include webhook class
601
- cdf5085 Begin a webhook class
602
- 67e97b9 WordPress standard modal for enabling support
603
- 5e3e235 Remove extra slash in include path
604
- 778403a Add a heading to the settings form
605
- 069b7e0 More work on excludes
606
- 005fe7b Another todo
607
- cd6c7b6 Add some todos
608
- a36e27a Don't include the parent directory in a browsable list
609
- c590af0 More work on Excludes
610
- f0b1678 Merge branch 'master' into re-design
611
- 936bfde Switch to only storing 3 backups by default
612
- 29f7dfa More work on redesign
613
- 49f444f Merge pull request #507 from humanmade/update-travis-tests
614
- 31b7bcb update paths
615
- 0fef6aa fix plugin path for tests
616
- 7a06dab Change bootstrap
617
- 2bce541 Use the new develop WordPress repo for testing
618
- aebfe53 Merge pull request #445 from elliott-stocks/enhancement-heartbeat
619
- 971bdfd Small typo in readme
620
- 4c039fc (tag: 2.6.2) Bump for 2.6.2 release
621
- 77255e3 Merge branch 're-design' of github.com:humanmade/backupwordpress into re-design
622
- 8372afa Merge pull request #495 from humanmade/revert-3e213ac
623
- 73200a8 commented out enable support button till we figure out what to do with it
624
- a26419f made tabs responsive below 639px
625
- 7e3ff9b Revert https://github.com/humanmade/hm-backup/commit/3e213ac2bbd06d02383ed5290d6475cc1bed0c36
626
- fc00c91 (tag: 2.6.1) Bump ready for 2.6.1
627
- 29ea240 Merge pull request #490 from rmccue/fix-tests
628
- fa3b97c Merge pull request #493 from humanmade/bugfix/add-nonce-check
629
- eb38af9 Add a nonce check to the schedule submit form
630
- edcd9ff Add redirect to heartbeat tick
631
- f8bb0dd More work on redesign
632
- d7e1300 Remove unnecessary code, add heartbeat functionality
633
- 4feafb9 Remove hmbkpRedirectOnBackupComplete
634
- c9ecd92 Enqueue heartbeat API
635
- b2121e1 Allow output to be returned for AJAX requests
636
- 8eb475e Add heartbeat received filter
637
- 207791c Use long-hand ternary for PHP 5.2
638
- d78df49 Remove namespaced code
639
- d624d64 Add more default excludes
640
- 6d11b42 Merge pull request #481 from humanmade/bugfix/481-fix-schedule-hours-display-local
641
- bef64d0 Merge pull request #487 from humanmade/bugfix/487-fix-excludes-rule-delete
642
- f5f50b8 Revert "latest hm backup"
643
- 929a93c Remove resize_options var
644
- 6b516e5 Revert "latest hm backup"
645
- b5ae8b1 Calculate local time for display
646
- 15a2e57 Correctly highlight the tab for the first schedule
647
- 2c3b3a7 Switch to tabs instead of subsubsub
648
- 44602bb latest hm backup
649
- 22768fe (tag: 2.6) Add a couple of missing change log points
650
- a0c705e First bash at a redesign settings UX
651
- ff4aa1e Merge branch 'master' of github.com:humanmade/backupwordpress
652
- be23fbc Fix a minor style issue with long exclude rules in the exclude rules table
653
- 2478775 Hide tabs until the modal is fully open
654
- f7e6c11 Merge pull request #477 from humanmade/fix-cancel
655
- e20d3a2 Bump for 2.6
656
- dab17ec Adds a missing id attribute to the max backup input so that the label works correctly.
657
- 8bc62e1 Fire actions for services first so that they come before the main status settings.
658
- bbad481 Deletes the backup running file in the cancel backup action
659
- 349fb51 Some minor CSS / JS improvements for colorbox
660
- 8ad272f Merge pull request #476 from humanmade/issue/fix-prefix
661
- 04fc42d spacing
662
- 3487b08 spacing
663
- 1daf76e fix textdomain
664
- 5b0e1ad declare vars explicitely
665
- c822fcb Merge pull request #428 from humanmade/running-schedule-start-time
666
- 2135da8 Merge branch 'master' of github.com:humanmade/backupwordpress
667
- 3d9f294 Avoid deleting the backup running file in hmbkp_cleanup
668
- 58a8118 Introduce get_schedule_running_timestamp and use it to show how long the current backup has been running for
669
- 43df7af Merge pull request #260 from humanmade/home-path-fix
670
- 78b5168 Merge branch 'refs/heads/master' into home-path-fix
671
- 669077d Merge pull request #459 from humanmade/button-spinner
672
- ab829f1 Merge branch 'refs/heads/master' into button-spinner
673
- 1e944ee Pull in fix for home_path from upstream
674
- 1320452 Merge pull request #474 from humanmade/trim_multiple_email
675
- 7e2bee3 Merge pull request #372 from humanmade/feature/schedule-recurrence-settings
676
- b10292a Move the spinner outside the button
677
- 124d3b4 Disable buttons while the ajax request they just triggered is running
678
- 2d07f4b Remove a redundant usage of sprint_f and correct the argument order for another.
679
- e156229 Brace up and trim any whitespace from $email
680
- 9c6a602 Only call set_schedule_start_time if we have a start time
681
- 3ee4f6d Fix notice
682
- fcbbce5 return 0 if we are passed a type we don't recognise
683
- 344d98c s/reoccurence/recurrence
684
- 5e61c67 Only show the total calculated schedule size when editing a schedule
685
- 86b1caf s/dpesnt\'t/doesn\'t
686
- be40709 Don't strip 0 from minutes in the schedule sentence otherwise 10 becomes 1
687
- 39ab8ef Let's die instead of just echo'ing the error message as it's cleaner
688
- fd3283c Introduce HMBKP::refresh_schedules to force schedules to be reloaded from the DB and use it when re-setting up the default schedules.
689
- 20b648d Finishes up the unit tests for hmbkp_determine_start_time
690
- c123b35 Merge pull request #472 from humanmade/fix-cli
691
- 611cce0 Use updated syntax for WP CLI.
692
- b8c230b Merge pull request #470 from humanmade/issue/470-update-upsell-link
693
- 27c37c8 Updates instances of bwp.hmn.md URL to https
694
- f9e138e Re-factor the underlying logic that allows the schedule time to be set + unit test
695
- 971f444 Merge branch 'master' into feature/schedule-recurrence-settings
696
- 6f0cacc Merge pull request #463 from humanmade/remove-deprecated-function-463
697
- 9116508 Remove deprecated function and fix translatable string
698
- 2972dee Merge pull request #461 from humanmade/various-typos-fix-461
699
- c75e504 Corrected 'back ups' typos
700
- 70e7f05 Cleanup whitespace
701
- c72c269 Hours and minutes can be 0 so we can't use ! empty
702
- 071cba7 Revert to previous state
703
- ec64df7 Merge branch 'master' into feature/schedule-recurrence-settings
704
- 53e886c Merge pull request #455 from humanmade/constant-help
705
- 261b370 Minor improvements to the server info tab
706
- f756417 Merge branch 'refs/heads/master' into constant-help
707
- 9fd2841 Merge branch 'refs/heads/master' into origin/feature/schedule-recurrence-settings
708
- 8db93e6 Minor copy / layout improvements
709
- 091b3ec Float the time fields right so they match the style of the other fields
710
- 9dbe724 Merge pull request #456 from humanmade/unreadable-root
711
- e268787 chmod the custom path so it's always possible to remove it
712
- 251123b Make sure the directory we are about to pass to RecursiveDirectoryIterator is readable
713
- 235ff2b Avoid a notice if there aren't any schedules
714
- d653463 Zebra stripe the table
715
- 21cc2dd Don't allow the plugin to function if the root dir is unreadable.
716
- ee0c87f Improve the layout of the Constants help panel
717
- 46dbc0e (tag: 2.5) Bump time
718
- 6f1949b Remove the old plugin.php file, having it symlinked didn't work anyway
719
- 60f9e7c Stop passing $_SERVER to Intercom
720
- 3657fc2 Show long strings on their own line in the enable support popup
721
- 1d3587c Improved positioning for the .subsubsub spinner
722
- 2a637d7 Merge branch 'master' into feature/schedule-recurrence-settings
723
- 21cbb74 Merge pull request #426 from humanmade/pass-display-name
724
- 712fa56 Merge pull request #420 from humanmade/pass-bwp-version-intercom-420
725
- a2b2473 Merge branch 'master' into feature/schedule-recurrence-settings
726
- ef0e2e7 Pass display name instead of nickname
727
- 7b0bd20 Merge branch 'master' into pass-display-name
728
- 42f67b5 Merge branch 'master' into pass-bwp-version-intercom-420
729
- 97f1a36 Couple of line breaks missing
730
- af74250 Merge pull request #371 from humanmade/wp-is-writable-function-371
731
- c36350d Merge pull request #427 from humanmade/pass-timeout-intercom
732
- efc592e Merge branch 'master' into wp-is-writable-function-371
733
- 77c5c76 Update UTM
734
- f4fb3f0 Clean up readme
735
- 94193bb pass display name to intercom
736
- 68832dc Send max execution time to intercom
737
- 338033a Add Plugin version to server info
738
- 403920b Merge pull request #446 from humanmade/close-php-session-446
739
- 6286e2f Merge pull request #443 from humanmade/use-new-spinner-443
740
- 326c3bd Merge pull request #450 from humanmade/contributing-instructions
741
- 4fb0f98 Translations instructions
742
- d653fb4 Merge branch 'master' into feature/schedule-recurrence-settings
743
- 04d1814 Merge pull request #442 from humanmade/minimum-3-7
744
- c44a934 Use new spinner
745
- 7a6bb3e Fixes an issue on servers which only allow a single session per client
746
- cfa942c Made sure resize_options is defined inside catchResponseAndOfferToEmail
747
- 37749d1 Merge pull request #434 from humanmade/filterable-from-email
748
- 24c9a9e Merge pull request #441 from humanmade/update-lang-files-2.4.2
749
- 8728da9 Make the from email address filterable
750
- a94d8d0 Bump the readme to require WordPress 3.7.1
751
- 1d5de52 Stop testing against 3.6
752
- 7311226 Get rid of some stray double line-breaks
753
- 31cc2e3 Stop checking the minimum supported PHP version
754
- d632660 Remove back-compat time constants
755
- a3839d2 Bump the minimum requirements to WordPress 3.7.1
756
- 45c624a Merge branch 'master' of github.com:humanmade/backupwordpress
757
- 71c2f54 master is now 2.5 alpha
758
- f9d5748 fix email address
759
- 152625a Update text strings for 2.4.2
760
- 1edb037 latest hm backup
761
- 7d4de70 Merge branch 'master' into feature/schedule-recurrence-settings
762
- 659a124 Merge pull request #407 from humanmade/safer-redirects
763
- fd826b0 Remove stray line break
764
- 2d6b0e2 (tag: 2.4.2) Readme for 2.4.2
765
- a064ca7 2.4.2
766
- 0726166 2.4.1
767
- 03baa8a Merge pull request #324 from humanmade/multisite-admin-324
768
- 58eece6 merge master into current branch and fix merge conflict
769
- 9edbf3d Merge pull request #394 from humanmade/load-bwp-first
770
- 77d346d Merge pull request #440 from humanmade/travis-test-wp-3.8.1
771
- 4217648 Merge pull request #437 from humanmade/filesize-failure-437
772
- dc1339d Merge pull request #439 from humanmade/intercom-file-sizes-439
773
- f3d07ce suppress error messages for filesize
774
- 84897fc Get calculated sizes of active schedules instead of calculating on every page load
775
- 74b23dd Merge pull request #417 from aubreypwd/master
776
- cf29bc0 do not test older versions of WP
777
- 68b670d test with WP 3.8.1
778
- 5147559 Merge pull request #438 from humanmade/shell-exec-test-432
779
- 95b586f test for function availability
780
- 07569fc Merge pull request #433 from humanmade/fix-php-notice-433
781
- a4310d5 Merge pull request #432 from humanmade/shell-exec-test-432
782
- 5344978 test for availability of command
783
- 9613f80 Fix PHP notice in default excludes functionality
784
- 7e11ff5 (tag: 2.4.1) Bump stable tag
785
- e0b5390 Bump for release
786
- 6546fd3 Merge pull request #412 from humanmade/exclude-cache-folders-412
787
- 1b49d2e Fix resize_options
788
- 139da4e Modal fix for long paths
789
- f3cb4e7 Fix issue where modals showing underneath WP Admin bar
790
- 7ac0c0a Add trailing slash to found folders
791
- 8e0c55d Add trailing slash to excluded folders
792
- 5a0b4c4 Code formatting
793
- 7365f17 Exclude cache folder by default
794
- 5bccad8 ensure bwp is activated before addons
795
- 439917f fix merge conflicts
796
- 1cb3651 Test against PHP 5.5 and WordPress 3.6/3.7/3.8
797
- 604c004 Merge pull request #411 from humanmade/rename-filesize-transient
798
- d6f5994 Rename file size transient to contain the backup type, so we don’t need to clear the cache when a schedule type is modified
799
- fe66aa0 Merge pull request #405 from humanmade/use-correct-escaping-functions
800
- 09ef19f Merge branch 'master' into use-correct-escaping-functions
801
- a410fc9 Merge branch 'master' into safer-redirects
802
- f135020 colorbox changes
803
- 923fa00 latest version of hm backup
804
- 49d3d6f reset hm-backup submodule to previous commit
805
- 44efeea use wp_safe_redirect
806
- cd7d7b3 no need to internationalise non language attributes
807
- 67316bc formatting and spacing
808
- becb46b Latest HM Backup
809
- 0037829 Merge pull request #402 from humanmade/revert-cherry-pick-time-settings
810
- 22c3efd remove the time settings that were wrongly added
811
- 2ff6ed9 Merge branch 'master' into feature/schedule-recurrence-settings
812
- 1e76c20 resolve merge conflict from cherry pick
813
- 20d41e1 Reload page on close modal so settings are refreshed
814
- c84d40a Branch out logic by detecting if submission was from destination form. If so, no need to process recurrence settings. Just service settings.
815
- 4bbf4df Reload page on close modal so settings are refreshed
816
- 5a19f66 Test recurrence settings
817
- 315bf8d adjust CSS
818
- efa03c6 use a div
819
- d983941 escape square brackets in ID selectors
820
- ba79dd0 wrap min hours with label to keep together
821
- 5a910ba move service validation
822
- 5a51719 use 24 format for input, remove AM/PM setting
823
- ee9cb46 only show twice daily note for that recurrence
824
- a54f489 make weekday strings translatable
825
- f24bd73 change textdomain
826
- cd52ef9 delete old backups before saving settings
827
- b1376b2 docblock and else curly braces
828
- 05fd873 indentation and formatting actions.php
829
- 6ba5ad3 prefix javascript functions
830
- 2fa06a9 Merge branch 'master' into multisite-admin-324
831
- 0a7bca1 Merge pull request #393 from humanmade/travis-encrypt
832
- 5456f14 New encrypted hipchat API token
833
- eb3b8a2 Merge pull request #387 from humanmade/fix-transient-387
834
- 4f0155e Latest HM Backup
835
- ef4a4b5 use get_transient to retrieve value
836
- 118753e Merge branch 'master' into wp-is-writable-function-371
837
- 6461824 Merge pull request #391 from humanmade/feature/service-intercom-data-function-390
838
- 5e3019e add the service constants to the intercom data
839
- 21d7849 display any service constant
840
- 842557e just return an empty array for now
841
- f714c4d alternate function for display
842
- e52e13d intercom_data should be static so we can call it with call_user_func
843
- b5e196a add the ATTACHMENT_MAX_FILESIZE email requirement constant
844
- e9a6f60 email intercom data is managed by BWP requirements class already
845
- e63a263 Merge pull request #389 from humanmade/bugfix/swapped-arguments-path-accessible
846
- 862db2e Merge pull request #390 from humanmade/feature/service-intercom-data-function-390
847
- 8f79d47 adds abstract function intercom_data
848
- 0d95733 input validation improvements for schedule form
849
- 31fe7bd return false if not set
850
- 5e262f2 arguments were swapped in the function that checks if home path is contained in the backups dir path
851
- 3615f44 set default schedule type
852
- 85bd820 only instantiate schedule if no errors
853
- dfaa12f we need this without instantiating a schedule
854
- 53bbf89 set recurrence when setting start time
855
- edada0e better validation
856
- 488aaf0 make sure there are no errors before saving
857
- 838f858 Merge branch 'master' into feature/schedule-recurrence-settings
858
- 8e8c20c add default day of month
859
- 19b8043 change input default value
860
- 0aba13c update schedule tests
861
- 4ae2feb use set schedule start time for default schedules
862
- 835670e default arguments for setting schedule start
863
- 3e38b6a fix backup action URLS
864
- 1708a6e return zero instead of WP_Error
865
- f2b314c schedule form field validation
866
- 70d091f more network_admin_url
867
- ecd1995 stupid mistake
868
- 0c344b2 fix syntax error
869
- 0954b51 use network_admin_url
870
- bb98cbb update more references to tools.php
871
- 0d6d33c Merge pull request #377 from humanmade/server-info-help-tab-377
872
- 67878a3 refactor by using a constant and only 1 conditional
873
- d5f15ef Merge pull request #381 from humanmade/use-wp-mkdir-p-381
874
- fa5ade1 Merge pull request #303 from humanmade/invalid-reoccurence-fix-303
875
- 061c7dd we should not use the constant here as it may not be defined.
876
- 335934f sets schedule start time for manual backups
877
- 16fde51 check that var is set before output
878
- 3d27331 schedule start time is now an option
879
- e298fc0 if the recurrence type is invalid just force it to manually
880
- 8df5d08 adds server info tab to help screen
881
- c442a8d replace mkdir with wp_mkdir_p
882
- bdaf86c move BackUpWordPress admin to network settings on multisite
883
- 4ede7ac Bump required version to 3.6.0
884
- 3ee284d Use wp_is_writable wherever is_writable was used.
885
- 2da238d Update CONTRIBUTING.md
886
- f985cfb Update CONTRIBUTING.md
887
- 5126579 Update CONTRIBUTING.md
888
- 3247144 Update CONTRIBUTING.md
889
- cdd9787 refactored the schedule recurrence logic
890
- d89a74b Add new schedule UI and logic
891
- 525a856 do not define the schedule start time constan by default
892
- f2eb346 Merge branch 'feature/schedule-recurrence-settings' of github.com:humanmade/backupwordpress into feature/schedule-recurrence-settings
893
- 0f31c11 prefix attribute
894
- b0f80f9 more recurrence logic
895
- 33d87c3 hide / reveal recurring settings based on chosen schedule
896
- d43f03f adds the day and time fields to the schedule settings form
897
- 53711e2 Merge pull request #379 from humanmade/update-po-mo-files
898
- 8eaba4e Merge pull request #380 from humanmade/update-colorbox
899
- 8efc03f update to latest colorbox
900
- 3d49129 Merge branch 'master' of github.com:humanmade/backupwordpress
901
- cd1ecab add new updated language files
902
- 3a29a70 updates po/mo files with latest strings
903
- e2544a5 Merge pull request #376 from humanmade/dont-hide-delete-links
904
- a72bea6 Release notes
905
- 3ce9d7a Correct translation function
906
- 7409e35 Latest HM Backup
907
- 1201ee5 Bump and release notes
908
- 2146eb3 Only hide download links when the backups directory isn't web accessible as deleting will work.
909
- ddd5d67 Merge pull request #366 from humanmade/enable-intercom-support-366
910
- b85ef87 Code comments
911
- e48d1ab Make a string translatable
912
- 7138bb2 Organise tests into more logical groups
913
- 1492f3f Store the result of the wp-cron test so we can pass it to Intercom
914
- dc9f415 Stop sanitising test names before passing them to Intercom
915
- cd8d6af Add new tests for site_url and home_url
916
- 9882fbd Better name for the support schedule that is created to calculate the backup size
917
- 8e208c8 Plugin filename should be backupwordpress.php not plugin.php
918
- ab54dfd prefix attribute
919
- 6f3f689 Use the new option name in deactivation and uninstallation
920
- 91957c3 Merge branch 'enable-intercom-support-366' of github.com:humanmade/backupwordpress into enable-intercom-support-366
921
- 0c91659 Move the support opt-in flow to be part of the support button and generally improve things.
922
- 67255b9 Code comments / formatting
923
- 1e869c2 more recurrence logic
924
- a6214c0 hide / reveal recurring settings based on chosen schedule
925
- 49cf5c6 Merge branch 'master' into feature/schedule-recurrence-settings
926
- 50ea2be delete optin option on deactivate / delete
927
- 91e71ed prefix functions
928
- 0d9565f Merge branch 'refs/heads/master' into enable-intercom-support-366
929
- f7aaeec Fix a notice if $services isn't defined.
930
- 66299ff Merge branch 'master' of github.com:humanmade/backupwordpress
931
- 0f23353 Bump
932
- 7a5bb3b Merge pull request #375 from humanmade/no-backups-colspan
933
- d20677f Ensure the message shown in the backups table when no backups have been completed spans all 4 columns
934
- d500312 Merge pull request #286 from humanmade/disable-dl-link-286
935
- c31ebd6 Merge pull request #288 from humanmade/pass-page-slug-as-var-288
936
- aa793c1 Merge branch 'master' into enable-intercom-support-366
937
- ff0ef9e adds a button and a colourbox modal with server info
938
- ca91ca2 refactoring
939
- 1fba846 add requirements class from compatibility branch and the server table output
940
- 2825763 reload page on settings change
941
- a5fdbfd adds the day and time fields to the schedule settings form
942
- b71ee59 Merge pull request #370 from humanmade/correct-language
943
- 58eb3c5 remove some unnecessary code
944
- 3185ff5 spacing
945
- a446d50 adds an option checkbox for intercom
946
- 9f3e115 spacing
947
- b5699e3 add intercom user hash
948
- 653ba19 spacing
949
- af22b2d check if path is accessible before displaying download link
950
- 60299b7 correct some language
951
- a38818a pass page slug as var to js
952
- b5e7ef4 schedule sentence escaping
953
- c71eaa9 Merge pull request #369 from humanmade/upsell-pro-addons-369
954
- d51c007 rename add-on to extension
955
- 911aba0 Merge pull request #368 from humanmade/fixes-uninstall-file-refs
956
- 0963fd3 adds an upsell message to the footer of the main plugin page
957
- 123feb3 enables intercom contact and tracking
958
- 75176a6 fix wrong file paths in uninstall
959
- 4874655 Merge pull request #361 from humanmade/password-field-width
960
- b00011d Merge branch 'master' into password-field-width
961
- 3fae243 Merge pull request #364 from humanmade/better-schedule-sentence
962
- 9dfe5b5 Improve the way destinations are handled in the schedule sentence in 2 ways
963
- a3e8e2c Merge pull request #362 from humanmade/schedule-title-status
964
- c06a7fe Merge pull request #363 from humanmade/esc-schudule-status
965
- 8cc3746 Use wp_post_data instead of esc_html and status's can contain html.
966
- ffaaf21 Show the running schedule status in the title attribute when hovering a running schedule title (that you are not currently viewing)
967
- f5ba48b Slightly re-position checkboxes
968
- 504f137 Force password fields to be the same width as text fields in the model forms
969
- 91c888c Merge pull request #346 from humanmade/dev
970
- 6cd0e6f Merge pull request #354 from humanmade/dont-escape-plain-text
971
- 0c53304 no need to escape the email address
972
- 7e7e8b3 Merge pull request #352 from humanmade/formatting
973
- 4c57e93 Merge pull request #353 from humanmade/prefixing
974
- b333c74 Merge pull request #355 from humanmade/escaping-email-address
975
- e8d6b6d Merge pull request #358 from humanmade/get-slug-condition
976
- 81333b1 Merge pull request #359 from humanmade/remove-openbasedir-heck
977
- b4622f2 no need for this check, already handled elsewhere
978
- 4359c85 slug could be set to an empty string, so check this
979
- 9bf881c use echo esc_attr on non tranlatable strings
980
- e925dd7 is_email already trims
981
- 2619f72 few escaping fixes
982
- f3ae151 prefix functions
983
- 7a1a913 remove extra line returns
984
- 04de7d3 limit style to text input
985
- a8bf160 resolve merge conflict
986
- 8b53c84 Merge branch 'fix-excludes' into dev
987
- 0cc97c8 exclude WP DB Manager default folder the correct way
988
- 5178f63 use stable version of hm-backup
989
- 06a9af5 really add the escaping
990
- 196fc78 more escaping
991
- 814cac5 escape on output
992
- c4e4a12 WP Standards formatting
993
- db82139 bump version
994
- 304aad7 Merge pull request #345 from humanmade/change-filenames
995
- 7361bab Merge branch 'dev' into change-filenames
996
- 68ab430 Merge pull request #343 from humanmade/enqueue-fix
997
- 73d8465 fix merge conflict
998
- a699cc0 Merge pull request #344 from humanmade/title-translation-337
999
- 1372013 change version back
1000
- 6daa045 french PO-MO files ready to translate
1001
- 9a1d35c introduce a backups_number function
1002
- 43afad9 few internationalisation fixes
1003
- 40839ac keep string in one sentence
1004
- 2958288 make schedule titles translatable
1005
- c7da92b Merge branch 'master' into enqueue-fix
1006
- 31abee9 enqueue differently to fix colorbox failing to load
1007
- f2dadf3 Merge pull request #339 from humanmade/fixes-open_basedir-warning
1008
- 0263fa2 don't use $schedules var if its not set
1009
- 3e68fa8 nioce error message
1010
- 345eb5d constructors dont return
1011
- 8ac306b Merge pull request #336 from humanmade/dev
1012
- 6d6941a v2.3.3
1013
- 44be3bf fix enqueud style src path
1014
- fdf3253 (tag: v2.3.4-alpha) v2.3.4-alpha
1015
- e759433 Merge pull request #333 from humanmade/dest-form-logic
1016
- 332cf3b Merge pull request #307 from humanmade/fixes-307
1017
- 6c1282c Merge pull request #334 from humanmade/exclude-leftover-bwp-folders
1018
- e40f395 formatting
1019
- 021ea52 adds a function to exclude leftover backup folders
1020
- 3787e47 check if path has changed
1021
- 36d3994 Merge pull request #332 from humanmade/fixes-332
1022
- b8bd2f0 removes extra slashes in enqueue source path
1023
- c602a22 form close button logic
1024
- ff86c78 refactored include path
1025
- 9d62136 use WP standard file naming
1026
- 4b446e8 Merge pull request #327 from humanmade/exclude-backupbuddy
1027
- fdb5077 refactored default excludes function
1028
- e8fd153 excludes backupbuddy default folder
1029
- 6ebc8da Merge pull request #326 from humanmade/sched-sentence-325
1030
- 0968d27 Merge pull request #292 from humanmade/use-wp-error-292
1031
- d697ecf only show addon sentence part when service is active
1032
- 5336d74 Remove old test/lib submodule
1033
- 826ee0e 2.3.2
1034
- a6b8a1e fixes unmatched closing parenthesis and docblock
1035
- 85b439b replace last Exception
1036
- d1bfb62 replace more exceptions
1037
- 650284b Merge branch 'master' into use-wp-error-292
1038
- 89de7a3 Merge pull request #323 from humanmade/adds-latvian
1039
- e5f5dcf add latvian lang files
1040
- 871ca07 Update CONTRIBUTING.md
1041
- d688862 Merge pull request #322 from humanmade/contributing-file
1042
- fab67ce instructions
1043
- b316d37 Merge pull request #321 from humanmade/fix-remaining-sched-instantiation
1044
- b3eccce fixes left over direct instantiations of singleton class HMBKP_Schedules
1045
- 4f0697a fix conflicts
1046
- e28653d Bump
1047
- a66ab31 Updated Readme
1048
- e27fed3 Revert "Merge pull request #304 from humanmade/update-close-buttons"
1049
- f60064a adds wp db backup to excludes
1050
- a0b1693 Merge pull request #320 from humanmade/changelog-2.4
1051
- a758156 2.3.1 instead of 2.4
1052
- d807d75 cleaning ip
1053
- 859e729 adds default excludes and removes ability to delete rule
1054
- 7cb471f Ignore the .svn repo
1055
- 27c6281 Merge branch 'master' into backup-folder-excludes
1056
- b0946fd update change log for 2.4
1057
- 5d91d3f Merge pull request #304 from humanmade/update-close-buttons
1058
- 5269e6f check if services array is not empty
1059
- e0fcf3d Merge branch 'master' of github.com:humanmade/backupwordpress
1060
- fc9d1f2 add default excludes array and setup on schedule init
1061
- aa874ea Merge pull request #282 from humanmade/singleton-schedules
1062
- feb900e Merge branch 'master' of github.com:humanmade/backupwordpress
1063
- 09e7669 add default excludes array and setup on schedule init
1064
- f113843 make HMBKP_Schedules class a singleton as it contains all the schedules and only need one instance
1065
- 71a3ee5 PHP Docblock
1066
- 1cb9a9c replace Exception with WP_Error error handling in 2 places.
1067
- a8dcff8 Merge pull request #315 from humanmade/fixes-undefined-notice
1068
- 271807e declares and initializes it
1069
- 42def6d Merge pull request #301 from humanmade/fixes-broken-local
1070
- bd42c22 Merge pull request #294 from humanmade/updates-lang-files
1071
- 4118772 Merge pull request #296 from humanmade/better-schedule-sentence
1072
- ca95e99 Remove "These external locations" from schedule sentence
1073
- d5ec251 Merge pull request #299 from humanmade/contrib-guidelines
1074
- b5dd322 Merge pull request #305 from humanmade/fixes-297
1075
- 1018be8 Store the return value of wp_mail in $sent so we don't send multiple notification emails
1076
- 3cbeeba Merge branch 'master' of github.com:humanmade/backupwordpress
1077
- f0f668e fixes #297 typo in option name
1078
- c250471 avoid undefined error
1079
- 1dcb1e2 save and close are separate actions
1080
- 939de53 remove commented out line
1081
- a810ae9 fixes #300
1082
- 52acd9c Disable email notifications for Travis builds
1083
- 467bb37 create file
1084
- 06cb2ac Merge branch 'better-schedule-sentence' of github.com:humanmade/backupwordpress
1085
- 1304540 Merge branch 'master' of github.com:humanmade/backupwordpress
1086
- 7889da2 Whitespace ftw
1087
- 359cc21 Merge pull request #295 from humanmade/new-unit-tests
1088
- f2c0661 implode on comma
1089
- 1eb874d make schedue sentence more consice
1090
- 42a242b Update the Travis
1091
- 4184643 Switch back to using WP_TESTS_DIR instead of hardcoding the path
1092
- ed09bfa Rely on the WP_TEST_DIR environment variable instead of shipping the whole wp-tests dir with the plugin
1093
- 1b0c3e8 s/add_command/addCommand
1094
- 551bc26 Remove extra linebreaks
1095
- 74dca7c Bump
1096
- f0095a9 Fix a PHP strict error
1097
- b8a695a updates lang files
1098
- e478f98 Update the path to lowercase now that we've renamed the github repo to be lowercase.
1099
- a2c4ace Setup our wp-tests-config.php file
1100
- 1697012 Tag as released.
1101
- 452c93f Move dash inside of string
1102
- 9da8cfc Remove the trailing slash from the backup path before checking it's validity
1103
- a78358b Merge branch 'master' of github.com:humanmade/BackUpWordPress
1104
- 423c901 Bump ready for release
1105
- e8f1d8b Merge pull request #229 from humanmade/single-calculating-thread
1106
- 8773324 Laetst HM Backup
1107
- 155156e Revert the changes to assertArchiveContains and assertArchiveNotContains in favour of introducing new methods
1108
- 31d1f53 Normalise slashes in paths
1109
- b75830f Normalise paths before comparing them in assertArchiveEquals and assertArchiveNotEquals
1110
- 6167a7b Bump
1111
- c463181 Always delete the backups directory after each unit test
1112
- 6461e10 Coding standards
1113
- 502d34f Prefix the backup path with backupwordpress so it's obvious where to look to find your backups
1114
- a20440b Remove stray error_logs
1115
- 63e785d Bump
1116
- 5ce9138 Re-calculate the backup path on upgrade and move any existing backups there.
1117
- 46d7b95 Don't access the hmbkp_default_path option directly as it may not be set.
1118
- 2df5eae Correctly calculate the HMBKP_SECURE_KEY
1119
- f8e2a19 No need to wrap hmbkp_init in a function not exists check.
1120
- 0ba4ba7 Remove stray line break
1121
- 38aa2ed Don't indent the copyright notice
1122
- 1acb085 Bump for pre-release
1123
- d4e5b4e Remove the help text for the HMBKP_EMAIL constant as it has been deprecated.
1124
- 7aa1b16 Latest HM Backup
1125
- d6929cc Don't allow the filesize of the site to be calculated in multiple thread at once.
1126
- 0596cdc Don't highlight the HMBKP_TIME_CONSTANT example if it's set to the default setting as the constant is defined in the plugin
1127
- faaa524 Correct hipchat room
1128
- 7eba138 Remove square brackets as they break travis.
1129
- c73e61b notify hipchat of build status's
1130
- 68b3d2e Merge pull request #284 from humanmade/fetch-destination-settings
1131
- 3ea959d adds function to copy settings from previous schedule
1132
- 6d050fc Code comments
1133
- 222849e Don't allow a scheduled backup to run if it's already running in another thread. Will prevent issues where load balancers and proxies re-send requests that don't return within some arbitrary timeout period
1134
- 613ccc9 Beginnings of a HMBKP_Error class
1135
- 3857efc Code standards
1136
- 7462055 Latest HM Backup
1137
- e65220d Whitespace
1138
- 65160ec Make the exclude help string translatable.
1139
- 8841bd9 Set a maximum height when displaying the error message so it doesn't cause the modal to be larger than the page.
1140
- f33a1d8 when moving the backups directory, don't delete the old one if it's outside of WP_CONTENT_DIR
1141
- bcd01a3 Only move zip files in hmbkp_move()
1142
- 821dd9d If HMBKP_PATH doesn't exist then use hmbkp_default_path()
1143
- b05975d Don't delete non-backup files in custom paths
1144
- 28e4512 Code formatting
1145
- 5400d39 Ensure the database dump is uniquely named per schedule to avoid possible collisions when multiple schedules are running at the same time.
1146
- bca2783 Backwards compatibility for the time constants which were introduced in WP 3.5
1147
- 48e365a Don't bother testing all version of multisite, just test master
1148
- c70df6f Stop testing in PHP 5.5 until it settles down
1149
- 4ca88b3 Remove PHP 5.3 ternary operator syntax as it breaks when running unit tests on PHP 5.2
1150
- 89a5749 Test against all major releases of WordPress since 3.2.1 across all major releases of PHP since 5.2
1151
- 293c4f4 Latest HM Backup with all unit tests passing locally
1152
- 123c880 Reference the plugin using a case sensitive path in the phpunit config
1153
- e996f9c Switch to a https checkout for the lib submodule
1154
- d47259d Switch to our fork of the test lib
1155
- 00ef12b Latest test lib
1156
- 34992e2 Latest HM Backup
1157
- 8dd4e9b Only test against a single instance of WP for now
1158
- 6d57cc3 Tell travis to recursively clone in all submodules
1159
- 581e2c2 Add the travis configuration file
1160
- c075f16 Switch the submodule clone url for gm-backup to https
1161
- c19960e Merge branch 'master' of github.com:humanmade/BackUpWordPress
1162
- 1872998 Make the unit tests phpunit compatible
1163
- 42c679b Add pauldewouters as contributor
1164
- bf306f3 Don't try to update the manual reoccurrence during the 2.2.5 upgrade routine.
1165
- 2e9ecd0 Add a line break
1166
- 344e850 Code formatting
1167
- 5355300 Use correct escaping functions
1168
- 487383d Re-jig the maximum backups help text to make it more concise.
1169
- 97f2392 Remove trailing tab
1170
- 4b5844d Whitespace
1171
- f8d5864 Remove duplicate is_string check
1172
- e15c62f Whitespace
1173
- d571fcc Set the initial width and height of the colorbox and set the transition to elastic.
1174
- a6f8d1c Upgrade any stored schedule reoccurrences to use the new naming convention.
1175
- 64e034f Code formatting
1176
- 1971bdb Untab the whole file
1177
- 6a9b384 Use single quotes and add missing space between closing quote and parenthesis
1178
- 37b3284 Merge pull request #257 from humanmade/dev
1179
- 2c3dcda Merge branch 'master' into dev
1180
- 73e3e97 Merge pull request #273 from humanmade/varname
1181
- cd3f1b1 underscores instead of camelcase for consistency
1182
- 793a970 refreshed mopo files
1183
- b4dc5ae add new function to load translation files in a flexible manner, add POT file for translators, regenerate PO and MO files
1184
- 8eae498 add a new function get_cron_schedules for filtering cron schedules
1185
- 1222714 fixes Docblocks
1186
- 7e3f476 remove random debug plugin version
1187
- ae1450f Merge branch 'master' of github.com:humanmade/BackUpWordPress into dev
1188
- 7c392fc Merge pull request #263 from thomasclausen/patch-2
1189
- 3e154bd Merge pull request #264 from thomasclausen/patch-3
1190
- 4f29425 update docblocks
1191
- 1b85f50 do not remove option prefix
1192
- 6a9aaae deleted a log file
1193
- 8dd078b changed main plugin file name for consistency
1194
- 6f92376 custom cron intervals need to be defined as their own array with the interval as key
1195
- ce81c5a update interval names in more places to avoid fatal errors
1196
- 8bc348b updated schedul interval name with prefix in several locations
1197
- 4dc7f1e schedule enhancements
1198
- 941cc58 added missing schedules param and merge custom schedules
1199
- b7437b1 use constants in schedul intervals
1200
- 7ad2db1 just some indentation
1201
- bed981f remove duplicate activate function causing fatal error
1202
- 289d0e1 fix docblock
1203
- f891fe3 add activation function and internationalize message
1204
- 3c1d7ad corrected typo in message text
1205
- 7d5f3fa fixes #262
1206
- 2af8543 Merge branch 'master' of github.com:humanmade/BackUpWordPress into dev
1207
- 5a59a64 indentation
1208
- 92436fb Merge pull request #267 from thomasclausen/patch-5
1209
- 7fb077f Missing translation
1210
- 0c63da9 Merge branch 'master' into dev
1211
- 8242be8 fixed bug in colorbox error message display
1212
- 202366a input[type="number"] is too small
1213
- f04e78e Missing translation
1214
- fc6dbe4 move the max backup size after description
1215
- 20da959 change wording of max backup size
1216
- f21e1d1 remove unnecessary vars
1217
- 99bc4ab new function get_formatted_filesize
1218
- a3d7e56 fixes #255
1219
- 806e031 Use correct filename for Danish translation files
1220
- 9270246 Latest HM Backup
1221
- 2e3a353 Slight refactor, remove need for variable variables
1222
- 53eb85b Correct @return docblock param
1223
- e96d8c5 s/de-register/unregister
1224
- 98fb94e Code formatting
1225
- 75bbd3b Set abstract methods to public as they are expected to be implemented in child classes as public
1226
- b49f557 Set the @var to the class that the variable will contain an object of
1227
- c7c24ba Correct @return in docblock
1228
- c13e2b0 Remove an unused variable
1229
- 892bc12 Don't store the return value of wp_mail in an unused variable
1230
- 2412774 Make sure we always return a string, even if the conditions are not met
1231
- cf6825c Correct docblock
1232
- 5452dd2 Fix a docblock
1233
- 34ce62f Introduce abstract protected function is_service_active() and use it in the email service
1234
- 3d2da20 Improved styling for popups which contain tabs
1235
- fa0872a Improved error message styling
1236
- dc6023b Merge pull request #249 from humanmade/colorbox
1237
- 1376383 Fix some styling on the new colorbox popups and ensure it resizes properly throughout the excludes process.
1238
- 6f4ee67 fixed a bug where jQuery alias not available
1239
- 8fc2ff7 colorbox lightbox width
1240
- e553bc0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1241
- aae12c2 Latest HM Backup
1242
- c729622 dont hardcode slug
1243
- 6c161ae deleted fancybox
1244
- d09062e Use correct constant for HMBKP_ATTACHMENT_MAX_FILESIZE
1245
- ea88d36 resize after adding buttons
1246
- 943096d removed remaining fancybo references and submodule
1247
- d8ad331 excludes form width
1248
- 6916f65 replaced fancybox with colorbox
1249
- 5b0d868 Merge pull request #247 from humanmade/dev
1250
- 243b4e1 resolved conflicts
1251
- f34622f fix bug in service settings
1252
- 72bd165 added property to toggle service tab visibility
1253
- a2a4671 resolved conflict
1254
- dc29250 Merge branch 'master' of https://github.com/humanmade/BackUpWordPress
1255
- 7ee581d Bump for release
1256
- 1fb986b Use call_user_func to call HMBKP_Service::constant for each service instead of the php 5.3 only way $service::constant()
1257
- 00566e8 Bump for release
1258
- 39d4a8c Code reformatting
1259
- f1ae908 Fix a parse error
1260
- 4b23e80 (tag: 2.2.2) Updated release notes.
1261
- 9e0f523 Update translations
1262
- 1463878 Minor text improvements
1263
- a8af5ae Update original strings
1264
- d2cf0f3 Bump and release notes
1265
- abdbb84 Silence possible warnings when unlinking
1266
- 0871bb2 Minor code formatting
1267
- 5684313 moved the destinations menu link
1268
- f46d61e add property to toggle tab visibility
1269
- 798bf11 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1270
- 61ca652 Latest HM Backup
1271
- 97ab36a Merge pull request #245 from pdewouters/master
1272
- 596123e Latest HM BackUp
1273
- ca4bd02 removed quotes wrapping a nonce var
1274
- 82e563c Merge branch 'nonces'
1275
- ec68546 removed unnecessary lines and did some formatting
1276
- 12b186f replace all calls to exit with die for consistency
1277
- 5ca6b17 added nonce check to all ajax post actions
1278
- 0210692 Merge pull request #243 from pdewouters/master
1279
- 77028d0 cancelled the slug capitalization
1280
- ffbbdbf added human readable name for services
1281
- 77bda92 reverted 2 commits
1282
- e32ce59 Merge branch 'master' of https://github.com/humanmade/BackUpWordPress
1283
- 52ac62f add name property
1284
- 7de9e1d Doh, fix a stupid fatal error
1285
- e059087 Pass back an empty array instead of all service options when asking for a service option that doesn't exist.
1286
- f92a8bc Make constant() a public method.
1287
- 43d296c make actions menu extendable with apply_filters
1288
- c1e0b69 Latest HM Backup
1289
- 503b3ae You can't have protected abstract methods since PHP 5.2.
1290
- 27be1d8 use plugins_url for assets, fixes case sensitive 404 error
1291
- 15293a7 fix plugin URL constant capitalization
1292
- 5a42c04 Latest HM Backup
1293
- 838831e Add a docblock to the abstract constant method
1294
- 6bd1f44 Update readme
1295
- fed0192 Ability to set the maximum email attachment filesize
1296
- 9a17eef Fix possible notice and Fatal error when uninstalling
1297
- 111a7af Only try to add the FAQ if we were able to connect to the plugins API.
1298
- fc9fe8c Released 2.2.1
1299
- 754fa00 Changelog for 2.2.1
1300
- 6c5b162 Force 500 error header for testing (commented out)
1301
- 6bfba16 Strip tags from error messages
1302
- 91bef0f Catch server errors during the ajax backup process and display them to the user
1303
- 7a236d2 Fix JS error and use correct class
1304
- 804c458 Only output an error / warning message if there are errors or warnings
1305
- 126bcb1 Changelog for 2.2.1
1306
- 3eb573b Bump
1307
- 79597cf Latest HM Backup
1308
- c0bad9e Display errors and warnings in error popup after backup
1309
- eecfe58 Catch all types of fatal error in backup process
1310
- 8645f7f Preserve whitespace in the error pre tag
1311
- a950698 Don't redirect if we have an error
1312
- b85cd76 Write errors and warnings as they happen.
1313
- 71af0ea Fix PHP Strict warnings
1314
- 4803568 Mark static functions as static
1315
- 4969597 Released
1316
- 1dcbc5e Chinese translation
1317
- a1a7d37 Serbian translation
1318
- aa703f7 Russian translation
1319
- 9fe56db Romanian translation
1320
- 566d8e9 Portuguese (Brazil) translation
1321
- d1ea675 Polish translation
1322
- e15e487 Dutch translation
1323
- 5fb564f Latvian translation
1324
- f2d5afb Lithuanian translation
1325
- bcf6f0b Italian translation
1326
- 280620d Hebrew translation
1327
- 0728c2f French translation
1328
- 3711134 Basque translation
1329
- 3b739a2 Spanish translation
1330
- 3c3f02e German translation
1331
- b754430 Danish translation
1332
- 531f9fc Czech translation
1333
- 064cf16 Latest po & mo files
1334
- 9c710de Bump for release
1335
- 1dbc5db Bump - close to release
1336
- 0860b48 Revert "Don't define private internal vars"
1337
- 56daef6 Latest HM Backup
1338
- 2c9a9d4 Cleanup on uninstall
1339
- a55c892 Formatting
1340
- 418640e Don't let hmbkp_rmdirtree delete directories outside the site root
1341
- 7e3bcfd Cleanup the deactivate hook, no point removing non-existent options
1342
- 27d2510 Explain yourself
1343
- fe8e817 Handle situations where HMBKP_SCHEDULE_TIME isn't defined
1344
- 4a7309c Switch to using activation and deactivation hook functions rather than calling the actions directly
1345
- ce5dab9 Add a test for fortnightly
1346
- 56464f6 Add unit tests for each of the schedule occurences
1347
- 7e2f57a Make sure we cleanup after ourselves
1348
- bb356ea Add our custom cron schedules to the default cron_schedules array so that we can schedule events using them
1349
- b92af3f Fix possible notice
1350
- 18ec091 Move .po and .mo files to languages folder
1351
- f9ca49b Latest HM Backup
1352
- fe2a42c Don't define private internal vars
1353
- 7b49f4e Don't esc_attr unless we are outputting
1354
- 45f9179 Fix possible warning
1355
- efddfa2 Only update backup type if it's changed
1356
- 3d47ce1 Namespace our script localizations
1357
- 32ba1de sanitise and escape all the things.
1358
- df48893 Increase the timeout on the ajax cron check to avoid errors on slow sites.
1359
- 6f6ed69 Sanitize some shit.
1360
- 26ddd39 Stop defining PCLZIP_TEMPORARY_DIR outside of hm_backup as it shouldn't always be set to hmbkp_path()
1361
- ae3212e Some code cleanup
1362
- 4930b4c Latest HM Backup
1363
- df27971 Use realpath to check that the path resolves somewhere before checking isReadable
1364
- 2409ef0 removed duplication of media query rules
1365
- 64d50ce Merge pull request #219 from humanmade/Mediaquery
1366
- ab00e92 media queries for modal buttons
1367
- bacafc5 manage excludes modal styles fixed. added retina spinner
1368
- 83ef61b delete old backups before the backups list is displayed and also before a new backup is run to catch instances where the backup process fatal errors after creating the backup file but before delete_old_backups is run
1369
- 0c04f05 revert deleting old backups in hmbkp_cleanup.
1370
- 1e9ba82 Remove old backups as part of hmbkp_cleanup
1371
- 74113fc Run hmbkp_cleanup on load of the admin page to help keep things clean
1372
- 5cd35c9 Replace the last 2 instances of wp_get_schedule missed in the previous commit
1373
- d3b95af Code formatting and clenaup
1374
- 5020b49 Define our own list of schedules rather than relying on wp_get_schedules as that can be filtered by other plugins which can cause unexpected consequences.
1375
- b933aab Merge branch 'master' of github.com:humanmade/BackUpWordPress
1376
- b8cb3ac Also include the legacy SECRET_KEY when checking for user defined auth keys
1377
- 37787b4 Bump time
1378
- ac0287d Include any user defined auth keys and salts when generating the HMBKP_SECRET_KEY
1379
- c4e49e6 Use the existing HMBKP_SECURE_KEY to calculate the randomised prefix for the backup path.
1380
- b84f426 Merge pull request #211 from humanmade/fix-for-service
1381
- cc9b732 When data is being saved for a service, default to empty array, as using input type=checked will cause it not to be set
1382
- 812f48e Make set_status() public, so services can update the status of a backup progress
1383
- 41d8437 Create readme.md
1384
- fa36380 Start on changelog
1385
- 74bf0f8 Bump
1386
- e5b8493 Use dirname( hmbkp_path ) instead of WP_CONTENT_DIR to account for custom backup paths and when the path is set to uploads.
1387
- 6dfc256 Correct logic so we only generate and save the default path once.
1388
- 00f364c Bump for release
1389
- ef8719d POST not GET, fixes previewing and adding exclude rules
1390
- ec5a323 Bump for release
1391
- 538eb12 Latest HM Backup
1392
- 953984d Exit don't return on error for ajax requests
1393
- f5fcc35 Treat '0' as empty when checking ajax responses as some servers return 0 even with exit('');
1394
- 6a6c268 Spelling correction
1395
- 9b66689 merge with master
1396
- 033781f Bump
1397
- 4382251 Fix a PHP notice on Apache servers
1398
- 6f991a0 Bump
1399
- ec42544 Latest HM Backup
1400
- 289b0c2 Correct dot file ('.' & '..') check
1401
- 9c22d5b Filter out blank statuses.
1402
- 2bc4fc4 Check global $is_apache instead of calling mod_rewrite_loaded as that function seems to cause issues on some servers.
1403
- 5483864 Remove errant error_log
1404
- 7e1e201 Bump
1405
- 82ac4bb Latest hm-backup
1406
- e78dbd2 Don't call url_shorten as it's only available in the admin, just str_replace instead. Fixes fatal errors when WP Remote triggers backups.
1407
- 9452dcb Don't load the whole of misc.php for apache_mod_loaded, just call the function directly.
1408
- 728c8b9 Move the function_exists, file_exists and is_writable checks into the parent if as there is no point running any of the code just to fail at the second if.
1409
- c7d5c45 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1410
- 0fdfd07 Merge pull request #191 from humanmade/fix-misc-include
1411
- 8b5b30c fixed including misc.php
1412
- 02d46bf Don't hardcode the english string for Update, instead use the translation.
1413
- d7ff153 fixed including misc.php
1414
- f4e96e2 latest hm backup
1415
- a5e1876 Release notes for 2.1
1416
- 2dd8dbf Bump ready for release
1417
- ee6a0f4 Latest translations
1418
- 0d3e027 New originals
1419
- ad10f6f Merge branch 'master' of github.com:humanmade/BackUpWordPress
1420
- a010894 Move placeholder to help text
1421
- 3e25ec8 Define the var outside the if
1422
- c11ff1d Improve the performance of the exclude files modal by iterating directly through the DirectoryIterator instead of storing the whole filesystem in an array.
1423
- fdd9d92 Latest HM Backup
1424
- 628aeea Don't stop people with safe_mode = On from using the plugin, instead just show a warning message.
1425
- ae94736 Add a next backup time tooltip to the hourly backup sentence
1426
- 976c89f Update the link to the restore backup post on hmn.md
1427
- 121148f Point people to the FAQ before telling them about the support email address
1428
- 5511b82 Add a line about rating the plugin on the plugin directory.
1429
- 4313d71 Bring back .htaccess protection for the backups directory on Apache servers
1430
- c235714 Create the backups dir in the uploads dir if it can't be created in WP_CONTENT_DIR.
1431
- d036fff Remove the "remove" link whilst the exclude rule is being removed.
1432
- b2a326a Add the spinner back to remove exclude rule
1433
- 01120c3 Mark the backup as running sooner
1434
- 37c8d96 Better check for default exclude
1435
- 5c188e9 Don't esc_attr vars that aren't being echo'd
1436
- 4193396 Get don't post
1437
- 13d888e Minor text improvements to code comment
1438
- 3937e5a Don't redirect the original backup request in case it hasn't had chance to start yet.
1439
- ef29112 Increase the time between polling the server for status updates to give requests a chance to finish
1440
- d962d7a be more specific as we use hmbkp-running in more places
1441
- 813bc6a A way to force memory errors
1442
- 8f67ba9 Improved status messages
1443
- 84b15c7 Show the spinner next to the schedule link when a schedule is running and you are viewing a different schedule.
1444
- 730bc54 Bump
1445
- 0c3450c get not pot
1446
- b5746aa Add correct class to cancel button
1447
- 41c84b7 s/_/-
1448
- 70082c6 Bump up the ajax interval
1449
- 07ea6b7 Always set the redirect arg
1450
- 4e39f11 dash not underscore
1451
- 0aac32d Bump
1452
- bb79b1f Bump
1453
- c05b34e Make sure args are passed through recursive calls to hmbkpRedirectOnBackupComplete
1454
- 1d1f415 Bump
1455
- 7ab99fc Catch Fatal errors that occur during the backup process and offer to email them to support@hmn.md
1456
- 20eca40 Display "Starting backup" if the status hasn't yet been set.
1457
- 5075764 Latest HM Backup
1458
- dbcad72 The running status should override the error status
1459
- fed73a2 Remove the error class when a new backup is started
1460
- 613a188 Latest HM Backup
1461
- 9d4e471 Bump
1462
- 48db33a Latest HM BackUp
1463
- 4cf0cc8 Include archive and mysqldump method and verification steps in the status messages.
1464
- ab105b6 Catch Fatal errors that happen during the do back ajax request and display them in a popup
1465
- 1bad676 Catch and Display E_ERROR errors on the do backup ajax request
1466
- 1a75167 Check for constant changes before we call hmbkp_path
1467
- 276c086 Release notes
1468
- efb3658 Latest HM Backup
1469
- 141922e Remove HMBKP_ARCHIVE_FILENAME
1470
- 422551d Prepend a random string to the beginning of the backups path
1471
- 05a47a4 Improvements and unit tests for moving backup path
1472
- 01dddf8 use sanitized url instead of site name in backup filename
1473
- 0372abc Latest HM Backup
1474
- 8d0dc69 Better cleanup after unit tests
1475
- 45b945f Make sure we have a plugin version saved before comparing against it. Stops update actions firing on first activation.
1476
- 184c917 Bump
1477
- 096326b Allow the archive filename to be overridden.
1478
- f4f9a49 Remove use of realpath as it causes issues on shared hosts which use symlinks for users server root.
1479
- 308b9b9 Don't attempt to download a backup which doesn't exist.
1480
- 9419082 Don't urldecode the urlencoded base64 string.
1481
- 85087e3 Don't throw an exception when the schedule start time isn't an int as they don't have to be.
1482
- 646dddc Updated original strings
1483
- 1744b94 Bump
1484
- 241faf7 Fix possible warning on update if cron is empty
1485
- b7cb90d Don't show the version warning for the constants tab as those are pulled from the current version not the repo
1486
- 3400e1e 2.0.5
1487
- d65efb2 use a proper version comparison when checking whether this is an update from 1.x to 2.x
1488
- 2eaa879 Specify 'i' directly as a time format instead of relying on the user set time_format when calculating whether a time is an absolute hour.
1489
- 55fd182 Convert to user set schedule time to UTC before comparing against now and if it is in the past add interval instead of "tomorrow"
1490
- c4a393e Docblocks
1491
- 0bdc9ca Introduce a new constant HMBKP_SCHEDULE_TIME to allow the schedule time to be controlled.
1492
- 0f76aff wp-cron should check for a non 200 response
1493
- 1619fa1 Whitespace
1494
- 5d01df2 Re-schedule on __construct if the schedule has become unscheduled somehow.
1495
- 4c29912 Use the WordPress built in size_format instead of defining our own function for human readable filesizes
1496
- ce0ca9b Remove all hmbkp schedules on deactivate
1497
- b442a80 Remove line break at end of file
1498
- b6591ab use wp_retrieve_response_code instead of accessing the response array directly and attempt to show the response description alongside the response code.
1499
- c6b3f4d Use wp_remote_head instead of wp_remote_get to speed up the wp-cron.php response check.
1500
- 21b9307 Bump
1501
- 927043f Revert change to the way the plugin path and url are calculated as it broke some installs
1502
- cfe0637 Fix some unit tests
1503
- 83e5cac 2.0.3
1504
- 5af28c0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1505
- dc85d6e Fix PHP errors when you try to activate BackUpWordPress with WP Remote already active
1506
- 6b5cfd6 Only call array_flip is the $errors array is populated, as it can be NULL which will cause a notice
1507
- 72d869c Bump tested up to version
1508
- f96b2ed Remove TODO and whitespace
1509
- ed2d5de Allow HMBKP_PLUGIN_URL to be filtered
1510
- 3a0ae30 Bump the minimum version check to match version in readme
1511
- 5c95f91 Remove unused constant
1512
- efaf8b4 Latest HM Backup
1513
- ed9af8a Don't use strict operator to check 200 response
1514
- 5098825 Fixed scheduled backups (by using a common hook for all), added get_schedule() function to HMBK_Schedules, split setup default schedules to it's own hook so it can be removed,
1515
- 856ca7f If the cron request is_wp_error() show different message
1516
- 9fe931a use dynamic paths, as this means you can have the plugin in a theme / embedded in another plugin
1517
- 90ed393 Added PHPDocblock
1518
- ab1fbd1 Remove empty bullet
1519
- 356eb6f 2.0.2
1520
- da7faf5 Remove the memory limit error message for now as it's causing more trouble than it's worth.
1521
- db5fb5f Merge branch 'master' of github.com:humanmade/BackUpWordPress
1522
- 92a5109 bump
1523
- 4a39b52 Catch wp-cron wp_errors
1524
- f00ab65 Make sure we have a running backup filename before doing a file_exists and an unlink, fixes a possible warning when backup_running_filename is false and thus we try to unlink hmbkp_path
1525
- 52da406 Only send backup failed message if the backup file doesn't exist.
1526
- a1adc00 2.0.1 fix fatal error on PHP 5.2
1527
- 40dd2f1 Getting ready for GM
1528
- 5fffb7d Move the screenshot outside of the plugin
1529
- e905875 RC 1
1530
- 642dee9 Add a couple of missing esc_attr's
1531
- f131b5f Protect against a possible Notice if there are no excludes.
1532
- 91cc071 Protect against a possible notice
1533
- 7eb4cca Don't remove the scheduled_id param when redirected so we don't lose our place.
1534
- 7abaf15 Reduce the time between status ajax polls. Fire the initial status check straight away.
1535
- f13bc07 Scrap that idea.
1536
- 56b7694 Don't pass .php to get_template_part
1537
- 1988899 Attempt to hide that the backups dir even exists by showing the 404 page.
1538
- 44dee09 Remove all query args before redirecting back
1539
- 850d9ad Nonce, escape and i18n
1540
- b2c9b00 Fix PHP Warning
1541
- a027720 Add a missing legacy option for removal
1542
- 325af18 setup the default schedules after update has been fired so we don't get default schedules as well as the legacy updated schedule
1543
- 22c791c Don't check the return value of set_type as it doesn't return
1544
- f0713fa Set the parent excludes in set_excludes
1545
- 13dfb05 Class shouldn't be escaping
1546
- 963aeaa No need to set_type of parent class on construct
1547
- acd1898 set correct type
1548
- a71cfe4 Set the legacy schedules start time if HMBKP_DAILY_SCHEDULE_TIME is defined
1549
- 7279090 Properly upgrade manually only settings when creating the legacy schedule
1550
- 54bbf5a Use correct sprint_f arg
1551
- 11e4446 Use the ajax url
1552
- 4bd341c Don't load a file that doesn't exist
1553
- 6d01616 Latest HM Backup
1554
- f423ebb Only set excludes if they are different
1555
- 4d3a666 re-org some functions and delete and unneeded file.
1556
- 6a63d93 style the default and defined excluded file reason
1557
- 3138673 Use proper english
1558
- 9e29427 mark default and defined excludes
1559
- c15e3f3 Skip the test if a custom backup directory is in use
1560
- 8bf37ac Bump
1561
- 4bae0e4 Don't allow the backups dir or defined excludes to be removed.
1562
- be0f3ea a's now use the ajax url directly.
1563
- db7f864 fix adding new exclude rules.
1564
- 390f603 Allow backup path to be overridden with a define.
1565
- 28399e1 Typo
1566
- bba3f72 Don't double escape the backup filename
1567
- 2995cb7 Use the Ajax urls directly as there is no non-js fallback for now.
1568
- 7c16e60 Lots of work making BackUpWordPress work better in low memory environments.
1569
- cdfa519 Redirect to the new schedule on add schedule
1570
- ca57a7d Latest HM Backup
1571
- c3a2cd0 Fix wp-cli command
1572
- e33fd1d include the spinner gif with the plugin as we can't reliably guess the location to wp-admin in CSS
1573
- a290c3c Latest HM Backup
1574
- 712e4fa Properly highlight the selected file list tab in excludes popup
1575
- 3a06e1b Add some missing docblocks
1576
- a5f3c46 Clear the cached filesize when excludes or backup type changes
1577
- 2e53742 Correctly store the calculated filesize in a transient.
1578
- 5fa64db Bump
1579
- 13e3e75 Escape DB_NAME
1580
- 5441035 Unit tests and improvements for manual only backups
1581
- 57e97cd Merge branch 'master' of github.com:humanmade/BackUpWordPress
1582
- 0bba9c4 s/Feedbask/Feedback props @herb_miller
1583
- c967acf Merge pull request #146 from elektronikLexikon/master
1584
- 7970180 %s %s to %1 %2
1585
- 667e7df Ability to have manual only backups
1586
- b059ba0 Latest HM Backup fixes #133
1587
- c575bcf Latest HM Backup
1588
- 859d73c Fix for when unit tests are run in a WordPress in a submodule env.
1589
- 72574d9 Use default black overlay
1590
- 4675fe9 todo
1591
- 720e210 Make it possible for PclZip to be targeted specifically.
1592
- aa4105f Delete the running backup file if there is one when a back up process is cancelled.
1593
- 90b7e20 We don't use modernizer
1594
- 43c1d72 Update translations.
1595
- f42d31d Merge pull request #144 from elektronikLexikon/master
1596
- 1d36444 updated German translation
1597
- 8cda712 Bump
1598
- 71b686e Branding
1599
- 1119601 allow argument swapping in email translations and move the email out of the translatable string.
1600
- e687b29 Move compat check to the top so we don't waste cycles on older versions of WordPress.
1601
- 85cf577 Latest HM Backup
1602
- 81c607c use HM_Backup::get_home_path in place of ABSPATH.
1603
- 27b099b Correct readme.txt
1604
- bd0bdc2 Merge branch 'refs/heads/master' into 2.0
1605
- fe024cb (tag: 1.6.9) 1.6.9 changelog
1606
- c45194d Support downloading backups when your site is in a symlinked path.
1607
- c4f5a14 Merge branch 'refs/heads/master' into change-content-dir
1608
- cd50cfe 1.6.9 bump
1609
- 5b3dd92 Merge branch 'master' of git://github.com/elektronikLexikon/BackUpWordPress
1610
- 6866e09 Strip ABSPATH not root from exclude rules.
1611
- 42c40a0 Calling a static method through a variable Class was not supported until 5.3
1612
- d5ea971 s/humanmade.co.uk/hmn.md
1613
- caa8ab3 Fix check for timestamp
1614
- 1e37953 Use root not ABSPATH
1615
- 003435f Inverse logic
1616
- d54f821 Remove debug cruft
1617
- cc99d14 Unit test schedule and changes to class to make it more testable.
1618
- 208ee1e Don't remove non-existent backups
1619
- e264bcc Latest HM Backup
1620
- 01241cc Latest hm-core
1621
- e4f65d6 Fixes to Schedules
1622
- fb2220e Some additional js strings
1623
- fd1711d Fix fatal error in unit tests
1624
- 161b278 Delete extra backups if max backups is changed to below the number of existing backups
1625
- ed0b6d8 Remove old settings on upgrade and clean up whitespace
1626
- 1eb8846 Fire update action for downgrades as well as upgrades.
1627
- 9b6b1c8 Convert legacy schedule names on update.
1628
- 67e1989 Migrate legacy settings into the legacy schedule on update to 2.0
1629
- 0024569 Remove some old messages
1630
- 942e63b Don't mention day in schedule sentence for daily schedule.
1631
- 4cc93df Correct comment
1632
- 748fd57 Proper entity for less than
1633
- 6c030a8 Fire update actions in chronological order
1634
- d131f4d setup a legacy schedule when updating from V1 to V2.
1635
- c63ce1e Improve default schedules message
1636
- c863044 Switch to using plugins_url with the first param as it handles symlinks.
1637
- b029f1a Access static methods directly instead of using a wrapper function.
1638
- f9ab14f Access static methods directly instead of using a wrapper function.
1639
- 9d80ca9 Improved comment.
1640
- 5ae7ac6 Make consistent with the PHP error message
1641
- e18f9d2 Use __FILE__ instead of manually building the path
1642
- b6206a0 use plugin version when enquiring scripts and styles.
1643
- 619a606 use plugin_dir_path and plugin_dir_url instead of manually building them.
1644
- d55a688 Use hmbkp_get_home_path() instead of ABSPATH
1645
- d348533 Actually… there is a function that does this.
1646
- 51012bd Don't use ABSPATH here - because that is the worpdress directory, rather that site root.
1647
- a9005ab (tag: 1.6.8) 1.6.8 readme
1648
- d174b40 Updated spanish translation props @radinamatic
1649
- 86fddbc 1.6.8
1650
- e068f27 Bump
1651
- be7a7b0 Documentation for the new HMBKP_ROOT constant
1652
- 602ed0a Merge branch 'refs/heads/master' into 2.0
1653
- cdd94a7 Updated Russian translation.
1654
- 756111b Romanian translation
1655
- fd69c42 Serbian translation props stefan
1656
- cfc7942 Lithuanian translation props vincentas
1657
- c7aceda French translation props christophe
1658
- d3dfa9b Updated Spanish translation props Radina
1659
- f8ceee1 Default schedules
1660
- 772bd90 Derive backup type from backup filename so we don't incorrectly label old backups when a schedule type is changed
1661
- 9900396 Email notifications
1662
- ad768b8 Better replacement of ajaxurl as it's sometimes relative
1663
- 226b938 Avoid error if no schedules are setup, we'll have some proper schedule setup at some point
1664
- 7a5fbf9 re-org + more work on stuff
1665
- 32a32d9 Show label and improve styling of add new exclude rule field
1666
- 69dd917 Remove unneeded class
1667
- 6ca965e edit excludes separately to settings as it creates a cleaner user experience
1668
- 15db12b Updated translation files
1669
- 5680910 Allow constants to be translated.
1670
- 8ab9541 Updated translation files
1671
- 3796dff Merge branch 'refs/heads/master' into 2.0
1672
- 35a8217 Updated pot file.
1673
- e4c0c17 Move .htaccess into sprintf arg
1674
- 2ea85b5 Move link into sprintf arg
1675
- 5ca3405 Add a link to translate.hmn.md
1676
- fb67fc7 Make contextual help tab titles translatable and add more missing text domains
1677
- 284cad3 Don't translate whole a tag
1678
- 7a41fa6 Add missing text domain
1679
- 1c814eb Make "Settings Save" translatable
1680
- bdefe85 Make "Save Changes" translatable
1681
- 5162bd6 rejig sentence structure so they are more translatable.
1682
- f3b26bd Make Cancel translatable
1683
- 35709e9 Delete schedule, delete backup, localise js strings, more php string translation.
1684
- b843f89 More work on schedule UI and logic
1685
- c1df8d1 throw new Exception( 'That backup wasn\'t created by this schedule' );
1686
- 834ab32 We're not using this
1687
- ec33561 Latest HM Backup
1688
- 062c88d Remove .DS_Store
1689
- 0e7f4c2 More UI work
1690
- aa2397e Unit tests work, schedule class done, started work on new UI
1691
- 8dab4e1 HM Backup 2.0 beta
1692
- b61833d Add fancybox
1693
- 3b32b29 Allow root to be overridden.
1694
- 5a1db5d Don't store invalid email address's
1695
- 600770a Don't load HM_Backup if it's already defined.
1696
- 79e7201 chmod 644
1697
- 3ddc906 (tag: 1.6.7) 1.6.7
1698
- 9870513 HM Backup 1.5.2
1699
- f12c956 Cache plugin data in a transient for a day to avoid a remote get on every page load.
1700
- 048be08 whitespace
1701
- 648a42d Support entering multiple comma separated emails.
1702
- f040c6f s/to/too
1703
- 65206aa line break
1704
- 3c4cd99 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1705
- 14bd967 krsort instead of ksort so that backups are returned in chronological order.
1706
- 73edf6b Use correct property when setting the mysqldump path
1707
- 1c79e47 Merge pull request #103 from radinamatic/patch-1
1708
- e533057 Hi Tom,
1709
- b99c123 Bump
1710
- d7e7b06 HM Backup 1.5.1
1711
- 41bf3b7 release notes
1712
- 21132ef HM Backup 1.5
1713
- e5e6ddc Bump
1714
- e5b9bec Make secure key override-able
1715
- d05983b Latest HM Backup
1716
- 39736fc check get_email_address() instead of HMBKP_EMAIL
1717
- a481bd7 Clear email error on cleannup
1718
- e008d54 Code formatting
1719
- de5645a Send email at end of backup process so fatal errors don't stop backup from completing.
1720
- 619d260 Code formatting
1721
- 2602e42 whitespace
1722
- f629358 @todo
1723
- 1410adb Make sure backup file is attached to email.
1724
- d21bd19 Make sure file_exists before deleting.
1725
- 37eb48d Store running backup filename in .runing_backup then use it to make sure we don't show partial backups in backups list.
1726
- f3374b0 Use better filename checks in hmbkp_cleanup
1727
- 30cb215 Fire error on failed backup
1728
- b2833c7 Proper capitalization
1729
- ae00fcd Bump
1730
- f7397ac Don't cache ajax requests
1731
- 87fecec (tag: 1.6.4) 1.6.4 readme
1732
- c3021d3 Pull upstream
1733
- 3719063 Delete .htaccess on update so it's always rewritten and check <IfModule mod_rewrite.c> to avoid 500 error on servers without mod_rewrite
1734
- 5c77f6e Pull upstream
1735
- 1a49838 PHPdoc
1736
- eacb15e Don't show message for warnings as they freak people out to much and cause people to think the backup has failed when it hasn't
1737
- 6fa9cc0 Pull upstream
1738
- 6b6115d Code formatting
1739
- a04b5fb Pull upstream
1740
- bd661e5 Use correct operator
1741
- 1316011 (tag: 1.6.3) 1.6.3
1742
- e9744b2 No need to add backup path to excludes as it's auto excluded.
1743
- f679a72 hook email backup into hmbkp_complete_action so that fatal errors in sending email can't break backup.
1744
- 8551aa3 Define PCLZIP_TEMPORARY_DIR earlier to ensure it's always set to backup path.
1745
- 755b787 Pull upstream
1746
- 864ae59 Pull upstream
1747
- d433c96 Introduce HMBKP_SECURE_KEY and use instead of SECURE_AUTH_KEY
1748
- cfeaaf5 Better error message text
1749
- 5c74fc2 Don't strpos blank ABSPATH
1750
- 62b4103 (tag: 1.6.2) 1.6.2 changelog.
1751
- d2b8280 1.6.2
1752
- 2db2e2c Code formatting.
1753
- 3479438 Load admin_actions earlier so they can hook into admin_init
1754
- e3982dd Ability to dismiss the backup error / warning messages
1755
- c90d541 Pull upstream
1756
- 74f49eb Clean up some obsolete update code.
1757
- 8578a6d Don't clear hmbkp_max_backups option on update.
1758
- c6be2c9 Don't send backup email if backup failed.
1759
- 24c91a9 Avoid NOTICE when no errors.
1760
- c42bab6 Pull upstream
1761
- a540d17 Only show warning message for php errors in backupwordpress files.
1762
- 7f8fcda Mark the button as backup started and settimeout to 500
1763
- 73b7a5b (tag: 1.6.1) 1.6.1 release.
1764
- b257307 (tag: 1.6) Bump to 1.6
1765
- fc99e52 Return button even if the status is empty.
1766
- defd817 More obvious that running backups can be canceled
1767
- cb82321 Use getter methods instead of accessing properties directly.
1768
- 693da83 Pull upstream
1769
- cae995a No need to set root as it defaults to ABSPATH
1770
- 193e138 Don't echo time() in full backup test.
1771
- def211d Pull upstream
1772
- 40bc667 Incorrect comments
1773
- 67c1cc4 Pull from upstream
1774
- d832205 Show a message for backup warnings.
1775
- 7edfa8c Cleanup on errors
1776
- e2802b8 Cleanup on errors.
1777
- 94bc92f Pull from upstream
1778
- bd914ec Make cancel backup work with new ajax backup
1779
- 6ce5e27 Remove Constant as it's no longer needed
1780
- 7d4b536 Fire manual backups using ajax, completely removes the reliance on wp-cron for manual backups.
1781
- 28f7fa9 Fix notice if backups dir isn't readable.
1782
- 8296a80 Nicely formatted errors in backup error message.
1783
- f265d19 Store backup errors in a .backup_errors file and show a message in the admin if there were errors in the last backup.
1784
- cea6d48 Pull upstream
1785
- 1a06b37 Test archive_method, mysqldump_method and errors in unit test.
1786
- 47068b7 Backup directory is now automatically excluded.
1787
- aeff432 Pull upstream
1788
- c152520 Minor code formatting
1789
- 11f0099 Pull upstream
1790
- 5afdb0f Pull upstream
1791
- ffbfc66 Allow direct http downloads.
1792
- 96ef2d2 Remove actions when running backups from unit tests.
1793
- 3f261b6 Use files() method instead of duplicating code.
1794
- eb69aff Pull upstream
1795
- 6f6be0e Latest hm-backup
1796
- 8ffbc00 Measure time in full backup unit test.
1797
- 2c816bc Consistent handling of symlinks
1798
- 826cdb1 Pull upstream
1799
- c7a84f8 Skip full backup tests until symlinks are properly handled.
1800
- e1e3e9a Unit test for a full backup
1801
- fcab193 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1802
- 4f13942 Pull upstream
1803
- 8071a9c silence rmdir and unlink errors
1804
- 05b58ba conform ABSPATH to normalise trailingslash on windows
1805
- 1708eea Add Email info to FAQ and start changelog for 1.5.2
1806
- 61bbdd3 Bump
1807
- baaef5e Minor code improvements, skip unreadable files in backup size calculation, use RecursiveDirectoryIterator in rmdir_tree
1808
- 85180bd Skip unreadable child directories in RecursiveDirectoryIterator
1809
- 5624aa8 Better help and fix possible error in backup path checks
1810
- 02a5593 Support passing excludes through wp-cli
1811
- 95998b7 (tag: 1.5.1) 1.5.1 changelog
1812
- 32b56d8 WP CLI support.
1813
- 10013f4 Minor code formatting.
1814
- 633d2c0 Release time.
1815
- 789a58c Pull from upstream
1816
- a8e48b2 Don't delete user settings on de-activate.
1817
- 04162ad Bump
1818
- 1273217 Use a DirectoryIterator instead of a recursive open_dir for hmbkp_calculate.
1819
- da9b8cf Only exclude backup path if it's in web root
1820
- ea2acf8 Add the warning to the top of all the tabs.
1821
- 70dbe74 preventDefault to stop the anchor being added to url and to stop page jump.
1822
- e29ff76 (tag: 1.5) 1.5 readme
1823
- 3160894 Ability to override the capability used to register the menu page.
1824
- a69d82c Suppress filemtime errors
1825
- 99a79b2 fiddle with the order and remove ABSPATH before preg_matching to better match the plc_zip logic
1826
- 641ec22 Pass defines straight to correct properties for command path.
1827
- 1cbb2cc Latest HM Backup.
1828
- 14247ef Always delete transient on save settings.
1829
- c1b3109 Back compat JS on old versions of WordPress.
1830
- c63d4ee Latest HM Backups
1831
- a4a157a Latest HM Backup
1832
- 8b68c4e Pre 3.3 compat for help tabs.
1833
- ba7f621 back compat for 3.1 when WP_MAX_MEMORY_LIMIT wasn't defined.
1834
- f73d114 Latest HM_Backup and more renames
1835
- c382e42 Latest HM Backup
1836
- 1a8025e Bump + code cleanup.
1837
- a8525f3 Add plugin FAQ and constants to help and convert to use new 3.3 help tabs.
1838
- 49c0f7c Call conform_dir statically.
1839
- 2998149 Rename Advanced Options to settings.
1840
- 66fad96 Get backups working
1841
- b2f0202 Latest hm-backup
1842
- 7286524 Load the HM Backup Tests.
1843
- 9d71836 First bash at using hm-backup
1844
- 516e5f5 Merge pull request #15 from valericus/patch-1
1845
- b0a8f3e Set proper charset of MySQL backup
1846
- 8b1c3c7 (tag: 1.4.1) 1.4.1
1847
- 4ed46d2 (tag: 1.4) 1.4 has gone golden.
1848
- f91a1d4 Fix a couple of last minute bugs.
1849
- 2b9d335 New screenshot for 1.4
1850
- 3b294c0 Finalising 1.4
1851
- bb531a0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1852
- 97e9479 Code formatting.
1853
- b21cb67 Rewrite incorrect comment.
1854
- 594e7ca Missing line break in .haccess comment.
1855
- e24cc2d Code formatting.
1856
- 7e9f2ad @todo
1857
- f9b5a4a Updated Readme
1858
- 630f55e Merge branch 'master' of github.com:humanmade/BackUpWordPress
1859
- 43f17b9 Should use the function for checking this - for backwards compatibility.
1860
- 57568ae Do not setup backup schedule if the option has been set to disable backups.
1861
- 08e7651 Rename the backup schedule function.
1862
- aeb8cd7 Clear the schedule if the automatic backup is disabled.
1863
- 056ca13 Add class = code to the excludes text area.
1864
- 3bdbc3b Code formatting.
1865
- fb46f82 Minor PHP comment error.
1866
- 93019af Correct author and plugin urls.
1867
- 952b4f7 Correct github url
1868
- e4e8425 Add Theo to contributors list and order alphabetically
1869
- 3aa9342 Bump
1870
- 10cdd57 Merge branch 'refs/heads/admin_gui'
1871
- 82d55f5 Code commentino, formattino & I18N
1872
- 07068cf Updated language.
1873
- 240e4ca Merge branch 'refs/heads/master' into admin_gui
1874
- 26da9e8 Remove cruft.
1875
- f7f1576 Localise dates.
1876
- a2d3273 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1877
- 2691a21 Use correct translation domain.
1878
- e93883c Russian translation, props Valera R
1879
- e52bd8e strtolower instead of checking both lowercase and capitalised
1880
- 9687d19 Merge branch 'master' into admin_gui
1881
- 61bfb20 Bug in i18n - thanks Valera R
1882
- 97e1447 Bug in i18n - thanks Valera R
1883
- 4385235 Looks like our cron schedules filter got lost in a merge back there.
1884
- 7fc9f1a Merge branch 'master' into admin_gui
1885
- 7c8b151 prevent notices when the plugin cannot connect to the WordPress plugin repository.
1886
- eee9059 Fix typo in constant.
1887
- 0637a16 BUG FIX - typo in the constant
1888
- f8507a2 Switch to use hmbkp_get_excludes()
1889
- ee15d43 Rewrite function for getting the list of excluded files/directories
1890
- b95b9a0 replace hmbkp_daily with standard WordPress daily
1891
- ee180fc Use the default daily schedule rather than registering our own
1892
- 358dba8 Merge branch 'master' into admin_gui
1893
- 97964cb Add an explanatory comment to the .htaccess.
1894
- 7eb2b14 Constant to disable the use of wp-cron with manual backups.
1895
- 40f6099 bump
1896
- 627d400 (tag: 1.3.2) Version 1.3.2
1897
- bb5af87 Ignore unreadable files in PCLZIP
1898
- 30928ec Properly export binary data.
1899
- a28656e Spanish translation.
1900
- 6c4d1b1 Bump min PHP version to 5.2.4 to match WordPress.
1901
- b412439 Use 303 redirect when redirecting form submissions.
1902
- 4655a80 If the database file doesn't exist after doing a mysqldump then fallback to the PHP fallback library.
1903
- f84fb70 Move set_time_limit outside of loop.
1904
- cfd6da5 Don't store .gitignore
1905
- a983c42 3.3 Style buttons
1906
- d32cf03 Stray line.
1907
- 477d848 Better comments
1908
- 1a1ebfd remove the last couple of bits of theos code that snuck in there.
1909
- 6eafe41 Revert "Added DB entries for backup archives"
1910
- c984020 missed some stuff
1911
- 9a254e3 Merge branch 'master' into admin_gui
1912
- b5970c2 improve the descriptions.
1913
- f825524 Revert "Added DB entries for backup archives"
1914
- 5de95f0 call deactivate on update to clear bad settings.
1915
- 59348db Merge branch 'db-logs'
1916
- 3c592a8 ignore
1917
- 40302fc Handle empty passwords in mysql_dump
1918
- 9f9b80a Added DB entries for backup archives
1919
- 0da2efb - Call deactivate on activation to clear everything out. A better cleaner solution. Thanks Tom.
1920
- d01c0a3 Merge branch 'master' into admin_gui
1921
- 00f5d5c Fix
1922
- f1fd0c2 - Instead of deleteing the transient, we should delete the .backup_running file. Should maybe do this on activate as well just in case something had gone wrong.
1923
- 00b0033 - Display advanced options panel if hash is set. - Close some tags.
1924
- c7e2bed - FIX - only show invalid no of backups if the field was actually submitted (note - disabled fields are not submitted)
1925
- e6decbe Merge branch 'master' into admin_gui
1926
- a58e4b2 - Update readme & stable tag
1927
- a132ab7 FIX add check for PHP Version, and die if less than 5.0
1928
- f0b4d16 Merge branch 'master' into admin_gui
1929
- bb5b787 - hmbkp_get_backups should return false if no backups.
1930
- 2be96cf - Advanced settings form should be visible if there are no backups.
1931
- 5b5eb6c - get_backups() should return false if there are no backups.
1932
- 4865793 - Display a notice to say that all files in the root directory of the site will be backed up if there is are no excludes set. - Make the function for advancing the schedule by the interval simpler.
1933
- 52d2d38 - tidy up
1934
- 0ef77d9 - Some functions seemed to get lost when merging! - Fix some notices.
1935
- 5a78ad7 - Fix some issues / duplications etc when caused by merge.
1936
- 9b99f73 Merge branch 'master' into admin_gui
1937
- 7cce37a Docs.
1938
- bfefb57 We no longer need mysql_ping
1939
- aa4608b Store running status as a hidden file instead of in the database.
1940
- 975a4f9 - Remove an old function
1941
- 48403f1 - Update readme
1942
- ca43c93 Don't show remaining space or warn when space is low as it's too unreliable.
1943
- 30f8dc0 (tag: 1.3) Version 1.3 Gold
1944
- 83acf1e Pull the FAQ into the contextual help section on the backupwordpress page.
1945
- efb8d10 Don't activate on old versions of WordPress
1946
- 531bcac Overhaul excludes to support excluding absolute folders /wp-contet/, folder fragments .svn/ and files *.php.
1947
- e219bf7 - Improve scheduling of the new cron jobs. Make sure it resets at the right time, and only the right time. - Better commenting
1948
- 8ce735d - When setting a new schedule - the first event should be advanced by the schedule interval.
1949
- df6d34c - FIX - make sure the schedule is cleared when it should be.
1950
- a2ab152 - Use deactivate_plugins() rather than manually unsetting. Thanks Joe.
1951
- 8c8e097 Merge branch 'master' into admin_gui
1952
- 3dce375 - Deactivate Plugin & Die if WordPress is too old.
1953
- 09b101b - Update readme a little.
1954
- 4cfff8a - FIX display real next scheduled.
1955
- 7db7b35 - Maybe they shouldn't be capitalized after all. - remove bug testing code.
1956
- ae49c2b - Clear schedule hook when changing schedule setting. - FIX: capitalize display name inline with wordpress default cron schedules - FIX: naming of option.
1957
- 93c87ca - FIX: make sure all options are deleted when the plugin is deactivated
1958
- 1fc1002 - oops. missed some commas.
1959
- 35238bb - add weekly, fortnightly and monthly to cron schedules.
1960
- e751d74 - Add setting of backup frequency in the advanced options form. - Save frequency settings.
1961
- 2374007 - Fix the scheduling so that it works in all timezones, correctly. And certainly doesn't schedule the event in the past so that it runs backups constantly.
1962
- 0996bf3 Don't attempt to guess compression, just display uncompressed size.
1963
- 8cff239 Wrap ini_get( 'safe_mode' ); so we handle both (bool) false and (string) Off.
1964
- c7a7f32 - Save file with correct localtime - Show correct localtime in table.
1965
- 5e11b63 - Adjust scheduled event for local time. - Display correct localtime.
1966
- b6ad6a1 - Stop even trying to guess the compressed size as it is totally inaccurate. Be honest, and just tell them the uncrompressed size.
1967
- bb15ff7 - Use php version_compare function to check versions.
1968
- 050a7b5 - FIX - used the wrong key.
1969
- 7a9a2ae - Move Advanced Options form notifications to the interface.functions file - and hook them in to admin_notices
1970
- 34880f1 - FIX: Just some isset checks on my $_POST data. Thanks Tom.
1971
- 0ef1c6e - If new exclude rules - delete cached est backup size stored as transient so that it is regenerated
1972
- f7b1e0f - Do not count excluded files & directories when calculating estimated filesize.
1973
- 315bd03 - Fix - When submitting the form - you did not go to the top of the page.
1974
- b6cad30 - Better handling of errors when processing the advanced options form. - Display some nice helpful messages.
1975
- d6e1436 - Fix some of the text in contextual help
1976
- 7985cc4 - Add 'settings saved' notification - tidy up
1977
- 4e5e609 - update & add check to see if readme used is from the actual version in use and if not, display some warnings.
1978
- c74e6ee - Add FAQ to Contextual Help dropdown - FAQ is taken from readme on wordpress repo.
1979
- 92e04c4 Merge branch 'master' into admin_gui
1980
- 479e1d2 Set database stored_filename directory rather than relying on str_replace.
1981
- 763b8f8 Better hmbkp_path default
1982
- 99bd09b Handle singular and plural for completed backup count
1983
- d2b5033 Better styling for advanced options.
1984
- de48557 Merge branch 'master' into admin_gui
1985
- dccdc32 - Do not hide the advanced options form if it has just been submitted.
1986
- a46533d - Fix message at the top not displaying the right message when the options form has just been submitted.
1987
- 1fd7a3d - fix message not displaying correct option - hmbkp_disable_automatic_backup
1988
- c3c1374 - get excludes to use stored option
1989
- 1b39875 - move save options function to admin.actions and process on admin_init - add some checks/nonce fields etc.
1990
- 65abfed - change everything to use my new option value functions
1991
- be9c254 - more switching to use of individual functions to get value of settings.
1992
- 09ee9d1 - move checking of max_backups to max_backups function
1993
- 453f54f - Do not delete stored email address just because new one is invalid. Just return error instead.
1994
- bd25c5c - Advanced options GUI - Options page save function - beginning of a Wrapper function for returning either defined setting, or stored option.
1995
- 197c346 Replace * with non greedy regex wildcard for PCLZIP.
1996
- ed85a9e Don't match against invalid exclude rules
1997
- 5cd78dd Trim whitespace from exclude rules, fixes issue with comma [space] separated list of rules.
1998
- 9dd836b Show examples for all advanced options.
1999
- 3764099 Add support for excluding directories via a define.
2000
- dc78e1e Replace \\ with / in windows paths not the other way round.
2001
- 65f0322 Support dynamic excludes in both zip and PCLZIP, lays foundation for user excludes.
2002
- f1b5173 Use consistent function names for admin_notices.
2003
- 7beaad1 Properly handle setting and changing backup directory.
2004
- 3223b24 Improve the get_backups code.
2005
- 3c1411b Tweak FAQ
2006
- 53c0d59 Merge branch 'master' of github.com:humanmade/BackUpWordPress
2007
- 0789452 1.3 bleeding
2008
- 5241d51 Correct handle for Matt
2009
- 3d20f86 Merge branch 'master' of github.com:humanmade/BackUpWordPress
2010
- 48102f5 - Update FAQ in Readme
2011
- b6e1607 (tag: 1.2) Version 1.2
2012
- da8e478 Tweak langauge.
2013
- 03e35da Tweak messages.
2014
- 887db23 Don't show message if email is invalid
2015
- 673450b Merge branch 'master' into backupwordpress_email
2016
- 1300f42 - oops. left in some debug code.
2017
- 98b2b49 file mode change,
2018
- 410b121 - Add some error messages for invalid email addresses and emails that failed to send.
2019
- f74e0a4 - Add ability to email a copy of the backup to a defined address.
2020
- 8879ebf Merge code from settings.functions.php into core.functions.php and delete redundant file.
2021
- 2b5a6db Don't hardcode Windows drive letters.
2022
- 3851dce Merge branch 'master' of github.com:willmot/BackUpWordPress
2023
- 87eabb9 - Icons - 32x32, 16x16, 16x16+hover - Add css for icon to hmbkp.css - Change screen_icon() to use backupwordpress icon - Icon for git repo
2024
- 02e8a7e chmod moved files so we can delete them.
2025
- f4bd99c Check for wp_error in wp-cron.php check
2026
- 40f0a36 Initial Import
2027
- 948b600 Committed to much
2028
- b126a23 Initial commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
admin/actions.php CHANGED
@@ -62,7 +62,7 @@ add_action( 'admin_post_hmbkp_request_delete_schedule', 'hmbkp_request_delete_sc
62
  */
63
  function hmbkp_request_do_backup() {
64
 
65
- if ( empty( $_GET['hmbkp_schedule_id'] ) ) {
66
  die;
67
  }
68
 
@@ -72,60 +72,37 @@ function hmbkp_request_do_backup() {
72
  check_admin_referer( 'hmbkp_run_schedule', 'hmbkp_run_schedule_nonce' );
73
  }
74
 
 
 
75
  // Fixes an issue on servers which only allow a single session per client
76
  session_write_close();
 
 
 
 
77
 
78
- // We want to display any fatal errors in this ajax request so we can catch them on the other side.
79
- error_reporting( E_ERROR | E_USER_ERROR | E_CORE_ERROR | E_COMPILE_ERROR | E_RECOVERABLE_ERROR );
80
- @ini_set( 'display_errors', 'On' );
81
- @ini_set( 'html_errors', 'Off' );
82
-
83
- // Force a memory error for testing purposes
84
- //ini_set( 'memory_limit', '2M' );
85
- //function a() { a(); } a();
86
-
87
- // Force a 500 error for testing purposes
88
- //header( 'HTTP/1.1 500 Internal Server Error' );
89
 
90
- ignore_user_abort( true );
 
 
91
 
92
- HM\BackUpWordPress\Path::get_instance()->cleanup();
93
 
94
- $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( urldecode( $_GET['hmbkp_schedule_id'] ) ) );
95
 
96
  $schedule->run();
97
 
98
- HM\BackUpWordPress\Notices::get_instance()->clear_all_notices();
99
-
100
  $errors = array_merge( $schedule->backup->get_errors(), $schedule->backup->get_warnings() );
101
 
102
- $error_message = '';
103
 
104
- foreach ( $errors as $error_set ) {
105
- $error_message .= implode( "\n\r", $error_set );
106
  }
107
 
108
- if ( $error_message && file_exists( $schedule->backup->get_archive_filepath() ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
109
- $error_message .= ' HMBKP_SUCCESS';
110
- }
111
-
112
- if ( trim( $error_message ) && defined( 'DOING_AJAX' ) && DOING_AJAX ) {
113
- echo $error_message;
114
- }
115
-
116
- if ( trim( $error_message ) && defined( 'DOING_AJAX' ) ) {
117
- wp_die( $error_message );
118
- }
119
-
120
- if ( ! defined( 'DOING_AJAX' ) ) {
121
- wp_safe_redirect( hmbkp_get_settings_url(), '303' );
122
- }
123
-
124
- die;
125
-
126
  }
127
- add_action( 'wp_ajax_hmbkp_run_schedule', 'hmbkp_request_do_backup' );
128
- add_action( 'admin_post_hmbkp_run_schedule', 'hmbkp_request_do_backup' );
129
 
130
  /**
131
  * Send the download file to the browser and then redirect back to the backups page
@@ -456,7 +433,7 @@ function hmbkp_add_exclude_rule() {
456
 
457
  $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
458
 
459
- $exclude_rule = str_ireplace( $schedule->backup->get_root(), '', sanitize_text_field( $_GET['hmbkp_exclude_pathname'] ) );
460
 
461
  $schedule->set_excludes( $exclude_rule, true );
462
 
62
  */
63
  function hmbkp_request_do_backup() {
64
 
65
+ if ( empty( $_POST['hmbkp_schedule_id'] ) ) {
66
  die;
67
  }
68
 
72
  check_admin_referer( 'hmbkp_run_schedule', 'hmbkp_run_schedule_nonce' );
73
  }
74
 
75
+ HM\BackUpWordPress\Path::get_instance()->cleanup();
76
+
77
  // Fixes an issue on servers which only allow a single session per client
78
  session_write_close();
79
+
80
+ $schedule_id = sanitize_text_field( urldecode( $_POST['hmbkp_schedule_id'] ) );
81
+ $task = new \HM\Backdrop\Task( 'hmbkp_run_schedule_async', $schedule_id );
82
+ $task->schedule();
83
 
84
+ die;
 
 
 
 
 
 
 
 
 
 
85
 
86
+ }
87
+ add_action( 'wp_ajax_hmbkp_run_schedule', 'hmbkp_request_do_backup' );
88
+ //add_action( 'admin_post_hmbkp_run_schedule', 'hmbkp_request_do_backup' );
89
 
90
+ function hmbkp_run_schedule_async( $schedule_id ) {
91
 
92
+ $schedule = new HM\BackUpWordPress\Scheduled_Backup( $schedule_id );
93
 
94
  $schedule->run();
95
 
 
 
96
  $errors = array_merge( $schedule->backup->get_errors(), $schedule->backup->get_warnings() );
97
 
98
+ $notices = array();
99
 
100
+ foreach ( $errors as $key => $error ) {
101
+ $notices[] = implode( ', ', $error );
102
  }
103
 
104
+ \HM\BackUpWordPress\Notices::get_instance()->set_notices( 'backup_errors', $notices );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  }
 
 
106
 
107
  /**
108
  * Send the download file to the browser and then redirect back to the backups page
433
 
434
  $schedule = new HM\BackUpWordPress\Scheduled_Backup( sanitize_text_field( $_GET['hmbkp_schedule_id'] ) );
435
 
436
+ $exclude_rule = sanitize_text_field( $_GET['hmbkp_exclude_pathname'] );
437
 
438
  $schedule->set_excludes( $exclude_rule, true );
439
 
admin/backups.php CHANGED
@@ -29,7 +29,7 @@ if ( ! empty( $_GET['hmbkp_schedule_id'] ) ) {
29
 
30
  add_thickbox(); ?>
31
 
32
- <a id="intercom-info" class="thickbox add-new-h2" href="<?php echo wp_nonce_url( add_query_arg( array( 'action' => 'load_enable_support', 'width' => '600', 'height' => '420' ), is_multisite() ? admin_url( 'admin-ajax.php' ) : network_admin_url( 'admin-ajax.php' ) ), 'hmbkp_nonce' ); ?>"><span class="dashicons dashicons-admin-users"></span>&nbsp;<?php _e( 'Enable Support', 'backupwordpress' ); ?></a>
33
 
34
  <?php } ?>
35
 
29
 
30
  add_thickbox(); ?>
31
 
32
+ <a id="intercom-info" class="thickbox add-new-h2" href="<?php echo esc_url( wp_nonce_url( add_query_arg( array( 'action' => 'load_enable_support', 'width' => '600', 'height' => '420' ), self_admin_url( 'admin-ajax.php' ) ), 'hmbkp_nonce' ) ); ?>"><span class="dashicons dashicons-admin-users"></span>&nbsp;<?php _e( 'Enable Support', 'backupwordpress' ); ?></a>
33
 
34
  <?php } ?>
35
 
admin/menu.php CHANGED
@@ -8,11 +8,17 @@
8
  */
9
  function hmbkp_admin_menu() {
10
 
11
- if ( is_multisite() )
12
- add_submenu_page( 'settings.php', __( 'Manage Backups','backupwordpress' ), __( 'Backups','backupwordpress' ), ( defined( 'HMBKP_CAPABILITY' ) && HMBKP_CAPABILITY ) ? HMBKP_CAPABILITY : 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
13
- else
14
- add_management_page( __( 'Manage Backups','backupwordpress' ), __( 'Backups','backupwordpress' ), ( defined( 'HMBKP_CAPABILITY' ) && HMBKP_CAPABILITY ) ? HMBKP_CAPABILITY : 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
 
 
 
 
 
15
  }
 
16
  add_action( 'network_admin_menu', 'hmbkp_admin_menu' );
17
  add_action( 'admin_menu', 'hmbkp_admin_menu' );
18
 
@@ -31,16 +37,19 @@ function hmbkp_manage_backups() {
31
  *
32
  * @param array $links
33
  * @param string $file
 
34
  * @return array $links
35
  */
36
  function hmbkp_plugin_action_link( $links, $file ) {
37
 
38
- if ( strpos( $file, HMBKP_PLUGIN_SLUG ) !== false )
39
  array_push( $links, '<a href="' . esc_url( HMBKP_ADMIN_URL ) . '">' . __( 'Backups', 'backupwordpress' ) . '</a>' );
 
40
 
41
  return $links;
42
 
43
  }
 
44
  add_filter( 'plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
45
 
46
  /**
@@ -53,8 +62,9 @@ add_filter( 'plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
53
  function hmbkp_contextual_help() {
54
 
55
  // Pre WordPress 3.3 compat
56
- if ( ! method_exists( get_current_screen(), 'add_help_tab' ) )
57
  return;
 
58
 
59
  ob_start();
60
  require_once( HMBKP_PLUGIN_PATH . 'admin/constants.php' );
@@ -64,9 +74,15 @@ function hmbkp_contextual_help() {
64
  include_once( HMBKP_PLUGIN_PATH . 'admin/faq.php' );
65
  $faq = ob_get_clean();
66
 
67
- get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'backupwordpress' ), 'id' => 'hmbkp_faq', 'content' => wp_kses_post( $faq ) ) );
 
 
 
68
 
69
- get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'backupwordpress' ), 'id' => 'hmbkp_constants', 'content' => wp_kses_post( $constants ) ) );
 
 
 
70
 
71
  require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirements.php' );
72
 
@@ -76,8 +92,8 @@ function hmbkp_contextual_help() {
76
 
77
  get_current_screen()->add_help_tab(
78
  array(
79
- 'title' => __( 'Server Info', 'backupwordpress' ),
80
- 'id' => 'hmbkp_server',
81
  'content' => $info,
82
  )
83
  );
@@ -85,9 +101,10 @@ function hmbkp_contextual_help() {
85
  get_current_screen()->set_help_sidebar(
86
  '<p><strong>' . __( 'For more information:', 'backupwordpress' ) . '</strong></p>' .
87
  '<p><a href="https://github.com/humanmade/backupwordpress" target="_blank">GitHub</a></p>' .
88
- '<p><a href="http://wordpress.org/tags/backupwordpress?forum_id=10" target="_blank">' . __( 'Support Forums', 'backupwordpress' ) .'</a></p>' .
89
- '<p><a href="http://translate.hmn.md/" target="_blank">' . __( 'Help with translation', 'backupwordpress' ) .'</a></p>'
90
  );
91
 
92
  }
93
- add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_contextual_help' );
 
8
  */
9
  function hmbkp_admin_menu() {
10
 
11
+ if ( is_multisite() ) {
12
+
13
+ add_submenu_page( 'settings.php', __( 'Manage Backups', 'backupwordpress' ), __( 'Backups', 'backupwordpress' ), ( defined( 'HMBKP_CAPABILITY' ) && HMBKP_CAPABILITY ) ? HMBKP_CAPABILITY : 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
14
+
15
+ } else {
16
+
17
+ add_management_page( __( 'Manage Backups', 'backupwordpress' ), __( 'Backups', 'backupwordpress' ), ( defined( 'HMBKP_CAPABILITY' ) && HMBKP_CAPABILITY ) ? HMBKP_CAPABILITY : 'manage_options', HMBKP_PLUGIN_SLUG, 'hmbkp_manage_backups' );
18
+
19
+ }
20
  }
21
+
22
  add_action( 'network_admin_menu', 'hmbkp_admin_menu' );
23
  add_action( 'admin_menu', 'hmbkp_admin_menu' );
24
 
37
  *
38
  * @param array $links
39
  * @param string $file
40
+ *
41
  * @return array $links
42
  */
43
  function hmbkp_plugin_action_link( $links, $file ) {
44
 
45
+ if ( false !== strpos( $file, HMBKP_PLUGIN_SLUG ) ) {
46
  array_push( $links, '<a href="' . esc_url( HMBKP_ADMIN_URL ) . '">' . __( 'Backups', 'backupwordpress' ) . '</a>' );
47
+ }
48
 
49
  return $links;
50
 
51
  }
52
+
53
  add_filter( 'plugin_action_links', 'hmbkp_plugin_action_link', 10, 2 );
54
 
55
  /**
62
  function hmbkp_contextual_help() {
63
 
64
  // Pre WordPress 3.3 compat
65
+ if ( ! method_exists( get_current_screen(), 'add_help_tab' ) ) {
66
  return;
67
+ }
68
 
69
  ob_start();
70
  require_once( HMBKP_PLUGIN_PATH . 'admin/constants.php' );
74
  include_once( HMBKP_PLUGIN_PATH . 'admin/faq.php' );
75
  $faq = ob_get_clean();
76
 
77
+ get_current_screen()->add_help_tab( array( 'title' => __( 'FAQ', 'backupwordpress' ),
78
+ 'id' => 'hmbkp_faq',
79
+ 'content' => wp_kses_post( $faq )
80
+ ) );
81
 
82
+ get_current_screen()->add_help_tab( array( 'title' => __( 'Constants', 'backupwordpress' ),
83
+ 'id' => 'hmbkp_constants',
84
+ 'content' => wp_kses_post( $constants )
85
+ ) );
86
 
87
  require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirements.php' );
88
 
92
 
93
  get_current_screen()->add_help_tab(
94
  array(
95
+ 'title' => __( 'Server Info', 'backupwordpress' ),
96
+ 'id' => 'hmbkp_server',
97
  'content' => $info,
98
  )
99
  );
101
  get_current_screen()->set_help_sidebar(
102
  '<p><strong>' . __( 'For more information:', 'backupwordpress' ) . '</strong></p>' .
103
  '<p><a href="https://github.com/humanmade/backupwordpress" target="_blank">GitHub</a></p>' .
104
+ '<p><a href="http://wordpress.org/tags/backupwordpress?forum_id=10" target="_blank">' . __( 'Support Forums', 'backupwordpress' ) . '</a></p>' .
105
+ '<p><a href="http://translate.hmn.md/" target="_blank">' . __( 'Help with translation', 'backupwordpress' ) . '</a></p>'
106
  );
107
 
108
  }
109
+
110
+ add_action( 'load-' . HMBKP_ADMIN_PAGE, 'hmbkp_contextual_help' );
admin/schedule-form-excludes.php CHANGED
@@ -2,58 +2,65 @@
2
 
3
  <?php if ( $schedule->get_excludes() ) : ?>
4
 
5
- <h3><?php _e( 'Currently Excluded', 'backupwordpress' ); ?></h3>
 
 
 
 
6
 
7
  <table class="widefat">
8
 
9
  <tbody>
10
 
11
- <?php foreach ( $schedule->get_excludes() as $key => $exclude ) :
12
 
13
- $exclude_path = new SplFileInfo( trailingslashit( $schedule->backup->get_root() ) . ltrim( str_ireplace( $schedule->backup->get_root(), '', $exclude ), '/' ) ); ?>
14
 
15
- <tr>
16
 
17
- <th scope="row">
18
 
19
- <?php if ( $exclude_path->isFile() ) { ?>
20
 
21
- <div class="dashicons dashicons-media-default"></div>
22
 
23
- <?php } elseif ( $exclude_path->isDir() ) { ?>
24
 
25
- <div class="dashicons dashicons-portfolio"></div>
26
 
27
- <?php } ?>
28
 
29
- </th>
30
 
31
- <td>
32
- <code><?php echo esc_html( str_ireplace( $schedule->backup->get_root(), '', $exclude ) ); ?></code>
33
 
34
- </td>
35
 
36
- <td>
37
 
38
- <?php if ( ( hmbkp_path() === untrailingslashit( $exclude ) ) || ( in_array( $exclude, $schedule->default_excludes() ) ) ) : ?>
39
 
40
- <?php _e( 'Default rule', 'backupwordpress' ); ?>
41
 
42
- <?php elseif ( defined( 'HMBKP_EXCLUDE' ) && strpos( HMBKP_EXCLUDE, $exclude ) !== false ) : ?>
43
 
44
- <?php _e( 'Defined in wp-config.php', 'backupwordpress' ); ?>
45
 
46
- <?php else : ?>
47
 
48
- <a href="<?php echo hmbkp_admin_action_url( 'remove_exclude_rule', array( 'hmbkp_remove_exclude' => $exclude, 'hmbkp_schedule_id' => $schedule->get_id() ) ); ?>" class="delete-action"><?php _e( 'Stop excluding', 'backupwordpress' ); ?></a>
 
 
 
49
 
50
- <?php endif; ?>
51
 
52
- </td>
53
 
54
- </tr>
55
 
56
- <?php endforeach; ?>
57
 
58
  </tbody>
59
 
@@ -70,12 +77,12 @@
70
  // The directory to display
71
  $directory = $schedule->backup->get_root();
72
 
73
- if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
74
 
75
  $untrusted_directory = urldecode( $_GET['hmbkp_directory_browse'] );
76
 
77
  // Only allow real sub directories of the site root to be browsed
78
- if ( strpos( $untrusted_directory, $schedule->backup->get_root() ) !== false && is_dir( $untrusted_directory ) ) {
79
  $directory = $untrusted_directory;
80
  }
81
 
@@ -92,246 +99,261 @@
92
 
93
  <thead>
94
 
95
- <tr>
96
- <th></th>
97
- <th scope="col"><?php _e( 'Name', 'backupwordpress' ); ?></th>
98
- <th scope="col" class="column-format"><?php _e( 'Size', 'backupwordpress' ); ?></th>
99
- <th scope="col" class="column-format"><?php _e( 'Permissions', 'backupwordpress' ); ?></th>
100
- <th scope="col" class="column-format"><?php _e( 'Type', 'backupwordpress' ); ?></th>
101
- <th scope="col" class="column-format"><?php _e( 'Status', 'backupwordpress' ); ?></th>
102
- </tr>
103
 
104
- <tr>
105
 
106
- <th scope="row">
107
- <div class="dashicons dashicons-admin-home"></div>
108
- </th>
109
 
110
- <th scope="col">
111
 
112
- <?php if ( $schedule->backup->get_root() !== $directory ) { ?>
113
 
114
- <a href="<?php echo remove_query_arg( 'hmbkp_directory_browse' ); ?>"><?php echo esc_html( $schedule->backup->get_root() ); ?></a> <code>/</code>
 
115
 
116
- <?php $parents = array_filter( explode( '/', str_replace( trailingslashit( $schedule->backup->get_root() ), '', trailingslashit( dirname( $directory ) ) ) ) );
117
 
118
- foreach ( $parents as $directory_basename ) { ?>
119
 
120
- <a href="<?php echo add_query_arg( 'hmbkp_directory_browse', urlencode( substr( $directory, 0, strpos( $directory, $directory_basename ) ) . $directory_basename ) ); ?>"><?php echo esc_html( $directory_basename ); ?></a> <code>/</code>
 
121
 
122
- <?php } ?>
123
 
124
- <?php echo esc_html( basename( $directory ) ); ?>
125
 
126
- <?php } else { ?>
127
 
128
- <?php echo esc_html( $schedule->backup->get_root() ); ?>
129
 
130
- <?php } ?>
131
 
132
- </th>
133
 
134
- <td class="column-filesize">
135
 
136
- <?php if ( $schedule->is_site_size_being_calculated() ) { ?>
137
 
138
- <span class="spinner"></span>
139
 
140
- <?php } else {
141
 
142
- $root = new SplFileInfo( $schedule->backup->get_root() );
143
 
144
- $size = $schedule->filesize( $root );
145
 
146
- if ( $size !== false ) {
147
 
148
- $size = size_format( $size );
149
 
150
- if ( ! $size ) {
151
- $size = '0 B';
152
- } ?>
153
-
154
- <code>
155
 
156
- <?php echo esc_html( $size ); ?>
157
 
158
- <a class="dashicons dashicons-update" href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $schedule->backup->get_root() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'backupwordpress' ); ?></span></a>
159
 
160
- </code>
 
161
 
 
162
 
163
- <?php } ?>
164
 
165
  <?php } ?>
166
 
167
- <td>
168
- <?php echo esc_html( substr( sprintf( '%o', fileperms( $schedule->backup->get_root() ) ), -4 ) ); ?>
169
- </td>
170
 
171
- <td>
 
 
172
 
173
- <?php if ( is_link( $schedule->backup->get_root() ) ) {
174
 
175
- _e( 'Symlink', 'backupwordpress' );
176
 
177
- } elseif ( is_dir( $schedule->backup->get_root() ) ) {
178
 
179
- _e( 'Folder', 'backupwordpress' );
180
 
181
- } ?>
182
 
183
- </td>
184
 
185
- <td></td>
186
 
187
- </tr>
 
 
188
 
189
  </thead>
190
 
191
  <tbody>
192
 
193
- <?php foreach ( $files as $size => $file ) {
194
 
195
- $is_excluded = $is_unreadable = false;
196
 
197
- // Check if the file is excluded
198
- if ( $exclude_string && preg_match( '(' . $exclude_string . ')', str_ireplace( trailingslashit( $schedule->backup->get_root() ), '', HM\BackUpWordPress\Backup::conform_dir( $file->getPathname() ) ) ) ) {
199
- $is_excluded = true;
200
- }
201
 
202
- // Skip unreadable files
203
- if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
204
- $is_unreadable = true;
205
- } ?>
206
 
207
- <tr>
208
 
209
- <td>
210
 
211
- <?php if ( $is_unreadable ) { ?>
212
 
213
- <div class="dashicons dashicons-dismiss"></div>
214
 
215
- <?php } elseif ( $file->isFile() ) { ?>
216
 
217
- <div class="dashicons dashicons-media-default"></div>
218
 
219
- <?php } elseif ( $file->isDir() ) { ?>
220
 
221
- <div class="dashicons dashicons-portfolio"></div>
222
 
223
- <?php } ?>
224
 
225
- </td>
226
 
227
- <td>
228
 
229
- <?php if ( $is_unreadable ) { ?>
230
 
231
- <code class="strikethrough" title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
 
232
 
233
- <?php } elseif ( $file->isFile() ) { ?>
234
 
235
- <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
 
236
 
237
- <?php } elseif ( $file->isDir() ) { ?>
238
 
239
- <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><a href="<?php echo add_query_arg( 'hmbkp_directory_browse', urlencode( $file->getPathname() ) ); ?>"><?php echo esc_html( $file->getBasename() ); ?></a></code>
 
240
 
241
- <?php } ?>
242
 
243
- </td>
244
 
245
- <td class="column-format column-filesize">
246
 
247
- <?php if ( $file->isDir() && $schedule->is_site_size_being_calculated() ) { ?>
248
 
249
- <span class="spinner"></span>
250
 
251
- <?php } else {
252
 
253
- $size = $schedule->filesize( $file );
254
 
255
- if ( false !== $size ) {
256
 
257
- $size = size_format( $size );
258
 
259
- if ( ! $size ) {
260
- $size = '0 B';
261
- } ?>
262
 
263
- <code>
264
 
265
- <?php echo esc_html( $size ); ?>
266
 
267
- <?php if ( $file->isDir() ) { ?>
268
 
269
- <a title="<?php _e( 'Recalculate the size of this directory', 'backupwordpress' ); ?>" class="dashicons dashicons-update" href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $file->getPathname() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'backupwordpress' ); ?></span></a>
 
 
270
 
271
- <?php } ?>
272
 
273
- </code>
274
 
275
 
276
- <?php } else { ?>
277
 
278
- <code>--</code>
279
 
280
- <?php }
281
- } ?>
282
 
283
- </td>
284
 
285
- <td>
286
- <?php echo esc_html( substr( sprintf( '%o', $file->getPerms() ), -4 ) ); ?>
287
- </td>
288
 
289
- <td>
290
 
291
- <?php if ( $file->isLink() ) { ?>
292
 
293
- <span title="<?php echo esc_attr( $file->GetRealPath() ); ?>"><?php _e( 'Symlink', 'backupwordpress' ); ?></span>
 
294
 
295
- <?php } elseif ( $file->isDir() ) {
296
 
297
- _e( 'Folder', 'backupwordpress' );
298
 
299
- } else {
300
 
301
- _e( 'File', 'backupwordpress' );
302
 
303
- } ?>
304
 
305
- </td>
306
 
307
- <td class="column-format">
308
 
309
- <?php if ( $is_unreadable ) { ?>
310
 
311
- <strong title="<?php _e( 'Unreadable files won\'t be backed up.', 'backupwordpress' ); ?>"><?php _e( 'Unreadable', 'backupwordpress' ); ?></strong>
 
312
 
313
- <?php } elseif ( $is_excluded ) { ?>
314
 
315
- <strong><?php _e( 'Excluded', 'backupwordpress' ); ?></strong>
316
 
317
- <?php } else {
318
 
319
- $exclude_path = $file->getPathname();
320
 
321
- // Excluded directories need to be trailingslashed
322
- if ( $file->isDir() ) {
323
- $exclude_path = trailingslashit( $file->getPathname() );
324
- } ?>
325
 
326
- <a href="<?php echo wp_nonce_url( add_query_arg( array( 'hmbkp_schedule_id' => $schedule->get_id(), 'action' => 'hmbkp_add_exclude_rule', 'hmbkp_exclude_pathname' => urlencode( $exclude_path ) ), admin_url( 'admin-post.php' ) ), 'hmbkp-add-exclude-rule', 'hmbkp-add-exclude-rule-nonce' ); ?>" class="button-secondary"><?php _e( 'Exclude &rarr;', 'backupwordpress' ); ?></a>
 
 
 
 
 
327
 
328
- <?php } ?>
329
 
330
- </td>
331
 
332
- </tr>
333
 
334
- <?php } ?>
335
 
336
  </tbody>
337
 
@@ -339,8 +361,9 @@
339
 
340
  <?php } ?>
341
 
342
- </div>
 
 
 
343
 
344
- <p class="submit">
345
- <a href="<?php echo esc_url( hmbkp_get_settings_url() ) ?>" class="button-primary"><?php _e( 'Done', 'backupwordpress' ); ?></a>
346
- </p>
2
 
3
  <?php if ( $schedule->get_excludes() ) : ?>
4
 
5
+ <h3>
6
+ <?php _e( 'Currently Excluded', 'backupwordpress' ); ?>
7
+ </h3>
8
+
9
+ <p><?php _e( 'We automatically detect and ignore common <abbr title="Version Control Systems">VCS</abbr> folders and other backup plugin folders.', 'backupwordpress' ); ?></p>
10
 
11
  <table class="widefat">
12
 
13
  <tbody>
14
 
15
+ <?php foreach ( array_diff( $schedule->get_excludes(), $schedule->backup->default_excludes() ) as $key => $exclude ) :
16
 
17
+ $exclude_path = new SplFileInfo( trailingslashit( $schedule->backup->get_root() ) . ltrim( str_ireplace( $schedule->backup->get_root(), '', $exclude ), '/' ) ); ?>
18
 
19
+ <tr>
20
 
21
+ <th scope="row">
22
 
23
+ <?php if ( $exclude_path->isFile() ) { ?>
24
 
25
+ <div class="dashicons dashicons-media-default"></div>
26
 
27
+ <?php } elseif ( $exclude_path->isDir() ) { ?>
28
 
29
+ <div class="dashicons dashicons-portfolio"></div>
30
 
31
+ <?php } ?>
32
 
33
+ </th>
34
 
35
+ <td>
36
+ <code><?php echo esc_html( str_ireplace( $schedule->backup->get_root(), '', $exclude ) ); ?></code>
37
 
38
+ </td>
39
 
40
+ <td>
41
 
42
+ <?php if ( ( in_array( $exclude, $schedule->backup->default_excludes() ) ) || ( hmbkp_path() === untrailingslashit( $exclude ) ) ) : ?>
43
 
44
+ <?php _e( 'Default rule', 'backupwordpress' ); ?>
45
 
46
+ <?php elseif ( defined( 'HMBKP_EXCLUDE' ) && false !== strpos( HMBKP_EXCLUDE, $exclude ) ) : ?>
47
 
48
+ <?php _e( 'Defined in wp-config.php', 'backupwordpress' ); ?>
49
 
50
+ <?php else : ?>
51
 
52
+ <a href="<?php echo hmbkp_admin_action_url( 'remove_exclude_rule', array(
53
+ 'hmbkp_remove_exclude' => $exclude,
54
+ 'hmbkp_schedule_id' => $schedule->get_id()
55
+ ) ); ?>" class="delete-action"><?php _e( 'Stop excluding', 'backupwordpress' ); ?></a>
56
 
57
+ <?php endif; ?>
58
 
59
+ </td>
60
 
61
+ </tr>
62
 
63
+ <?php endforeach; ?>
64
 
65
  </tbody>
66
 
77
  // The directory to display
78
  $directory = $schedule->backup->get_root();
79
 
80
+ if ( isset( $_GET['hmbkp_directory_browse'] ) ) {
81
 
82
  $untrusted_directory = urldecode( $_GET['hmbkp_directory_browse'] );
83
 
84
  // Only allow real sub directories of the site root to be browsed
85
+ if ( false !== strpos( $untrusted_directory, $schedule->backup->get_root() ) && is_dir( $untrusted_directory ) ) {
86
  $directory = $untrusted_directory;
87
  }
88
 
99
 
100
  <thead>
101
 
102
+ <tr>
103
+ <th></th>
104
+ <th scope="col"><?php _e( 'Name', 'backupwordpress' ); ?></th>
105
+ <th scope="col" class="column-format"><?php _e( 'Size', 'backupwordpress' ); ?></th>
106
+ <th scope="col" class="column-format"><?php _e( 'Permissions', 'backupwordpress' ); ?></th>
107
+ <th scope="col" class="column-format"><?php _e( 'Type', 'backupwordpress' ); ?></th>
108
+ <th scope="col" class="column-format"><?php _e( 'Status', 'backupwordpress' ); ?></th>
109
+ </tr>
110
 
111
+ <tr>
112
 
113
+ <th scope="row">
114
+ <div class="dashicons dashicons-admin-home"></div>
115
+ </th>
116
 
117
+ <th scope="col">
118
 
119
+ <?php if ( $schedule->backup->get_root() !== $directory ) { ?>
120
 
121
+ <a href="<?php echo esc_url( remove_query_arg( 'hmbkp_directory_browse' ) ); ?>"><?php echo esc_html( $schedule->backup->get_root() ); ?></a>
122
+ <code>/</code>
123
 
124
+ <?php $parents = array_filter( explode( '/', str_replace( trailingslashit( $schedule->backup->get_root() ), '', trailingslashit( dirname( $directory ) ) ) ) );
125
 
126
+ foreach ( $parents as $directory_basename ) { ?>
127
 
128
+ <a href="<?php echo esc_url( add_query_arg( 'hmbkp_directory_browse', urlencode( substr( $directory, 0, strpos( $directory, $directory_basename ) ) . $directory_basename ) ) ); ?>"><?php echo esc_html( $directory_basename ); ?></a>
129
+ <code>/</code>
130
 
131
+ <?php } ?>
132
 
133
+ <?php echo esc_html( basename( $directory ) ); ?>
134
 
135
+ <?php } else { ?>
136
 
137
+ <?php echo esc_html( $schedule->backup->get_root() ); ?>
138
 
139
+ <?php } ?>
140
 
141
+ </th>
142
 
143
+ <td class="column-filesize">
144
 
145
+ <?php if ( $schedule->is_site_size_being_calculated() ) { ?>
146
 
147
+ <span class="spinner"></span>
148
 
149
+ <?php } else {
150
 
151
+ $root = new SplFileInfo( $schedule->backup->get_root() );
152
 
153
+ $size = $schedule->filesize( $root, true );
154
 
155
+ if ( false !== $size ) {
156
 
157
+ $size = size_format( $size );
158
 
159
+ if ( ! $size ) {
160
+ $size = '0 B';
161
+ } ?>
 
 
162
 
163
+ <code>
164
 
165
+ <?php echo esc_html( $size ); ?>
166
 
167
+ <a class="dashicons dashicons-update"
168
+ href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $schedule->backup->get_root() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'backupwordpress' ); ?></span></a>
169
 
170
+ </code>
171
 
 
172
 
173
  <?php } ?>
174
 
175
+ <?php } ?>
 
 
176
 
177
+ <td>
178
+ <?php echo esc_html( substr( sprintf( '%o', fileperms( $schedule->backup->get_root() ) ), - 4 ) ); ?>
179
+ </td>
180
 
181
+ <td>
182
 
183
+ <?php if ( is_link( $schedule->backup->get_root() ) ) {
184
 
185
+ _e( 'Symlink', 'backupwordpress' );
186
 
187
+ } elseif ( is_dir( $schedule->backup->get_root() ) ) {
188
 
189
+ _e( 'Folder', 'backupwordpress' );
190
 
191
+ } ?>
192
 
193
+ </td>
194
 
195
+ <td></td>
196
+
197
+ </tr>
198
 
199
  </thead>
200
 
201
  <tbody>
202
 
203
+ <?php foreach ( $files as $size => $file ) {
204
 
205
+ $is_excluded = $is_unreadable = false;
206
 
207
+ // Check if the file is excluded
208
+ if ( $exclude_string && preg_match( '(' . $exclude_string . ')', str_ireplace( trailingslashit( $schedule->backup->get_root() ), '', HM\BackUpWordPress\Backup::conform_dir( $file->getPathname() ) ) ) ) {
209
+ $is_excluded = true;
210
+ }
211
 
212
+ // Skip unreadable files
213
+ if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
214
+ $is_unreadable = true;
215
+ } ?>
216
 
217
+ <tr>
218
 
219
+ <td>
220
 
221
+ <?php if ( $is_unreadable ) { ?>
222
 
223
+ <div class="dashicons dashicons-dismiss"></div>
224
 
225
+ <?php } elseif ( $file->isFile() ) { ?>
226
 
227
+ <div class="dashicons dashicons-media-default"></div>
228
 
229
+ <?php } elseif ( $file->isDir() ) { ?>
230
 
231
+ <div class="dashicons dashicons-portfolio"></div>
232
 
233
+ <?php } ?>
234
 
235
+ </td>
236
 
237
+ <td>
238
 
239
+ <?php if ( $is_unreadable ) { ?>
240
 
241
+ <code class="strikethrough"
242
+ title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
243
 
244
+ <?php } elseif ( $file->isFile() ) { ?>
245
 
246
+ <code
247
+ title="<?php echo esc_attr( $file->getRealPath() ); ?>"><?php echo esc_html( $file->getBasename() ); ?></code>
248
 
249
+ <?php } elseif ( $file->isDir() ) { ?>
250
 
251
+ <code title="<?php echo esc_attr( $file->getRealPath() ); ?>"><a
252
+ href="<?php echo add_query_arg( 'hmbkp_directory_browse', urlencode( $file->getPathname() ) ); ?>"><?php echo esc_html( $file->getBasename() ); ?></a></code>
253
 
254
+ <?php } ?>
255
 
256
+ </td>
257
 
258
+ <td class="column-format column-filesize">
259
 
260
+ <?php if ( $file->isDir() && $schedule->is_site_size_being_calculated() ) { ?>
261
 
262
+ <span class="spinner"></span>
263
 
264
+ <?php } else {
265
 
266
+ $size = $schedule->filesize( $file );
267
 
268
+ if ( false !== $size ) {
269
 
270
+ $size = size_format( $size );
271
 
272
+ if ( ! $size ) {
273
+ $size = '0 B';
274
+ } ?>
275
 
276
+ <code>
277
 
278
+ <?php echo esc_html( $size ); ?>
279
 
280
+ <?php if ( $file->isDir() ) { ?>
281
 
282
+ <a title="<?php _e( 'Recalculate the size of this directory', 'backupwordpress' ); ?>"
283
+ class="dashicons dashicons-update"
284
+ href="<?php echo wp_nonce_url( add_query_arg( 'hmbkp_recalculate_directory_filesize', urlencode( $file->getPathname() ) ), 'hmbkp-recalculate_directory_filesize' ); ?>"><span><?php _e( 'Refresh', 'backupwordpress' ); ?></span></a>
285
 
286
+ <?php } ?>
287
 
288
+ </code>
289
 
290
 
291
+ <?php } else { ?>
292
 
293
+ <code>--</code>
294
 
295
+ <?php }
296
+ } ?>
297
 
298
+ </td>
299
 
300
+ <td>
301
+ <?php echo esc_html( substr( sprintf( '%o', $file->getPerms() ), - 4 ) ); ?>
302
+ </td>
303
 
304
+ <td>
305
 
306
+ <?php if ( $file->isLink() ) { ?>
307
 
308
+ <span
309
+ title="<?php echo esc_attr( $file->GetRealPath() ); ?>"><?php _e( 'Symlink', 'backupwordpress' ); ?></span>
310
 
311
+ <?php } elseif ( $file->isDir() ) {
312
 
313
+ _e( 'Folder', 'backupwordpress' );
314
 
315
+ } else {
316
 
317
+ _e( 'File', 'backupwordpress' );
318
 
319
+ } ?>
320
 
321
+ </td>
322
 
323
+ <td class="column-format">
324
 
325
+ <?php if ( $is_unreadable ) { ?>
326
 
327
+ <strong
328
+ title="<?php _e( 'Unreadable files won\'t be backed up.', 'backupwordpress' ); ?>"><?php _e( 'Unreadable', 'backupwordpress' ); ?></strong>
329
 
330
+ <?php } elseif ( $is_excluded ) { ?>
331
 
332
+ <strong><?php _e( 'Excluded', 'backupwordpress' ); ?></strong>
333
 
334
+ <?php } else {
335
 
336
+ $exclude_path = $file->getPathname();
337
 
338
+ // Excluded directories need to be trailingslashed
339
+ if ( $file->isDir() ) {
340
+ $exclude_path = trailingslashit( $file->getPathname() );
341
+ } ?>
342
 
343
+ <a href="<?php echo wp_nonce_url( add_query_arg( array(
344
+ 'hmbkp_schedule_id' => $schedule->get_id(),
345
+ 'action' => 'hmbkp_add_exclude_rule',
346
+ 'hmbkp_exclude_pathname' => urlencode( $exclude_path )
347
+ ), admin_url( 'admin-post.php' ) ), 'hmbkp-add-exclude-rule', 'hmbkp-add-exclude-rule-nonce' ); ?>"
348
+ class="button-secondary"><?php _e( 'Exclude &rarr;', 'backupwordpress' ); ?></a>
349
 
350
+ <?php } ?>
351
 
352
+ </td>
353
 
354
+ </tr>
355
 
356
+ <?php } ?>
357
 
358
  </tbody>
359
 
361
 
362
  <?php } ?>
363
 
364
+ <p class="submit">
365
+ <a href="<?php echo esc_url( hmbkp_get_settings_url() ) ?>"
366
+ class="button-primary"><?php _e( 'Done', 'backupwordpress' ); ?></a>
367
+ </p>
368
 
369
+ </div>
 
 
admin/schedule-form.php CHANGED
@@ -84,6 +84,8 @@ hmbkp_clear_settings_errors();
84
  $start_time = time();
85
  } ?>
86
 
 
 
87
  <tr id="start-day" class="recurring-setting">
88
 
89
  <th scope="row">
@@ -123,7 +125,7 @@ hmbkp_clear_settings_errors();
123
  </th>
124
 
125
  <td>
126
- <input type="number" min="0" max="31" step="1" id="hmbkp_schedule_start_day_of_month" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_month]" value="<?php echo esc_attr( date_i18n( 'j', $start_time ) ); ?>">
127
  </td>
128
 
129
  </tr>
@@ -138,16 +140,16 @@ hmbkp_clear_settings_errors();
138
 
139
  <span class="field-group">
140
 
141
- <label for="hmbkp_schedule_start_hours"><input type="number" min="0" max="23" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_hours]" id="hmbkp_schedule_start_hours" value="<?php echo esc_attr( date_i18n( 'G', $start_time ) ); ?>">
142
 
143
  <?php _e( 'Hours', 'backupwordpress' ); ?></label>
144
 
145
- <label for="hmbkp_schedule_start_minutes"><input type="number" min="0" max="59" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_minutes]" id="hmbkp_schedule_start_minutes" value="<?php echo esc_attr( (float) date_i18n( 'i', $start_time ) ); ?>">
146
 
147
  <?php _e( 'Minutes', 'backupwordpress' ); ?></label>
148
 
149
  </span>
150
-
151
  <p class="twice-js description<?php if ( $schedule->get_reoccurrence() !== 'hmbkp_fortnightly' ) { ?> hidden<?php } ?>"><?php _e( 'The second backup will run 12 hours after the first', 'backupwordpress' ); ?></p>
152
 
153
  </td>
84
  $start_time = time();
85
  } ?>
86
 
87
+ <?php $start_date_array = date_parse( date_i18n( get_option( 'date_format' ) . ' ' . get_option( 'time_format' ), $start_time ) ); ?>
88
+
89
  <tr id="start-day" class="recurring-setting">
90
 
91
  <th scope="row">
125
  </th>
126
 
127
  <td>
128
+ <input type="number" min="0" max="31" step="1" id="hmbkp_schedule_start_day_of_month" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_day_of_month]" value="<?php echo esc_attr( $start_date_array['day'] ); ?>">
129
  </td>
130
 
131
  </tr>
140
 
141
  <span class="field-group">
142
 
143
+ <label for="hmbkp_schedule_start_hours"><input type="number" min="0" max="23" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_hours]" id="hmbkp_schedule_start_hours" value="<?php echo esc_attr( $start_date_array['hour'] ); ?>">
144
 
145
  <?php _e( 'Hours', 'backupwordpress' ); ?></label>
146
 
147
+ <label for="hmbkp_schedule_start_minutes"><input type="number" min="0" max="59" step="1" name="hmbkp_schedule_recurrence[hmbkp_schedule_start_minutes]" id="hmbkp_schedule_start_minutes" value="<?php echo esc_attr( $start_date_array['minute'] ); ?>">
148
 
149
  <?php _e( 'Minutes', 'backupwordpress' ); ?></label>
150
 
151
  </span>
152
+ <p class="descriprion"><strong><?php esc_html_e( 'Please use 24 hour format for hours', 'backupwordpress' ); ?></strong></p>
153
  <p class="twice-js description<?php if ( $schedule->get_reoccurrence() !== 'hmbkp_fortnightly' ) { ?> hidden<?php } ?>"><?php _e( 'The second backup will run 12 hours after the first', 'backupwordpress' ); ?></p>
154
 
155
  </td>
admin/schedule-sentence.php CHANGED
@@ -148,11 +148,17 @@ if ( ! empty( $services ) && count( $services ) > 1 ) {
148
  function hmbkp_get_site_size_text( HM\BackUpWordPress\Scheduled_Backup $schedule ) {
149
 
150
  if ( isset( $_GET['hmbkp_add_schedule'] ) ) {
 
151
  return '';
152
- } elseif ( ( 'database' === $schedule->get_type() ) || $schedule->is_site_size_cached() ) {
 
 
153
  return sprintf( '(<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'backupwordpress' ) . '">%s</code>)', esc_attr( $schedule->get_formatted_site_size() ) );
 
154
  } else {
155
- return sprintf('(<code class="calculating" title="' . __( 'this shouldn\'t take long&hellip;', 'backupwordpress' ) . '">' . __( 'calculating the size of your backup&hellip;', 'backupwordpress' ) . '</code>)');
 
 
156
  }
157
 
158
  }
148
  function hmbkp_get_site_size_text( HM\BackUpWordPress\Scheduled_Backup $schedule ) {
149
 
150
  if ( isset( $_GET['hmbkp_add_schedule'] ) ) {
151
+
152
  return '';
153
+
154
+ } elseif ( ( 'database' === $schedule->get_type() ) || $schedule->is_site_size_cached() ) {
155
+
156
  return sprintf( '(<code title="' . __( 'Backups will be compressed and should be smaller than this.', 'backupwordpress' ) . '">%s</code>)', esc_attr( $schedule->get_formatted_site_size() ) );
157
+
158
  } else {
159
+
160
+ return sprintf( '(<code class="calculating" title="' . __( 'this shouldn\'t take long&hellip;', 'backupwordpress' ) . '">' . __( 'calculating the size of your backup&hellip;', 'backupwordpress' ) . '</code>)' );
161
+
162
  }
163
 
164
  }
assets/hmbkp.js CHANGED
@@ -58,23 +58,14 @@ jQuery(document).ready(function ( $ ) {
58
 
59
  var scheduleId = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
60
 
61
- var ajaxRequest = $.get(
62
  ajaxurl,
63
  {
64
  'hmbkp_run_schedule_nonce': hmbkp.hmbkp_run_schedule_nonce,
65
  'action': 'hmbkp_run_schedule',
66
  'hmbkp_schedule_id': scheduleId
67
  }
68
- ).done( function ( data ) {
69
-
70
- hmbkpCatchResponseAndOfferToEmail( data );
71
-
72
- // Redirect back on error
73
- }).fail( function ( jqXHR ) {
74
-
75
- hmbkpCatchResponseAndOfferToEmail( jqXHR.responseText );
76
-
77
- });
78
 
79
  e.preventDefault();
80
 
@@ -134,7 +125,9 @@ function hmbkpToggleScheduleFields( recurrence ) {
134
  settingFields.hide();
135
  break;
136
 
137
- case 'hmbkp_hourly' : // fall through
 
 
138
  case 'hmbkp_daily' :
139
  settingFields.hide();
140
  scheduleSettingFields.show();
58
 
59
  var scheduleId = $( '[data-hmbkp-schedule-id]' ).attr( 'data-hmbkp-schedule-id' );
60
 
61
+ $.post(
62
  ajaxurl,
63
  {
64
  'hmbkp_run_schedule_nonce': hmbkp.hmbkp_run_schedule_nonce,
65
  'action': 'hmbkp_run_schedule',
66
  'hmbkp_schedule_id': scheduleId
67
  }
68
+ );
 
 
 
 
 
 
 
 
 
69
 
70
  e.preventDefault();
71
 
125
  settingFields.hide();
126
  break;
127
 
128
+ case 'hmbkp_hourly' :
129
+ settingFields.hide();
130
+ break;
131
  case 'hmbkp_daily' :
132
  settingFields.hide();
133
  scheduleSettingFields.show();
assets/hmbkp.min.js CHANGED
@@ -1 +1 @@
1
- function hmbkpToggleScheduleFields(a){a="undefined"!=typeof a?a:"manually";var b=jQuery(".recurring-setting"),c=jQuery("#schedule-start"),d=jQuery("p.twice-js");switch(a){case"manually":b.hide();break;case"hmbkp_hourly":case"hmbkp_daily":b.hide(),c.show(),d.hide();break;case"hmbkp_twicedaily":b.hide(),c.show(),d.show();break;case"hmbkp_weekly":case"hmbkp_fortnightly":b.hide(),jQuery("#start-day").show(),c.show(),d.hide();break;case"hmbkp_monthly":b.hide(),c.show(),jQuery("#start-date").show(),d.hide()}}function hmbkpCatchResponseAndOfferToEmail(a){a&&0!==a?(jQuery(".hmbkp-schedule-sentence.hmbkp-running").removeClass("hmbkp-running").addClass("hmbkp-error"),jQuery.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_backup_error",hmbkp_error:a},function(a){a&&0!==a&&location.reload(!0)})):location.reload(!0),jQuery(document).one("click",".hmbkp_send_error_via_email",function(b){b.preventDefault(),jQuery(this).addClass("hmbkp-ajax-loading").attr("disabled","disabled"),jQuery.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_email_error",hmbkp_error:a},function(){})})}jQuery(document).ready(function(a){a.ajaxSetup({cache:!1}),a("select#hmbkp_schedule_recurrence_type").size()&&(hmbkpToggleScheduleFields(a("select#hmbkp_schedule_recurrence_type").val()),a(document).on("change","select#hmbkp_schedule_recurrence_type",function(){hmbkpToggleScheduleFields(a(this).val())})),a(document).on("click",".hmbkp-schedule-actions .delete-action",function(a){confirm(hmbkp.delete_schedule)||a.preventDefault()}),a(document).on("click",".hmbkp_manage_backups_row .delete-action",function(a){confirm(hmbkp.delete_backup)||a.preventDefault()}),a(document).on("click",".hmbkp-edit-schedule-excludes-form .delete-action",function(a){confirm(hmbkp.remove_exclude_rule)||a.preventDefault()}),a.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_cron_test"},function(b){"1"!==b&&a(".wrap > h2").after(b)}),a(document).on("click",".hmbkp-run",function(b){a(this).closest(".hmbkp-schedule-sentence").addClass("hmbkp-running"),a(".hmbkp-error").removeClass("hmbkp-error");{var c=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id");a.get(ajaxurl,{hmbkp_run_schedule_nonce:hmbkp.hmbkp_run_schedule_nonce,action:"hmbkp_run_schedule",hmbkp_schedule_id:c}).done(function(a){hmbkpCatchResponseAndOfferToEmail(a)}).fail(function(a){hmbkpCatchResponseAndOfferToEmail(a.responseText)})}b.preventDefault()}),a(document).on("heartbeat-send",function(b,c){c.hmbkp_schedule_id=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id"),a(".hmbkp-schedule-sentence.hmbkp-running").size()?c.hmbkp_is_in_progress=!0:c.hmbkp_client_request="site_size"}),a(document).on("heartbeat-tick",function(b,c){if(0!==c.hmbkp_schedule_status||a(".hmbkp-error").size()||location.reload(!0),0!==c.hmbkp_schedule_status&&void 0!==c.hmbkp_schedule_status&&a(".hmbkp-status").replaceWith(c.hmbkp_schedule_status),void 0!==c.hmbkp_site_size&&a("code.calculating").size()){a("code.calculating").text(c.hmbkp_site_size);var d=a(".hmbkp-exclude-settings");d.size()&&d.replaceWith(c.hmbkp_dir_sizes)}})});
1
+ function hmbkpToggleScheduleFields(a){a="undefined"!=typeof a?a:"manually";var b=jQuery(".recurring-setting"),c=jQuery("#schedule-start"),d=jQuery("p.twice-js");switch(a){case"manually":b.hide();break;case"hmbkp_hourly":b.hide();break;case"hmbkp_daily":b.hide(),c.show(),d.hide();break;case"hmbkp_twicedaily":b.hide(),c.show(),d.show();break;case"hmbkp_weekly":case"hmbkp_fortnightly":b.hide(),jQuery("#start-day").show(),c.show(),d.hide();break;case"hmbkp_monthly":b.hide(),c.show(),jQuery("#start-date").show(),d.hide()}}function hmbkpCatchResponseAndOfferToEmail(a){a&&0!==a?(jQuery(".hmbkp-schedule-sentence.hmbkp-running").removeClass("hmbkp-running").addClass("hmbkp-error"),jQuery.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_backup_error",hmbkp_error:a},function(a){a&&0!==a&&location.reload(!0)})):location.reload(!0),jQuery(document).one("click",".hmbkp_send_error_via_email",function(b){b.preventDefault(),jQuery(this).addClass("hmbkp-ajax-loading").attr("disabled","disabled"),jQuery.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_email_error",hmbkp_error:a},function(){})})}jQuery(document).ready(function(a){a.ajaxSetup({cache:!1}),a("select#hmbkp_schedule_recurrence_type").size()&&(hmbkpToggleScheduleFields(a("select#hmbkp_schedule_recurrence_type").val()),a(document).on("change","select#hmbkp_schedule_recurrence_type",function(){hmbkpToggleScheduleFields(a(this).val())})),a(document).on("click",".hmbkp-schedule-actions .delete-action",function(a){confirm(hmbkp.delete_schedule)||a.preventDefault()}),a(document).on("click",".hmbkp_manage_backups_row .delete-action",function(a){confirm(hmbkp.delete_backup)||a.preventDefault()}),a(document).on("click",".hmbkp-edit-schedule-excludes-form .delete-action",function(a){confirm(hmbkp.remove_exclude_rule)||a.preventDefault()}),a.post(ajaxurl,{nonce:hmbkp.nonce,action:"hmbkp_cron_test"},function(b){"1"!==b&&a(".wrap > h2").after(b)}),a(document).on("click",".hmbkp-run",function(b){a(this).closest(".hmbkp-schedule-sentence").addClass("hmbkp-running"),a(".hmbkp-error").removeClass("hmbkp-error");var c=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id");a.post(ajaxurl,{hmbkp_run_schedule_nonce:hmbkp.hmbkp_run_schedule_nonce,action:"hmbkp_run_schedule",hmbkp_schedule_id:c}),b.preventDefault()}),a(document).on("heartbeat-send",function(b,c){c.hmbkp_schedule_id=a("[data-hmbkp-schedule-id]").attr("data-hmbkp-schedule-id"),a(".hmbkp-schedule-sentence.hmbkp-running").size()?c.hmbkp_is_in_progress=!0:c.hmbkp_client_request="site_size"}),a(document).on("heartbeat-tick",function(b,c){if(0!==c.hmbkp_schedule_status||a(".hmbkp-error").size()||location.reload(!0),0!==c.hmbkp_schedule_status&&void 0!==c.hmbkp_schedule_status&&a(".hmbkp-status").replaceWith(c.hmbkp_schedule_status),void 0!==c.hmbkp_site_size&&a("code.calculating").size()){a("code.calculating").text(c.hmbkp_site_size);var d=a(".hmbkp-exclude-settings");d.size()&&d.replaceWith(c.hmbkp_dir_sizes)}})});
backupwordpress.php CHANGED
@@ -3,7 +3,7 @@
3
  Plugin Name: BackUpWordPress
4
  Plugin URI: http://bwp.hmn.md/
5
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>. On multisite, you'll find me under the Network Settings menu.
6
- Version: 3.1.4
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  License: GPL-2.0+
@@ -31,395 +31,19 @@ along with this program; if not, write to the Free Software
31
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
  */
33
 
34
- namespace HM\BackUpWordPress;
 
35
 
36
- require_once( plugin_dir_path( __FILE__ ) . 'classes/class-setup.php' );
37
-
38
- register_activation_hook( __FILE__, array( 'HM\BackUpWordPress\Setup', 'activate' ) );
39
- register_deactivation_hook( __FILE__, array( 'HM\BackUpWordPress\Setup', 'deactivate' ) );
40
-
41
- /**
42
- * Class Plugin
43
- */
44
- final class Plugin {
45
-
46
- const PLUGIN_VERSION = '3.1.4';
47
-
48
- /**
49
- * @var Plugin The singleton instance.
50
- */
51
- private static $instance;
52
-
53
- /**
54
- * Instantiates a new Plugin object.
55
- */
56
- private function __construct() {
57
- add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
58
- }
59
-
60
- /**
61
- * Insures we always return the same object.
62
- *
63
- * @return Plugin
64
- */
65
- public static function get_instance() {
66
-
67
- if ( ! ( self::$instance instanceof Plugin ) ) {
68
- self::$instance = new Plugin();
69
- }
70
-
71
- return self::$instance;
72
  }
73
 
74
- /**
75
- * Initialize the plugin.
76
- */
77
- public function plugins_loaded() {
78
-
79
- if ( false !== $this->maybe_self_deactivate() ) {
80
-
81
- $this->constants();
82
-
83
- $this->includes();
84
-
85
- $this->hooks();
86
-
87
- $this->text_domain();
88
-
89
- // If we get here, then BWP is loaded
90
- do_action( 'backupwordpress_loaded' );
91
-
92
- }
93
-
94
- }
95
-
96
- public function maybe_self_deactivate() {
97
-
98
- if ( ! Setup::meets_requirements() ) {
99
- add_action( 'admin_init', array( 'HM\BackUpWordPress\Setup', 'self_deactivate' ) );
100
- add_action( 'admin_notices', array( 'HM\BackUpWordPress\Setup', 'display_admin_notices' ) );
101
- }
102
-
103
- }
104
-
105
- /**
106
- * Define all the constants.
107
- */
108
- public function constants() {
109
-
110
- if ( ! defined( 'HMBKP_PLUGIN_SLUG' ) ) {
111
- define( 'HMBKP_PLUGIN_SLUG', dirname( plugin_basename( __FILE__ ) ) );
112
- }
113
-
114
- if ( ! defined( 'HMBKP_PLUGIN_PATH' ) ) {
115
- define( 'HMBKP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
116
- }
117
-
118
- if ( ! defined( 'HMBKP_PLUGIN_URL' ) ) {
119
- define( 'HMBKP_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
120
- }
121
-
122
- if ( ! defined( 'HMBKP_PLUGIN_LANG_DIR' ) ) {
123
- define( 'HMBKP_PLUGIN_LANG_DIR', apply_filters( 'hmbkp_filter_lang_dir', HMBKP_PLUGIN_SLUG . '/languages/' ) );
124
- }
125
-
126
- if ( ! defined( 'HMBKP_ADMIN_URL' ) ) {
127
- $page = is_multisite() ? network_admin_url( 'settings.php' ) : admin_url( 'tools.php' );
128
- define( 'HMBKP_ADMIN_URL', add_query_arg( 'page', HMBKP_PLUGIN_SLUG, $page ) );
129
- }
130
-
131
- if ( ! defined( 'HMBKP_ADMIN_PAGE' ) ) {
132
- $prefix = is_multisite() ? 'settings_page_' : 'tools_page_';
133
- define( 'HMBKP_ADMIN_PAGE', $prefix . HMBKP_PLUGIN_SLUG );
134
- }
135
-
136
- define( 'HMBKP_SECURE_KEY', $this->generate_key() );
137
-
138
  }
139
 
140
- /**
141
- * Load all BackUpWordPress functions.
142
- */
143
- protected function includes() {
144
-
145
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-notices.php' );
146
-
147
- // Load the admin menu
148
- require_once( HMBKP_PLUGIN_PATH . 'admin/menu.php' );
149
- require_once( HMBKP_PLUGIN_PATH . 'admin/actions.php' );
150
-
151
- // Load Backdrop if necessary.
152
- if ( ! class_exists( 'HM_Backdrop_Task' ) ) {
153
- require_once( HMBKP_PLUGIN_PATH . 'backdrop/hm-backdrop.php' );
154
- }
155
-
156
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirements.php' );
157
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirement.php' );
158
-
159
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-path.php' );
160
-
161
- // Load the core backup class
162
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-backup.php' );
163
-
164
- // Load the backup scheduling classes
165
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-schedule.php' );
166
- require_once( plugin_dir_path( __FILE__ ) . 'classes/class-schedules.php' );
167
-
168
- // Load the core functions
169
- require_once( HMBKP_PLUGIN_PATH . 'functions/core.php' );
170
- require_once( HMBKP_PLUGIN_PATH . 'functions/interface.php' );
171
-
172
- // Load the services
173
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-services.php' );
174
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-service.php' );
175
-
176
- // Load the email service
177
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-email-service.php' );
178
-
179
- // Load the webhook services
180
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-webhook-service.php' );
181
- require_once( HMBKP_PLUGIN_PATH . 'classes/class-wpremote-webhook-service.php' );
182
-
183
- require_once( HMBKP_PLUGIN_PATH . 'classes/deprecated.php' );
184
-
185
- // Load the wp cli command
186
- if ( defined( 'WP_CLI' ) && WP_CLI ) {
187
- include( HMBKP_PLUGIN_PATH . 'classes/class-backupwordpress-wp-cli-command.php' );
188
- }
189
-
190
- }
191
-
192
- /**
193
- * Hook into WordPress page lifecycle and execute BackUpWordPress functions.
194
- */
195
- public function hooks() {
196
-
197
- add_action( 'activated_plugin', array( $this, 'load_first' ) );
198
-
199
- add_action( 'admin_init', array( $this, 'upgrade' ) );
200
-
201
- add_action( 'admin_init', array( $this, 'init' ) );
202
-
203
- add_action( 'hmbkp_schedule_hook', array( $this, 'schedule_hook_run' ) );
204
-
205
- add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
206
-
207
- add_action( 'admin_footer-' . HMBKP_ADMIN_PAGE, array( $this, 'load_intercom_script' ) );
208
-
209
- add_action( 'admin_enqueue_scripts', array( $this, 'styles' ) );
210
-
211
- }
212
-
213
- /**
214
- * Load the Javascript in the admin.
215
- *
216
- * @param $hook The name of the admin page hook.
217
- */
218
- public function scripts( $hook ) {
219
-
220
- if ( HMBKP_ADMIN_PAGE !== $hook ) {
221
- return;
222
- }
223
-
224
- $js_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.min.js';
225
-
226
- // TODO shuold this also support WP_SCRIPT_DEBUG
227
- if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
228
- $js_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.js';
229
- }
230
-
231
- wp_enqueue_script( 'hmbkp', $js_file, array( 'heartbeat' ), sanitize_key( self::PLUGIN_VERSION ) );
232
-
233
- wp_localize_script(
234
- 'hmbkp',
235
- 'hmbkp',
236
- array(
237
- 'page_slug' => HMBKP_PLUGIN_SLUG,
238
- 'nonce' => wp_create_nonce( 'hmbkp_nonce' ),
239
- 'hmbkp_run_schedule_nonce' => wp_create_nonce( 'hmbkp_run_schedule' ),
240
- 'update' => __( 'Update', 'backupwordpress' ),
241
- 'cancel' => __( 'Cancel', 'backupwordpress' ),
242
- 'delete_schedule' => __( 'Are you sure you want to delete this schedule? All of it\'s backups will also be deleted.', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
243
- 'delete_backup' => __( 'Are you sure you want to delete this backup?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
244
- 'remove_exclude_rule' => __( 'Are you sure you want to remove this exclude rule?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
245
- 'remove_old_backups' => __( 'Reducing the number of backups that are stored on this server will cause some of your existing backups to be deleted, are you sure that\'s what you want?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n"
246
- )
247
- );
248
-
249
- }
250
-
251
- /**
252
- * Loads the plugin text domain for translation.
253
- * This setup allows a user to just drop his custom translation files into the WordPress language directory
254
- * Files will need to be in a subdirectory with the name of the textdomain 'backupwordpress'
255
- */
256
- public function text_domain() {
257
-
258
- // Set unique textdomain string
259
- $textdomain = 'backupwordpress';
260
-
261
- // The 'plugin_locale' filter is also used by default in load_plugin_textdomain()
262
- $locale = apply_filters( 'plugin_locale', get_locale(), $textdomain );
263
-
264
- // Set filter for WordPress languages directory
265
- $hmbkp_wp_lang_dir = apply_filters( 'hmbkp_do_filter_wp_lang_dir', trailingslashit( WP_LANG_DIR ) . trailingslashit( $textdomain ) . $textdomain . '-' . $locale . '.mo' );
266
-
267
- // Translations: First, look in WordPress' "languages" folder = custom & update-secure!
268
- load_textdomain( $textdomain, $hmbkp_wp_lang_dir );
269
-
270
- // Translations: Secondly, look in plugin's "languages" folder = default
271
- load_plugin_textdomain( $textdomain, false, HMBKP_PLUGIN_LANG_DIR );
272
-
273
- }
274
-
275
- /**
276
- * Determine if we need to run an upgrade routine.
277
- */
278
- public function upgrade() {
279
-
280
- // Fire the update action
281
- if ( self::PLUGIN_VERSION != get_option( 'hmbkp_plugin_version' ) ) {
282
- hmbkp_update();
283
- }
284
-
285
- }
286
-
287
- /**
288
- * Runs on every admin page load
289
- */
290
- public function init() {
291
-
292
- // If we have multiple paths for some reason then clean them up
293
- Path::get_instance()->merge_existing_paths();
294
- }
295
-
296
- /**
297
- * Generate a unique key.
298
- *
299
- * @return string
300
- */
301
- protected function generate_key() {
302
-
303
- $key = array( ABSPATH, time() );
304
- $constants = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT', 'SECRET_KEY' );
305
-
306
- foreach ( $constants as $constant ) {
307
- if ( defined( $constant ) ) {
308
- $key[] = constant( $constant );
309
- }
310
- }
311
-
312
- shuffle( $key );
313
-
314
- return md5( serialize( $key ) );
315
-
316
- }
317
-
318
- /**
319
- * Ensure BackUpWordPress is loaded before add-ons, changes the order of the serialized values in the DB field.
320
- */
321
- public function load_first() {
322
-
323
- $active_plugins = get_option( 'active_plugins' );
324
-
325
- $plugin_path = plugin_basename( __FILE__ );
326
-
327
- $key = array_search( $plugin_path, $active_plugins );
328
-
329
- if ( $key > 0 ) {
330
-
331
- array_splice( $active_plugins, $key, 1 );
332
-
333
- array_unshift( $active_plugins, $plugin_path );
334
-
335
- update_option( 'active_plugins', $active_plugins );
336
-
337
- }
338
-
339
- }
340
-
341
- /**
342
- * Function to run when the schedule cron fires.
343
- *
344
- * @param $schedule_id
345
- */
346
- public function schedule_hook_run( $schedule_id ) {
347
-
348
- if ( ! hmbkp_possible() ) {
349
- return;
350
- }
351
-
352
- $schedules = Schedules::get_instance();
353
- $schedule = $schedules->get_schedule( $schedule_id );
354
-
355
- if ( ! $schedule ) {
356
- return;
357
- }
358
-
359
- $schedule->run();
360
-
361
- }
362
-
363
- /**
364
- * Enqueue the plugin styles.
365
- *
366
- * @param $hook
367
- */
368
- public function styles( $hook ) {
369
-
370
- if ( HMBKP_ADMIN_PAGE !== $hook ) {
371
- return;
372
- }
373
-
374
- $css_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.min.css';
375
-
376
- if ( WP_DEBUG ) {
377
- $css_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.css';
378
- }
379
-
380
- wp_enqueue_style( 'backupwordpress', $css_file, false, sanitize_key( self::PLUGIN_VERSION ) );
381
-
382
- }
383
-
384
- /**
385
- * Load Intercom and send across user information and server info. Only loaded if the user has opted in.
386
- *
387
- * @param $hook
388
- */
389
- public function load_intercom_script() {
390
-
391
- if ( ! get_option( 'hmbkp_enable_support' ) ) {
392
- return;
393
- }
394
-
395
- $info = array();
396
-
397
- foreach ( Requirements::get_requirement_groups() as $group ) {
398
- foreach ( Requirements::get_requirements( $group ) as $requirement ) {
399
- $info[ $requirement->name() ] = $requirement->result();
400
- }
401
- }
402
-
403
- foreach ( Services::get_services() as $file => $service ) {
404
- array_merge( $info, call_user_func( array( $service, 'intercom_data' ) ) );
405
- }
406
-
407
- $current_user = wp_get_current_user();
408
-
409
- $info['user_hash'] = hash_hmac( 'sha256', $current_user->user_email, 'fcUEt7Vi4ym5PXdcr2UNpGdgZTEvxX9NJl8YBTxK' );
410
- $info['email'] = $current_user->user_email;
411
- $info['created_at'] = strtotime( $current_user->user_registered );
412
- $info['app_id'] = '7f1l4qyq';
413
- $info['name'] = $current_user->display_name;
414
- $info['widget'] = array( 'activator' => '#intercom' ); ?>
415
-
416
- <script id="IntercomSettingsScriptTag">
417
- window.intercomSettings = <?php echo json_encode( $info ); ?>;
418
- </script>
419
- <script>!function(){function e(){var a=c.createElement("script");a.type="text/javascript",a.async=!0,a.src="https://static.intercomcdn.com/intercom.v1.js";var b=c.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}var a=window,b=a.Intercom;if("function"==typeof b)b("reattach_activator"),b("update",intercomSettings);else{var c=document,d=function(){d.c(arguments)};d.q=[],d.c=function(a){d.q.push(a)},a.Intercom=d,a.attachEvent?a.attachEvent("onload",e):a.addEventListener("load",e,!1)}}();</script>
420
-
421
- <?php }
422
 
 
 
423
  }
424
-
425
- Plugin::get_instance();
3
  Plugin Name: BackUpWordPress
4
  Plugin URI: http://bwp.hmn.md/
5
  Description: Simple automated backups of your WordPress powered website. Once activated you'll find me under <strong>Tools &rarr; Backups</strong>. On multisite, you'll find me under the Network Settings menu.
6
+ Version: 3.2.0
7
  Author: Human Made Limited
8
  Author URI: http://hmn.md/
9
  License: GPL-2.0+
31
  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
32
  */
33
 
34
+ // Only load if >= PHP 5.3
35
+ if ( version_compare( phpversion(), '5.3', '>=' ) ) {
36
 
37
+ if ( ! defined( 'HMBKP_PLUGIN_PATH' ) ) {
38
+ define( 'HMBKP_PLUGIN_PATH', plugin_dir_path( __FILE__ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
39
  }
40
 
41
+ if ( ! defined( 'HMBKP_BASENAME' ) ) {
42
+ define( 'HMBKP_BASENAME', plugin_basename( __FILE__ ) );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
43
  }
44
 
45
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-plugin.php' );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
46
 
47
+ } else {
48
+ wp_die( sprintf( __( 'BackUpWordPress will not work on this site. ( PHP Version %s is unsupported )', 'backupwordpress' ), phpversion() ), __( 'BackUpWordPress Error', 'backupwordpress' ), array( 'back_link' => true ) );
49
  }
 
 
changelog DELETED
@@ -1,2024 +0,0 @@
1
- da0eb54 (HEAD, origin/master, master) Merge pull request #728 from humanmade/issue-728
2
- 0417e75 Merge pull request #739 from humanmade/upgrade-options
3
- 6bcc87f (upgrade-options) Bump version
4
- ba75dd3 strtolower is redundant
5
- a384804 Upgrade routine
6
- 8cbe010 (origin/change-settings-names, change-settings-names) Use the Service name as the setting name
7
- dc8b1a1 (issue-728) Cleear settings for schedule settings
8
- 54dafb4 Fixes bug in displaying settings error notices
9
- 39f1df4 (php52-compat, backup-progress) Update version number
10
- a88d1b0 Merge pull request #726 from humanmade/fix-fatal-error-missing-class-addons
11
- 76329ce (fix-fatal-error-missing-class-addons) Leave bare minimum to avoid fatal error
12
- 4c6846d remove old main plugin class
13
- ce4f3c8 remove deprecated notice
14
- b37d112 Throw a deprecated warning
15
- 95fd673 (tag: 3.1.3) Merge pull request #727 from danielbachhuber/patch-1
16
- 68aea7f Fix class name
17
- 6bca5e5 Add BWP class
18
- 7b32eca Bump version
19
- 2410dcd Introduces a deprecated.php file
20
- 62d6b16 (tag: 3.1.2) Version 3.1.2
21
- 974a939 Merge pull request #687 from humanmade/fixup-setup-class
22
- f6f6169 Merge pull request #724 from humanmade/simplify-bwp-file-timestamp
23
- f29e319 (simplify-bwp-file-timestamp) Simplify the file name timestamp
24
- 54327e0 Fix class file name
25
- b97f805 Merge pull request #723 from humanmade/willmot-slack-notifications
26
- acad348 (fixup-setup-class) Add missing transients to uninstall routine
27
- e3857e7 switch Travis notifications to Slack instead of Hipchat
28
- 2ff2b3c Do not delete backups on uninstall
29
- 2ae3630 wrap in parenthesis
30
- 0c1d81f Fix include paths after moving uninstall to own file herpderp
31
- 08ebd69 Update BackUp class include
32
- 4d25ebe Merge branch 'master' into fixup-setup-class
33
- a79e649 (refactor-fixes, issue-688) Merge pull request #719 from humanmade/iis-fixes
34
- d7b5b73 Merge pull request #720 from humanmade/refactor-fixes
35
- c93c3a5 Add all cases to switch
36
- c8a0068 Pass scanned files sizes through conform_dir()
37
- 5746c66 Fix some classes and requires
38
- ec54f3b Merge branch 'master' into fixup-setup-class
39
- ea32820 Merge branch 'master' into fixup-setup-class
40
- c7e556c Merge pull request #684 from humanmade/issue-684
41
- 8ab6a83 (origin/issue-684, issue-684) Fix namespaces
42
- 9c8f826 Remove unnecessary wildcard from regex
43
- 021feb3 Merge branch 'master' into issue-684
44
- d4c215e Merge pull request #667 from humanmade/crazy-refactor
45
- 3d8ffca (crazy-refactor) Remove some duplication
46
- eb09901 Formatting
47
- b020077 Fix Class name
48
- 4533bf0 Merge branch 'master' into crazy-refactor
49
- a329b61 Blank line
50
- 2700f66 Uses a DirectoryIterator to delete files
51
- 449ef48 Merge pull request #683 from humanmade/change-singleton-implementation
52
- 219fe77 Merge branch 'master' into crazy-refactor
53
- de70b1f Remove tests for now
54
- d0e23a0 Fix stable tag number
55
- fc912ee Revert to using uninstall.php
56
- bf672f6 Add tests for uninstall and deactivate
57
- 660fd78 Remove double lie break
58
- 32c6b8e Remove double line break
59
- f084b60 Remove phpdocumentor
60
- 51eaa6e We still need to require some scripts...
61
- b5261a5 We dont need to check for this constant in the hook callback
62
- 867ff5d Use get_col to directly have an array of schedule option names
63
- fee584f Remove namespacing
64
- 5130b38 Remove debugging
65
- 176c084 Make the uninstall, activation and deactivation hooks work
66
- 239f539 (change-singleton-implementation) Change the singleton implementation to not use the static() function
67
- fd13166 (adds-filters) Merge pull request #682 from duritong/fix_path_argument
68
- ddc75d8 path argument interfers with wp-cli path argument.
69
- e3c2b22 (tag: v3.1.1) Version 3.1.1
70
- b3ffe16 Merge pull request #670 from humanmade/fix-668
71
- ad7e0fa Correct $response1 variable
72
- 89c87e8 (tag: 3.1-alpha) Merge pull request #475 from humanmade/issue-475
73
- d0e6d0c Merge pull request #652 from humanmade/issue-652
74
- 804c472 (issue-652) Suppress warnings from filesystem functions
75
- 9861f06 Remove debugging function
76
- 6601346 Merge branch 'master' into issue-652
77
- 65808bb (issue-475) Fix a French string
78
- ca35ba3 Format the intercom data better
79
- c8cd859 Load Intercom in the admin footer
80
- 34c3af0 Fix some HTML issues
81
- b896803 Fix tests
82
- 4c3fade Add a function that returns a given option value
83
- 071a23a Return Unknown if no average exists or invalid
84
- 4e6ca12 Add a start parameter to function
85
- 6d8047a Pass in the start time as a parameter
86
- 0410b01 Add some unit tests
87
- 740583a Make strings translatable
88
- 9861f70 Escape values
89
- 61a0441 Adds a function to track backup duration and anpther to display it
90
- adb7b8a Adds Average Backup Duration Info
91
- e9a4088 Improve display of arrays
92
- dcbe510 Fix some scrutinizer issues, mostly major ones
93
- cbc5a85 Consistent default name for database dumps
94
- 9e9725d Major 5.3 re-factoring fun
95
- ef82471 Merge hm-backup into backupwordpress
96
- 4e3bfb6 Minor code formatting
97
- 6c0efd4 else if should be elseif
98
- a970696 Update the WP_CLI command to fix some issues
99
- 35a473d Add support for copying and updating an existing backups
100
- 1ee8c69 Fixes open_basedir warnings
101
- 8de17c3 Replace spaces with tabs for indentation
102
- 082a038 Merge pull request #664 from humanmade/wp-cron-test-improvements
103
- cc8e46e (wp-cron-test-improvements) Improve the reliability of the wp-cron test
104
- 8bf18c5 Merge pull request #639 from humanmade/issue-639
105
- 5ad724e Merge pull request #588 from humanmade/issue-588
106
- b87396b (issue-639) Do not start schedule if backups are not possible
107
- 069553b (issue-588) Merge branch 'master' into issue-588
108
- 876b955 Pop in the directory sizes
109
- f6d99f6 No need to return the whole array
110
- 81fc305 Merge pull request #640 from humanmade/issue-640
111
- c11b1b5 Merge pull request #605 from humanmade/issue-605
112
- 809528e Adapt heartbeat pulse
113
- bdb1142 Update Javascript
114
- 0f4f758 A few adjustments based on peer review feedback.
115
- 315ff75 Update constant name
116
- 195189b Load the default translations so that activation error message is in user language
117
- cb6fbe5 Fix a few translatable strings
118
- 8c52f3a Update French translations
119
- 2f1a3a5 Re-uglify Intercom js
120
- 727579e Use provided callback argument to determine current screen
121
- 036998c remove deprecated code
122
- 34cfdc9 Merge branch 'master' into issue-605
123
- 6951b7e Merge pull request #612 from humanmade/hmbkp-path
124
- 5c48e64 Remove PHPDoc build process
125
- f3e9fc3 Merge branch 'master' into hmbkp-path
126
- 6457232 Merge branch 'master' into issue-605
127
- c134e41 Ignore IDE project files
128
- c127848 Merge pull request #651 from humanmade/remove_memory_limit_define
129
- 16213e9 Only show notices on BWP admin page
130
- 4945ce9 Merge pull request #649 from humanmade/improved_notices
131
- b2a228c Fix class name
132
- 3ffb704 Formating
133
- d128ae5 Make function public for now
134
- a491cfc Get an instance of BWP to load functions
135
- 45af4c4 Fix conditional
136
- 9675432 Fix conditional
137
- 6769d23 Show admin notice if fails to meet requirements
138
- bd56ea0 Remove unneeded function
139
- 7d7b515 Fix references
140
- b4a9a0e Refactor main class after addition of the Setup class
141
- 0e6febe Introduce a setup class
142
- 26cb5ab Update tests
143
- 8cc3a85 Determine if we need to run a cleanup routine
144
- 71fca9c Introduce a custom hook for addons
145
- ca5fbc7 Refactor main plugin file into a singleton class
146
- bf5be41 Bring activation and deactivation into main plugin class
147
- ae82d2c Ignore IDE project files
148
- 5cf0843 Merge pull request #648 from humanmade/issue-648-sprtbtnfix
149
- 93cc9ce css changes to fix support button alignment
150
- 0165a6c Merge pull request #644 from humanmade/issue-644
151
- ea4854b Merge pull request #650 from humanmade/fix_nojs_backup
152
- 46d3601 Merge pull request #642 from humanmade/fix-missing-i18n
153
- 2fa87b0 Merge branch 'master' into hmbkp-path
154
- bdada67 Fixes issue preventing backups from running without JS
155
- b901112 Remove back compat memory limit define
156
- b3fb80e Refactot HMBKP_Notices to support non-persistant notices
157
- e9cac5f Minor refactor for PHP minimum requirements notice
158
- 65b89ff Clear previous backup notices when running a new backup
159
- 25ce583 Fix issues with custom paths
160
- eaf520b Fixup some issues in merge_existing_paths
161
- ca6b691 Improved singleton pattern
162
- f679be5 Display errors in network admin
163
- b30722e Change to text input so multiple email address are supported
164
- 6100176 Removes HTML tag from string
165
- fe62548 Merge pull request #643 from humanmade/fix-conditional
166
- 9743f32 code is of type string
167
- d4e8765 Remove unneeded code
168
- 070dd9e Account for new schedule
169
- 27f9e77 Make upsell sentence translatable
170
- 97aa688 Regenerate minified
171
- 6bb46f7 Fix a few linting issue
172
- 2b1ef2d Extract to a function
173
- 6401221 JSHint config
174
- 0bf6248 fix return type
175
- d5170dd Return true if transient exists
176
- 6a0a704 Check if constant is defined
177
- 198f40a Request the site size fvia heartbeat send
178
- b4ee172 Pass site size through heartbeat
179
- 4155280 Only calculate if necessary
180
- 939ccdb Remove phpunit and naming checks
181
- c2a199e (tag: v3.0.4) Remove naming checks as we do this with phpcs
182
- 8cc1f65 Bump version to 3.0.4
183
- 65f5095 Don't run phpunit on Scrutinizer
184
- e5bc0dc Merge pull request #624 from humanmade/issue-624
185
- 95873c5 Merge pull request #629 from humanmade/issue-629
186
- fc495bd Merge pull request #633 from humanmade/fix-help-tabs-display
187
- 823107e Merge pull request #634 from humanmade/issue-634
188
- 6eece13 Merge pull request #636 from humanmade/fix-admin-scripts
189
- 7a56b46 Only build docs on master
190
- 868ae6b Wait for tests
191
- 42838dc Try using a hardcoded string
192
- 6ab00bc Simplify the backup count display
193
- 6b4684e Enqueue scripts properly
194
- 17b0610 Change how we check directory_sizes
195
- 31baca0 Disable php_cpd
196
- 7b9f9cb Merge branch 'master' into fix-help-tabs-display
197
- 1e01d21 Fix typo
198
- d98e143 Merge branch 'master' into issue-629
199
- 5438c20 Add BackUpWordPress test case class
200
- b03582c Move class to separate file
201
- 2102a88 Account for various testing environments
202
- 2c1469a Use HTTPS in tests setup
203
- 0766c37 Add required functions
204
- 8b9a4d8 Remove deprecated property
205
- 20bf107 Simplify writing status to file and throw Exception on failure
206
- 48d45e2 Spacing
207
- 710fbc0 Group help tab display functions
208
- 8ad56ee Remove deprecated function
209
- 9358318 call hmbkp_path directly
210
- 0f96866 Merge pull request #628 from humanmade/wpml-compat
211
- b27e2f2 expected actual
212
- 23d3e78 Update POT file
213
- cca1f0b Make strings ready for translation
214
- 0d0f270 Run test suites separately
215
- 69812bb Reorganize tests
216
- 43d20c4 Get the singleton instead of instantiating
217
- b3aa187 Do not delete backups folder between tests
218
- a771a02 Expected then Actual
219
- e52bb77 Fix order of arguments in assertions
220
- 50fe291 No need for this var
221
- a8a8659 Add BackUpWordPress test case class
222
- dcbac12 Move class to separate file
223
- 4e88297 Account for various testing environments
224
- c1e3158 Use HTTPS in tests setup
225
- b9ce28c Merge branch 'master' into hmbkp-path
226
- 1e093b6 Update dependencies in composer.lock
227
- 40faa7c (tag: v3.0.3) Fix code coverage config
228
- 486d6c7 Fix code coverage config
229
- 04e4d9d Fix class name
230
- 889572d Merge branch 'master' into hmbkp-path
231
- 748f132 Remove asterisk from pattern
232
- d91cfe7 Fix asterisk
233
- a5d6af5 Rename translation files
234
- d67f3d6 Bump plugin version to 3.0.3
235
- 4bdb26f bump version
236
- 3e3aa0d refresh readme
237
- 0e15823 Regenerate readme
238
- 40d72ce Refresh POT file
239
- 5afe400 Latest hm backup
240
- c81b561 Merge pull request #621 from humanmade/fix-time-dependent-tests
241
- e96e73b Merge branch 'master' into hmbkp-path
242
- 91ed195 Merge pull request #623 from humanmade/issue-623
243
- 11dcfa0 Merge pull request #620 from humanmade/issue-620
244
- 07bcd59 Merge branch 'master' into hmbkp-path
245
- 6702908 Merge pull request #597 from humanmade/issue-597
246
- 69daeef Add French translations
247
- 4396c41 Update textdomain
248
- abd3585 Fix deleted function
249
- 1bdf3ff Use HM_Backup function to determine if shell_exec is enabled
250
- d0c7d70 Merge branch 'master' into issue-620
251
- b894d52 Check if file is readable first
252
- 025c581 Fix how we kick off Task
253
- be92693 Merge pull request #625 from humanmade/issue-625
254
- 1bc3eb7 Remove unused var
255
- db0ec01 Call recursive filescanner on admin page load
256
- 99cbe70 Update package.json
257
- 804d727 Update the POT file task params
258
- f10bf82 Replace hmbkp with backupwordpress as textdomain
259
- 80aae82 Exclude folders
260
- a490f77 Add Grunt task options
261
- c73afab Checkout hmbkp-path branch
262
- 9d163c1 Make function public
263
- 32e7b12 Merge branch 'master' into hmbkp-path
264
- 32a36a4 Comments and formatting
265
- af7c0c3 Fix scrutinizer issues
266
- 909332a Remove hard line returns
267
- c603734 Display placeholder if exec fails
268
- 9869c23 Add 30 second time diff allowance
269
- 845b9fe Use $TRAVIS_BUILD_DIR
270
- d163ee6 we do this in travis.yml
271
- 9e4fda4 Regenerate github account info
272
- 5722e0c Update command to reflect function rename
273
- bcc100e Update tests to reflect function name change
274
- 1853d7b Rename function
275
- 1fe371a Filter tests to run
276
- 6892c2c Fix group flags
277
- 8b1f65c Return true on success, false on failure
278
- 012866b Unit tests php ini configs
279
- 960d5b0 Add unit tests for hmbkp_is_function_available
280
- dddd1f8 Check if exec is available before using it
281
- aaf06c1 Introduce a function to determine if a function was disabled in the PHP config
282
- d3ac584 Merge branch 'master' into issue-597
283
- 225aea9 (tag: v3.0.2) Merge pull request #610 from humanmade/phpdocs
284
- bee261b (phpdocs) Change composer flags
285
- 6b354f1 Need to call bash to run script
286
- b69921c Display debug info
287
- f3e0391 Merge branch 'master' into phpdocs
288
- 14a67f2 Ignore PHP Docs and Vendor during build
289
- dd37733 Rename hmbkp pot file
290
- a223cc1 Changelog
291
- 128e6ab Update readme
292
- 5c8308c Update translatable strings
293
- a9a30d0 Regenerate CSS
294
- 01fd58a Bump version
295
- 4cc2f99 Add github user info
296
- f43e036 Regenerate encrypted notification key for Hipchat
297
- 245b460 Regenerate composer lock file
298
- aeeb8b2 Merge branch 'master' into phpdocs
299
- 14912a5 Merge pull request #600 from humanmade/issue-600
300
- e8f2993 Merge pull request #347 from humanmade/issue-347
301
- 5d89edd Calculate site size on page load
302
- f45f1ab Pull out logic into own function
303
- bdc0572 Add parenthesis to require_once
304
- d8158a9 Remove disk space info
305
- a358977 Merge branch 'master' into issue-347
306
- ea2687e Merge pull request #614 from humanmade/remove-custom-webhook
307
- 9483558 Merge branch 'master' into remove-custom-webhook
308
- 621e73b Merge branch 'master' into issue-600
309
- 54eda33 Merge pull request #611 from humanmade/fix_unit_tests
310
- aae1791 Attempt to fix build
311
- 431df76 Merge branch 'master' into fix_unit_tests
312
- 7ae6772 define WP_TESTS_DIR
313
- bca3838 Make sure current_action fnction is loaded
314
- e004fe0 Remove extra slashes and semicolons
315
- 4f35f2a Use Travis env var
316
- 5126fb4 Last try
317
- 8bd5d53 Try Travis var unquoted sigh
318
- 4145a4a Actually load the HMBKP_Path class
319
- 4e32368 Merge branch 'master' into hmbkp-path
320
- 16fb29c Remove the custom webhook service
321
- a595864 Better default WP_TESTS_DIR
322
- c6583bd move trailingslash calls out of the loop for performance
323
- 272d663 Stop excluding duplicate backup directories
324
- b4de446 Update wp-cli to use hmbkp_path
325
- 0286823 Introduce a HMBKP_Path class to replace hmbkp_path();
326
- 56b7aee Minor code cleanup
327
- aeabc8c Merge pull request #599 from humanmade/issue-599
328
- b816d56 Correct path for hm-backup so it's tests are run
329
- ac40ab7 try this
330
- 4ac18e0 other syntax
331
- db7873f Try just a subfolder
332
- 0ab3771 try another thing
333
- ca4dfed test
334
- 7a35636 debugging travis
335
- 563e16d Try using travis var
336
- c702657 Warp var in quotes
337
- 27833f0 Fix invalid command
338
- 00db4f7 Use env var
339
- cd4042f Add list of ignored folders
340
- 6c6348a Update composer lock file
341
- 064653f Set required version to dev-master
342
- c99feb1 Fix deprecated call
343
- 5cef443 Don't test PHP 5.2
344
- 36279c1 Rename script
345
- 4bb9cea Install composer requirements
346
- d29dc96 add composer.lock
347
- e707f13 Use scrutinizer code coverage
348
- 02c1cd6 Merge pull request #609 from waffle-iron/master
349
- 99084c6 Ignore vendor
350
- f80d6ca Add composer
351
- da54899 Add custom documentation script builder
352
- 68e5a49 Add PHPdoc tasks
353
- a9510b5 add waffle.io badge
354
- 16bf682 Use up to date commands for coverage
355
- aadcac6 Add code rating
356
- 4be70a3 Don't test 5.2
357
- dced064 Update readme.md
358
- 496dfab excluded_dirs is deprecated
359
- 277134b Update scrutinizer config
360
- 6ff23df Add composer config and dev dependencies
361
- 93d76ec Make PHPUnit generate an XML for coveralls
362
- b19656e Add scrutinizer config
363
- de04025 Ignore vendor dir
364
- b480376 Add a link to Help page
365
- 288b562 Move to activation hook
366
- 863fd4c Bump up required WP version
367
- a42df0e Escape all the things
368
- 86dee22 Save errors to a notices option
369
- 275727b Reload page on errors
370
- 6cc016b Remove script
371
- 25fa141 Remove unneeded class
372
- 9fb9d09 Merge branch 'nice-errors' into issue-600
373
- 16f9a71 Check PHP version on plugins loaded
374
- cb50705 Check PHP version on activate
375
- ca0bdcb Merge branch 'master' into issue-599
376
- ad7545a Merge pull request #522 from humanmade/issue-522
377
- f3c1926 Merge branch 'master' into nice-errors
378
- cd9f659 Update readme
379
- 7e56616 Set required version to 5.3.2
380
- a1e232a Update tests
381
- f5b647d Merge branch 'master' into issue-522
382
- c3a4120 Merge pull request #567 from humanmade/issue-567
383
- 63828db Merge branch 'master' into issue-522
384
- fc8dc0f Merge pull request #559 from humanmade/issue-559
385
- ab910df Merge branch 'master' into issue-522
386
- 53dd5ec Merge branch 'master' into nice-errors
387
- 96463b5 Allow for a 30 second delta in asserting schedule time
388
- 28f3fee Merge pull request #603 from joshk/patch-1
389
- b2e6b4d Use the new build env on Travis
390
- 7003ac1 Restrict plugin to be network only
391
- ddc10dc Fix admin URL logic
392
- 80bac40 Merge pull request #571 from humanmade/codesniffs
393
- 7d372a7 Formatting
394
- 1554f59 Merge branch 'master' into codesniffs
395
- a3360a5 Merge branch 'master' into nice-errors
396
- 3588d85 Update readme changelog
397
- 8ee1642 Bump version
398
- aa02f24 Ignoe history log
399
- f441eec Merge branch 'master' into nice-errors
400
- a33db27 remove uneeded images
401
- 1bc5460 latest hm-backup
402
- ed1cf87 latest hm-backup
403
- a9d5bf3 Latest hm backup
404
- ac9daea Added known errors and nice messages
405
- d5ab157 Fix the support button splitting on 2 lines when too many tabs
406
- 74f7298 Spaces
407
- 4866fb7 Merge branch 'master' into nice-errors
408
- 19a7c14 Typos in v 3.0 changelog
409
- 8011d69 Specify POT filename in grunt task
410
- feac2fa Update POT file
411
- e86b19c Markdown readme
412
- 8452647 Regenerate readme
413
- b6ed354 Add plugin headers
414
- 5f0ced8 Fix semicolon
415
- 7d94870 Merge branch 'master' of github.com:humanmade/backupwordpress
416
- 572479e Refactor the recursive filesize scanner
417
- 611fe90 correct text domain
418
- 028a406 Merge pull request #556 from humanmade/issue-556
419
- d252312 Merge pull request #580 from humanmade/issue-580
420
- f45eb75 Merge pull request #584 from humanmade/update-backdrop
421
- 6a5053b See if this fixes tests
422
- b9bf7f6 Remove unneede statements
423
- ab6d058 Use correct action hook
424
- b4f9c9e Fix display notices
425
- 6ba1774 Set notices
426
- cdf4b01 Formatting
427
- c31db46 Merge branch 'master' into nice-errors
428
- 104c0ea reload the excludes filelist in the correct place when someone excludes a file
429
- 6a78aa9 Latest backdrop
430
- 1507855 Regenerate minified CSS
431
- c6f6b19 Regenerate minified JS
432
- f141d82 Fix cancel backup action
433
- b18075d WordPress Coding Standards
434
- 1bf78f3 Exit early if incompatible version of WordPress
435
- 0371f2d Update translations
436
- 7d10add Update changelog
437
- 9135ff1 Merge pull request #573 from humanmade/design
438
- 834e55f Load minified CSS
439
- 026d280 Formatting
440
- fd7f6f3 Biweekly wording
441
- 2baaa0f More Yoda conditions
442
- 9373e66 Spaces
443
- 61672e1 Comma after last array element
444
- 2fd458e Yoda conditions
445
- f61f8cb Add missing period
446
- 27d076c use nonce_url instead of manually adding the nonce query param
447
- 309a57c close the settings form when done
448
- f2cefe0 Design changes as per ticket
449
- b965549 Start tracking langauge in server info
450
- e2e1484 Right align the primary button in the enable support modal
451
- b9302b2 Re-factor the directory filesize code to use a single array instead of thoussands of transients
452
- fd5e4b7 Remove the warning that would show if you were using anything other than the latest stable, it's no longer needed now that the FAQ is local
453
- 2ec7406 switch to using a single transient to store directory filesize data
454
- e7668ab Merge pull request #552 from humanmade/issue-552
455
- ecf868b Merge pull request #562 from humanmade/enhancement/issue-562
456
- 66dfebe Add an anchor link
457
- c10a760 Add error message
458
- d9f2f64 Rename function
459
- 205355d Prefix GET params
460
- 4424535 Update exclude rule action
461
- a40fb52 Adds function for building admin action urls
462
- 0bb6d12 fix vertical scroll
463
- 1349691 Adds some functions to manage settings form submission errors
464
- cd5ca41 Rename nonce and action
465
- bf5eeb4 fetch errors to display
466
- 1461319 Form submission handling for BWP and add-ons settings
467
- 2e753d6 Use a new function that persists form submission errors to a transient
468
- 1379329 None check
469
- 8f8e84c Pass the nonce around in the ajax request
470
- dd220c9 Enable support action links
471
- db63646 Check nonces
472
- 689cf4e Modify action URLs to use the admin_post hook
473
- b3926bf Remove unneeded code
474
- be579ff New line at end
475
- 0b8a892 Use admin_post hook
476
- 784733f Merge pull request #502 from humanmade/stream-integration
477
- e9d20dc Merge pull request #554 from humanmade/fix-display-schedule-time
478
- 6a3ac22 Display schedule start time in local timezone
479
- 4f20f32 (tag: 3.0.0-beta) Update change log
480
- 6342aad Remove duplicate file
481
- f9ba00d update read me.md
482
- 010159a Update translatable strings POT file
483
- 8e93e09 Bump version
484
- ca037bd Bump nom version
485
- f6b3e6b Update min WP version and tested up to
486
- 73ba64d Bump version
487
- f37c3dc Merge pull request #482 from humanmade/re-design
488
- 61f644d fix some more issues with time
489
- 7727c51 try fixing the time
490
- d3c93b8 exclude tests dir from test backup
491
- 075023c PHP 5.2 compatible time mock
492
- 5fb1475 fix tests bootstrap
493
- 743f9b1 Update tests shell script
494
- 7aeb0f9 Update tests config
495
- fcaa5e6 Use HTTPS URL
496
- 64d38aa Merge branch 'master' into re-design
497
- 7da213c Merge pull request #536 from humanmade/fix-transients
498
- 8eb71c9 Update tests shell script
499
- ad16c2c Update tests config
500
- d435898 Make it clear we want one week
501
- f538a4b Display our notices - still WIP
502
- b136062 Add a class to track common errors and their nice message
503
- 7331c01 Add a notices class.
504
- 5e6e858 Reload the page to display notices
505
- 480e56a Set our notices option in the database with the backup errors.
506
- 16d08a5 Handle the dismiss action for backup errors
507
- afe325c Include the notices and errors classes
508
- fa4a7a1 Add a singleton to handle known errors thrown by backups
509
- 29c5795 Add remaining disk space
510
- e97f76b accidently used dash instead of underscore
511
- 4e76cf8 namespaced option and added option to uninstall.php
512
- 628486c basic show/hide of premium upsell
513
- ee76b21 Merge branch 'fix-transients' into nice-errors
514
- 3e8060b Merge branch 're-design' into nice-errors
515
- 2eaa37e Merge branch 'master' into nice-errors
516
- 07e61d1 Set BWP WPR web hook url to live url
517
- b870d0f BWP webhooks - 2nd iteration
518
- 1b4ce2a Fix incorrect transient expiry
519
- 13526d8 Add an action hook that gives access to consumers to the backup progress
520
- 0f82eb7 Merge pull request #406 from humanmade/issue-406
521
- 14bb5fc Show the spinner in the tab if a schedule other than the current is running
522
- 7ad8cdb Snip snip
523
- 5cf3737 Bring back the some javascript enhancements
524
- bb41a2b Switch to the PHP 5.2 compatible version of Backdrop
525
- f9bbe62 Finish up support
526
- fb1a135 Brace up single line if's and foreach's
527
- 613100a Only load minified scripts and styles if WP_DEBUG isn't on
528
- d656ee5 Load the minified css and js files by default
529
- 1fea51c Remove the combined css files as we only have one now. Stop loading colorbox.
530
- 0922885 Remove colorbox
531
- 259476d Merge branch 'master' into re-design
532
- cc3bf2d Merge branch 'master' into re-design
533
- 332c84f Improvements
534
- bb112ea More improvements
535
- f33e735 Latest BackUpWordpress
536
- 43d1f7b Don't die when directly running a backup on page load
537
- a03b0ab Re-factor the backup filesize calculation
538
- 4c1f49a make capability filterable
539
- a8b4cbc use core capabilities instead of custom
540
- 0715c88 Switch to Backdrop
541
- b250577 Merge pull request #486 from humanmade/feature/486-exclude-directories-default
542
- 94125e6 Fix typo in prefix
543
- ee06cd5 Merge pull request #523 from humanmade/build-tasks
544
- 03c2ff7 Hook function onto admin_post
545
- b3d776f Update delete link
546
- 72be8d2 Bookmark current admin page for redirect
547
- 44243ca Add custom capabilities and role
548
- 60815cd Exclude BackUpWP by default
549
- 0c97e6f Merge branch 'master' into feature/486-exclude-directories-default
550
- e569fbb add fake endpoint
551
- 9cf9a82 Configure WP Remote webhook on instantiation
552
- c170405 Inject the schedule to the constructor
553
- 33d8e59 JSON encode body
554
- 0d903b7 Sanitize URL
555
- 2952179 Encrypt the header with WPR key
556
- a0e3ca3 Ignore the build folder
557
- 75e492d Add more build excludes
558
- d3a8ceb minify JS
559
- cd15331 generate markdown readme
560
- 0126061 minify css
561
- 737d1c2 combine css
562
- 17f8975 regenerate readme
563
- 1eeed38 Make links consistent for the grunt task
564
- 8a6d52f Convert URLS to markdown
565
- f04f804 Update lang files
566
- 06eb230 Add colorbox as bower dependency
567
- 1d4066a remove colorbox folder
568
- 402129b Remove colorbox submodule
569
- 2015eb2 Change how we include FAQ
570
- 8b72677 Add readme partials
571
- 87e4cbf Add package.json
572
- f70a6fd Add Gruntfile
573
- f5253b6 Add bower.json
574
- 8d9760a JSHint rules
575
- 89975f7 remove from ignore
576
- 452320d Update ignore list
577
- 0e59aa8 Add bower config
578
- f16e93a Add FAQ strings
579
- 344d9ba Return the cached directory size early if we have it
580
- bac6613 Re-factor the file browser scanner
581
- 3fbcb3f correct sprintf usage
582
- ba52842 Handle saving service forms
583
- 9aa9396 Merge branch 're-design' of github.com:humanmade/backupwordpress into re-design
584
- c32babc Codeing standards
585
- b882cd9 Move the error check outside of the foreach
586
- 38633d8 Remove uneeded $is_tab_visible
587
- b515c6c Only show excludes for backups which include files
588
- 918c984 Show destinations in the list of schedule links
589
- 6e3a449 Merge pull request #514 from humanmade/issue-514
590
- dc33eac Fix property name
591
- 12f791b Fix property name
592
- aa90eaa Return errors
593
- 631b382 Add the remote post action
594
- 5b01a1e Start on the remote post
595
- cd03423 Display and validate settings
596
- 0e3ab94 Include webhook class
597
- cdf5085 Begin a webhook class
598
- 67e97b9 WordPress standard modal for enabling support
599
- 5e3e235 Remove extra slash in include path
600
- 778403a Add a heading to the settings form
601
- 069b7e0 More work on excludes
602
- 005fe7b Another todo
603
- cd6c7b6 Add some todos
604
- a36e27a Don't include the parent directory in a browsable list
605
- c590af0 More work on Excludes
606
- f0b1678 Merge branch 'master' into re-design
607
- 936bfde Switch to only storing 3 backups by default
608
- 29f7dfa More work on redesign
609
- 49f444f Merge pull request #507 from humanmade/update-travis-tests
610
- 31b7bcb update paths
611
- 0fef6aa fix plugin path for tests
612
- 7a06dab Change bootstrap
613
- 2bce541 Use the new develop WordPress repo for testing
614
- aebfe53 Merge pull request #445 from elliott-stocks/enhancement-heartbeat
615
- 971bdfd Small typo in readme
616
- 4c039fc (tag: 2.6.2) Bump for 2.6.2 release
617
- 77255e3 Merge branch 're-design' of github.com:humanmade/backupwordpress into re-design
618
- 8372afa Merge pull request #495 from humanmade/revert-3e213ac
619
- 73200a8 commented out enable support button till we figure out what to do with it
620
- a26419f made tabs responsive below 639px
621
- 7e3ff9b Revert https://github.com/humanmade/hm-backup/commit/3e213ac2bbd06d02383ed5290d6475cc1bed0c36
622
- fc00c91 (tag: 2.6.1) Bump ready for 2.6.1
623
- 29ea240 Merge pull request #490 from rmccue/fix-tests
624
- fa3b97c Merge pull request #493 from humanmade/bugfix/add-nonce-check
625
- eb38af9 Add a nonce check to the schedule submit form
626
- edcd9ff Add redirect to heartbeat tick
627
- f8bb0dd More work on redesign
628
- d7e1300 Remove unnecessary code, add heartbeat functionality
629
- 4feafb9 Remove hmbkpRedirectOnBackupComplete
630
- c9ecd92 Enqueue heartbeat API
631
- b2121e1 Allow output to be returned for AJAX requests
632
- 8eb475e Add heartbeat received filter
633
- 207791c Use long-hand ternary for PHP 5.2
634
- d78df49 Remove namespaced code
635
- d624d64 Add more default excludes
636
- 6d11b42 Merge pull request #481 from humanmade/bugfix/481-fix-schedule-hours-display-local
637
- bef64d0 Merge pull request #487 from humanmade/bugfix/487-fix-excludes-rule-delete
638
- f5f50b8 Revert "latest hm backup"
639
- 929a93c Remove resize_options var
640
- 6b516e5 Revert "latest hm backup"
641
- b5ae8b1 Calculate local time for display
642
- 15a2e57 Correctly highlight the tab for the first schedule
643
- 2c3b3a7 Switch to tabs instead of subsubsub
644
- 44602bb latest hm backup
645
- 22768fe (tag: 2.6) Add a couple of missing change log points
646
- a0c705e First bash at a redesign settings UX
647
- ff4aa1e Merge branch 'master' of github.com:humanmade/backupwordpress
648
- be23fbc Fix a minor style issue with long exclude rules in the exclude rules table
649
- 2478775 Hide tabs until the modal is fully open
650
- f7e6c11 Merge pull request #477 from humanmade/fix-cancel
651
- e20d3a2 Bump for 2.6
652
- dab17ec Adds a missing id attribute to the max backup input so that the label works correctly.
653
- 8bc62e1 Fire actions for services first so that they come before the main status settings.
654
- bbad481 Deletes the backup running file in the cancel backup action
655
- 349fb51 Some minor CSS / JS improvements for colorbox
656
- 8ad272f Merge pull request #476 from humanmade/issue/fix-prefix
657
- 04fc42d spacing
658
- 3487b08 spacing
659
- 1daf76e fix textdomain
660
- 5b0e1ad declare vars explicitely
661
- c822fcb Merge pull request #428 from humanmade/running-schedule-start-time
662
- 2135da8 Merge branch 'master' of github.com:humanmade/backupwordpress
663
- 3d9f294 Avoid deleting the backup running file in hmbkp_cleanup
664
- 58a8118 Introduce get_schedule_running_timestamp and use it to show how long the current backup has been running for
665
- 43df7af Merge pull request #260 from humanmade/home-path-fix
666
- 78b5168 Merge branch 'refs/heads/master' into home-path-fix
667
- 669077d Merge pull request #459 from humanmade/button-spinner
668
- ab829f1 Merge branch 'refs/heads/master' into button-spinner
669
- 1e944ee Pull in fix for home_path from upstream
670
- 1320452 Merge pull request #474 from humanmade/trim_multiple_email
671
- 7e2bee3 Merge pull request #372 from humanmade/feature/schedule-recurrence-settings
672
- b10292a Move the spinner outside the button
673
- 124d3b4 Disable buttons while the ajax request they just triggered is running
674
- 2d07f4b Remove a redundant usage of sprint_f and correct the argument order for another.
675
- e156229 Brace up and trim any whitespace from $email
676
- 9c6a602 Only call set_schedule_start_time if we have a start time
677
- 3ee4f6d Fix notice
678
- fcbbce5 return 0 if we are passed a type we don't recognise
679
- 344d98c s/reoccurence/recurrence
680
- 5e61c67 Only show the total calculated schedule size when editing a schedule
681
- 86b1caf s/dpesnt\'t/doesn\'t
682
- be40709 Don't strip 0 from minutes in the schedule sentence otherwise 10 becomes 1
683
- 39ab8ef Let's die instead of just echo'ing the error message as it's cleaner
684
- fd3283c Introduce HMBKP::refresh_schedules to force schedules to be reloaded from the DB and use it when re-setting up the default schedules.
685
- 20b648d Finishes up the unit tests for hmbkp_determine_start_time
686
- c123b35 Merge pull request #472 from humanmade/fix-cli
687
- 611cce0 Use updated syntax for WP CLI.
688
- b8c230b Merge pull request #470 from humanmade/issue/470-update-upsell-link
689
- 27c37c8 Updates instances of bwp.hmn.md URL to https
690
- f9e138e Re-factor the underlying logic that allows the schedule time to be set + unit test
691
- 971f444 Merge branch 'master' into feature/schedule-recurrence-settings
692
- 6f0cacc Merge pull request #463 from humanmade/remove-deprecated-function-463
693
- 9116508 Remove deprecated function and fix translatable string
694
- 2972dee Merge pull request #461 from humanmade/various-typos-fix-461
695
- c75e504 Corrected 'back ups' typos
696
- 70e7f05 Cleanup whitespace
697
- c72c269 Hours and minutes can be 0 so we can't use ! empty
698
- 071cba7 Revert to previous state
699
- ec64df7 Merge branch 'master' into feature/schedule-recurrence-settings
700
- 53e886c Merge pull request #455 from humanmade/constant-help
701
- 261b370 Minor improvements to the server info tab
702
- f756417 Merge branch 'refs/heads/master' into constant-help
703
- 9fd2841 Merge branch 'refs/heads/master' into origin/feature/schedule-recurrence-settings
704
- 8db93e6 Minor copy / layout improvements
705
- 091b3ec Float the time fields right so they match the style of the other fields
706
- 9dbe724 Merge pull request #456 from humanmade/unreadable-root
707
- e268787 chmod the custom path so it's always possible to remove it
708
- 251123b Make sure the directory we are about to pass to RecursiveDirectoryIterator is readable
709
- 235ff2b Avoid a notice if there aren't any schedules
710
- d653463 Zebra stripe the table
711
- 21cc2dd Don't allow the plugin to function if the root dir is unreadable.
712
- ee0c87f Improve the layout of the Constants help panel
713
- 46dbc0e (tag: 2.5) Bump time
714
- 6f1949b Remove the old plugin.php file, having it symlinked didn't work anyway
715
- 60f9e7c Stop passing $_SERVER to Intercom
716
- 3657fc2 Show long strings on their own line in the enable support popup
717
- 1d3587c Improved positioning for the .subsubsub spinner
718
- 2a637d7 Merge branch 'master' into feature/schedule-recurrence-settings
719
- 21cbb74 Merge pull request #426 from humanmade/pass-display-name
720
- 712fa56 Merge pull request #420 from humanmade/pass-bwp-version-intercom-420
721
- a2b2473 Merge branch 'master' into feature/schedule-recurrence-settings
722
- ef0e2e7 Pass display name instead of nickname
723
- 7b0bd20 Merge branch 'master' into pass-display-name
724
- 42f67b5 Merge branch 'master' into pass-bwp-version-intercom-420
725
- 97f1a36 Couple of line breaks missing
726
- af74250 Merge pull request #371 from humanmade/wp-is-writable-function-371
727
- c36350d Merge pull request #427 from humanmade/pass-timeout-intercom
728
- efc592e Merge branch 'master' into wp-is-writable-function-371
729
- 77c5c76 Update UTM
730
- f4fb3f0 Clean up readme
731
- 94193bb pass display name to intercom
732
- 68832dc Send max execution time to intercom
733
- 338033a Add Plugin version to server info
734
- 403920b Merge pull request #446 from humanmade/close-php-session-446
735
- 6286e2f Merge pull request #443 from humanmade/use-new-spinner-443
736
- 326c3bd Merge pull request #450 from humanmade/contributing-instructions
737
- 4fb0f98 Translations instructions
738
- d653fb4 Merge branch 'master' into feature/schedule-recurrence-settings
739
- 04d1814 Merge pull request #442 from humanmade/minimum-3-7
740
- c44a934 Use new spinner
741
- 7a6bb3e Fixes an issue on servers which only allow a single session per client
742
- cfa942c Made sure resize_options is defined inside catchResponseAndOfferToEmail
743
- 37749d1 Merge pull request #434 from humanmade/filterable-from-email
744
- 24c9a9e Merge pull request #441 from humanmade/update-lang-files-2.4.2
745
- 8728da9 Make the from email address filterable
746
- a94d8d0 Bump the readme to require WordPress 3.7.1
747
- 1d5de52 Stop testing against 3.6
748
- 7311226 Get rid of some stray double line-breaks
749
- 31cc2e3 Stop checking the minimum supported PHP version
750
- d632660 Remove back-compat time constants
751
- a3839d2 Bump the minimum requirements to WordPress 3.7.1
752
- 45c624a Merge branch 'master' of github.com:humanmade/backupwordpress
753
- 71c2f54 master is now 2.5 alpha
754
- f9d5748 fix email address
755
- 152625a Update text strings for 2.4.2
756
- 1edb037 latest hm backup
757
- 7d4de70 Merge branch 'master' into feature/schedule-recurrence-settings
758
- 659a124 Merge pull request #407 from humanmade/safer-redirects
759
- fd826b0 Remove stray line break
760
- 2d6b0e2 (tag: 2.4.2) Readme for 2.4.2
761
- a064ca7 2.4.2
762
- 0726166 2.4.1
763
- 03baa8a Merge pull request #324 from humanmade/multisite-admin-324
764
- 58eece6 merge master into current branch and fix merge conflict
765
- 9edbf3d Merge pull request #394 from humanmade/load-bwp-first
766
- 77d346d Merge pull request #440 from humanmade/travis-test-wp-3.8.1
767
- 4217648 Merge pull request #437 from humanmade/filesize-failure-437
768
- dc1339d Merge pull request #439 from humanmade/intercom-file-sizes-439
769
- f3d07ce suppress error messages for filesize
770
- 84897fc Get calculated sizes of active schedules instead of calculating on every page load
771
- 74b23dd Merge pull request #417 from aubreypwd/master
772
- cf29bc0 do not test older versions of WP
773
- 68b670d test with WP 3.8.1
774
- 5147559 Merge pull request #438 from humanmade/shell-exec-test-432
775
- 95b586f test for function availability
776
- 07569fc Merge pull request #433 from humanmade/fix-php-notice-433
777
- a4310d5 Merge pull request #432 from humanmade/shell-exec-test-432
778
- 5344978 test for availability of command
779
- 9613f80 Fix PHP notice in default excludes functionality
780
- 7e11ff5 (tag: 2.4.1) Bump stable tag
781
- e0b5390 Bump for release
782
- 6546fd3 Merge pull request #412 from humanmade/exclude-cache-folders-412
783
- 1b49d2e Fix resize_options
784
- 139da4e Modal fix for long paths
785
- f3cb4e7 Fix issue where modals showing underneath WP Admin bar
786
- 7ac0c0a Add trailing slash to found folders
787
- 8e0c55d Add trailing slash to excluded folders
788
- 5a0b4c4 Code formatting
789
- 7365f17 Exclude cache folder by default
790
- 5bccad8 ensure bwp is activated before addons
791
- 439917f fix merge conflicts
792
- 1cb3651 Test against PHP 5.5 and WordPress 3.6/3.7/3.8
793
- 604c004 Merge pull request #411 from humanmade/rename-filesize-transient
794
- d6f5994 Rename file size transient to contain the backup type, so we don’t need to clear the cache when a schedule type is modified
795
- fe66aa0 Merge pull request #405 from humanmade/use-correct-escaping-functions
796
- 09ef19f Merge branch 'master' into use-correct-escaping-functions
797
- a410fc9 Merge branch 'master' into safer-redirects
798
- f135020 colorbox changes
799
- 923fa00 latest version of hm backup
800
- 49d3d6f reset hm-backup submodule to previous commit
801
- 44efeea use wp_safe_redirect
802
- cd7d7b3 no need to internationalise non language attributes
803
- 67316bc formatting and spacing
804
- becb46b Latest HM Backup
805
- 0037829 Merge pull request #402 from humanmade/revert-cherry-pick-time-settings
806
- 22c3efd remove the time settings that were wrongly added
807
- 2ff6ed9 Merge branch 'master' into feature/schedule-recurrence-settings
808
- 1e76c20 resolve merge conflict from cherry pick
809
- 20d41e1 Reload page on close modal so settings are refreshed
810
- c84d40a Branch out logic by detecting if submission was from destination form. If so, no need to process recurrence settings. Just service settings.
811
- 4bbf4df Reload page on close modal so settings are refreshed
812
- 5a19f66 Test recurrence settings
813
- 315bf8d adjust CSS
814
- efa03c6 use a div
815
- d983941 escape square brackets in ID selectors
816
- ba79dd0 wrap min hours with label to keep together
817
- 5a910ba move service validation
818
- 5a51719 use 24 format for input, remove AM/PM setting
819
- ee9cb46 only show twice daily note for that recurrence
820
- a54f489 make weekday strings translatable
821
- f24bd73 change textdomain
822
- cd52ef9 delete old backups before saving settings
823
- b1376b2 docblock and else curly braces
824
- 05fd873 indentation and formatting actions.php
825
- 6ba5ad3 prefix javascript functions
826
- 2fa06a9 Merge branch 'master' into multisite-admin-324
827
- 0a7bca1 Merge pull request #393 from humanmade/travis-encrypt
828
- 5456f14 New encrypted hipchat API token
829
- eb3b8a2 Merge pull request #387 from humanmade/fix-transient-387
830
- 4f0155e Latest HM Backup
831
- ef4a4b5 use get_transient to retrieve value
832
- 118753e Merge branch 'master' into wp-is-writable-function-371
833
- 6461824 Merge pull request #391 from humanmade/feature/service-intercom-data-function-390
834
- 5e3019e add the service constants to the intercom data
835
- 21d7849 display any service constant
836
- 842557e just return an empty array for now
837
- f714c4d alternate function for display
838
- e52e13d intercom_data should be static so we can call it with call_user_func
839
- b5e196a add the ATTACHMENT_MAX_FILESIZE email requirement constant
840
- e9a6f60 email intercom data is managed by BWP requirements class already
841
- e63a263 Merge pull request #389 from humanmade/bugfix/swapped-arguments-path-accessible
842
- 862db2e Merge pull request #390 from humanmade/feature/service-intercom-data-function-390
843
- 8f79d47 adds abstract function intercom_data
844
- 0d95733 input validation improvements for schedule form
845
- 31fe7bd return false if not set
846
- 5e262f2 arguments were swapped in the function that checks if home path is contained in the backups dir path
847
- 3615f44 set default schedule type
848
- 85bd820 only instantiate schedule if no errors
849
- dfaa12f we need this without instantiating a schedule
850
- 53bbf89 set recurrence when setting start time
851
- edada0e better validation
852
- 488aaf0 make sure there are no errors before saving
853
- 838f858 Merge branch 'master' into feature/schedule-recurrence-settings
854
- 8e8c20c add default day of month
855
- 19b8043 change input default value
856
- 0aba13c update schedule tests
857
- 4ae2feb use set schedule start time for default schedules
858
- 835670e default arguments for setting schedule start
859
- 3e38b6a fix backup action URLS
860
- 1708a6e return zero instead of WP_Error
861
- f2b314c schedule form field validation
862
- 70d091f more network_admin_url
863
- ecd1995 stupid mistake
864
- 0c344b2 fix syntax error
865
- 0954b51 use network_admin_url
866
- bb98cbb update more references to tools.php
867
- 0d6d33c Merge pull request #377 from humanmade/server-info-help-tab-377
868
- 67878a3 refactor by using a constant and only 1 conditional
869
- d5f15ef Merge pull request #381 from humanmade/use-wp-mkdir-p-381
870
- fa5ade1 Merge pull request #303 from humanmade/invalid-reoccurence-fix-303
871
- 061c7dd we should not use the constant here as it may not be defined.
872
- 335934f sets schedule start time for manual backups
873
- 16fde51 check that var is set before output
874
- 3d27331 schedule start time is now an option
875
- e298fc0 if the recurrence type is invalid just force it to manually
876
- 8df5d08 adds server info tab to help screen
877
- c442a8d replace mkdir with wp_mkdir_p
878
- bdaf86c move BackUpWordPress admin to network settings on multisite
879
- 4ede7ac Bump required version to 3.6.0
880
- 3ee284d Use wp_is_writable wherever is_writable was used.
881
- 2da238d Update CONTRIBUTING.md
882
- f985cfb Update CONTRIBUTING.md
883
- 5126579 Update CONTRIBUTING.md
884
- 3247144 Update CONTRIBUTING.md
885
- cdd9787 refactored the schedule recurrence logic
886
- d89a74b Add new schedule UI and logic
887
- 525a856 do not define the schedule start time constan by default
888
- f2eb346 Merge branch 'feature/schedule-recurrence-settings' of github.com:humanmade/backupwordpress into feature/schedule-recurrence-settings
889
- 0f31c11 prefix attribute
890
- b0f80f9 more recurrence logic
891
- 33d87c3 hide / reveal recurring settings based on chosen schedule
892
- d43f03f adds the day and time fields to the schedule settings form
893
- 53711e2 Merge pull request #379 from humanmade/update-po-mo-files
894
- 8eaba4e Merge pull request #380 from humanmade/update-colorbox
895
- 8efc03f update to latest colorbox
896
- 3d49129 Merge branch 'master' of github.com:humanmade/backupwordpress
897
- cd1ecab add new updated language files
898
- 3a29a70 updates po/mo files with latest strings
899
- e2544a5 Merge pull request #376 from humanmade/dont-hide-delete-links
900
- a72bea6 Release notes
901
- 3ce9d7a Correct translation function
902
- 7409e35 Latest HM Backup
903
- 1201ee5 Bump and release notes
904
- 2146eb3 Only hide download links when the backups directory isn't web accessible as deleting will work.
905
- ddd5d67 Merge pull request #366 from humanmade/enable-intercom-support-366
906
- b85ef87 Code comments
907
- e48d1ab Make a string translatable
908
- 7138bb2 Organise tests into more logical groups
909
- 1492f3f Store the result of the wp-cron test so we can pass it to Intercom
910
- dc9f415 Stop sanitising test names before passing them to Intercom
911
- cd8d6af Add new tests for site_url and home_url
912
- 9882fbd Better name for the support schedule that is created to calculate the backup size
913
- 8e208c8 Plugin filename should be backupwordpress.php not plugin.php
914
- ab54dfd prefix attribute
915
- 6f3f689 Use the new option name in deactivation and uninstallation
916
- 91957c3 Merge branch 'enable-intercom-support-366' of github.com:humanmade/backupwordpress into enable-intercom-support-366
917
- 0c91659 Move the support opt-in flow to be part of the support button and generally improve things.
918
- 67255b9 Code comments / formatting
919
- 1e869c2 more recurrence logic
920
- a6214c0 hide / reveal recurring settings based on chosen schedule
921
- 49cf5c6 Merge branch 'master' into feature/schedule-recurrence-settings
922
- 50ea2be delete optin option on deactivate / delete
923
- 91e71ed prefix functions
924
- 0d9565f Merge branch 'refs/heads/master' into enable-intercom-support-366
925
- f7aaeec Fix a notice if $services isn't defined.
926
- 66299ff Merge branch 'master' of github.com:humanmade/backupwordpress
927
- 0f23353 Bump
928
- 7a5bb3b Merge pull request #375 from humanmade/no-backups-colspan
929
- d20677f Ensure the message shown in the backups table when no backups have been completed spans all 4 columns
930
- d500312 Merge pull request #286 from humanmade/disable-dl-link-286
931
- c31ebd6 Merge pull request #288 from humanmade/pass-page-slug-as-var-288
932
- aa793c1 Merge branch 'master' into enable-intercom-support-366
933
- ff0ef9e adds a button and a colourbox modal with server info
934
- ca91ca2 refactoring
935
- 1fba846 add requirements class from compatibility branch and the server table output
936
- 2825763 reload page on settings change
937
- a5fdbfd adds the day and time fields to the schedule settings form
938
- b71ee59 Merge pull request #370 from humanmade/correct-language
939
- 58eb3c5 remove some unnecessary code
940
- 3185ff5 spacing
941
- a446d50 adds an option checkbox for intercom
942
- 9f3e115 spacing
943
- b5699e3 add intercom user hash
944
- 653ba19 spacing
945
- af22b2d check if path is accessible before displaying download link
946
- 60299b7 correct some language
947
- a38818a pass page slug as var to js
948
- b5e7ef4 schedule sentence escaping
949
- c71eaa9 Merge pull request #369 from humanmade/upsell-pro-addons-369
950
- d51c007 rename add-on to extension
951
- 911aba0 Merge pull request #368 from humanmade/fixes-uninstall-file-refs
952
- 0963fd3 adds an upsell message to the footer of the main plugin page
953
- 123feb3 enables intercom contact and tracking
954
- 75176a6 fix wrong file paths in uninstall
955
- 4874655 Merge pull request #361 from humanmade/password-field-width
956
- b00011d Merge branch 'master' into password-field-width
957
- 3fae243 Merge pull request #364 from humanmade/better-schedule-sentence
958
- 9dfe5b5 Improve the way destinations are handled in the schedule sentence in 2 ways
959
- a3e8e2c Merge pull request #362 from humanmade/schedule-title-status
960
- c06a7fe Merge pull request #363 from humanmade/esc-schudule-status
961
- 8cc3746 Use wp_post_data instead of esc_html and status's can contain html.
962
- ffaaf21 Show the running schedule status in the title attribute when hovering a running schedule title (that you are not currently viewing)
963
- f5ba48b Slightly re-position checkboxes
964
- 504f137 Force password fields to be the same width as text fields in the model forms
965
- 91c888c Merge pull request #346 from humanmade/dev
966
- 6cd0e6f Merge pull request #354 from humanmade/dont-escape-plain-text
967
- 0c53304 no need to escape the email address
968
- 7e7e8b3 Merge pull request #352 from humanmade/formatting
969
- 4c57e93 Merge pull request #353 from humanmade/prefixing
970
- b333c74 Merge pull request #355 from humanmade/escaping-email-address
971
- e8d6b6d Merge pull request #358 from humanmade/get-slug-condition
972
- 81333b1 Merge pull request #359 from humanmade/remove-openbasedir-heck
973
- b4622f2 no need for this check, already handled elsewhere
974
- 4359c85 slug could be set to an empty string, so check this
975
- 9bf881c use echo esc_attr on non tranlatable strings
976
- e925dd7 is_email already trims
977
- 2619f72 few escaping fixes
978
- f3ae151 prefix functions
979
- 7a1a913 remove extra line returns
980
- 04de7d3 limit style to text input
981
- a8bf160 resolve merge conflict
982
- 8b53c84 Merge branch 'fix-excludes' into dev
983
- 0cc97c8 exclude WP DB Manager default folder the correct way
984
- 5178f63 use stable version of hm-backup
985
- 06a9af5 really add the escaping
986
- 196fc78 more escaping
987
- 814cac5 escape on output
988
- c4e4a12 WP Standards formatting
989
- db82139 bump version
990
- 304aad7 Merge pull request #345 from humanmade/change-filenames
991
- 7361bab Merge branch 'dev' into change-filenames
992
- 68ab430 Merge pull request #343 from humanmade/enqueue-fix
993
- 73d8465 fix merge conflict
994
- a699cc0 Merge pull request #344 from humanmade/title-translation-337
995
- 1372013 change version back
996
- 6daa045 french PO-MO files ready to translate
997
- 9a1d35c introduce a backups_number function
998
- 43afad9 few internationalisation fixes
999
- 40839ac keep string in one sentence
1000
- 2958288 make schedule titles translatable
1001
- c7da92b Merge branch 'master' into enqueue-fix
1002
- 31abee9 enqueue differently to fix colorbox failing to load
1003
- f2dadf3 Merge pull request #339 from humanmade/fixes-open_basedir-warning
1004
- 0263fa2 don't use $schedules var if its not set
1005
- 3e68fa8 nioce error message
1006
- 345eb5d constructors dont return
1007
- 8ac306b Merge pull request #336 from humanmade/dev
1008
- 6d6941a v2.3.3
1009
- 44be3bf fix enqueud style src path
1010
- fdf3253 (tag: v2.3.4-alpha) v2.3.4-alpha
1011
- e759433 Merge pull request #333 from humanmade/dest-form-logic
1012
- 332cf3b Merge pull request #307 from humanmade/fixes-307
1013
- 6c1282c Merge pull request #334 from humanmade/exclude-leftover-bwp-folders
1014
- e40f395 formatting
1015
- 021ea52 adds a function to exclude leftover backup folders
1016
- 3787e47 check if path has changed
1017
- 36d3994 Merge pull request #332 from humanmade/fixes-332
1018
- b8bd2f0 removes extra slashes in enqueue source path
1019
- c602a22 form close button logic
1020
- ff86c78 refactored include path
1021
- 9d62136 use WP standard file naming
1022
- 4b446e8 Merge pull request #327 from humanmade/exclude-backupbuddy
1023
- fdb5077 refactored default excludes function
1024
- e8fd153 excludes backupbuddy default folder
1025
- 6ebc8da Merge pull request #326 from humanmade/sched-sentence-325
1026
- 0968d27 Merge pull request #292 from humanmade/use-wp-error-292
1027
- d697ecf only show addon sentence part when service is active
1028
- 5336d74 Remove old test/lib submodule
1029
- 826ee0e 2.3.2
1030
- a6b8a1e fixes unmatched closing parenthesis and docblock
1031
- 85b439b replace last Exception
1032
- d1bfb62 replace more exceptions
1033
- 650284b Merge branch 'master' into use-wp-error-292
1034
- 89de7a3 Merge pull request #323 from humanmade/adds-latvian
1035
- e5f5dcf add latvian lang files
1036
- 871ca07 Update CONTRIBUTING.md
1037
- d688862 Merge pull request #322 from humanmade/contributing-file
1038
- fab67ce instructions
1039
- b316d37 Merge pull request #321 from humanmade/fix-remaining-sched-instantiation
1040
- b3eccce fixes left over direct instantiations of singleton class HMBKP_Schedules
1041
- 4f0697a fix conflicts
1042
- e28653d Bump
1043
- a66ab31 Updated Readme
1044
- e27fed3 Revert "Merge pull request #304 from humanmade/update-close-buttons"
1045
- f60064a adds wp db backup to excludes
1046
- a0b1693 Merge pull request #320 from humanmade/changelog-2.4
1047
- a758156 2.3.1 instead of 2.4
1048
- d807d75 cleaning ip
1049
- 859e729 adds default excludes and removes ability to delete rule
1050
- 7cb471f Ignore the .svn repo
1051
- 27c6281 Merge branch 'master' into backup-folder-excludes
1052
- b0946fd update change log for 2.4
1053
- 5d91d3f Merge pull request #304 from humanmade/update-close-buttons
1054
- 5269e6f check if services array is not empty
1055
- e0fcf3d Merge branch 'master' of github.com:humanmade/backupwordpress
1056
- fc9d1f2 add default excludes array and setup on schedule init
1057
- aa874ea Merge pull request #282 from humanmade/singleton-schedules
1058
- feb900e Merge branch 'master' of github.com:humanmade/backupwordpress
1059
- 09e7669 add default excludes array and setup on schedule init
1060
- f113843 make HMBKP_Schedules class a singleton as it contains all the schedules and only need one instance
1061
- 71a3ee5 PHP Docblock
1062
- 1cb9a9c replace Exception with WP_Error error handling in 2 places.
1063
- a8dcff8 Merge pull request #315 from humanmade/fixes-undefined-notice
1064
- 271807e declares and initializes it
1065
- 42def6d Merge pull request #301 from humanmade/fixes-broken-local
1066
- bd42c22 Merge pull request #294 from humanmade/updates-lang-files
1067
- 4118772 Merge pull request #296 from humanmade/better-schedule-sentence
1068
- ca95e99 Remove "These external locations" from schedule sentence
1069
- d5ec251 Merge pull request #299 from humanmade/contrib-guidelines
1070
- b5dd322 Merge pull request #305 from humanmade/fixes-297
1071
- 1018be8 Store the return value of wp_mail in $sent so we don't send multiple notification emails
1072
- 3cbeeba Merge branch 'master' of github.com:humanmade/backupwordpress
1073
- f0f668e fixes #297 typo in option name
1074
- c250471 avoid undefined error
1075
- 1dcb1e2 save and close are separate actions
1076
- 939de53 remove commented out line
1077
- a810ae9 fixes #300
1078
- 52acd9c Disable email notifications for Travis builds
1079
- 467bb37 create file
1080
- 06cb2ac Merge branch 'better-schedule-sentence' of github.com:humanmade/backupwordpress
1081
- 1304540 Merge branch 'master' of github.com:humanmade/backupwordpress
1082
- 7889da2 Whitespace ftw
1083
- 359cc21 Merge pull request #295 from humanmade/new-unit-tests
1084
- f2c0661 implode on comma
1085
- 1eb874d make schedue sentence more consice
1086
- 42a242b Update the Travis
1087
- 4184643 Switch back to using WP_TESTS_DIR instead of hardcoding the path
1088
- ed09bfa Rely on the WP_TEST_DIR environment variable instead of shipping the whole wp-tests dir with the plugin
1089
- 1b0c3e8 s/add_command/addCommand
1090
- 551bc26 Remove extra linebreaks
1091
- 74dca7c Bump
1092
- f0095a9 Fix a PHP strict error
1093
- b8a695a updates lang files
1094
- e478f98 Update the path to lowercase now that we've renamed the github repo to be lowercase.
1095
- a2c4ace Setup our wp-tests-config.php file
1096
- 1697012 Tag as released.
1097
- 452c93f Move dash inside of string
1098
- 9da8cfc Remove the trailing slash from the backup path before checking it's validity
1099
- a78358b Merge branch 'master' of github.com:humanmade/BackUpWordPress
1100
- 423c901 Bump ready for release
1101
- e8f1d8b Merge pull request #229 from humanmade/single-calculating-thread
1102
- 8773324 Laetst HM Backup
1103
- 155156e Revert the changes to assertArchiveContains and assertArchiveNotContains in favour of introducing new methods
1104
- 31d1f53 Normalise slashes in paths
1105
- b75830f Normalise paths before comparing them in assertArchiveEquals and assertArchiveNotEquals
1106
- 6167a7b Bump
1107
- c463181 Always delete the backups directory after each unit test
1108
- 6461e10 Coding standards
1109
- 502d34f Prefix the backup path with backupwordpress so it's obvious where to look to find your backups
1110
- a20440b Remove stray error_logs
1111
- 63e785d Bump
1112
- 5ce9138 Re-calculate the backup path on upgrade and move any existing backups there.
1113
- 46d7b95 Don't access the hmbkp_default_path option directly as it may not be set.
1114
- 2df5eae Correctly calculate the HMBKP_SECURE_KEY
1115
- f8e2a19 No need to wrap hmbkp_init in a function not exists check.
1116
- 0ba4ba7 Remove stray line break
1117
- 38aa2ed Don't indent the copyright notice
1118
- 1acb085 Bump for pre-release
1119
- d4e5b4e Remove the help text for the HMBKP_EMAIL constant as it has been deprecated.
1120
- 7aa1b16 Latest HM Backup
1121
- d6929cc Don't allow the filesize of the site to be calculated in multiple thread at once.
1122
- 0596cdc Don't highlight the HMBKP_TIME_CONSTANT example if it's set to the default setting as the constant is defined in the plugin
1123
- faaa524 Correct hipchat room
1124
- 7eba138 Remove square brackets as they break travis.
1125
- c73e61b notify hipchat of build status's
1126
- 68b3d2e Merge pull request #284 from humanmade/fetch-destination-settings
1127
- 3ea959d adds function to copy settings from previous schedule
1128
- 6d050fc Code comments
1129
- 222849e Don't allow a scheduled backup to run if it's already running in another thread. Will prevent issues where load balancers and proxies re-send requests that don't return within some arbitrary timeout period
1130
- 613ccc9 Beginnings of a HMBKP_Error class
1131
- 3857efc Code standards
1132
- 7462055 Latest HM Backup
1133
- e65220d Whitespace
1134
- 65160ec Make the exclude help string translatable.
1135
- 8841bd9 Set a maximum height when displaying the error message so it doesn't cause the modal to be larger than the page.
1136
- f33a1d8 when moving the backups directory, don't delete the old one if it's outside of WP_CONTENT_DIR
1137
- bcd01a3 Only move zip files in hmbkp_move()
1138
- 821dd9d If HMBKP_PATH doesn't exist then use hmbkp_default_path()
1139
- b05975d Don't delete non-backup files in custom paths
1140
- 28e4512 Code formatting
1141
- 5400d39 Ensure the database dump is uniquely named per schedule to avoid possible collisions when multiple schedules are running at the same time.
1142
- bca2783 Backwards compatibility for the time constants which were introduced in WP 3.5
1143
- 48e365a Don't bother testing all version of multisite, just test master
1144
- c70df6f Stop testing in PHP 5.5 until it settles down
1145
- 4ca88b3 Remove PHP 5.3 ternary operator syntax as it breaks when running unit tests on PHP 5.2
1146
- 89a5749 Test against all major releases of WordPress since 3.2.1 across all major releases of PHP since 5.2
1147
- 293c4f4 Latest HM Backup with all unit tests passing locally
1148
- 123c880 Reference the plugin using a case sensitive path in the phpunit config
1149
- e996f9c Switch to a https checkout for the lib submodule
1150
- d47259d Switch to our fork of the test lib
1151
- 00ef12b Latest test lib
1152
- 34992e2 Latest HM Backup
1153
- 8dd4e9b Only test against a single instance of WP for now
1154
- 6d57cc3 Tell travis to recursively clone in all submodules
1155
- 581e2c2 Add the travis configuration file
1156
- c075f16 Switch the submodule clone url for gm-backup to https
1157
- c19960e Merge branch 'master' of github.com:humanmade/BackUpWordPress
1158
- 1872998 Make the unit tests phpunit compatible
1159
- 42c679b Add pauldewouters as contributor
1160
- bf306f3 Don't try to update the manual reoccurrence during the 2.2.5 upgrade routine.
1161
- 2e9ecd0 Add a line break
1162
- 344e850 Code formatting
1163
- 5355300 Use correct escaping functions
1164
- 487383d Re-jig the maximum backups help text to make it more concise.
1165
- 97f2392 Remove trailing tab
1166
- 4b5844d Whitespace
1167
- f8d5864 Remove duplicate is_string check
1168
- e15c62f Whitespace
1169
- d571fcc Set the initial width and height of the colorbox and set the transition to elastic.
1170
- a6f8d1c Upgrade any stored schedule reoccurrences to use the new naming convention.
1171
- 64e034f Code formatting
1172
- 1971bdb Untab the whole file
1173
- 6a9b384 Use single quotes and add missing space between closing quote and parenthesis
1174
- 37b3284 Merge pull request #257 from humanmade/dev
1175
- 2c3dcda Merge branch 'master' into dev
1176
- 73e3e97 Merge pull request #273 from humanmade/varname
1177
- cd3f1b1 underscores instead of camelcase for consistency
1178
- 793a970 refreshed mopo files
1179
- b4dc5ae add new function to load translation files in a flexible manner, add POT file for translators, regenerate PO and MO files
1180
- 8eae498 add a new function get_cron_schedules for filtering cron schedules
1181
- 1222714 fixes Docblocks
1182
- 7e3f476 remove random debug plugin version
1183
- ae1450f Merge branch 'master' of github.com:humanmade/BackUpWordPress into dev
1184
- 7c392fc Merge pull request #263 from thomasclausen/patch-2
1185
- 3e154bd Merge pull request #264 from thomasclausen/patch-3
1186
- 4f29425 update docblocks
1187
- 1b85f50 do not remove option prefix
1188
- 6a9aaae deleted a log file
1189
- 8dd078b changed main plugin file name for consistency
1190
- 6f92376 custom cron intervals need to be defined as their own array with the interval as key
1191
- ce81c5a update interval names in more places to avoid fatal errors
1192
- 8bc348b updated schedul interval name with prefix in several locations
1193
- 4dc7f1e schedule enhancements
1194
- 941cc58 added missing schedules param and merge custom schedules
1195
- b7437b1 use constants in schedul intervals
1196
- 7ad2db1 just some indentation
1197
- bed981f remove duplicate activate function causing fatal error
1198
- 289d0e1 fix docblock
1199
- f891fe3 add activation function and internationalize message
1200
- 3c1d7ad corrected typo in message text
1201
- 7d5f3fa fixes #262
1202
- 2af8543 Merge branch 'master' of github.com:humanmade/BackUpWordPress into dev
1203
- 5a59a64 indentation
1204
- 92436fb Merge pull request #267 from thomasclausen/patch-5
1205
- 7fb077f Missing translation
1206
- 0c63da9 Merge branch 'master' into dev
1207
- 8242be8 fixed bug in colorbox error message display
1208
- 202366a input[type="number"] is too small
1209
- f04e78e Missing translation
1210
- fc6dbe4 move the max backup size after description
1211
- 20da959 change wording of max backup size
1212
- f21e1d1 remove unnecessary vars
1213
- 99bc4ab new function get_formatted_filesize
1214
- a3d7e56 fixes #255
1215
- 806e031 Use correct filename for Danish translation files
1216
- 9270246 Latest HM Backup
1217
- 2e3a353 Slight refactor, remove need for variable variables
1218
- 53eb85b Correct @return docblock param
1219
- e96d8c5 s/de-register/unregister
1220
- 98fb94e Code formatting
1221
- 75bbd3b Set abstract methods to public as they are expected to be implemented in child classes as public
1222
- b49f557 Set the @var to the class that the variable will contain an object of
1223
- c7c24ba Correct @return in docblock
1224
- c13e2b0 Remove an unused variable
1225
- 892bc12 Don't store the return value of wp_mail in an unused variable
1226
- 2412774 Make sure we always return a string, even if the conditions are not met
1227
- cf6825c Correct docblock
1228
- 5452dd2 Fix a docblock
1229
- 34ce62f Introduce abstract protected function is_service_active() and use it in the email service
1230
- 3d2da20 Improved styling for popups which contain tabs
1231
- fa0872a Improved error message styling
1232
- dc6023b Merge pull request #249 from humanmade/colorbox
1233
- 1376383 Fix some styling on the new colorbox popups and ensure it resizes properly throughout the excludes process.
1234
- 6f4ee67 fixed a bug where jQuery alias not available
1235
- 8fc2ff7 colorbox lightbox width
1236
- e553bc0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1237
- aae12c2 Latest HM Backup
1238
- c729622 dont hardcode slug
1239
- 6c161ae deleted fancybox
1240
- d09062e Use correct constant for HMBKP_ATTACHMENT_MAX_FILESIZE
1241
- ea88d36 resize after adding buttons
1242
- 943096d removed remaining fancybo references and submodule
1243
- d8ad331 excludes form width
1244
- 6916f65 replaced fancybox with colorbox
1245
- 5b0d868 Merge pull request #247 from humanmade/dev
1246
- 243b4e1 resolved conflicts
1247
- f34622f fix bug in service settings
1248
- 72bd165 added property to toggle service tab visibility
1249
- a2a4671 resolved conflict
1250
- dc29250 Merge branch 'master' of https://github.com/humanmade/BackUpWordPress
1251
- 7ee581d Bump for release
1252
- 1fb986b Use call_user_func to call HMBKP_Service::constant for each service instead of the php 5.3 only way $service::constant()
1253
- 00566e8 Bump for release
1254
- 39d4a8c Code reformatting
1255
- f1ae908 Fix a parse error
1256
- 4b23e80 (tag: 2.2.2) Updated release notes.
1257
- 9e0f523 Update translations
1258
- 1463878 Minor text improvements
1259
- a8af5ae Update original strings
1260
- d2cf0f3 Bump and release notes
1261
- abdbb84 Silence possible warnings when unlinking
1262
- 0871bb2 Minor code formatting
1263
- 5684313 moved the destinations menu link
1264
- f46d61e add property to toggle tab visibility
1265
- 798bf11 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1266
- 61ca652 Latest HM Backup
1267
- 97ab36a Merge pull request #245 from pdewouters/master
1268
- 596123e Latest HM BackUp
1269
- ca4bd02 removed quotes wrapping a nonce var
1270
- 82e563c Merge branch 'nonces'
1271
- ec68546 removed unnecessary lines and did some formatting
1272
- 12b186f replace all calls to exit with die for consistency
1273
- 5ca6b17 added nonce check to all ajax post actions
1274
- 0210692 Merge pull request #243 from pdewouters/master
1275
- 77028d0 cancelled the slug capitalization
1276
- ffbbdbf added human readable name for services
1277
- 77bda92 reverted 2 commits
1278
- e32ce59 Merge branch 'master' of https://github.com/humanmade/BackUpWordPress
1279
- 52ac62f add name property
1280
- 7de9e1d Doh, fix a stupid fatal error
1281
- e059087 Pass back an empty array instead of all service options when asking for a service option that doesn't exist.
1282
- f92a8bc Make constant() a public method.
1283
- 43d296c make actions menu extendable with apply_filters
1284
- c1e0b69 Latest HM Backup
1285
- 503b3ae You can't have protected abstract methods since PHP 5.2.
1286
- 27be1d8 use plugins_url for assets, fixes case sensitive 404 error
1287
- 15293a7 fix plugin URL constant capitalization
1288
- 5a42c04 Latest HM Backup
1289
- 838831e Add a docblock to the abstract constant method
1290
- 6bd1f44 Update readme
1291
- fed0192 Ability to set the maximum email attachment filesize
1292
- 9a17eef Fix possible notice and Fatal error when uninstalling
1293
- 111a7af Only try to add the FAQ if we were able to connect to the plugins API.
1294
- fc9fe8c Released 2.2.1
1295
- 754fa00 Changelog for 2.2.1
1296
- 6c5b162 Force 500 error header for testing (commented out)
1297
- 6bfba16 Strip tags from error messages
1298
- 91bef0f Catch server errors during the ajax backup process and display them to the user
1299
- 7a236d2 Fix JS error and use correct class
1300
- 804c458 Only output an error / warning message if there are errors or warnings
1301
- 126bcb1 Changelog for 2.2.1
1302
- 3eb573b Bump
1303
- 79597cf Latest HM Backup
1304
- c0bad9e Display errors and warnings in error popup after backup
1305
- eecfe58 Catch all types of fatal error in backup process
1306
- 8645f7f Preserve whitespace in the error pre tag
1307
- a950698 Don't redirect if we have an error
1308
- b85cd76 Write errors and warnings as they happen.
1309
- 71af0ea Fix PHP Strict warnings
1310
- 4803568 Mark static functions as static
1311
- 4969597 Released
1312
- 1dcbc5e Chinese translation
1313
- a1a7d37 Serbian translation
1314
- aa703f7 Russian translation
1315
- 9fe56db Romanian translation
1316
- 566d8e9 Portuguese (Brazil) translation
1317
- d1ea675 Polish translation
1318
- e15e487 Dutch translation
1319
- 5fb564f Latvian translation
1320
- f2d5afb Lithuanian translation
1321
- bcf6f0b Italian translation
1322
- 280620d Hebrew translation
1323
- 0728c2f French translation
1324
- 3711134 Basque translation
1325
- 3b739a2 Spanish translation
1326
- 3c3f02e German translation
1327
- b754430 Danish translation
1328
- 531f9fc Czech translation
1329
- 064cf16 Latest po & mo files
1330
- 9c710de Bump for release
1331
- 1dbc5db Bump - close to release
1332
- 0860b48 Revert "Don't define private internal vars"
1333
- 56daef6 Latest HM Backup
1334
- 2c9a9d4 Cleanup on uninstall
1335
- a55c892 Formatting
1336
- 418640e Don't let hmbkp_rmdirtree delete directories outside the site root
1337
- 7e3bcfd Cleanup the deactivate hook, no point removing non-existent options
1338
- 27d2510 Explain yourself
1339
- fe8e817 Handle situations where HMBKP_SCHEDULE_TIME isn't defined
1340
- 4a7309c Switch to using activation and deactivation hook functions rather than calling the actions directly
1341
- ce5dab9 Add a test for fortnightly
1342
- 56464f6 Add unit tests for each of the schedule occurences
1343
- 7e2f57a Make sure we cleanup after ourselves
1344
- bb356ea Add our custom cron schedules to the default cron_schedules array so that we can schedule events using them
1345
- b92af3f Fix possible notice
1346
- 18ec091 Move .po and .mo files to languages folder
1347
- f9ca49b Latest HM Backup
1348
- fe2a42c Don't define private internal vars
1349
- 7b49f4e Don't esc_attr unless we are outputting
1350
- 45f9179 Fix possible warning
1351
- efddfa2 Only update backup type if it's changed
1352
- 3d47ce1 Namespace our script localizations
1353
- 32ba1de sanitise and escape all the things.
1354
- df48893 Increase the timeout on the ajax cron check to avoid errors on slow sites.
1355
- 6f6ed69 Sanitize some shit.
1356
- 26ddd39 Stop defining PCLZIP_TEMPORARY_DIR outside of hm_backup as it shouldn't always be set to hmbkp_path()
1357
- ae3212e Some code cleanup
1358
- 4930b4c Latest HM Backup
1359
- df27971 Use realpath to check that the path resolves somewhere before checking isReadable
1360
- 2409ef0 removed duplication of media query rules
1361
- 64d50ce Merge pull request #219 from humanmade/Mediaquery
1362
- ab00e92 media queries for modal buttons
1363
- bacafc5 manage excludes modal styles fixed. added retina spinner
1364
- 83ef61b delete old backups before the backups list is displayed and also before a new backup is run to catch instances where the backup process fatal errors after creating the backup file but before delete_old_backups is run
1365
- 0c04f05 revert deleting old backups in hmbkp_cleanup.
1366
- 1e9ba82 Remove old backups as part of hmbkp_cleanup
1367
- 74113fc Run hmbkp_cleanup on load of the admin page to help keep things clean
1368
- 5cd35c9 Replace the last 2 instances of wp_get_schedule missed in the previous commit
1369
- d3b95af Code formatting and clenaup
1370
- 5020b49 Define our own list of schedules rather than relying on wp_get_schedules as that can be filtered by other plugins which can cause unexpected consequences.
1371
- b933aab Merge branch 'master' of github.com:humanmade/BackUpWordPress
1372
- b8cb3ac Also include the legacy SECRET_KEY when checking for user defined auth keys
1373
- 37787b4 Bump time
1374
- ac0287d Include any user defined auth keys and salts when generating the HMBKP_SECRET_KEY
1375
- c4e49e6 Use the existing HMBKP_SECURE_KEY to calculate the randomised prefix for the backup path.
1376
- b84f426 Merge pull request #211 from humanmade/fix-for-service
1377
- cc9b732 When data is being saved for a service, default to empty array, as using input type=checked will cause it not to be set
1378
- 812f48e Make set_status() public, so services can update the status of a backup progress
1379
- 41d8437 Create readme.md
1380
- fa36380 Start on changelog
1381
- 74bf0f8 Bump
1382
- e5b8493 Use dirname( hmbkp_path ) instead of WP_CONTENT_DIR to account for custom backup paths and when the path is set to uploads.
1383
- 6dfc256 Correct logic so we only generate and save the default path once.
1384
- 00f364c Bump for release
1385
- ef8719d POST not GET, fixes previewing and adding exclude rules
1386
- ec5a323 Bump for release
1387
- 538eb12 Latest HM Backup
1388
- 953984d Exit don't return on error for ajax requests
1389
- f5fcc35 Treat '0' as empty when checking ajax responses as some servers return 0 even with exit('');
1390
- 6a6c268 Spelling correction
1391
- 9b66689 merge with master
1392
- 033781f Bump
1393
- 4382251 Fix a PHP notice on Apache servers
1394
- 6f991a0 Bump
1395
- ec42544 Latest HM Backup
1396
- 289b0c2 Correct dot file ('.' & '..') check
1397
- 9c22d5b Filter out blank statuses.
1398
- 2bc4fc4 Check global $is_apache instead of calling mod_rewrite_loaded as that function seems to cause issues on some servers.
1399
- 5483864 Remove errant error_log
1400
- 7e1e201 Bump
1401
- 82ac4bb Latest hm-backup
1402
- e78dbd2 Don't call url_shorten as it's only available in the admin, just str_replace instead. Fixes fatal errors when WP Remote triggers backups.
1403
- 9452dcb Don't load the whole of misc.php for apache_mod_loaded, just call the function directly.
1404
- 728c8b9 Move the function_exists, file_exists and is_writable checks into the parent if as there is no point running any of the code just to fail at the second if.
1405
- c7d5c45 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1406
- 0fdfd07 Merge pull request #191 from humanmade/fix-misc-include
1407
- 8b5b30c fixed including misc.php
1408
- 02d46bf Don't hardcode the english string for Update, instead use the translation.
1409
- d7ff153 fixed including misc.php
1410
- f4e96e2 latest hm backup
1411
- a5e1876 Release notes for 2.1
1412
- 2dd8dbf Bump ready for release
1413
- ee6a0f4 Latest translations
1414
- 0d3e027 New originals
1415
- ad10f6f Merge branch 'master' of github.com:humanmade/BackUpWordPress
1416
- a010894 Move placeholder to help text
1417
- 3e25ec8 Define the var outside the if
1418
- c11ff1d Improve the performance of the exclude files modal by iterating directly through the DirectoryIterator instead of storing the whole filesystem in an array.
1419
- fdd9d92 Latest HM Backup
1420
- 628aeea Don't stop people with safe_mode = On from using the plugin, instead just show a warning message.
1421
- ae94736 Add a next backup time tooltip to the hourly backup sentence
1422
- 976c89f Update the link to the restore backup post on hmn.md
1423
- 121148f Point people to the FAQ before telling them about the support email address
1424
- 5511b82 Add a line about rating the plugin on the plugin directory.
1425
- 4313d71 Bring back .htaccess protection for the backups directory on Apache servers
1426
- c235714 Create the backups dir in the uploads dir if it can't be created in WP_CONTENT_DIR.
1427
- d036fff Remove the "remove" link whilst the exclude rule is being removed.
1428
- b2a326a Add the spinner back to remove exclude rule
1429
- 01120c3 Mark the backup as running sooner
1430
- 37c8d96 Better check for default exclude
1431
- 5c188e9 Don't esc_attr vars that aren't being echo'd
1432
- 4193396 Get don't post
1433
- 13d888e Minor text improvements to code comment
1434
- 3937e5a Don't redirect the original backup request in case it hasn't had chance to start yet.
1435
- ef29112 Increase the time between polling the server for status updates to give requests a chance to finish
1436
- d962d7a be more specific as we use hmbkp-running in more places
1437
- 813bc6a A way to force memory errors
1438
- 8f67ba9 Improved status messages
1439
- 84b15c7 Show the spinner next to the schedule link when a schedule is running and you are viewing a different schedule.
1440
- 730bc54 Bump
1441
- 0c3450c get not pot
1442
- b5746aa Add correct class to cancel button
1443
- 41c84b7 s/_/-
1444
- 70082c6 Bump up the ajax interval
1445
- 07ea6b7 Always set the redirect arg
1446
- 4e39f11 dash not underscore
1447
- 0aac32d Bump
1448
- bb79b1f Bump
1449
- c05b34e Make sure args are passed through recursive calls to hmbkpRedirectOnBackupComplete
1450
- 1d1f415 Bump
1451
- 7ab99fc Catch Fatal errors that occur during the backup process and offer to email them to support@hmn.md
1452
- 20eca40 Display "Starting backup" if the status hasn't yet been set.
1453
- 5075764 Latest HM Backup
1454
- dbcad72 The running status should override the error status
1455
- fed73a2 Remove the error class when a new backup is started
1456
- 613a188 Latest HM Backup
1457
- 9d4e471 Bump
1458
- 48db33a Latest HM BackUp
1459
- 4cf0cc8 Include archive and mysqldump method and verification steps in the status messages.
1460
- ab105b6 Catch Fatal errors that happen during the do back ajax request and display them in a popup
1461
- 1bad676 Catch and Display E_ERROR errors on the do backup ajax request
1462
- 1a75167 Check for constant changes before we call hmbkp_path
1463
- 276c086 Release notes
1464
- efb3658 Latest HM Backup
1465
- 141922e Remove HMBKP_ARCHIVE_FILENAME
1466
- 422551d Prepend a random string to the beginning of the backups path
1467
- 05a47a4 Improvements and unit tests for moving backup path
1468
- 01dddf8 use sanitized url instead of site name in backup filename
1469
- 0372abc Latest HM Backup
1470
- 8d0dc69 Better cleanup after unit tests
1471
- 45b945f Make sure we have a plugin version saved before comparing against it. Stops update actions firing on first activation.
1472
- 184c917 Bump
1473
- 096326b Allow the archive filename to be overridden.
1474
- f4f9a49 Remove use of realpath as it causes issues on shared hosts which use symlinks for users server root.
1475
- 308b9b9 Don't attempt to download a backup which doesn't exist.
1476
- 9419082 Don't urldecode the urlencoded base64 string.
1477
- 85087e3 Don't throw an exception when the schedule start time isn't an int as they don't have to be.
1478
- 646dddc Updated original strings
1479
- 1744b94 Bump
1480
- 241faf7 Fix possible warning on update if cron is empty
1481
- b7cb90d Don't show the version warning for the constants tab as those are pulled from the current version not the repo
1482
- 3400e1e 2.0.5
1483
- d65efb2 use a proper version comparison when checking whether this is an update from 1.x to 2.x
1484
- 2eaa879 Specify 'i' directly as a time format instead of relying on the user set time_format when calculating whether a time is an absolute hour.
1485
- 55fd182 Convert to user set schedule time to UTC before comparing against now and if it is in the past add interval instead of "tomorrow"
1486
- c4a393e Docblocks
1487
- 0bdc9ca Introduce a new constant HMBKP_SCHEDULE_TIME to allow the schedule time to be controlled.
1488
- 0f76aff wp-cron should check for a non 200 response
1489
- 1619fa1 Whitespace
1490
- 5d01df2 Re-schedule on __construct if the schedule has become unscheduled somehow.
1491
- 4c29912 Use the WordPress built in size_format instead of defining our own function for human readable filesizes
1492
- ce0ca9b Remove all hmbkp schedules on deactivate
1493
- b442a80 Remove line break at end of file
1494
- b6591ab use wp_retrieve_response_code instead of accessing the response array directly and attempt to show the response description alongside the response code.
1495
- c6b3f4d Use wp_remote_head instead of wp_remote_get to speed up the wp-cron.php response check.
1496
- 21b9307 Bump
1497
- 927043f Revert change to the way the plugin path and url are calculated as it broke some installs
1498
- cfe0637 Fix some unit tests
1499
- 83e5cac 2.0.3
1500
- 5af28c0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1501
- dc85d6e Fix PHP errors when you try to activate BackUpWordPress with WP Remote already active
1502
- 6b5cfd6 Only call array_flip is the $errors array is populated, as it can be NULL which will cause a notice
1503
- 72d869c Bump tested up to version
1504
- f96b2ed Remove TODO and whitespace
1505
- ed2d5de Allow HMBKP_PLUGIN_URL to be filtered
1506
- 3a0ae30 Bump the minimum version check to match version in readme
1507
- 5c95f91 Remove unused constant
1508
- efaf8b4 Latest HM Backup
1509
- ed9af8a Don't use strict operator to check 200 response
1510
- 5098825 Fixed scheduled backups (by using a common hook for all), added get_schedule() function to HMBK_Schedules, split setup default schedules to it's own hook so it can be removed,
1511
- 856ca7f If the cron request is_wp_error() show different message
1512
- 9fe931a use dynamic paths, as this means you can have the plugin in a theme / embedded in another plugin
1513
- 90ed393 Added PHPDocblock
1514
- ab1fbd1 Remove empty bullet
1515
- 356eb6f 2.0.2
1516
- da7faf5 Remove the memory limit error message for now as it's causing more trouble than it's worth.
1517
- db5fb5f Merge branch 'master' of github.com:humanmade/BackUpWordPress
1518
- 92a5109 bump
1519
- 4a39b52 Catch wp-cron wp_errors
1520
- f00ab65 Make sure we have a running backup filename before doing a file_exists and an unlink, fixes a possible warning when backup_running_filename is false and thus we try to unlink hmbkp_path
1521
- 52da406 Only send backup failed message if the backup file doesn't exist.
1522
- a1adc00 2.0.1 fix fatal error on PHP 5.2
1523
- 40dd2f1 Getting ready for GM
1524
- 5fffb7d Move the screenshot outside of the plugin
1525
- e905875 RC 1
1526
- 642dee9 Add a couple of missing esc_attr's
1527
- f131b5f Protect against a possible Notice if there are no excludes.
1528
- 91cc071 Protect against a possible notice
1529
- 7eb4cca Don't remove the scheduled_id param when redirected so we don't lose our place.
1530
- 7abaf15 Reduce the time between status ajax polls. Fire the initial status check straight away.
1531
- f13bc07 Scrap that idea.
1532
- 56b7694 Don't pass .php to get_template_part
1533
- 1988899 Attempt to hide that the backups dir even exists by showing the 404 page.
1534
- 44dee09 Remove all query args before redirecting back
1535
- 850d9ad Nonce, escape and i18n
1536
- b2c9b00 Fix PHP Warning
1537
- a027720 Add a missing legacy option for removal
1538
- 325af18 setup the default schedules after update has been fired so we don't get default schedules as well as the legacy updated schedule
1539
- 22c791c Don't check the return value of set_type as it doesn't return
1540
- f0713fa Set the parent excludes in set_excludes
1541
- 13dfb05 Class shouldn't be escaping
1542
- 963aeaa No need to set_type of parent class on construct
1543
- acd1898 set correct type
1544
- a71cfe4 Set the legacy schedules start time if HMBKP_DAILY_SCHEDULE_TIME is defined
1545
- 7279090 Properly upgrade manually only settings when creating the legacy schedule
1546
- 54bbf5a Use correct sprint_f arg
1547
- 11e4446 Use the ajax url
1548
- 4bd341c Don't load a file that doesn't exist
1549
- 6d01616 Latest HM Backup
1550
- f423ebb Only set excludes if they are different
1551
- 4d3a666 re-org some functions and delete and unneeded file.
1552
- 6a63d93 style the default and defined excluded file reason
1553
- 3138673 Use proper english
1554
- 9e29427 mark default and defined excludes
1555
- c15e3f3 Skip the test if a custom backup directory is in use
1556
- 8bf37ac Bump
1557
- 4bae0e4 Don't allow the backups dir or defined excludes to be removed.
1558
- be0f3ea a's now use the ajax url directly.
1559
- db7f864 fix adding new exclude rules.
1560
- 390f603 Allow backup path to be overridden with a define.
1561
- 28399e1 Typo
1562
- bba3f72 Don't double escape the backup filename
1563
- 2995cb7 Use the Ajax urls directly as there is no non-js fallback for now.
1564
- 7c16e60 Lots of work making BackUpWordPress work better in low memory environments.
1565
- cdfa519 Redirect to the new schedule on add schedule
1566
- ca57a7d Latest HM Backup
1567
- c3a2cd0 Fix wp-cli command
1568
- e33fd1d include the spinner gif with the plugin as we can't reliably guess the location to wp-admin in CSS
1569
- a290c3c Latest HM Backup
1570
- 712e4fa Properly highlight the selected file list tab in excludes popup
1571
- 3a06e1b Add some missing docblocks
1572
- a5f3c46 Clear the cached filesize when excludes or backup type changes
1573
- 2e53742 Correctly store the calculated filesize in a transient.
1574
- 5fa64db Bump
1575
- 13e3e75 Escape DB_NAME
1576
- 5441035 Unit tests and improvements for manual only backups
1577
- 57e97cd Merge branch 'master' of github.com:humanmade/BackUpWordPress
1578
- 0bba9c4 s/Feedbask/Feedback props @herb_miller
1579
- c967acf Merge pull request #146 from elektronikLexikon/master
1580
- 7970180 %s %s to %1 %2
1581
- 667e7df Ability to have manual only backups
1582
- b059ba0 Latest HM Backup fixes #133
1583
- c575bcf Latest HM Backup
1584
- 859d73c Fix for when unit tests are run in a WordPress in a submodule env.
1585
- 72574d9 Use default black overlay
1586
- 4675fe9 todo
1587
- 720e210 Make it possible for PclZip to be targeted specifically.
1588
- aa4105f Delete the running backup file if there is one when a back up process is cancelled.
1589
- 90b7e20 We don't use modernizer
1590
- 43c1d72 Update translations.
1591
- f42d31d Merge pull request #144 from elektronikLexikon/master
1592
- 1d36444 updated German translation
1593
- 8cda712 Bump
1594
- 71b686e Branding
1595
- 1119601 allow argument swapping in email translations and move the email out of the translatable string.
1596
- e687b29 Move compat check to the top so we don't waste cycles on older versions of WordPress.
1597
- 85cf577 Latest HM Backup
1598
- 81c607c use HM_Backup::get_home_path in place of ABSPATH.
1599
- 27b099b Correct readme.txt
1600
- bd0bdc2 Merge branch 'refs/heads/master' into 2.0
1601
- fe024cb (tag: 1.6.9) 1.6.9 changelog
1602
- c45194d Support downloading backups when your site is in a symlinked path.
1603
- c4f5a14 Merge branch 'refs/heads/master' into change-content-dir
1604
- cd50cfe 1.6.9 bump
1605
- 5b3dd92 Merge branch 'master' of git://github.com/elektronikLexikon/BackUpWordPress
1606
- 6866e09 Strip ABSPATH not root from exclude rules.
1607
- 42c40a0 Calling a static method through a variable Class was not supported until 5.3
1608
- d5ea971 s/humanmade.co.uk/hmn.md
1609
- caa8ab3 Fix check for timestamp
1610
- 1e37953 Use root not ABSPATH
1611
- 003435f Inverse logic
1612
- d54f821 Remove debug cruft
1613
- cc99d14 Unit test schedule and changes to class to make it more testable.
1614
- 208ee1e Don't remove non-existent backups
1615
- e264bcc Latest HM Backup
1616
- 01241cc Latest hm-core
1617
- e4f65d6 Fixes to Schedules
1618
- fb2220e Some additional js strings
1619
- fd1711d Fix fatal error in unit tests
1620
- 161b278 Delete extra backups if max backups is changed to below the number of existing backups
1621
- ed0b6d8 Remove old settings on upgrade and clean up whitespace
1622
- 1eb8846 Fire update action for downgrades as well as upgrades.
1623
- 9b6b1c8 Convert legacy schedule names on update.
1624
- 67e1989 Migrate legacy settings into the legacy schedule on update to 2.0
1625
- 0024569 Remove some old messages
1626
- 942e63b Don't mention day in schedule sentence for daily schedule.
1627
- 4cc93df Correct comment
1628
- 748fd57 Proper entity for less than
1629
- 6c030a8 Fire update actions in chronological order
1630
- d131f4d setup a legacy schedule when updating from V1 to V2.
1631
- c63ce1e Improve default schedules message
1632
- c863044 Switch to using plugins_url with the first param as it handles symlinks.
1633
- b029f1a Access static methods directly instead of using a wrapper function.
1634
- f9ab14f Access static methods directly instead of using a wrapper function.
1635
- 9d80ca9 Improved comment.
1636
- 5ae7ac6 Make consistent with the PHP error message
1637
- e18f9d2 Use __FILE__ instead of manually building the path
1638
- b6206a0 use plugin version when enquiring scripts and styles.
1639
- 619a606 use plugin_dir_path and plugin_dir_url instead of manually building them.
1640
- d55a688 Use hmbkp_get_home_path() instead of ABSPATH
1641
- d348533 Actually… there is a function that does this.
1642
- 51012bd Don't use ABSPATH here - because that is the worpdress directory, rather that site root.
1643
- a9005ab (tag: 1.6.8) 1.6.8 readme
1644
- d174b40 Updated spanish translation props @radinamatic
1645
- 86fddbc 1.6.8
1646
- e068f27 Bump
1647
- be7a7b0 Documentation for the new HMBKP_ROOT constant
1648
- 602ed0a Merge branch 'refs/heads/master' into 2.0
1649
- cdd94a7 Updated Russian translation.
1650
- 756111b Romanian translation
1651
- fd69c42 Serbian translation props stefan
1652
- cfc7942 Lithuanian translation props vincentas
1653
- c7aceda French translation props christophe
1654
- d3dfa9b Updated Spanish translation props Radina
1655
- f8ceee1 Default schedules
1656
- 772bd90 Derive backup type from backup filename so we don't incorrectly label old backups when a schedule type is changed
1657
- 9900396 Email notifications
1658
- ad768b8 Better replacement of ajaxurl as it's sometimes relative
1659
- 226b938 Avoid error if no schedules are setup, we'll have some proper schedule setup at some point
1660
- 7a5fbf9 re-org + more work on stuff
1661
- 32a32d9 Show label and improve styling of add new exclude rule field
1662
- 69dd917 Remove unneeded class
1663
- 6ca965e edit excludes separately to settings as it creates a cleaner user experience
1664
- 15db12b Updated translation files
1665
- 5680910 Allow constants to be translated.
1666
- 8ab9541 Updated translation files
1667
- 3796dff Merge branch 'refs/heads/master' into 2.0
1668
- 35a8217 Updated pot file.
1669
- e4c0c17 Move .htaccess into sprintf arg
1670
- 2ea85b5 Move link into sprintf arg
1671
- 5ca3405 Add a link to translate.hmn.md
1672
- fb67fc7 Make contextual help tab titles translatable and add more missing text domains
1673
- 284cad3 Don't translate whole a tag
1674
- 7a41fa6 Add missing text domain
1675
- 1c814eb Make "Settings Save" translatable
1676
- bdefe85 Make "Save Changes" translatable
1677
- 5162bd6 rejig sentence structure so they are more translatable.
1678
- f3b26bd Make Cancel translatable
1679
- 35709e9 Delete schedule, delete backup, localise js strings, more php string translation.
1680
- b843f89 More work on schedule UI and logic
1681
- c1df8d1 throw new Exception( 'That backup wasn\'t created by this schedule' );
1682
- 834ab32 We're not using this
1683
- ec33561 Latest HM Backup
1684
- 062c88d Remove .DS_Store
1685
- 0e7f4c2 More UI work
1686
- aa2397e Unit tests work, schedule class done, started work on new UI
1687
- 8dab4e1 HM Backup 2.0 beta
1688
- b61833d Add fancybox
1689
- 3b32b29 Allow root to be overridden.
1690
- 5a1db5d Don't store invalid email address's
1691
- 600770a Don't load HM_Backup if it's already defined.
1692
- 79e7201 chmod 644
1693
- 3ddc906 (tag: 1.6.7) 1.6.7
1694
- 9870513 HM Backup 1.5.2
1695
- f12c956 Cache plugin data in a transient for a day to avoid a remote get on every page load.
1696
- 048be08 whitespace
1697
- 648a42d Support entering multiple comma separated emails.
1698
- f040c6f s/to/too
1699
- 65206aa line break
1700
- 3c4cd99 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1701
- 14bd967 krsort instead of ksort so that backups are returned in chronological order.
1702
- 73edf6b Use correct property when setting the mysqldump path
1703
- 1c79e47 Merge pull request #103 from radinamatic/patch-1
1704
- e533057 Hi Tom,
1705
- b99c123 Bump
1706
- d7e7b06 HM Backup 1.5.1
1707
- 41bf3b7 release notes
1708
- 21132ef HM Backup 1.5
1709
- e5e6ddc Bump
1710
- e5b9bec Make secure key override-able
1711
- d05983b Latest HM Backup
1712
- 39736fc check get_email_address() instead of HMBKP_EMAIL
1713
- a481bd7 Clear email error on cleannup
1714
- e008d54 Code formatting
1715
- de5645a Send email at end of backup process so fatal errors don't stop backup from completing.
1716
- 619d260 Code formatting
1717
- 2602e42 whitespace
1718
- f629358 @todo
1719
- 1410adb Make sure backup file is attached to email.
1720
- d21bd19 Make sure file_exists before deleting.
1721
- 37eb48d Store running backup filename in .runing_backup then use it to make sure we don't show partial backups in backups list.
1722
- f3374b0 Use better filename checks in hmbkp_cleanup
1723
- 30cb215 Fire error on failed backup
1724
- b2833c7 Proper capitalization
1725
- ae00fcd Bump
1726
- f7397ac Don't cache ajax requests
1727
- 87fecec (tag: 1.6.4) 1.6.4 readme
1728
- c3021d3 Pull upstream
1729
- 3719063 Delete .htaccess on update so it's always rewritten and check <IfModule mod_rewrite.c> to avoid 500 error on servers without mod_rewrite
1730
- 5c77f6e Pull upstream
1731
- 1a49838 PHPdoc
1732
- eacb15e Don't show message for warnings as they freak people out to much and cause people to think the backup has failed when it hasn't
1733
- 6fa9cc0 Pull upstream
1734
- 6b6115d Code formatting
1735
- a04b5fb Pull upstream
1736
- bd661e5 Use correct operator
1737
- 1316011 (tag: 1.6.3) 1.6.3
1738
- e9744b2 No need to add backup path to excludes as it's auto excluded.
1739
- f679a72 hook email backup into hmbkp_complete_action so that fatal errors in sending email can't break backup.
1740
- 8551aa3 Define PCLZIP_TEMPORARY_DIR earlier to ensure it's always set to backup path.
1741
- 755b787 Pull upstream
1742
- 864ae59 Pull upstream
1743
- d433c96 Introduce HMBKP_SECURE_KEY and use instead of SECURE_AUTH_KEY
1744
- cfeaaf5 Better error message text
1745
- 5c74fc2 Don't strpos blank ABSPATH
1746
- 62b4103 (tag: 1.6.2) 1.6.2 changelog.
1747
- d2b8280 1.6.2
1748
- 2db2e2c Code formatting.
1749
- 3479438 Load admin_actions earlier so they can hook into admin_init
1750
- e3982dd Ability to dismiss the backup error / warning messages
1751
- c90d541 Pull upstream
1752
- 74f49eb Clean up some obsolete update code.
1753
- 8578a6d Don't clear hmbkp_max_backups option on update.
1754
- c6be2c9 Don't send backup email if backup failed.
1755
- 24c91a9 Avoid NOTICE when no errors.
1756
- c42bab6 Pull upstream
1757
- a540d17 Only show warning message for php errors in backupwordpress files.
1758
- 7f8fcda Mark the button as backup started and settimeout to 500
1759
- 73b7a5b (tag: 1.6.1) 1.6.1 release.
1760
- b257307 (tag: 1.6) Bump to 1.6
1761
- fc99e52 Return button even if the status is empty.
1762
- defd817 More obvious that running backups can be canceled
1763
- cb82321 Use getter methods instead of accessing properties directly.
1764
- 693da83 Pull upstream
1765
- cae995a No need to set root as it defaults to ABSPATH
1766
- 193e138 Don't echo time() in full backup test.
1767
- def211d Pull upstream
1768
- 40bc667 Incorrect comments
1769
- 67c1cc4 Pull from upstream
1770
- d832205 Show a message for backup warnings.
1771
- 7edfa8c Cleanup on errors
1772
- e2802b8 Cleanup on errors.
1773
- 94bc92f Pull from upstream
1774
- bd914ec Make cancel backup work with new ajax backup
1775
- 6ce5e27 Remove Constant as it's no longer needed
1776
- 7d4b536 Fire manual backups using ajax, completely removes the reliance on wp-cron for manual backups.
1777
- 28f7fa9 Fix notice if backups dir isn't readable.
1778
- 8296a80 Nicely formatted errors in backup error message.
1779
- f265d19 Store backup errors in a .backup_errors file and show a message in the admin if there were errors in the last backup.
1780
- cea6d48 Pull upstream
1781
- 1a06b37 Test archive_method, mysqldump_method and errors in unit test.
1782
- 47068b7 Backup directory is now automatically excluded.
1783
- aeff432 Pull upstream
1784
- c152520 Minor code formatting
1785
- 11f0099 Pull upstream
1786
- 5afdb0f Pull upstream
1787
- ffbfc66 Allow direct http downloads.
1788
- 96ef2d2 Remove actions when running backups from unit tests.
1789
- 3f261b6 Use files() method instead of duplicating code.
1790
- eb69aff Pull upstream
1791
- 6f6be0e Latest hm-backup
1792
- 8ffbc00 Measure time in full backup unit test.
1793
- 2c816bc Consistent handling of symlinks
1794
- 826cdb1 Pull upstream
1795
- c7a84f8 Skip full backup tests until symlinks are properly handled.
1796
- e1e3e9a Unit test for a full backup
1797
- fcab193 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1798
- 4f13942 Pull upstream
1799
- 8071a9c silence rmdir and unlink errors
1800
- 05b58ba conform ABSPATH to normalise trailingslash on windows
1801
- 1708eea Add Email info to FAQ and start changelog for 1.5.2
1802
- 61bbdd3 Bump
1803
- baaef5e Minor code improvements, skip unreadable files in backup size calculation, use RecursiveDirectoryIterator in rmdir_tree
1804
- 85180bd Skip unreadable child directories in RecursiveDirectoryIterator
1805
- 5624aa8 Better help and fix possible error in backup path checks
1806
- 02a5593 Support passing excludes through wp-cli
1807
- 95998b7 (tag: 1.5.1) 1.5.1 changelog
1808
- 32b56d8 WP CLI support.
1809
- 10013f4 Minor code formatting.
1810
- 633d2c0 Release time.
1811
- 789a58c Pull from upstream
1812
- a8e48b2 Don't delete user settings on de-activate.
1813
- 04162ad Bump
1814
- 1273217 Use a DirectoryIterator instead of a recursive open_dir for hmbkp_calculate.
1815
- da9b8cf Only exclude backup path if it's in web root
1816
- ea2acf8 Add the warning to the top of all the tabs.
1817
- 70dbe74 preventDefault to stop the anchor being added to url and to stop page jump.
1818
- e29ff76 (tag: 1.5) 1.5 readme
1819
- 3160894 Ability to override the capability used to register the menu page.
1820
- a69d82c Suppress filemtime errors
1821
- 99a79b2 fiddle with the order and remove ABSPATH before preg_matching to better match the plc_zip logic
1822
- 641ec22 Pass defines straight to correct properties for command path.
1823
- 1cbb2cc Latest HM Backup.
1824
- 14247ef Always delete transient on save settings.
1825
- c1b3109 Back compat JS on old versions of WordPress.
1826
- c63d4ee Latest HM Backups
1827
- a4a157a Latest HM Backup
1828
- 8b68c4e Pre 3.3 compat for help tabs.
1829
- ba7f621 back compat for 3.1 when WP_MAX_MEMORY_LIMIT wasn't defined.
1830
- f73d114 Latest HM_Backup and more renames
1831
- c382e42 Latest HM Backup
1832
- 1a8025e Bump + code cleanup.
1833
- a8525f3 Add plugin FAQ and constants to help and convert to use new 3.3 help tabs.
1834
- 49c0f7c Call conform_dir statically.
1835
- 2998149 Rename Advanced Options to settings.
1836
- 66fad96 Get backups working
1837
- b2f0202 Latest hm-backup
1838
- 7286524 Load the HM Backup Tests.
1839
- 9d71836 First bash at using hm-backup
1840
- 516e5f5 Merge pull request #15 from valericus/patch-1
1841
- b0a8f3e Set proper charset of MySQL backup
1842
- 8b1c3c7 (tag: 1.4.1) 1.4.1
1843
- 4ed46d2 (tag: 1.4) 1.4 has gone golden.
1844
- f91a1d4 Fix a couple of last minute bugs.
1845
- 2b9d335 New screenshot for 1.4
1846
- 3b294c0 Finalising 1.4
1847
- bb531a0 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1848
- 97e9479 Code formatting.
1849
- b21cb67 Rewrite incorrect comment.
1850
- 594e7ca Missing line break in .haccess comment.
1851
- e24cc2d Code formatting.
1852
- 7e9f2ad @todo
1853
- f9b5a4a Updated Readme
1854
- 630f55e Merge branch 'master' of github.com:humanmade/BackUpWordPress
1855
- 43f17b9 Should use the function for checking this - for backwards compatibility.
1856
- 57568ae Do not setup backup schedule if the option has been set to disable backups.
1857
- 08e7651 Rename the backup schedule function.
1858
- aeb8cd7 Clear the schedule if the automatic backup is disabled.
1859
- 056ca13 Add class = code to the excludes text area.
1860
- 3bdbc3b Code formatting.
1861
- fb46f82 Minor PHP comment error.
1862
- 93019af Correct author and plugin urls.
1863
- 952b4f7 Correct github url
1864
- e4e8425 Add Theo to contributors list and order alphabetically
1865
- 3aa9342 Bump
1866
- 10cdd57 Merge branch 'refs/heads/admin_gui'
1867
- 82d55f5 Code commentino, formattino & I18N
1868
- 07068cf Updated language.
1869
- 240e4ca Merge branch 'refs/heads/master' into admin_gui
1870
- 26da9e8 Remove cruft.
1871
- f7f1576 Localise dates.
1872
- a2d3273 Merge branch 'master' of github.com:humanmade/BackUpWordPress
1873
- 2691a21 Use correct translation domain.
1874
- e93883c Russian translation, props Valera R
1875
- e52bd8e strtolower instead of checking both lowercase and capitalised
1876
- 9687d19 Merge branch 'master' into admin_gui
1877
- 61bfb20 Bug in i18n - thanks Valera R
1878
- 97e1447 Bug in i18n - thanks Valera R
1879
- 4385235 Looks like our cron schedules filter got lost in a merge back there.
1880
- 7fc9f1a Merge branch 'master' into admin_gui
1881
- 7c8b151 prevent notices when the plugin cannot connect to the WordPress plugin repository.
1882
- eee9059 Fix typo in constant.
1883
- 0637a16 BUG FIX - typo in the constant
1884
- f8507a2 Switch to use hmbkp_get_excludes()
1885
- ee15d43 Rewrite function for getting the list of excluded files/directories
1886
- b95b9a0 replace hmbkp_daily with standard WordPress daily
1887
- ee180fc Use the default daily schedule rather than registering our own
1888
- 358dba8 Merge branch 'master' into admin_gui
1889
- 97964cb Add an explanatory comment to the .htaccess.
1890
- 7eb2b14 Constant to disable the use of wp-cron with manual backups.
1891
- 40f6099 bump
1892
- 627d400 (tag: 1.3.2) Version 1.3.2
1893
- bb5af87 Ignore unreadable files in PCLZIP
1894
- 30928ec Properly export binary data.
1895
- a28656e Spanish translation.
1896
- 6c4d1b1 Bump min PHP version to 5.2.4 to match WordPress.
1897
- b412439 Use 303 redirect when redirecting form submissions.
1898
- 4655a80 If the database file doesn't exist after doing a mysqldump then fallback to the PHP fallback library.
1899
- f84fb70 Move set_time_limit outside of loop.
1900
- cfd6da5 Don't store .gitignore
1901
- a983c42 3.3 Style buttons
1902
- d32cf03 Stray line.
1903
- 477d848 Better comments
1904
- 1a1ebfd remove the last couple of bits of theos code that snuck in there.
1905
- 6eafe41 Revert "Added DB entries for backup archives"
1906
- c984020 missed some stuff
1907
- 9a254e3 Merge branch 'master' into admin_gui
1908
- b5970c2 improve the descriptions.
1909
- f825524 Revert "Added DB entries for backup archives"
1910
- 5de95f0 call deactivate on update to clear bad settings.
1911
- 59348db Merge branch 'db-logs'
1912
- 3c592a8 ignore
1913
- 40302fc Handle empty passwords in mysql_dump
1914
- 9f9b80a Added DB entries for backup archives
1915
- 0da2efb - Call deactivate on activation to clear everything out. A better cleaner solution. Thanks Tom.
1916
- d01c0a3 Merge branch 'master' into admin_gui
1917
- 00f5d5c Fix
1918
- f1fd0c2 - Instead of deleteing the transient, we should delete the .backup_running file. Should maybe do this on activate as well just in case something had gone wrong.
1919
- 00b0033 - Display advanced options panel if hash is set. - Close some tags.
1920
- c7e2bed - FIX - only show invalid no of backups if the field was actually submitted (note - disabled fields are not submitted)
1921
- e6decbe Merge branch 'master' into admin_gui
1922
- a58e4b2 - Update readme & stable tag
1923
- a132ab7 FIX add check for PHP Version, and die if less than 5.0
1924
- f0b4d16 Merge branch 'master' into admin_gui
1925
- bb5b787 - hmbkp_get_backups should return false if no backups.
1926
- 2be96cf - Advanced settings form should be visible if there are no backups.
1927
- 5b5eb6c - get_backups() should return false if there are no backups.
1928
- 4865793 - Display a notice to say that all files in the root directory of the site will be backed up if there is are no excludes set. - Make the function for advancing the schedule by the interval simpler.
1929
- 52d2d38 - tidy up
1930
- 0ef77d9 - Some functions seemed to get lost when merging! - Fix some notices.
1931
- 5a78ad7 - Fix some issues / duplications etc when caused by merge.
1932
- 9b99f73 Merge branch 'master' into admin_gui
1933
- 7cce37a Docs.
1934
- bfefb57 We no longer need mysql_ping
1935
- aa4608b Store running status as a hidden file instead of in the database.
1936
- 975a4f9 - Remove an old function
1937
- 48403f1 - Update readme
1938
- ca43c93 Don't show remaining space or warn when space is low as it's too unreliable.
1939
- 30f8dc0 (tag: 1.3) Version 1.3 Gold
1940
- 83acf1e Pull the FAQ into the contextual help section on the backupwordpress page.
1941
- efb8d10 Don't activate on old versions of WordPress
1942
- 531bcac Overhaul excludes to support excluding absolute folders /wp-contet/, folder fragments .svn/ and files *.php.
1943
- e219bf7 - Improve scheduling of the new cron jobs. Make sure it resets at the right time, and only the right time. - Better commenting
1944
- 8ce735d - When setting a new schedule - the first event should be advanced by the schedule interval.
1945
- df6d34c - FIX - make sure the schedule is cleared when it should be.
1946
- a2ab152 - Use deactivate_plugins() rather than manually unsetting. Thanks Joe.
1947
- 8c8e097 Merge branch 'master' into admin_gui
1948
- 3dce375 - Deactivate Plugin & Die if WordPress is too old.
1949
- 09b101b - Update readme a little.
1950
- 4cfff8a - FIX display real next scheduled.
1951
- 7db7b35 - Maybe they shouldn't be capitalized after all. - remove bug testing code.
1952
- ae49c2b - Clear schedule hook when changing schedule setting. - FIX: capitalize display name inline with wordpress default cron schedules - FIX: naming of option.
1953
- 93c87ca - FIX: make sure all options are deleted when the plugin is deactivated
1954
- 1fc1002 - oops. missed some commas.
1955
- 35238bb - add weekly, fortnightly and monthly to cron schedules.
1956
- e751d74 - Add setting of backup frequency in the advanced options form. - Save frequency settings.
1957
- 2374007 - Fix the scheduling so that it works in all timezones, correctly. And certainly doesn't schedule the event in the past so that it runs backups constantly.
1958
- 0996bf3 Don't attempt to guess compression, just display uncompressed size.
1959
- 8cff239 Wrap ini_get( 'safe_mode' ); so we handle both (bool) false and (string) Off.
1960
- c7a7f32 - Save file with correct localtime - Show correct localtime in table.
1961
- 5e11b63 - Adjust scheduled event for local time. - Display correct localtime.
1962
- b6ad6a1 - Stop even trying to guess the compressed size as it is totally inaccurate. Be honest, and just tell them the uncrompressed size.
1963
- bb15ff7 - Use php version_compare function to check versions.
1964
- 050a7b5 - FIX - used the wrong key.
1965
- 7a9a2ae - Move Advanced Options form notifications to the interface.functions file - and hook them in to admin_notices
1966
- 34880f1 - FIX: Just some isset checks on my $_POST data. Thanks Tom.
1967
- 0ef1c6e - If new exclude rules - delete cached est backup size stored as transient so that it is regenerated
1968
- f7b1e0f - Do not count excluded files & directories when calculating estimated filesize.
1969
- 315bd03 - Fix - When submitting the form - you did not go to the top of the page.
1970
- b6cad30 - Better handling of errors when processing the advanced options form. - Display some nice helpful messages.
1971
- d6e1436 - Fix some of the text in contextual help
1972
- 7985cc4 - Add 'settings saved' notification - tidy up
1973
- 4e5e609 - update & add check to see if readme used is from the actual version in use and if not, display some warnings.
1974
- c74e6ee - Add FAQ to Contextual Help dropdown - FAQ is taken from readme on wordpress repo.
1975
- 92e04c4 Merge branch 'master' into admin_gui
1976
- 479e1d2 Set database stored_filename directory rather than relying on str_replace.
1977
- 763b8f8 Better hmbkp_path default
1978
- 99bd09b Handle singular and plural for completed backup count
1979
- d2b5033 Better styling for advanced options.
1980
- de48557 Merge branch 'master' into admin_gui
1981
- dccdc32 - Do not hide the advanced options form if it has just been submitted.
1982
- a46533d - Fix message at the top not displaying the right message when the options form has just been submitted.
1983
- 1fd7a3d - fix message not displaying correct option - hmbkp_disable_automatic_backup
1984
- c3c1374 - get excludes to use stored option
1985
- 1b39875 - move save options function to admin.actions and process on admin_init - add some checks/nonce fields etc.
1986
- 65abfed - change everything to use my new option value functions
1987
- be9c254 - more switching to use of individual functions to get value of settings.
1988
- 09ee9d1 - move checking of max_backups to max_backups function
1989
- 453f54f - Do not delete stored email address just because new one is invalid. Just return error instead.
1990
- bd25c5c - Advanced options GUI - Options page save function - beginning of a Wrapper function for returning either defined setting, or stored option.
1991
- 197c346 Replace * with non greedy regex wildcard for PCLZIP.
1992
- ed85a9e Don't match against invalid exclude rules
1993
- 5cd78dd Trim whitespace from exclude rules, fixes issue with comma [space] separated list of rules.
1994
- 9dd836b Show examples for all advanced options.
1995
- 3764099 Add support for excluding directories via a define.
1996
- dc78e1e Replace \\ with / in windows paths not the other way round.
1997
- 65f0322 Support dynamic excludes in both zip and PCLZIP, lays foundation for user excludes.
1998
- f1b5173 Use consistent function names for admin_notices.
1999
- 7beaad1 Properly handle setting and changing backup directory.
2000
- 3223b24 Improve the get_backups code.
2001
- 3c1411b Tweak FAQ
2002
- 53c0d59 Merge branch 'master' of github.com:humanmade/BackUpWordPress
2003
- 0789452 1.3 bleeding
2004
- 5241d51 Correct handle for Matt
2005
- 3d20f86 Merge branch 'master' of github.com:humanmade/BackUpWordPress
2006
- 48102f5 - Update FAQ in Readme
2007
- b6e1607 (tag: 1.2) Version 1.2
2008
- da8e478 Tweak langauge.
2009
- 03e35da Tweak messages.
2010
- 887db23 Don't show message if email is invalid
2011
- 673450b Merge branch 'master' into backupwordpress_email
2012
- 1300f42 - oops. left in some debug code.
2013
- 98b2b49 file mode change,
2014
- 410b121 - Add some error messages for invalid email addresses and emails that failed to send.
2015
- f74e0a4 - Add ability to email a copy of the backup to a defined address.
2016
- 8879ebf Merge code from settings.functions.php into core.functions.php and delete redundant file.
2017
- 2b5a6db Don't hardcode Windows drive letters.
2018
- 3851dce Merge branch 'master' of github.com:willmot/BackUpWordPress
2019
- 87eabb9 - Icons - 32x32, 16x16, 16x16+hover - Add css for icon to hmbkp.css - Change screen_icon() to use backupwordpress icon - Icon for git repo
2020
- 02e8a7e chmod moved files so we can delete them.
2021
- f4bd99c Check for wp_error in wp-cron.php check
2022
- 40f0a36 Initial Import
2023
- 948b600 Committed to much
2024
- b126a23 Initial commit
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
classes/class-backup.php CHANGED
@@ -1,6 +1,7 @@
1
  <?php
2
 
3
  namespace HM\BackUpWordPress {
 
4
 
5
  /**
6
  * Generic file and database backup class
@@ -155,10 +156,38 @@ namespace HM\BackUpWordPress {
155
  */
156
  protected $action_callback = '';
157
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
158
  /**
159
  * Check whether safe mode is active or not
160
  *
161
  * @param string $ini_get_callback
 
162
  * @return bool
163
  */
164
  public static function is_safe_mode_active( $ini_get_callback = 'ini_get' ) {
@@ -206,7 +235,11 @@ namespace HM\BackUpWordPress {
206
 
207
  protected static function is_function_disabled( $ini_setting ) {
208
 
209
- if ( array_intersect( array( 'shell_exec', 'escapeshellarg', 'escapeshellcmd' ), array_map( 'trim', explode( ',', @ini_get( $ini_setting ) ) ) ) ) {
 
 
 
 
210
  return false;
211
  }
212
 
@@ -240,15 +273,11 @@ namespace HM\BackUpWordPress {
240
  * Sanitize a directory path
241
  *
242
  * @param string $dir
243
- * @param bool $recursive
 
244
  * @return string
245
  */
246
- public static function conform_dir( $dir, $recursive = false ) {
247
-
248
- // Assume empty dir is root
249
- if ( ! $dir ) {
250
- $dir = '/';
251
- }
252
 
253
  // Replace single forward slash (looks like double slash because we have to escape it)
254
  $dir = str_replace( '\\', '/', $dir );
@@ -329,7 +358,15 @@ namespace HM\BackUpWordPress {
329
  public function get_archive_filename() {
330
 
331
  if ( empty( $this->archive_filename ) ) {
332
- $this->set_archive_filename( implode( '-', array( sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ), 'backup', current_time( 'Y-m-d-H-i-s' ) ) ) . '.zip' );
 
 
 
 
 
 
 
 
333
  }
334
 
335
  return $this->archive_filename;
@@ -340,6 +377,7 @@ namespace HM\BackUpWordPress {
340
  * Set the filename of the archive file
341
  *
342
  * @param string $filename
 
343
  * @return \WP_Error|null
344
  */
345
  public function set_archive_filename( $filename ) {
@@ -384,6 +422,7 @@ namespace HM\BackUpWordPress {
384
  * Set the filename of the database dump file
385
  *
386
  * @param string $filename
 
387
  * @return \WP_Error|null
388
  */
389
  public function set_database_dump_filename( $filename ) {
@@ -421,6 +460,7 @@ namespace HM\BackUpWordPress {
421
  * Set the root directory to backup from
422
  *
423
  * @param string $path
 
424
  * @return \WP_Error|null
425
  */
426
  public function set_root( $path ) {
@@ -446,6 +486,7 @@ namespace HM\BackUpWordPress {
446
  * Set the filepath for the existing archive
447
  *
448
  * @param string $existing_archive_filepath
 
449
  * @return null
450
  */
451
  public function set_existing_archive_filepath( $existing_archive_filepath ) {
@@ -500,6 +541,7 @@ namespace HM\BackUpWordPress {
500
  * $type must be one of complete, database or file
501
  *
502
  * @param string $type
 
503
  * @return \WP_Error|null
504
  */
505
  public function set_type( $type ) {
@@ -557,6 +599,8 @@ namespace HM\BackUpWordPress {
557
  '/xampp/mysql/bin/mysqldump',
558
  '/Program Files/xampp/mysql/bin/mysqldump',
559
  '/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
 
 
560
  '/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
561
  '/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
562
  '/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
@@ -567,7 +611,7 @@ namespace HM\BackUpWordPress {
567
 
568
  // Find the first one which works
569
  foreach ( $mysqldump_locations as $location ) {
570
- if ( @is_executable( self::conform_dir( $location ) ) ) {
571
  $this->set_mysqldump_command_path( $location );
572
  break; // Found one
573
  }
@@ -659,7 +703,8 @@ namespace HM\BackUpWordPress {
659
  * Both the action and the instance on Backup are then passed to the callback function
660
  *
661
  * @see set_action_callback
662
- * @param string $action The event to fire
 
663
  */
664
  protected function do_action( $action ) {
665
 
@@ -688,11 +733,12 @@ namespace HM\BackUpWordPress {
688
  *
689
  * @see do_action
690
  * @see /do_action
 
691
  * @param callable $callback The function or method to be called
692
- * @param int $priority The priority of the callback
693
  */
694
  public function set_action_callback( $callback, $priority = 10 ) {
695
- $this->action_callback[$priority][] = $callback;
696
  }
697
 
698
  /**
@@ -726,28 +772,62 @@ namespace HM\BackUpWordPress {
726
  */
727
  public function dump_database() {
728
 
729
- if ( $this->get_mysqldump_command_path() ) {
730
- $this->mysqldump();
731
- }
732
-
733
- if ( empty( $this->mysqldump_verified ) ) {
734
  $this->mysqldump_fallback();
 
 
 
 
 
 
 
 
 
735
  }
736
 
737
  $this->do_action( 'hmbkp_mysqldump_finished' );
738
 
739
  }
740
 
 
 
 
741
  public function mysqldump() {
742
 
743
  $this->mysqldump_method = 'mysqldump';
744
 
745
  $this->do_action( 'hmbkp_mysqldump_started' );
746
 
747
- $host = explode( ':', DB_HOST );
 
 
 
 
 
 
 
 
 
748
 
749
- $host = reset( $host );
750
- $port = strpos( DB_HOST, ':' ) ? end( explode( ':', DB_HOST ) ) : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
751
 
752
  // Path to the mysqldump executable
753
  $cmd = escapeshellarg( $this->get_mysqldump_command_path() );
@@ -756,7 +836,7 @@ namespace HM\BackUpWordPress {
756
  $cmd .= ' --no-create-db';
757
 
758
  // Allow lock-tables to be overridden
759
- if ( ! defined( 'HMBKP_MYSQLDUMP_SINGLE_TRANSACTION' ) || HMBKP_MYSQLDUMP_SINGLE_TRANSACTION !== false ) {
760
  $cmd .= ' --single-transaction';
761
  }
762
 
@@ -779,6 +859,11 @@ namespace HM\BackUpWordPress {
779
  $cmd .= ' -P ' . $port;
780
  }
781
 
 
 
 
 
 
782
  // The file we're saving too
783
  $cmd .= ' -r ' . escapeshellarg( $this->get_database_dump_filepath() );
784
 
@@ -792,9 +877,9 @@ namespace HM\BackUpWordPress {
792
  $stderr = shell_exec( $cmd );
793
 
794
  // Skip the new password warning that is output in mysql > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
795
- if ( trim( $stderr ) === 'Warning: Using a password on the command line interface can be insecure.' ) {
796
  $stderr = '';
797
- }
798
 
799
  if ( $stderr ) {
800
  $this->error( $this->get_mysqldump_method(), $stderr );
@@ -896,17 +981,17 @@ namespace HM\BackUpWordPress {
896
  */
897
  public function zip() {
898
 
899
- // If we have an existing archive let's duplicate it so we can just add changed files to save time
900
- if ( $this->get_existing_archive_filepath() ) {
901
- copy( $this->get_existing_archive_filepath(), $this->get_archive_filepath() );
902
- }
903
-
904
  $this->archive_method = 'zip';
905
 
906
  $this->do_action( 'hmbkp_archive_started' );
907
 
 
 
 
 
 
908
  // Zip up $this->root
909
- if ( $this->get_type() !== 'database' ) {
910
 
911
  // cd to the site root
912
  $command = 'cd ' . escapeshellarg( $this->get_root() );
@@ -934,11 +1019,6 @@ namespace HM\BackUpWordPress {
934
 
935
  }
936
 
937
- // Add the database dump to the archive
938
- if ( $this->get_type() !== 'file' && file_exists( $this->get_database_dump_filepath() ) ) {
939
- $stderr = shell_exec( 'cd ' . escapeshellarg( $this->get_path() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -q ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . escapeshellarg( $this->get_database_dump_filename() ) . ' 2>&1' );
940
- }
941
-
942
  if ( ! empty( $stderr ) ) {
943
  $this->warning( $this->get_archive_method(), $stderr );
944
  }
@@ -994,13 +1074,11 @@ namespace HM\BackUpWordPress {
994
 
995
  if ( $file->isDir() ) {
996
  $zip->addEmptyDir( trailingslashit( str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) );
997
- }
998
-
999
- elseif ( $file->isFile() ) {
1000
  $zip->addFile( $file->getPathname(), str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) );
1001
  }
1002
 
1003
- if ( ++$files_added % 500 === 0 ) {
1004
  if ( ! $zip->close() || ! $zip->open( $this->get_archive_filepath(), \ZIPARCHIVE::CREATE ) ) {
1005
  return;
1006
  }
@@ -1129,11 +1207,24 @@ namespace HM\BackUpWordPress {
1129
  */
1130
  public function get_files() {
1131
 
 
 
1132
  if ( ! empty( $this->files ) ) {
1133
  return $this->files;
1134
  }
1135
 
1136
- $this->files = new \RecursiveIteratorIterator( new \RecursiveDirectoryIterator( $this->get_root(), \RecursiveDirectoryIterator::SKIP_DOTS + \RecursiveDirectoryIterator::FOLLOW_SYMLINKS ), \RecursiveIteratorIterator::SELF_FIRST, \RecursiveIteratorIterator::CATCH_GET_CHILD );
 
 
 
 
 
 
 
 
 
 
 
1137
 
1138
  return $this->files;
1139
 
@@ -1286,7 +1377,7 @@ namespace HM\BackUpWordPress {
1286
  * Set the excludes, expects and array
1287
  *
1288
  * @param Array $excludes
1289
- * @param Bool $append
1290
  */
1291
  public function set_excludes( $excludes, $append = false ) {
1292
 
@@ -1308,7 +1399,8 @@ namespace HM\BackUpWordPress {
1308
  * Takes the exclude rules and formats them for use with either
1309
  * the shell zip command or pclzip
1310
  *
1311
- * @param string $context. (default: 'zip')
 
1312
  * @return string
1313
  */
1314
  public function exclude_string( $context = 'zip' ) {
@@ -1323,8 +1415,7 @@ namespace HM\BackUpWordPress {
1323
  $separator = ' -x ';
1324
 
1325
  // The PclZip fallback library
1326
- }
1327
- elseif ( $context === 'regex' ) {
1328
  $wildcard = '([\s\S]*?)';
1329
  $separator = '|';
1330
  }
@@ -1338,14 +1429,10 @@ namespace HM\BackUpWordPress {
1338
  // Files don't end with /
1339
  if ( ! in_array( substr( $rule, - 1 ), array( '\\', '/' ) ) ) {
1340
  $file = true;
1341
- }
1342
-
1343
- // If rule starts with a / then treat as absolute path
1344
  elseif ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) ) {
1345
  $absolute = true;
1346
- }
1347
-
1348
- // Otherwise treat as dir fragment
1349
  else {
1350
  $fragment = true;
1351
  }
@@ -1405,6 +1492,7 @@ namespace HM\BackUpWordPress {
1405
  * Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
1406
  *
1407
  * @param mixed $a_name
 
1408
  * @return array|string
1409
  */
1410
  private function sql_backquote( $a_name ) {
@@ -1418,7 +1506,7 @@ namespace HM\BackUpWordPress {
1418
  reset( $a_name );
1419
 
1420
  while ( list( $key, $val ) = each( $a_name ) ) {
1421
- $result[$key] = '`' . $val . '`';
1422
  }
1423
 
1424
  return $result;
@@ -1487,7 +1575,7 @@ namespace HM\BackUpWordPress {
1487
  $result = mysql_query( $query, $this->db );
1488
 
1489
  $fields_cnt = 0;
1490
- $rows_cnt = 0;
1491
 
1492
  if ( $result ) {
1493
  $fields_cnt = mysql_num_fields( $result );
@@ -1506,13 +1594,13 @@ namespace HM\BackUpWordPress {
1506
  // Checks whether the field is an integer or not
1507
  for ( $j = 0; $j < $fields_cnt; $j ++ ) {
1508
 
1509
- $field_set[$j] = $this->sql_backquote( mysql_field_name( $result, $j ) );
1510
- $type = mysql_field_type( $result, $j );
1511
 
1512
  if ( $type === 'tinyint' || $type === 'smallint' || $type === 'mediumint' || $type === 'int' || $type === 'bigint' ) {
1513
- $field_num[$j] = true;
1514
  } else {
1515
- $field_num[$j] = false;
1516
  }
1517
 
1518
  }
@@ -1533,17 +1621,16 @@ namespace HM\BackUpWordPress {
1533
  // build the statement
1534
  for ( $j = 0; $j < $fields_cnt; $j ++ ) {
1535
 
1536
- if ( ! isset( $row[$j] ) ) {
1537
  $values[] = 'NULL';
1538
 
1539
- }
1540
- elseif ( $row[$j] === '0' || $row[$j] !== '' ) {
1541
 
1542
  // a number
1543
- if ( $field_num[$j] ) {
1544
- $values[] = $row[$j];
1545
  } else {
1546
- $values[] = "'" . str_replace( $search, $replace, $this->sql_addslashes( $row[$j] ) ) . "'";
1547
  }
1548
 
1549
  } else {
@@ -1585,7 +1672,8 @@ namespace HM\BackUpWordPress {
1585
  * Taken from phpMyAdmin.
1586
  *
1587
  * @param string $a_string (default: '')
1588
- * @param bool $is_like (default: false)
 
1589
  * @return mixed
1590
  */
1591
  private function sql_addslashes( $a_string = '', $is_like = false ) {
@@ -1605,6 +1693,7 @@ namespace HM\BackUpWordPress {
1605
  * Write the SQL file
1606
  *
1607
  * @param string $sql
 
1608
  * @return null|boolean
1609
  */
1610
  private function write_sql( $sql ) {
@@ -1637,7 +1726,7 @@ namespace HM\BackUpWordPress {
1637
  public function get_errors( $context = null ) {
1638
 
1639
  if ( ! empty( $context ) ) {
1640
- return isset( $this->errors[$context] ) ? $this->errors[$context] : array();
1641
  }
1642
 
1643
  return $this->errors;
@@ -1648,7 +1737,7 @@ namespace HM\BackUpWordPress {
1648
  * Add an error to the errors stack
1649
  *
1650
  * @param string $context
1651
- * @param mixed $error
1652
  */
1653
  public function error( $context, $error ) {
1654
 
@@ -1658,7 +1747,7 @@ namespace HM\BackUpWordPress {
1658
 
1659
  $this->do_action( 'hmbkp_error' );
1660
 
1661
- $this->errors[$context][$_key = md5( implode( ':', (array) $error ) )] = $error;
1662
 
1663
  }
1664
 
@@ -1682,10 +1771,8 @@ namespace HM\BackUpWordPress {
1682
  }
1683
 
1684
  if ( $context ) {
1685
- unset( $this->errors[$context] );
1686
- }
1687
-
1688
- else {
1689
  $this->errors = array();
1690
  }
1691
 
@@ -1698,7 +1785,7 @@ namespace HM\BackUpWordPress {
1698
  public function get_warnings( $context = null ) {
1699
 
1700
  if ( ! empty( $context ) ) {
1701
- return isset( $this->warnings[$context] ) ? $this->warnings[$context] : array();
1702
  }
1703
 
1704
  return $this->warnings;
@@ -1709,7 +1796,7 @@ namespace HM\BackUpWordPress {
1709
  * Add an warning to the warnings stack
1710
  *
1711
  * @param string $context
1712
- * @param mixed $warning
1713
  */
1714
  private function warning( $context, $warning ) {
1715
 
@@ -1719,7 +1806,7 @@ namespace HM\BackUpWordPress {
1719
 
1720
  $this->do_action( 'hmbkp_warning' );
1721
 
1722
- $this->warnings[$context][$_key = md5( implode( ':', (array) $warning ) )] = $warning;
1723
 
1724
  }
1725
 
@@ -1727,6 +1814,7 @@ namespace HM\BackUpWordPress {
1727
  * Custom error handler for catching php errors
1728
  *
1729
  * @param $type
 
1730
  * @return bool
1731
  */
1732
  public function error_handler( $type ) {
@@ -1746,6 +1834,42 @@ namespace HM\BackUpWordPress {
1746
 
1747
  }
1748
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1749
  }
1750
 
1751
  }
@@ -1760,7 +1884,8 @@ namespace {
1760
  * of the zip
1761
  *
1762
  * @param string $event
1763
- * @param array $file
 
1764
  * @return bool
1765
  */
1766
  function hmbkp_pclzip_callback( $event, $file ) {
@@ -1770,9 +1895,7 @@ namespace {
1770
  // Don't try to add unreadable files.
1771
  if ( ! is_readable( $file['filename'] ) || ! file_exists( $file['filename'] ) ) {
1772
  return false;
1773
- }
1774
-
1775
- // Match everything else past the exclude list
1776
  elseif ( $_hmbkp_exclude_string && preg_match( '(' . $_hmbkp_exclude_string . ')', $file['stored_filename'] ) ) {
1777
  return false;
1778
  }
1
  <?php
2
 
3
  namespace HM\BackUpWordPress {
4
+ use Symfony\Component\Finder\Finder;
5
 
6
  /**
7
  * Generic file and database backup class
156
  */
157
  protected $action_callback = '';
158
 
159
+ protected $default_excludes = array(
160
+ '.git/',
161
+ '.svn/',
162
+ '.DS_Store',
163
+ '.idea/',
164
+ 'backup-*',
165
+ 'backwpup-*',
166
+ 'updraft',
167
+ 'backups',
168
+ 'wp-snapshots',
169
+ 'backupbuddy_backups',
170
+ 'pb_backupbuddy',
171
+ 'backup-db',
172
+ 'cache',
173
+ 'Envato-backups',
174
+ 'managewp',
175
+ );
176
+
177
+ /**
178
+ * Returns a filterable array of excluded directories and files.
179
+ *
180
+ * @return mixed|void
181
+ */
182
+ public function default_excludes() {
183
+ return apply_filters( 'hmbkp_default_excludes', $this->default_excludes );
184
+ }
185
+
186
  /**
187
  * Check whether safe mode is active or not
188
  *
189
  * @param string $ini_get_callback
190
+ *
191
  * @return bool
192
  */
193
  public static function is_safe_mode_active( $ini_get_callback = 'ini_get' ) {
235
 
236
  protected static function is_function_disabled( $ini_setting ) {
237
 
238
+ if ( array_intersect( array(
239
+ 'shell_exec',
240
+ 'escapeshellarg',
241
+ 'escapeshellcmd'
242
+ ), array_map( 'trim', explode( ',', @ini_get( $ini_setting ) ) ) ) ) {
243
  return false;
244
  }
245
 
273
  * Sanitize a directory path
274
  *
275
  * @param string $dir
276
+ * @param bool $recursive
277
+ *
278
  * @return string
279
  */
280
+ public static function conform_dir( $dir = '/', $recursive = false ) {
 
 
 
 
 
281
 
282
  // Replace single forward slash (looks like double slash because we have to escape it)
283
  $dir = str_replace( '\\', '/', $dir );
358
  public function get_archive_filename() {
359
 
360
  if ( empty( $this->archive_filename ) ) {
361
+ $this->set_archive_filename( implode( '-', array(
362
+ sanitize_title( str_ireplace( array(
363
+ 'http://',
364
+ 'https://',
365
+ 'www'
366
+ ), '', home_url() ) ),
367
+ 'backup',
368
+ current_time( 'Y-m-d-H-i-s' )
369
+ ) ) . '.zip' );
370
  }
371
 
372
  return $this->archive_filename;
377
  * Set the filename of the archive file
378
  *
379
  * @param string $filename
380
+ *
381
  * @return \WP_Error|null
382
  */
383
  public function set_archive_filename( $filename ) {
422
  * Set the filename of the database dump file
423
  *
424
  * @param string $filename
425
+ *
426
  * @return \WP_Error|null
427
  */
428
  public function set_database_dump_filename( $filename ) {
460
  * Set the root directory to backup from
461
  *
462
  * @param string $path
463
+ *
464
  * @return \WP_Error|null
465
  */
466
  public function set_root( $path ) {
486
  * Set the filepath for the existing archive
487
  *
488
  * @param string $existing_archive_filepath
489
+ *
490
  * @return null
491
  */
492
  public function set_existing_archive_filepath( $existing_archive_filepath ) {
541
  * $type must be one of complete, database or file
542
  *
543
  * @param string $type
544
+ *
545
  * @return \WP_Error|null
546
  */
547
  public function set_type( $type ) {
599
  '/xampp/mysql/bin/mysqldump',
600
  '/Program Files/xampp/mysql/bin/mysqldump',
601
  '/Program Files/MySQL/MySQL Server 6.0/bin/mysqldump',
602
+ '/Program Files/MySQL/MySQL Server 5.7/bin/mysqldump',
603
+ '/Program Files/MySQL/MySQL Server 5.6/bin/mysqldump',
604
  '/Program Files/MySQL/MySQL Server 5.5/bin/mysqldump',
605
  '/Program Files/MySQL/MySQL Server 5.4/bin/mysqldump',
606
  '/Program Files/MySQL/MySQL Server 5.1/bin/mysqldump',
611
 
612
  // Find the first one which works
613
  foreach ( $mysqldump_locations as $location ) {
614
+ if ( (is_null( shell_exec( 'hash ' . self::conform_dir( $location ) . ' 2>&1' ) ) ) && @is_executable( self::conform_dir( $location ) ) ) {
615
  $this->set_mysqldump_command_path( $location );
616
  break; // Found one
617
  }
703
  * Both the action and the instance on Backup are then passed to the callback function
704
  *
705
  * @see set_action_callback
706
+ *
707
+ * @param string $action The event to fire
708
  */
709
  protected function do_action( $action ) {
710
 
733
  *
734
  * @see do_action
735
  * @see /do_action
736
+ *
737
  * @param callable $callback The function or method to be called
738
+ * @param int $priority The priority of the callback
739
  */
740
  public function set_action_callback( $callback, $priority = 10 ) {
741
+ $this->action_callback[ $priority ][] = $callback;
742
  }
743
 
744
  /**
772
  */
773
  public function dump_database() {
774
 
775
+ // If we cannot run mysqldump via CLI, fallback to PHP
776
+ if ( is_wp_error( $this->user_can_connect() ) ) {
 
 
 
777
  $this->mysqldump_fallback();
778
+ } else {
779
+ // Attempt mysqldump command
780
+ if ( $this->get_mysqldump_command_path() ) {
781
+ $this->mysqldump();
782
+ }
783
+
784
+ if ( empty( $this->mysqldump_verified ) ) {
785
+ $this->mysqldump_fallback();
786
+ }
787
  }
788
 
789
  $this->do_action( 'hmbkp_mysqldump_finished' );
790
 
791
  }
792
 
793
+ /**
794
+ * Export the database to an .sql file via the command line with mysqldump
795
+ */
796
  public function mysqldump() {
797
 
798
  $this->mysqldump_method = 'mysqldump';
799
 
800
  $this->do_action( 'hmbkp_mysqldump_started' );
801
 
802
+ // Guess port or socket connection type
803
+ $port_or_socket = strstr( DB_HOST, ':' );
804
+
805
+ $host = DB_HOST;
806
+
807
+ if ( ! empty( $port_or_socket ) ) {
808
+
809
+ $host = substr( DB_HOST, 0, strpos( DB_HOST, ':' ) );
810
+
811
+ $port_or_socket = substr( $port_or_socket, 1 );
812
 
813
+ if ( 0 !== strpos( $port_or_socket, '/' ) ) {
814
+
815
+ $port = intval( $port_or_socket );
816
+
817
+ $maybe_socket = strstr( $port_or_socket, ':' );
818
+
819
+ if ( ! empty( $maybe_socket ) ) {
820
+
821
+ $socket = substr( $maybe_socket, 1 );
822
+
823
+ }
824
+
825
+ } else {
826
+
827
+ $socket = $port_or_socket;
828
+
829
+ }
830
+ }
831
 
832
  // Path to the mysqldump executable
833
  $cmd = escapeshellarg( $this->get_mysqldump_command_path() );
836
  $cmd .= ' --no-create-db';
837
 
838
  // Allow lock-tables to be overridden
839
+ if ( ! defined( 'HMBKP_MYSQLDUMP_SINGLE_TRANSACTION' ) || false !== HMBKP_MYSQLDUMP_SINGLE_TRANSACTION ) {
840
  $cmd .= ' --single-transaction';
841
  }
842
 
859
  $cmd .= ' -P ' . $port;
860
  }
861
 
862
+ // Set the socket path
863
+ if ( ! empty( $socket ) && ! is_numeric( $socket ) ) {
864
+ $cmd .= ' --protocol=socket -S ' . $socket;
865
+ }
866
+
867
  // The file we're saving too
868
  $cmd .= ' -r ' . escapeshellarg( $this->get_database_dump_filepath() );
869
 
877
  $stderr = shell_exec( $cmd );
878
 
879
  // Skip the new password warning that is output in mysql > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
880
+ if ( 'Warning: Using a password on the command line interface can be insecure.' === trim( $stderr ) ) {
881
  $stderr = '';
882
+ }
883
 
884
  if ( $stderr ) {
885
  $this->error( $this->get_mysqldump_method(), $stderr );
981
  */
982
  public function zip() {
983
 
 
 
 
 
 
984
  $this->archive_method = 'zip';
985
 
986
  $this->do_action( 'hmbkp_archive_started' );
987
 
988
+ // Add the database dump to the archive
989
+ if ( 'file' !== $this->get_type() && file_exists( $this->get_database_dump_filepath() ) ) {
990
+ $stderr = shell_exec( 'cd ' . escapeshellarg( $this->get_path() ) . ' && ' . escapeshellcmd( $this->get_zip_command_path() ) . ' -q ' . escapeshellarg( $this->get_archive_filepath() ) . ' ' . escapeshellarg( $this->get_database_dump_filename() ) . ' 2>&1' );
991
+ }
992
+
993
  // Zip up $this->root
994
+ if ( 'database' !== $this->get_type() ) {
995
 
996
  // cd to the site root
997
  $command = 'cd ' . escapeshellarg( $this->get_root() );
1019
 
1020
  }
1021
 
 
 
 
 
 
1022
  if ( ! empty( $stderr ) ) {
1023
  $this->warning( $this->get_archive_method(), $stderr );
1024
  }
1074
 
1075
  if ( $file->isDir() ) {
1076
  $zip->addEmptyDir( trailingslashit( str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) ) );
1077
+ } elseif ( $file->isFile() ) {
 
 
1078
  $zip->addFile( $file->getPathname(), str_ireplace( trailingslashit( $this->get_root() ), '', self::conform_dir( $file->getPathname() ) ) );
1079
  }
1080
 
1081
+ if ( ++ $files_added % 500 === 0 ) {
1082
  if ( ! $zip->close() || ! $zip->open( $this->get_archive_filepath(), \ZIPARCHIVE::CREATE ) ) {
1083
  return;
1084
  }
1207
  */
1208
  public function get_files() {
1209
 
1210
+ $found = array();
1211
+
1212
  if ( ! empty( $this->files ) ) {
1213
  return $this->files;
1214
  }
1215
 
1216
+ $finder = new Finder();
1217
+ $finder->followLinks();
1218
+ $finder->ignoreDotFiles( false );
1219
+ $finder->ignoreUnreadableDirs();
1220
+
1221
+ foreach ( $this->default_excludes as $exclude ) {
1222
+ $finder->notPath( $exclude );
1223
+ }
1224
+
1225
+ foreach ( $finder->in( $this->get_root() ) as $entry ) {
1226
+ $this->files[] = $entry;
1227
+ }
1228
 
1229
  return $this->files;
1230
 
1377
  * Set the excludes, expects and array
1378
  *
1379
  * @param Array $excludes
1380
+ * @param Bool $append
1381
  */
1382
  public function set_excludes( $excludes, $append = false ) {
1383
 
1399
  * Takes the exclude rules and formats them for use with either
1400
  * the shell zip command or pclzip
1401
  *
1402
+ * @param string $context . (default: 'zip')
1403
+ *
1404
  * @return string
1405
  */
1406
  public function exclude_string( $context = 'zip' ) {
1415
  $separator = ' -x ';
1416
 
1417
  // The PclZip fallback library
1418
+ } elseif ( $context === 'regex' ) {
 
1419
  $wildcard = '([\s\S]*?)';
1420
  $separator = '|';
1421
  }
1429
  // Files don't end with /
1430
  if ( ! in_array( substr( $rule, - 1 ), array( '\\', '/' ) ) ) {
1431
  $file = true;
1432
+ } // If rule starts with a / then treat as absolute path
 
 
1433
  elseif ( in_array( substr( $rule, 0, 1 ), array( '\\', '/' ) ) ) {
1434
  $absolute = true;
1435
+ } // Otherwise treat as dir fragment
 
 
1436
  else {
1437
  $fragment = true;
1438
  }
1492
  * Add backquotes to tables and db-names in SQL queries. Taken from phpMyAdmin.
1493
  *
1494
  * @param mixed $a_name
1495
+ *
1496
  * @return array|string
1497
  */
1498
  private function sql_backquote( $a_name ) {
1506
  reset( $a_name );
1507
 
1508
  while ( list( $key, $val ) = each( $a_name ) ) {
1509
+ $result[ $key ] = '`' . $val . '`';
1510
  }
1511
 
1512
  return $result;
1575
  $result = mysql_query( $query, $this->db );
1576
 
1577
  $fields_cnt = 0;
1578
+ $rows_cnt = 0;
1579
 
1580
  if ( $result ) {
1581
  $fields_cnt = mysql_num_fields( $result );
1594
  // Checks whether the field is an integer or not
1595
  for ( $j = 0; $j < $fields_cnt; $j ++ ) {
1596
 
1597
+ $field_set[ $j ] = $this->sql_backquote( mysql_field_name( $result, $j ) );
1598
+ $type = mysql_field_type( $result, $j );
1599
 
1600
  if ( $type === 'tinyint' || $type === 'smallint' || $type === 'mediumint' || $type === 'int' || $type === 'bigint' ) {
1601
+ $field_num[ $j ] = true;
1602
  } else {
1603
+ $field_num[ $j ] = false;
1604
  }
1605
 
1606
  }
1621
  // build the statement
1622
  for ( $j = 0; $j < $fields_cnt; $j ++ ) {
1623
 
1624
+ if ( ! isset( $row[ $j ] ) ) {
1625
  $values[] = 'NULL';
1626
 
1627
+ } elseif ( $row[ $j ] === '0' || $row[ $j ] !== '' ) {
 
1628
 
1629
  // a number
1630
+ if ( $field_num[ $j ] ) {
1631
+ $values[] = $row[ $j ];
1632
  } else {
1633
+ $values[] = "'" . str_replace( $search, $replace, $this->sql_addslashes( $row[ $j ] ) ) . "'";
1634
  }
1635
 
1636
  } else {
1672
  * Taken from phpMyAdmin.
1673
  *
1674
  * @param string $a_string (default: '')
1675
+ * @param bool $is_like (default: false)
1676
+ *
1677
  * @return mixed
1678
  */
1679
  private function sql_addslashes( $a_string = '', $is_like = false ) {
1693
  * Write the SQL file
1694
  *
1695
  * @param string $sql
1696
+ *
1697
  * @return null|boolean
1698
  */
1699
  private function write_sql( $sql ) {
1726
  public function get_errors( $context = null ) {
1727
 
1728
  if ( ! empty( $context ) ) {
1729
+ return isset( $this->errors[ $context ] ) ? $this->errors[ $context ] : array();
1730
  }
1731
 
1732
  return $this->errors;
1737
  * Add an error to the errors stack
1738
  *
1739
  * @param string $context
1740
+ * @param mixed $error
1741
  */
1742
  public function error( $context, $error ) {
1743
 
1747
 
1748
  $this->do_action( 'hmbkp_error' );
1749
 
1750
+ $this->errors[ $context ][ $_key = md5( implode( ':', (array) $error ) ) ] = $error;
1751
 
1752
  }
1753
 
1771
  }
1772
 
1773
  if ( $context ) {
1774
+ unset( $this->errors[ $context ] );
1775
+ } else {
 
 
1776
  $this->errors = array();
1777
  }
1778
 
1785
  public function get_warnings( $context = null ) {
1786
 
1787
  if ( ! empty( $context ) ) {
1788
+ return isset( $this->warnings[ $context ] ) ? $this->warnings[ $context ] : array();
1789
  }
1790
 
1791
  return $this->warnings;
1796
  * Add an warning to the warnings stack
1797
  *
1798
  * @param string $context
1799
+ * @param mixed $warning
1800
  */
1801
  private function warning( $context, $warning ) {
1802
 
1806
 
1807
  $this->do_action( 'hmbkp_warning' );
1808
 
1809
+ $this->warnings[ $context ][ $_key = md5( implode( ':', (array) $warning ) ) ] = $warning;
1810
 
1811
  }
1812
 
1814
  * Custom error handler for catching php errors
1815
  *
1816
  * @param $type
1817
+ *
1818
  * @return bool
1819
  */
1820
  public function error_handler( $type ) {
1834
 
1835
  }
1836
 
1837
+ /**
1838
+ * Determine if user can connect via the CLI
1839
+ *
1840
+ * @return \WP_Error
1841
+ */
1842
+ public function user_can_connect() {
1843
+
1844
+ // mysql --host=localhost --user=myname --password=mypass mydb
1845
+
1846
+ $user = escapeshellarg( DB_USER );
1847
+
1848
+ $pwd = escapeshellarg( DB_PASSWORD );
1849
+
1850
+ $host = escapeshellarg( DB_HOST );
1851
+
1852
+ $db = escapeshellarg( DB_NAME );
1853
+
1854
+ $cmd = "mysql --host={$host} --user={$user} --password={$pwd} {$db}";
1855
+
1856
+ // Pipe STDERR to STDOUT
1857
+ $cmd .= ' 2>&1';
1858
+
1859
+ // Store any returned data in an error
1860
+ $stderr = shell_exec( $cmd );
1861
+
1862
+ // Skip the new password warning that is output in mysql > 5.6 (@see http://bugs.mysql.com/bug.php?id=66546)
1863
+ if ( 'Warning: Using a password on the command line interface can be insecure.' === trim( $stderr ) ) {
1864
+ $stderr = '';
1865
+ }
1866
+
1867
+ if ( $stderr ) {
1868
+ return new \WP_Error( 'connection-error', $stderr );
1869
+ }
1870
+
1871
+ }
1872
+
1873
  }
1874
 
1875
  }
1884
  * of the zip
1885
  *
1886
  * @param string $event
1887
+ * @param array $file
1888
+ *
1889
  * @return bool
1890
  */
1891
  function hmbkp_pclzip_callback( $event, $file ) {
1895
  // Don't try to add unreadable files.
1896
  if ( ! is_readable( $file['filename'] ) || ! file_exists( $file['filename'] ) ) {
1897
  return false;
1898
+ } // Match everything else past the exclude list
 
 
1899
  elseif ( $_hmbkp_exclude_string && preg_match( '(' . $_hmbkp_exclude_string . ')', $file['stored_filename'] ) ) {
1900
  return false;
1901
  }
classes/class-plugin.php ADDED
@@ -0,0 +1,407 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ namespace HM\BackUpWordPress;
4
+
5
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-setup.php' );
6
+
7
+ register_activation_hook( __FILE__, array( 'HM\BackUpWordPress\Setup', 'activate' ) );
8
+ register_deactivation_hook( __FILE__, array( 'HM\BackUpWordPress\Setup', 'deactivate' ) );
9
+
10
+ /**
11
+ * Class Plugin
12
+ */
13
+ final class Plugin {
14
+
15
+ const PLUGIN_VERSION = '3.2.0';
16
+
17
+ /**
18
+ * @var Plugin The singleton instance.
19
+ */
20
+ private static $instance;
21
+
22
+ /**
23
+ * Instantiates a new Plugin object.
24
+ */
25
+ private function __construct() {
26
+ add_action( 'plugins_loaded', array( $this, 'plugins_loaded' ) );
27
+ }
28
+
29
+ /**
30
+ * Insures we always return the same object.
31
+ *
32
+ * @return Plugin
33
+ */
34
+ public static function get_instance() {
35
+
36
+ if ( ! ( self::$instance instanceof Plugin ) ) {
37
+ self::$instance = new Plugin();
38
+ }
39
+
40
+ return self::$instance;
41
+ }
42
+
43
+ /**
44
+ * Initialize the plugin.
45
+ */
46
+ public function plugins_loaded() {
47
+
48
+ if ( true !== $this->maybe_self_deactivate() ) {
49
+
50
+ $this->constants();
51
+
52
+ $this->includes();
53
+
54
+ $this->hooks();
55
+
56
+ $this->text_domain();
57
+
58
+ // If we get here, then BWP is loaded
59
+ do_action( 'backupwordpress_loaded' );
60
+
61
+ }
62
+
63
+ }
64
+
65
+ /**
66
+ * Check plugin requirements.
67
+ *
68
+ * @return bool True is fails requirements. False otherwise.
69
+ */
70
+ public function maybe_self_deactivate() {
71
+
72
+ if ( false === Setup::meets_requirements() ) {
73
+
74
+ add_action( 'admin_init', array( 'HM\BackUpWordPress\Setup', 'self_deactivate' ) );
75
+
76
+ add_action( 'admin_notices', array( 'HM\BackUpWordPress\Setup', 'display_admin_notices' ) );
77
+
78
+ return true;
79
+
80
+ }
81
+
82
+ return false;
83
+
84
+ }
85
+
86
+ /**
87
+ * Define all the constants.
88
+ */
89
+ public function constants() {
90
+
91
+ if ( ! defined( 'HMBKP_PLUGIN_SLUG' ) ) {
92
+ define( 'HMBKP_PLUGIN_SLUG', dirname( HMBKP_BASENAME ) );
93
+ }
94
+
95
+ if ( ! defined( 'HMBKP_PLUGIN_URL' ) ) {
96
+ define( 'HMBKP_PLUGIN_URL', plugin_dir_url( HMBKP_BASENAME ) );
97
+ }
98
+
99
+ if ( ! defined( 'HMBKP_PLUGIN_LANG_DIR' ) ) {
100
+ define( 'HMBKP_PLUGIN_LANG_DIR', apply_filters( 'hmbkp_filter_lang_dir', HMBKP_PLUGIN_SLUG . '/languages/' ) );
101
+ }
102
+
103
+ if ( ! defined( 'HMBKP_ADMIN_URL' ) ) {
104
+ $page = is_multisite() ? network_admin_url( 'settings.php' ) : admin_url( 'tools.php' );
105
+ define( 'HMBKP_ADMIN_URL', add_query_arg( 'page', HMBKP_PLUGIN_SLUG, $page ) );
106
+ }
107
+
108
+ if ( ! defined( 'HMBKP_ADMIN_PAGE' ) ) {
109
+ $prefix = is_multisite() ? 'settings_page_' : 'tools_page_';
110
+ define( 'HMBKP_ADMIN_PAGE', $prefix . HMBKP_PLUGIN_SLUG );
111
+ }
112
+
113
+ define( 'HMBKP_SECURE_KEY', $this->generate_key() );
114
+
115
+ }
116
+
117
+ /**
118
+ * Load all BackUpWordPress functions.
119
+ */
120
+ protected function includes() {
121
+
122
+ require_once( HMBKP_PLUGIN_PATH . 'vendor/autoload.php' );
123
+
124
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-notices.php' );
125
+
126
+ // Load the admin menu
127
+ require_once( HMBKP_PLUGIN_PATH . 'admin/menu.php' );
128
+ require_once( HMBKP_PLUGIN_PATH . 'admin/actions.php' );
129
+
130
+ // Load Backdrop if necessary.
131
+ if ( ! class_exists( 'HM_Backdrop_Task' ) ) {
132
+ require_once( HMBKP_PLUGIN_PATH . 'backdrop/hm-backdrop.php' );
133
+ }
134
+
135
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirements.php' );
136
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-requirement.php' );
137
+
138
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-path.php' );
139
+
140
+ // Load the core backup class
141
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-backup.php' );
142
+
143
+ // Load the backup scheduling classes
144
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-schedule.php' );
145
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-schedules.php' );
146
+
147
+ // Load the core functions
148
+ require_once( HMBKP_PLUGIN_PATH . 'functions/core.php' );
149
+ require_once( HMBKP_PLUGIN_PATH . 'functions/interface.php' );
150
+
151
+ // Load the services
152
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-services.php' );
153
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-service.php' );
154
+
155
+ // Load the email service
156
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-email-service.php' );
157
+
158
+ // Load the webhook services
159
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-webhook-service.php' );
160
+ require_once( HMBKP_PLUGIN_PATH . 'classes/class-wpremote-webhook-service.php' );
161
+
162
+ require_once( HMBKP_PLUGIN_PATH . 'classes/deprecated.php' );
163
+
164
+ // Load the wp cli command
165
+ if ( defined( 'WP_CLI' ) && WP_CLI ) {
166
+ include( HMBKP_PLUGIN_PATH . 'classes/class-backupwordpress-wp-cli-command.php' );
167
+ }
168
+
169
+ }
170
+
171
+ /**
172
+ * Hook into WordPress page lifecycle and execute BackUpWordPress functions.
173
+ */
174
+ public function hooks() {
175
+
176
+ add_action( 'activated_plugin', array( $this, 'load_first' ) );
177
+
178
+ add_action( 'admin_init', array( $this, 'upgrade' ) );
179
+
180
+ add_action( 'admin_init', array( $this, 'init' ) );
181
+
182
+ add_action( 'hmbkp_schedule_hook', array( $this, 'schedule_hook_run' ) );
183
+
184
+ add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
185
+
186
+ add_action( 'admin_footer-' . HMBKP_ADMIN_PAGE, array( $this, 'load_intercom_script' ) );
187
+
188
+ add_action( 'admin_enqueue_scripts', array( $this, 'styles' ) );
189
+
190
+ }
191
+
192
+ /**
193
+ * Load the Javascript in the admin.
194
+ *
195
+ * @param $hook The name of the admin page hook.
196
+ */
197
+ public function scripts( $hook ) {
198
+
199
+ if ( HMBKP_ADMIN_PAGE !== $hook ) {
200
+ return;
201
+ }
202
+
203
+ $js_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.min.js';
204
+
205
+ // TODO shuold this also support WP_SCRIPT_DEBUG
206
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
207
+ $js_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.js';
208
+ }
209
+
210
+ wp_enqueue_script( 'hmbkp', $js_file, array( 'heartbeat' ), sanitize_key( self::PLUGIN_VERSION ) );
211
+
212
+ wp_localize_script(
213
+ 'hmbkp',
214
+ 'hmbkp',
215
+ array(
216
+ 'page_slug' => HMBKP_PLUGIN_SLUG,
217
+ 'nonce' => wp_create_nonce( 'hmbkp_nonce' ),
218
+ 'hmbkp_run_schedule_nonce' => wp_create_nonce( 'hmbkp_run_schedule' ),
219
+ 'update' => __( 'Update', 'backupwordpress' ),
220
+ 'cancel' => __( 'Cancel', 'backupwordpress' ),
221
+ 'delete_schedule' => __( 'Are you sure you want to delete this schedule? All of it\'s backups will also be deleted.', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
222
+ 'delete_backup' => __( 'Are you sure you want to delete this backup?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
223
+ 'remove_exclude_rule' => __( 'Are you sure you want to remove this exclude rule?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n",
224
+ 'remove_old_backups' => __( 'Reducing the number of backups that are stored on this server will cause some of your existing backups to be deleted, are you sure that\'s what you want?', 'backupwordpress' ) . "\n\n" . __( '\'Cancel\' to go back, \'OK\' to delete.', 'backupwordpress' ) . "\n"
225
+ )
226
+ );
227
+
228
+ }
229
+
230
+ /**
231
+ * Loads the plugin text domain for translation.
232
+ * This setup allows a user to just drop his custom translation files into the WordPress language directory
233
+ * Files will need to be in a subdirectory with the name of the textdomain 'backupwordpress'
234
+ */
235
+ public function text_domain() {
236
+
237
+ // Set unique textdomain string
238
+ $textdomain = 'backupwordpress';
239
+
240
+ // The 'plugin_locale' filter is also used by default in load_plugin_textdomain()
241
+ $locale = apply_filters( 'plugin_locale', get_locale(), $textdomain );
242
+
243
+ // Set filter for WordPress languages directory
244
+ $hmbkp_wp_lang_dir = apply_filters( 'hmbkp_do_filter_wp_lang_dir', trailingslashit( WP_LANG_DIR ) . trailingslashit( $textdomain ) . $textdomain . '-' . $locale . '.mo' );
245
+
246
+ // Translations: First, look in WordPress' "languages" folder = custom & update-secure!
247
+ load_textdomain( $textdomain, $hmbkp_wp_lang_dir );
248
+
249
+ // Translations: Secondly, look in plugin's "languages" folder = default
250
+ load_plugin_textdomain( $textdomain, false, HMBKP_PLUGIN_LANG_DIR );
251
+
252
+ }
253
+
254
+ /**
255
+ * Determine if we need to run an upgrade routine.
256
+ */
257
+ public function upgrade() {
258
+
259
+ // Fire the update action
260
+ if ( self::PLUGIN_VERSION != get_option( 'hmbkp_plugin_version' ) ) {
261
+ hmbkp_update();
262
+ }
263
+
264
+ }
265
+
266
+ /**
267
+ * Runs on every admin page load
268
+ */
269
+ public function init() {
270
+
271
+ // If we have multiple paths for some reason then clean them up
272
+ Path::get_instance()->merge_existing_paths();
273
+ }
274
+
275
+ /**
276
+ * Generate a unique key.
277
+ *
278
+ * @return string
279
+ */
280
+ protected function generate_key() {
281
+
282
+ $key = array( ABSPATH, time() );
283
+ $constants = array( 'AUTH_KEY', 'SECURE_AUTH_KEY', 'LOGGED_IN_KEY', 'NONCE_KEY', 'AUTH_SALT', 'SECURE_AUTH_SALT', 'LOGGED_IN_SALT', 'NONCE_SALT', 'SECRET_KEY' );
284
+
285
+ foreach ( $constants as $constant ) {
286
+ if ( defined( $constant ) ) {
287
+ $key[] = constant( $constant );
288
+ }
289
+ }
290
+
291
+ shuffle( $key );
292
+
293
+ return md5( serialize( $key ) );
294
+
295
+ }
296
+
297
+ /**
298
+ * Ensure BackUpWordPress is loaded before add-ons, changes the order of the serialized values in the DB field.
299
+ */
300
+ public function load_first() {
301
+
302
+ $active_plugins = get_option( 'active_plugins' );
303
+
304
+ $plugin_path = plugin_basename( __FILE__ );
305
+
306
+ $key = array_search( $plugin_path, $active_plugins );
307
+
308
+ if ( $key > 0 ) {
309
+
310
+ array_splice( $active_plugins, $key, 1 );
311
+
312
+ array_unshift( $active_plugins, $plugin_path );
313
+
314
+ update_option( 'active_plugins', $active_plugins );
315
+
316
+ }
317
+
318
+ }
319
+
320
+ /**
321
+ * Function to run when the schedule cron fires.
322
+ *
323
+ * @param $schedule_id
324
+ */
325
+ public function schedule_hook_run( $schedule_id ) {
326
+
327
+ if ( ! hmbkp_possible() ) {
328
+ return;
329
+ }
330
+
331
+ $schedules = Schedules::get_instance();
332
+ $schedule = $schedules->get_schedule( $schedule_id );
333
+
334
+ if ( ! $schedule ) {
335
+ return;
336
+ }
337
+
338
+ $schedule->run();
339
+
340
+ }
341
+
342
+ /**
343
+ * Enqueue the plugin styles.
344
+ *
345
+ * @param $hook
346
+ */
347
+ public function styles( $hook ) {
348
+
349
+ if ( HMBKP_ADMIN_PAGE !== $hook ) {
350
+ return;
351
+ }
352
+
353
+ $css_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.min.css';
354
+
355
+ if ( WP_DEBUG ) {
356
+ $css_file = HMBKP_PLUGIN_URL . 'assets/hmbkp.css';
357
+ }
358
+
359
+ wp_enqueue_style( 'backupwordpress', $css_file, false, sanitize_key( self::PLUGIN_VERSION ) );
360
+
361
+ }
362
+
363
+ /**
364
+ * Load Intercom and send across user information and server info. Only loaded if the user has opted in.
365
+ *
366
+ * @param $hook
367
+ */
368
+ public function load_intercom_script() {
369
+
370
+ if ( ! get_option( 'hmbkp_enable_support' ) ) {
371
+ return;
372
+ }
373
+
374
+ $info = array();
375
+
376
+ foreach ( Requirements::get_requirement_groups() as $group ) {
377
+ foreach ( Requirements::get_requirements( $group ) as $requirement ) {
378
+ $info[ $requirement->name() ] = $requirement->result();
379
+ }
380
+ }
381
+
382
+ foreach ( Services::get_services() as $file => $service ) {
383
+ array_merge( $info, call_user_func( array( $service, 'intercom_data' ) ) );
384
+ }
385
+
386
+ $current_user = wp_get_current_user();
387
+
388
+ $info['user_hash'] = hash_hmac( 'sha256', $current_user->user_email, 'fcUEt7Vi4ym5PXdcr2UNpGdgZTEvxX9NJl8YBTxK' );
389
+ $info['email'] = $current_user->user_email;
390
+ $info['created_at'] = strtotime( $current_user->user_registered );
391
+ $info['app_id'] = '7f1l4qyq';
392
+ $info['name'] = $current_user->display_name;
393
+ $info['widget'] = array( 'activator' => '#intercom' ); ?>
394
+
395
+ <script id="IntercomSettingsScriptTag">
396
+ window.intercomSettings = <?php echo json_encode( $info ); ?>;
397
+ </script>
398
+ <script>!function(){function e(){var a=c.createElement("script");a.type="text/javascript",a.async=!0,a.src="https://static.intercomcdn.com/intercom.v1.js";var b=c.getElementsByTagName("script")[0];b.parentNode.insertBefore(a,b)}var a=window,b=a.Intercom;if("function"==typeof b)b("reattach_activator"),b("update",intercomSettings);else{var c=document,d=function(){d.c(arguments)};d.q=[],d.c=function(a){d.q.push(a)},a.Intercom=d,a.attachEvent?a.attachEvent("onload",e):a.addEventListener("load",e,!1)}}();</script>
399
+
400
+ <?php }
401
+
402
+ }
403
+
404
+ if ( is_multisite() && ! is_main_site() ) {
405
+ return;
406
+ }
407
+ Plugin::get_instance();
classes/class-schedule.php CHANGED
@@ -2,6 +2,8 @@
2
 
3
  namespace HM\BackUpWordPress;
4
 
 
 
5
  /**
6
  * The Backup Scheduler
7
  *
@@ -69,14 +71,26 @@ class Scheduled_Backup {
69
  $this->backup = new Backup();
70
 
71
  // Set the archive filename to site name + schedule slug + date
72
- $this->backup->set_archive_filename( implode( '-', array( sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ), $this->get_id(), $this->get_type(), current_time( 'Y-m-d-H-i-s' ) ) ) . '.zip' );
73
-
74
- $this->backup->set_database_dump_filename( implode( '-', array( 'database', sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ), $this->get_id() ) ) . '.sql' );
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  $this->backup->set_type( $this->get_type() );
77
- $this->backup->set_excludes( $this->default_excludes(), true );
78
  $this->backup->set_excludes( $this->get_excludes() );
79
-
80
  $this->backup->set_action_callback( array( $this, 'do_action' ) );
81
 
82
  if ( defined( 'HMBKP_SCHEDULE_START_TIME' ) && strtotime( 'HMBKP_SCHEDULE_START_TIME' ) ) {
@@ -301,7 +315,7 @@ class Scheduled_Backup {
301
 
302
  $size = 0;
303
 
304
- // Don't include database if file only
305
  if ( 'file' !== $this->get_type() ) {
306
 
307
  global $wpdb;
@@ -313,12 +327,12 @@ class Scheduled_Backup {
313
  }
314
  }
315
 
316
- // Don't include files if database only
317
  if ( 'database' !== $this->get_type() ) {
318
 
319
  $root = new \SplFileInfo( $this->backup->get_root() );
320
 
321
- $size += $this->filesize( $root, true );
322
 
323
  }
324
 
@@ -373,56 +387,49 @@ class Scheduled_Backup {
373
  return $files;
374
  }
375
 
376
- $handle = opendir( $directory );
377
 
378
- if ( ! $handle ) {
379
- return $files;
380
  }
381
 
382
- while ( $file_handle = readdir( $handle ) ) {
383
 
384
- // Ignore current dir and containing dir
385
- if ( '.' === $file_handle || '..' === $file_handle ) {
386
- continue;
387
- }
388
-
389
- $file = new \SplFileInfo( Backup::conform_dir( trailingslashit( $directory ) . $file_handle ) );
390
 
391
- // Unreadable files are moved to the bottom
392
- if ( ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
393
- $unreadable_files[] = $file;
394
- continue;
395
- }
396
 
 
 
397
  // Get the total filesize for each file and directory
398
- $filesize = $this->filesize( $file );
399
 
400
  if ( $filesize ) {
401
 
402
  // If there is already a file with exactly the same filesize then let's keep increasing the filesize of this one until we don't have a clash
403
  while ( array_key_exists( $filesize, $files_with_size ) ) {
404
- $filesize++;
405
  }
406
 
407
- $files_with_size[ $filesize ] = $file;
408
 
409
  } elseif ( 0 === $filesize ) {
410
 
411
- $empty_files[] = $file;
412
 
413
  } else {
414
 
415
- $files_with_no_size[] = $file;
416
 
417
  }
418
-
419
  }
420
 
421
- closedir( $handle );
422
-
423
- // Sort files largest first
424
- krsort( $files_with_size );
425
-
426
  // Add 0 byte files / directories to the bottom
427
  $files = $files_with_size + array_merge( $empty_files, $unreadable_files );
428
 
@@ -430,8 +437,8 @@ class Scheduled_Backup {
430
  if ( $files_with_no_size ) {
431
 
432
  // We have to loop as merging or concatenating the array would re-flow the keys which we don't want because the filesize is stored in the key
433
- foreach ( $files_with_no_size as $file ) {
434
- array_unshift( $files, $file );
435
  }
436
  }
437
 
@@ -460,20 +467,21 @@ class Scheduled_Backup {
460
 
461
  }
462
 
463
- $directory_sizes[ $this->backup->get_root() ] = filesize( $this->backup->get_root() );
464
-
465
  $files = $this->backup->get_files();
466
 
467
  foreach ( $files as $file ) {
468
 
469
  if ( $file->isReadable() ) {
470
- $directory_sizes[ Backup::conform_dir( $file->getPathname() ) ] = $file->getSize();
471
  } else {
472
- $directory_sizes[ Backup::conform_dir( $file->getPathname() ) ] = 0;
473
  }
474
 
475
  }
476
 
 
 
 
477
  set_transient( 'hmbkp_directory_filesizes', $directory_sizes, DAY_IN_SECONDS );
478
 
479
  delete_transient( 'hmbkp_directory_filesizes_running' );
@@ -488,14 +496,15 @@ class Scheduled_Backup {
488
  * If $file is a file then just return the result of `filesize()`.
489
  * If $file is a directory then schedule a recursive filesize scan.
490
  *
491
- * @param \SplFileInfo $file The file or directory you want to know the size of
492
- * @param bool $skip_excluded_files Skip excluded files when calculating a directories total size
493
- * @return int The total of the file or directory
 
494
  */
495
  public function filesize( \SplFileInfo $file, $skip_excluded_files = false ) {
496
 
497
  // Skip missing or unreadable files
498
- if ( ! file_exists( $file->getPathname() ) || ! @realpath( $file->getPathname() ) || ! $file->isReadable() ) {
499
  return false;
500
  }
501
 
@@ -527,8 +536,12 @@ class Scheduled_Backup {
527
 
528
  }
529
 
 
 
 
 
530
  $current_pathname = trailingslashit( $file->getPathname() );
531
- $root = trailingslashit( $this->backup->get_root() );
532
 
533
  foreach ( $directory_sizes as $path => $size ) {
534
 
@@ -837,6 +850,7 @@ class Scheduled_Backup {
837
  * Set the status of the running backup
838
  *
839
  * @param string $message
 
840
  * @return null
841
  */
842
  public function set_status( $message ) {
@@ -1011,7 +1025,7 @@ class Scheduled_Backup {
1011
 
1012
  $duration = 'Unknown';
1013
 
1014
- if ( ! isset( $this->options['duration_total'] ) || ! isset( $this->options['backup_run_count'] ) ) {
1015
  return $duration;
1016
  }
1017
 
@@ -1167,82 +1181,5 @@ class Scheduled_Backup {
1167
 
1168
  }
1169
 
1170
- /**
1171
- * Sets the default excluded folders fr a schedule
1172
- *
1173
- * @return Array
1174
- */
1175
- public function default_excludes() {
1176
-
1177
- $excluded = array();
1178
-
1179
- // Leftover backup folders can be either under content dir, or under the uploads dir
1180
- $hmn_upload_dir = wp_upload_dir();
1181
-
1182
- $backupwp_folders = $this->find_backup_folders( 'backwpup-', $hmn_upload_dir['path'] );
1183
-
1184
- if ( ! empty( $backupwp_folders ) ) {
1185
- foreach ( $backupwp_folders as $path ) {
1186
- $excluded[] = $path;
1187
- }
1188
- }
1189
-
1190
- $blacklisted = array(
1191
- 'updraft' => trailingslashit( WP_CONTENT_DIR ) . trailingslashit( 'updraft' ),
1192
- 'wponlinebckp' => trailingslashit( WP_CONTENT_DIR ) . trailingslashit( 'backups' ),
1193
- 'duplicator' => trailingslashit( ABSPATH ) . trailingslashit( 'wp-snapshots' ),
1194
- 'backupbuddy' => trailingslashit( $hmn_upload_dir['path'] ) . trailingslashit( 'backupbuddy_backups' ),
1195
- 'pb_backupbuddy' => trailingslashit( $hmn_upload_dir['path'] ) . trailingslashit( 'pb_backupbuddy' ),
1196
- 'wpdbmanager' => trailingslashit( WP_CONTENT_DIR ) . trailingslashit( 'backup-db' ),
1197
- 'supercache' => trailingslashit( WP_CONTENT_DIR ) . trailingslashit( 'cache' ),
1198
- );
1199
-
1200
- foreach ( $blacklisted as $key => $path ) {
1201
- if ( is_dir( $path ) ) {
1202
- $excluded[] = $path;
1203
- }
1204
- }
1205
-
1206
- // version control dirs
1207
- // @todo stop excluding these once they are skipped entirely
1208
- $excluded[] = '.svn/';
1209
- $excluded[] = '.git/';
1210
-
1211
- return apply_filters( 'hmbkp_default_excludes', $excluded );
1212
- }
1213
-
1214
-
1215
- /**
1216
- * Returns an array of other backup folders in the specified directory
1217
- *
1218
- * @param $needle
1219
- * @param $haystack
1220
- *
1221
- * @return array
1222
- */
1223
- protected function find_backup_folders( $needle, $haystack ) {
1224
-
1225
- $found_folders = array();
1226
-
1227
- // @todo can be simplified
1228
- $folders_to_search = glob( $haystack . '/*', GLOB_ONLYDIR | GLOB_NOSORT );
1229
-
1230
- if ( ! empty( $folders_to_search ) ) {
1231
-
1232
- foreach ( $folders_to_search as $folder ) {
1233
-
1234
- $pos = strpos( $folder, $needle );
1235
-
1236
- if ( false !== $pos ) {
1237
- $found_folders[] = trailingslashit( $folder );
1238
- }
1239
-
1240
- }
1241
-
1242
- }
1243
-
1244
- return $found_folders;
1245
-
1246
- }
1247
-
1248
  }
 
2
 
3
  namespace HM\BackUpWordPress;
4
 
5
+ use Symfony\Component\Finder\Finder;
6
+
7
  /**
8
  * The Backup Scheduler
9
  *
71
  $this->backup = new Backup();
72
 
73
  // Set the archive filename to site name + schedule slug + date
74
+ $this->backup->set_archive_filename( implode( '-', array(
75
+ sanitize_title( str_ireplace( array(
76
+ 'http://',
77
+ 'https://',
78
+ 'www'
79
+ ), '', home_url() ) ),
80
+ $this->get_id(),
81
+ $this->get_type(),
82
+ current_time( 'Y-m-d-H-i-s' )
83
+ ) ) . '.zip' );
84
+
85
+ $this->backup->set_database_dump_filename( implode( '-', array(
86
+ 'database',
87
+ sanitize_title( str_ireplace( array( 'http://', 'https://', 'www' ), '', home_url() ) ),
88
+ $this->get_id()
89
+ ) ) . '.sql' );
90
 
91
  $this->backup->set_type( $this->get_type() );
92
+ $this->backup->set_excludes( $this->backup->default_excludes(), true );
93
  $this->backup->set_excludes( $this->get_excludes() );
 
94
  $this->backup->set_action_callback( array( $this, 'do_action' ) );
95
 
96
  if ( defined( 'HMBKP_SCHEDULE_START_TIME' ) && strtotime( 'HMBKP_SCHEDULE_START_TIME' ) ) {
315
 
316
  $size = 0;
317
 
318
+ // Include database size except for file only schedule.
319
  if ( 'file' !== $this->get_type() ) {
320
 
321
  global $wpdb;
327
  }
328
  }
329
 
330
+ // Include total size of dirs/files except for database only schedule.
331
  if ( 'database' !== $this->get_type() ) {
332
 
333
  $root = new \SplFileInfo( $this->backup->get_root() );
334
 
335
+ $size += $this->filesize( $root );
336
 
337
  }
338
 
387
  return $files;
388
  }
389
 
390
+ $found = array();
391
 
392
+ if ( ! empty( $this->files ) ) {
393
+ return $this->files;
394
  }
395
 
396
+ $default_excludes = $this->backup->default_excludes();
397
 
398
+ $finder = new Finder();
399
+ $finder->ignoreDotFiles( false );
400
+ $finder->ignoreUnreadableDirs();
401
+ $finder->followLinks();
402
+ $finder->depth( '== 0' );
 
403
 
404
+ foreach ( $default_excludes as $exclude ) {
405
+ $finder->notPath( $exclude );
406
+ }
 
 
407
 
408
+ foreach ( $finder->in( $directory ) as $entry ) {
409
+ $files[] = $entry;
410
  // Get the total filesize for each file and directory
411
+ $filesize = $this->filesize( $entry );
412
 
413
  if ( $filesize ) {
414
 
415
  // If there is already a file with exactly the same filesize then let's keep increasing the filesize of this one until we don't have a clash
416
  while ( array_key_exists( $filesize, $files_with_size ) ) {
417
+ $filesize ++;
418
  }
419
 
420
+ $files_with_size[ $filesize ] = $entry;
421
 
422
  } elseif ( 0 === $filesize ) {
423
 
424
+ $empty_files[] = $entry;
425
 
426
  } else {
427
 
428
+ $files_with_no_size[] = $entry;
429
 
430
  }
 
431
  }
432
 
 
 
 
 
 
433
  // Add 0 byte files / directories to the bottom
434
  $files = $files_with_size + array_merge( $empty_files, $unreadable_files );
435
 
437
  if ( $files_with_no_size ) {
438
 
439
  // We have to loop as merging or concatenating the array would re-flow the keys which we don't want because the filesize is stored in the key
440
+ foreach ( $files_with_no_size as $entry ) {
441
+ array_unshift( $files, $entry );
442
  }
443
  }
444
 
467
 
468
  }
469
 
 
 
470
  $files = $this->backup->get_files();
471
 
472
  foreach ( $files as $file ) {
473
 
474
  if ( $file->isReadable() ) {
475
+ $directory_sizes[ Backup::conform_dir( $file->getRealpath() ) ] = $file->getSize();
476
  } else {
477
+ $directory_sizes[ Backup::conform_dir( $file->getRealpath() ) ] = 0;
478
  }
479
 
480
  }
481
 
482
+ // This will be the total size of the included folders MINUS default excludes.
483
+ $directory_sizes[ $this->backup->get_root() ] = array_sum( $directory_sizes );
484
+
485
  set_transient( 'hmbkp_directory_filesizes', $directory_sizes, DAY_IN_SECONDS );
486
 
487
  delete_transient( 'hmbkp_directory_filesizes_running' );
496
  * If $file is a file then just return the result of `filesize()`.
497
  * If $file is a directory then schedule a recursive filesize scan.
498
  *
499
+ * @param \SplFileInfo $file The file or directory you want to know the size of
500
+ * @param bool $skip_excluded_files Skip excluded files when calculating a directories total size
501
+ *
502
+ * @return int The total of the file or directory
503
  */
504
  public function filesize( \SplFileInfo $file, $skip_excluded_files = false ) {
505
 
506
  // Skip missing or unreadable files
507
+ if ( ! file_exists( $file->getPathname() ) || ! $file->getRealpath() || ! $file->isReadable() ) {
508
  return false;
509
  }
510
 
536
 
537
  }
538
 
539
+ if ( $this->backup->get_root() === $file->getPathname() ) {
540
+ return $directory_sizes[ $file->getPathname() ];
541
+ }
542
+
543
  $current_pathname = trailingslashit( $file->getPathname() );
544
+ $root = trailingslashit( $this->backup->get_root() );
545
 
546
  foreach ( $directory_sizes as $path => $size ) {
547
 
850
  * Set the status of the running backup
851
  *
852
  * @param string $message
853
+ *
854
  * @return null
855
  */
856
  public function set_status( $message ) {
1025
 
1026
  $duration = 'Unknown';
1027
 
1028
+ if ( ! isset( $this->options['duration_total'] ) || ! isset( $this->options['backup_run_count'] ) ) {
1029
  return $duration;
1030
  }
1031
 
1181
 
1182
  }
1183
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1184
  }
1185
+
classes/class-schedules.php CHANGED
@@ -87,4 +87,4 @@ class Schedules {
87
  return new Scheduled_Backup( str_replace( 'hmbkp_schedule_', '', $id ) );
88
  }
89
 
90
- }
87
  return new Scheduled_Backup( str_replace( 'hmbkp_schedule_', '', $id ) );
88
  }
89
 
90
+ }
classes/class-setup.php CHANGED
@@ -10,7 +10,7 @@ class Setup {
10
  /**
11
  * Defines the minimum version of WordPress required by BWP.
12
  */
13
- const MIN_WP_VERSION = '3.9.3';
14
 
15
  /**
16
  * Defines the minimum version of PHP required by BWP.
@@ -56,10 +56,23 @@ class Setup {
56
 
57
  $schedules = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", 'hmbkp_schedule_%' ) );
58
 
59
- foreach ( array_map( function( $item ){ return ltrim( $item, 'hmbkp_schedule_' ); }, $schedules ) as $item ) {
 
 
60
  wp_clear_scheduled_hook( 'hmbkp_schedule_hook', array( 'id' => $item ) );
61
  }
62
 
 
 
 
 
 
 
 
 
 
 
 
63
  }
64
 
65
  /**
10
  /**
11
  * Defines the minimum version of WordPress required by BWP.
12
  */
13
+ const MIN_WP_VERSION = '3.9';
14
 
15
  /**
16
  * Defines the minimum version of PHP required by BWP.
56
 
57
  $schedules = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", 'hmbkp_schedule_%' ) );
58
 
59
+ foreach ( array_map( function ( $item ) {
60
+ return ltrim( $item, 'hmbkp_schedule_' );
61
+ }, $schedules ) as $item ) {
62
  wp_clear_scheduled_hook( 'hmbkp_schedule_hook', array( 'id' => $item ) );
63
  }
64
 
65
+ // Delete all transients
66
+ $transients = array(
67
+ 'hmbkp_plugin_data',
68
+ 'hmbkp_directory_filesizes',
69
+ 'hmbkp_directory_filesizes_running',
70
+ 'hmbkp_wp_cron_test_beacon',
71
+ 'hm_backdrop',
72
+ );
73
+
74
+ array_map( 'delete_transient', $transients );
75
+
76
  }
77
 
78
  /**
functions/core.php CHANGED
@@ -217,6 +217,60 @@ function hmbkp_update() {
217
 
218
  }
219
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
220
  // Every update
221
  if ( get_option( 'hmbkp_plugin_version' ) && version_compare( HM\BackUpWordPress\Plugin::PLUGIN_VERSION, get_option( 'hmbkp_plugin_version' ), '>' ) ) {
222
 
217
 
218
  }
219
 
220
+ // Update to 3.1.5
221
+ if ( get_option( 'hmbkp_plugin_version' ) && version_compare( '3.1.5', get_option( 'hmbkp_plugin_version' ), '>' ) ) {
222
+
223
+ // Delete all transients
224
+ $transients = array(
225
+ 'hmbkp_plugin_data',
226
+ 'hmbkp_directory_filesizes',
227
+ 'hmbkp_directory_filesizes_running',
228
+ 'hmbkp_wp_cron_test_beacon',
229
+ 'hm_backdrop',
230
+ );
231
+
232
+ array_map( 'delete_transient', $transients );
233
+
234
+ // Clear duplicate schedules on multisite
235
+ if ( is_multisite() ) {
236
+
237
+ // get current blogs from DB
238
+ $blogs = wp_get_sites();
239
+
240
+ foreach ( $blogs as $blog ) {
241
+
242
+ switch_to_blog( get_current_blog_id() );
243
+
244
+ if ( is_main_site( get_current_blog_id() ) ) {
245
+ continue;
246
+ }
247
+
248
+ global $wpdb;
249
+
250
+ // Get the schedule options
251
+ $schedules = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s", 'hmbkp_schedule_%' ) );
252
+
253
+ // clear schedules
254
+ foreach ( array_map( function ( $item ) {
255
+ return ltrim( $item, 'hmbkp_schedule_' );
256
+ }, $schedules ) as $item ) {
257
+ wp_clear_scheduled_hook( 'hmbkp_schedule_hook', array( 'id' => $item ) );
258
+ }
259
+
260
+ // delete options
261
+ array_map( 'delete_option', $schedules );
262
+
263
+ array_map( 'delete_option', array( 'hmbkp_enable_support', 'hmbkp_plugin_version', 'hmbkp_path', 'hmbkp_default_path', 'hmbkp_upsell' ) );
264
+
265
+ // Delete all transients
266
+ array_map( 'delete_transient', array( 'hmbkp_plugin_data', 'hmbkp_directory_filesizes', 'hmbkp_directory_filesize_running', 'timeout_hmbkp_wp_cron_test_beacon', 'hmbkp_wp_cron_test_beacon' ) );
267
+
268
+ }
269
+
270
+ restore_current_blog();
271
+ }
272
+ }
273
+
274
  // Every update
275
  if ( get_option( 'hmbkp_plugin_version' ) && version_compare( HM\BackUpWordPress\Plugin::PLUGIN_VERSION, get_option( 'hmbkp_plugin_version' ), '>' ) ) {
276
 
functions/interface.php CHANGED
@@ -173,8 +173,10 @@ add_action( 'admin_init', 'hmbkp_set_server_config_notices' );
173
  */
174
  function hmbkp_plugin_row( $plugins ) {
175
 
 
 
176
  if ( isset( $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php'] ) ) {
177
- $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php']['Description'] = str_replace( 'Once activated you\'ll find me under <strong>Tools &rarr; Backups</strong>', 'Find me under <strong><a href="' . esc_url( hmbkp_get_settings_url() ) . '">Tools &rarr; Backups</a></strong>', $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php']['Description'] );
178
  }
179
 
180
  return $plugins;
@@ -339,11 +341,7 @@ function hmbkp_translated_schedule_title( $slug, $title ) {
339
 
340
  function hmbkp_get_settings_url() {
341
 
342
- if ( is_multisite() ) {
343
- $url = network_admin_url( 'settings.php?page=' . HMBKP_PLUGIN_SLUG );
344
- } else {
345
- $url = admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG );
346
- }
347
 
348
  HM\BackUpWordPress\schedules::get_instance()->refresh_schedules();
349
 
173
  */
174
  function hmbkp_plugin_row( $plugins ) {
175
 
176
+ $menu = is_multisite() ? 'Settings' : 'Tools';
177
+
178
  if ( isset( $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php'] ) ) {
179
+ $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php']['Description'] = str_replace( 'Once activated you\'ll find me under <strong>' . $menu . ' &rarr; Backups</strong>', 'Find me under <strong><a href="' . esc_url( hmbkp_get_settings_url() ) . '">' . $menu . ' &rarr; Backups</a></strong>', $plugins[HMBKP_PLUGIN_SLUG . '/backupwordpress.php']['Description'] );
180
  }
181
 
182
  return $plugins;
341
 
342
  function hmbkp_get_settings_url() {
343
 
344
+ $url = is_multisite() ? self_admin_url( 'settings.php?page=' . HMBKP_PLUGIN_SLUG ) : self_admin_url( 'tools.php?page=' . HMBKP_PLUGIN_SLUG );
 
 
 
 
345
 
346
  HM\BackUpWordPress\schedules::get_instance()->refresh_schedules();
347
 
languages/backupwordpress.pot CHANGED
@@ -2,9 +2,9 @@
2
  # This file is distributed under the GPL-2.0+.
3
  msgid ""
4
  msgstr ""
5
- "Project-Id-Version: BackUpWordPress 3.1.4\n"
6
  "Report-Msgid-Bugs-To: support@humanmade.co.uk\n"
7
- "POT-Creation-Date: 2015-02-24 08:44:19+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
@@ -13,70 +13,70 @@ msgstr ""
13
  "Language-Team: Human Made Limited\n"
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
- #: admin/actions.php:215
17
  msgid "The schedule ID was not provided. Aborting."
18
  msgstr ""
19
 
20
- #: admin/actions.php:265
21
  msgid "Backup type cannot be empty"
22
  msgstr ""
23
 
24
- #: admin/actions.php:269
25
  msgid "Invalid backup type"
26
  msgstr ""
27
 
28
- #: admin/actions.php:283
29
  msgid "Schedule cannot be empty"
30
  msgstr ""
31
 
32
- #: admin/actions.php:287
33
  msgid "Invalid schedule"
34
  msgstr ""
35
 
36
- #: admin/actions.php:301
37
  msgid "Day of the week must be a valid lowercase day name"
38
  msgstr ""
39
 
40
- #: admin/actions.php:320
41
  msgid "Day of month must be between 1 and 31"
42
  msgstr ""
43
 
44
- #: admin/actions.php:339
45
  msgid "Hours must be between 0 and 23"
46
  msgstr ""
47
 
48
- #: admin/actions.php:358
49
  msgid "Minutes must be between 0 and 59"
50
  msgstr ""
51
 
52
- #: admin/actions.php:372
53
  msgid "Max backups can't be empty"
54
  msgstr ""
55
 
56
- #: admin/actions.php:376
57
  msgid "Max backups must be a number"
58
  msgstr ""
59
 
60
- #: admin/actions.php:380
61
  msgid "Max backups must be greater than 0"
62
  msgstr ""
63
 
64
- #: admin/actions.php:732 admin/actions.php:738
65
  msgid "BackUpWordPress has detected a problem."
66
  msgstr ""
67
 
68
- #: admin/actions.php:732 admin/actions.php:738
69
  msgid ""
70
  "%1$s is returning a %2$s response which could mean cron jobs aren't getting "
71
  "fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. "
72
  "See the %3$s for more details."
73
  msgstr ""
74
 
75
- #: admin/backups-table.php:8 admin/schedule-form-excludes.php:98
76
  msgid "Size"
77
  msgstr ""
78
 
79
- #: admin/backups-table.php:9 admin/schedule-form-excludes.php:100
80
  msgid "Type"
81
  msgstr ""
82
 
@@ -106,7 +106,7 @@ msgid ""
106
  "settings. %4$s. Defined %5$s will be highlighted."
107
  msgstr ""
108
 
109
- #: admin/constants.php:3 admin/menu.php:69
110
  msgid "Constants"
111
  msgstr ""
112
 
@@ -364,31 +364,31 @@ msgid ""
364
  "your Admin Dashboard (recommended), or email support@hmn.md"
365
  msgstr ""
366
 
367
- #: admin/menu.php:12 admin/menu.php:14
368
  msgid "Manage Backups"
369
  msgstr ""
370
 
371
- #: admin/menu.php:12 admin/menu.php:14 admin/menu.php:39
372
  msgid "Backups"
373
  msgstr ""
374
 
375
- #: admin/menu.php:67
376
  msgid "FAQ"
377
  msgstr ""
378
 
379
- #: admin/menu.php:79
380
  msgid "Server Info"
381
  msgstr ""
382
 
383
- #: admin/menu.php:86
384
  msgid "For more information:"
385
  msgstr ""
386
 
387
- #: admin/menu.php:88
388
  msgid "Support Forums"
389
  msgstr ""
390
 
391
- #: admin/menu.php:89
392
  msgid "Help with translation"
393
  msgstr ""
394
 
@@ -398,82 +398,88 @@ msgid ""
398
  "directory%2$s."
399
  msgstr ""
400
 
401
- #: admin/schedule-form-excludes.php:5
402
  msgid "Currently Excluded"
403
  msgstr ""
404
 
405
- #: admin/schedule-form-excludes.php:40
406
- msgid "Default rule"
 
 
407
  msgstr ""
408
 
409
  #: admin/schedule-form-excludes.php:44
410
- msgid "Defined in wp-config.php"
411
  msgstr ""
412
 
413
  #: admin/schedule-form-excludes.php:48
 
 
 
 
414
  msgid "Stop excluding"
415
  msgstr ""
416
 
417
- #: admin/schedule-form-excludes.php:64
418
  msgid "Directory Listing"
419
  msgstr ""
420
 
421
- #: admin/schedule-form-excludes.php:66
422
  msgid ""
423
  "Here's a directory listing of all files on your site, you can browse "
424
  "through and exclude files or folders that you don't want included in your "
425
  "backup."
426
  msgstr ""
427
 
428
- #: admin/schedule-form-excludes.php:97
429
  msgid "Name"
430
  msgstr ""
431
 
432
- #: admin/schedule-form-excludes.php:99
433
  msgid "Permissions"
434
  msgstr ""
435
 
436
- #: admin/schedule-form-excludes.php:101
437
  msgid "Status"
438
  msgstr ""
439
 
440
- #: admin/schedule-form-excludes.php:158 admin/schedule-form-excludes.php:269
441
  msgid "Refresh"
442
  msgstr ""
443
 
444
- #: admin/schedule-form-excludes.php:175 admin/schedule-form-excludes.php:293
445
  msgid "Symlink"
446
  msgstr ""
447
 
448
- #: admin/schedule-form-excludes.php:179 admin/schedule-form-excludes.php:297
449
  msgid "Folder"
450
  msgstr ""
451
 
452
- #: admin/schedule-form-excludes.php:269
453
  msgid "Recalculate the size of this directory"
454
  msgstr ""
455
 
456
- #: admin/schedule-form-excludes.php:301
457
  msgid "File"
458
  msgstr ""
459
 
460
- #: admin/schedule-form-excludes.php:311
461
  msgid "Unreadable files won't be backed up."
462
  msgstr ""
463
 
464
- #: admin/schedule-form-excludes.php:311
465
  msgid "Unreadable"
466
  msgstr ""
467
 
468
- #: admin/schedule-form-excludes.php:315
469
  msgid "Excluded"
470
  msgstr ""
471
 
472
- #: admin/schedule-form-excludes.php:326
473
  msgid "Exclude &rarr;"
474
  msgstr ""
475
 
476
- #: admin/schedule-form-excludes.php:345 admin/schedule-form.php:190
477
  #: admin/schedule-settings.php:88
478
  msgid "Done"
479
  msgstr ""
@@ -506,67 +512,71 @@ msgstr ""
506
  msgid "Manual Only"
507
  msgstr ""
508
 
509
- #: admin/schedule-form.php:90
510
  msgid "Start Day"
511
  msgstr ""
512
 
513
- #: admin/schedule-form.php:98
514
  msgid "Monday"
515
  msgstr ""
516
 
517
- #: admin/schedule-form.php:99
518
  msgid "Tuesday"
519
  msgstr ""
520
 
521
- #: admin/schedule-form.php:100
522
  msgid "Wednesday"
523
  msgstr ""
524
 
525
- #: admin/schedule-form.php:101
526
  msgid "Thursday"
527
  msgstr ""
528
 
529
- #: admin/schedule-form.php:102
530
  msgid "Friday"
531
  msgstr ""
532
 
533
- #: admin/schedule-form.php:103
534
  msgid "Saturday"
535
  msgstr ""
536
 
537
- #: admin/schedule-form.php:104
538
  msgid "Sunday"
539
  msgstr ""
540
 
541
- #: admin/schedule-form.php:122
542
  msgid "Start Day of Month"
543
  msgstr ""
544
 
545
- #: admin/schedule-form.php:134
546
  msgid "Start Time"
547
  msgstr ""
548
 
549
- #: admin/schedule-form.php:143
550
  msgid "Hours"
551
  msgstr ""
552
 
553
- #: admin/schedule-form.php:147
554
  msgid "Minutes"
555
  msgstr ""
556
 
557
- #: admin/schedule-form.php:151
 
 
 
 
558
  msgid "The second backup will run 12 hours after the first"
559
  msgstr ""
560
 
561
- #: admin/schedule-form.php:160
562
  msgid "Number of backups to store on this server"
563
  msgstr ""
564
 
565
- #: admin/schedule-form.php:169
566
  msgid "Past this limit older backups will be deleted automatically."
567
  msgstr ""
568
 
569
- #: admin/schedule-form.php:172
570
  msgid "This schedule will store a maximum of %s of backups."
571
  msgstr ""
572
 
@@ -630,15 +640,15 @@ msgstr ""
630
  msgid "Send a copy of each backup to %s."
631
  msgstr ""
632
 
633
- #: admin/schedule-sentence.php:153
634
  msgid "Backups will be compressed and should be smaller than this."
635
  msgstr ""
636
 
637
- #: admin/schedule-sentence.php:155
638
  msgid "this shouldn't take long&hellip;"
639
  msgstr ""
640
 
641
- #: admin/schedule-sentence.php:155
642
  msgid "calculating the size of your backup&hellip;"
643
  msgstr ""
644
 
@@ -668,67 +678,43 @@ msgid ""
668
  "Destinations &amp; Unlimited Sites)%4$s"
669
  msgstr ""
670
 
671
- #: backupwordpress.php:240
672
- msgid "Update"
673
- msgstr ""
674
-
675
- #: backupwordpress.php:241
676
- msgid "Cancel"
677
- msgstr ""
678
-
679
- #: backupwordpress.php:242
680
  msgid ""
681
- "Are you sure you want to delete this schedule? All of it's backups will "
682
- "also be deleted."
683
  msgstr ""
684
 
685
- #: backupwordpress.php:242 backupwordpress.php:243 backupwordpress.php:244
686
- #: backupwordpress.php:245
687
- msgid "'Cancel' to go back, 'OK' to delete."
688
- msgstr ""
689
-
690
- #: backupwordpress.php:243
691
- msgid "Are you sure you want to delete this backup?"
692
- msgstr ""
693
-
694
- #: backupwordpress.php:244
695
- msgid "Are you sure you want to remove this exclude rule?"
696
  msgstr ""
697
 
698
- #: backupwordpress.php:245
699
- msgid ""
700
- "Reducing the number of backups that are stored on this server will cause "
701
- "some of your existing backups to be deleted, are you sure that's what you "
702
- "want?"
703
- msgstr ""
704
-
705
- #: classes/class-backup.php:348
706
  msgid "archive filename must be a non empty string"
707
  msgstr ""
708
 
709
- #: classes/class-backup.php:352
710
  msgid "invalid file extension for archive filename <code>%s</code>"
711
  msgstr ""
712
 
713
- #: classes/class-backup.php:392
714
  msgid "database dump filename must be a non empty string"
715
  msgstr ""
716
 
717
- #: classes/class-backup.php:396
718
  msgid "invalid file extension for database dump filename <code>%s</code>"
719
  msgstr ""
720
 
721
- #: classes/class-backup.php:429
722
  msgid "Invalid root path <code>%s</code> must be a valid directory path"
723
  msgstr ""
724
 
725
- #: classes/class-backup.php:454
726
  msgid ""
727
  "Invalid existing archive filepath <code>%s</code> must be a non empty "
728
  "(string)"
729
  msgstr ""
730
 
731
- #: classes/class-backup.php:508
732
  msgid ""
733
  "Invalid backup type <code>%s</code> must be one of (string) file, database "
734
  "or complete"
@@ -837,76 +823,110 @@ msgstr ""
837
  msgid "This %s file ensures that other people cannot download your backup files."
838
  msgstr ""
839
 
840
- #: classes/class-schedule.php:137
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
841
  msgid "Invalid Option Name"
842
  msgstr ""
843
 
844
- #: classes/class-schedule.php:250
845
  msgid "Argument 1 for %s must be a valid integer"
846
  msgstr ""
847
 
848
- #: classes/class-schedule.php:599
849
  msgid "Argument 1 for %s must be a valid future timestamp"
850
  msgstr ""
851
 
852
- #: classes/class-schedule.php:636
853
  msgid "Argument 1 for %s must be a valid cron reoccurrence or \"manually\""
854
  msgstr ""
855
 
856
- #: classes/class-schedule.php:765 functions/interface.php:249
857
  msgid "Starting Backup"
858
  msgstr ""
859
 
860
- #: classes/class-schedule.php:851
861
  msgid "Error writing to file. (%s)"
862
  msgstr ""
863
 
864
- #: classes/class-schedule.php:899
865
  msgid "Dumping Database %s"
866
  msgstr ""
867
 
868
- #: classes/class-schedule.php:904
869
  msgid "Verifying Database Dump %s"
870
  msgstr ""
871
 
872
- #: classes/class-schedule.php:909
873
  msgid "Creating zip archive %s"
874
  msgstr ""
875
 
876
- #: classes/class-schedule.php:914
877
  msgid "Verifying Zip Archive %s"
878
  msgstr ""
879
 
880
- #: classes/class-schedule.php:919
881
  msgid "Finishing Backup"
882
  msgstr ""
883
 
884
- #: classes/class-schedule.php:970
885
  msgid "An unexpected error occured"
886
  msgstr ""
887
 
888
- #: classes/class-schedule.php:1033
889
  #. translators: min=minute
890
  msgid "%s min"
891
  msgid_plural "%s mins"
892
  msgstr[0] ""
893
  msgstr[1] ""
894
 
895
- #: classes/class-schedule.php:1043
896
  msgid "%s hour"
897
  msgid_plural "%s hours"
898
  msgstr[0] ""
899
  msgstr[1] ""
900
 
901
- #: classes/class-schedule.php:1105
902
  msgid "Argument 1 for %s must be a non empty string"
903
  msgstr ""
904
 
905
- #: classes/class-schedule.php:1110
906
  msgid "%s doesn't exist"
907
  msgstr ""
908
 
909
- #: classes/class-schedule.php:1115
910
  msgid "That backup wasn't created by this schedule"
911
  msgstr ""
912
 
@@ -926,7 +946,7 @@ msgstr ""
926
  msgid "BackUpWordPress"
927
  msgstr ""
928
 
929
- #: classes/class-setup.php:141
930
  msgid ""
931
  "BackUpWordPress requires PHP version %1$s or later and WordPress version "
932
  "%2$s or later to run. It has not been activated. %3$s%4$s%5$sLearn more%6$s"
@@ -936,41 +956,41 @@ msgstr ""
936
  msgid "Error: %s"
937
  msgstr ""
938
 
939
- #: functions/core.php:272
940
  msgid "BackUpWordPress has setup your default schedules."
941
  msgstr ""
942
 
943
- #: functions/core.php:272
944
  msgid ""
945
  "By default BackUpWordPress performs a daily backup of your database and a "
946
  "weekly backup of your database &amp; files. You can modify these schedules."
947
  msgstr ""
948
 
949
- #: functions/core.php:287
950
  msgid "Once Hourly"
951
  msgstr ""
952
 
953
- #: functions/core.php:288
954
  msgid "Twice Daily"
955
  msgstr ""
956
 
957
- #: functions/core.php:289
958
  msgid "Once Daily"
959
  msgstr ""
960
 
961
- #: functions/core.php:290
962
  msgid "Once Weekly"
963
  msgstr ""
964
 
965
- #: functions/core.php:291
966
  msgid "Once Biweekly"
967
  msgstr ""
968
 
969
- #: functions/core.php:292
970
  msgid "Once Monthly"
971
  msgstr ""
972
 
973
- #: functions/core.php:310
974
  msgid "You can only delete directories inside your WordPress installation"
975
  msgstr ""
976
 
@@ -1038,115 +1058,115 @@ msgstr ""
1038
  msgid "Your site root path %s isn't readable."
1039
  msgstr ""
1040
 
1041
- #: functions/interface.php:218
1042
  msgid "Database and Files"
1043
  msgstr ""
1044
 
1045
- #: functions/interface.php:222
1046
  msgid "Files"
1047
  msgstr ""
1048
 
1049
- #: functions/interface.php:226
1050
  msgid "Database"
1051
  msgstr ""
1052
 
1053
- #: functions/interface.php:233
1054
  msgid "Legacy"
1055
  msgstr ""
1056
 
1057
- #: functions/interface.php:248
1058
  msgid "Started %s ago"
1059
  msgstr ""
1060
 
1061
- #: functions/interface.php:250
1062
  msgid "cancel"
1063
  msgstr ""
1064
 
1065
- #: functions/interface.php:298
1066
  msgid "No backups completed"
1067
  msgstr ""
1068
 
1069
- #: functions/interface.php:309
1070
  msgid "Complete Hourly"
1071
  msgstr ""
1072
 
1073
- #: functions/interface.php:310
1074
  msgid "File Hourly"
1075
  msgstr ""
1076
 
1077
- #: functions/interface.php:311
1078
  msgid "Database Hourly"
1079
  msgstr ""
1080
 
1081
- #: functions/interface.php:312
1082
  msgid "Complete Twicedaily"
1083
  msgstr ""
1084
 
1085
- #: functions/interface.php:313
1086
  msgid "File Twicedaily"
1087
  msgstr ""
1088
 
1089
- #: functions/interface.php:314
1090
  msgid "Database Twicedaily"
1091
  msgstr ""
1092
 
1093
- #: functions/interface.php:315
1094
  msgid "Complete Daily"
1095
  msgstr ""
1096
 
1097
- #: functions/interface.php:316
1098
  msgid "File Daily"
1099
  msgstr ""
1100
 
1101
- #: functions/interface.php:317
1102
  msgid "Database Daily"
1103
  msgstr ""
1104
 
1105
- #: functions/interface.php:318
1106
  msgid "Complete Weekly"
1107
  msgstr ""
1108
 
1109
- #: functions/interface.php:319
1110
  msgid "File Weekly"
1111
  msgstr ""
1112
 
1113
- #: functions/interface.php:320
1114
  msgid "Database Weekly"
1115
  msgstr ""
1116
 
1117
- #: functions/interface.php:321
1118
  msgid "Complete Biweekly"
1119
  msgstr ""
1120
 
1121
- #: functions/interface.php:322
1122
  msgid "File Biweekly"
1123
  msgstr ""
1124
 
1125
- #: functions/interface.php:323
1126
  msgid "Database Biweekly"
1127
  msgstr ""
1128
 
1129
- #: functions/interface.php:324
1130
  msgid "Complete Monthly"
1131
  msgstr ""
1132
 
1133
- #: functions/interface.php:325
1134
  msgid "File Monthly"
1135
  msgstr ""
1136
 
1137
- #: functions/interface.php:326
1138
  msgid "Database Monthly"
1139
  msgstr ""
1140
 
1141
- #: functions/interface.php:327
1142
  msgid "Complete Manually"
1143
  msgstr ""
1144
 
1145
- #: functions/interface.php:328
1146
  msgid "File Manually"
1147
  msgstr ""
1148
 
1149
- #: functions/interface.php:329
1150
  msgid "Database Manually"
1151
  msgstr ""
1152
 
@@ -1176,7 +1196,7 @@ msgctxt ""
1176
  msgid "Backup my %1$s %2$s %3$s, %4$s."
1177
  msgstr ""
1178
 
1179
- #: functions/interface.php:300
1180
  msgctxt "backups count"
1181
  msgid "One backup completed"
1182
  msgid_plural "%1$s backups completed"
2
  # This file is distributed under the GPL-2.0+.
3
  msgid ""
4
  msgstr ""
5
+ "Project-Id-Version: BackUpWordPress 3.2.0\n"
6
  "Report-Msgid-Bugs-To: support@humanmade.co.uk\n"
7
+ "POT-Creation-Date: 2015-03-16 08:25:27+00:00\n"
8
  "MIME-Version: 1.0\n"
9
  "Content-Type: text/plain; charset=utf-8\n"
10
  "Content-Transfer-Encoding: 8bit\n"
13
  "Language-Team: Human Made Limited\n"
14
  "X-Generator: grunt-wp-i18n 0.4.9\n"
15
 
16
+ #: admin/actions.php:192
17
  msgid "The schedule ID was not provided. Aborting."
18
  msgstr ""
19
 
20
+ #: admin/actions.php:242
21
  msgid "Backup type cannot be empty"
22
  msgstr ""
23
 
24
+ #: admin/actions.php:246
25
  msgid "Invalid backup type"
26
  msgstr ""
27
 
28
+ #: admin/actions.php:260
29
  msgid "Schedule cannot be empty"
30
  msgstr ""
31
 
32
+ #: admin/actions.php:264
33
  msgid "Invalid schedule"
34
  msgstr ""
35
 
36
+ #: admin/actions.php:278
37
  msgid "Day of the week must be a valid lowercase day name"
38
  msgstr ""
39
 
40
+ #: admin/actions.php:297
41
  msgid "Day of month must be between 1 and 31"
42
  msgstr ""
43
 
44
+ #: admin/actions.php:316
45
  msgid "Hours must be between 0 and 23"
46
  msgstr ""
47
 
48
+ #: admin/actions.php:335
49
  msgid "Minutes must be between 0 and 59"
50
  msgstr ""
51
 
52
+ #: admin/actions.php:349
53
  msgid "Max backups can't be empty"
54
  msgstr ""
55
 
56
+ #: admin/actions.php:353
57
  msgid "Max backups must be a number"
58
  msgstr ""
59
 
60
+ #: admin/actions.php:357
61
  msgid "Max backups must be greater than 0"
62
  msgstr ""
63
 
64
+ #: admin/actions.php:709 admin/actions.php:715
65
  msgid "BackUpWordPress has detected a problem."
66
  msgstr ""
67
 
68
+ #: admin/actions.php:709 admin/actions.php:715
69
  msgid ""
70
  "%1$s is returning a %2$s response which could mean cron jobs aren't getting "
71
  "fired properly. BackUpWordPress relies on wp-cron to run scheduled backups. "
72
  "See the %3$s for more details."
73
  msgstr ""
74
 
75
+ #: admin/backups-table.php:8 admin/schedule-form-excludes.php:105
76
  msgid "Size"
77
  msgstr ""
78
 
79
+ #: admin/backups-table.php:9 admin/schedule-form-excludes.php:107
80
  msgid "Type"
81
  msgstr ""
82
 
106
  "settings. %4$s. Defined %5$s will be highlighted."
107
  msgstr ""
108
 
109
+ #: admin/constants.php:3 admin/menu.php:82
110
  msgid "Constants"
111
  msgstr ""
112
 
364
  "your Admin Dashboard (recommended), or email support@hmn.md"
365
  msgstr ""
366
 
367
+ #: admin/menu.php:13 admin/menu.php:17
368
  msgid "Manage Backups"
369
  msgstr ""
370
 
371
+ #: admin/menu.php:13 admin/menu.php:17 admin/menu.php:46
372
  msgid "Backups"
373
  msgstr ""
374
 
375
+ #: admin/menu.php:77
376
  msgid "FAQ"
377
  msgstr ""
378
 
379
+ #: admin/menu.php:95
380
  msgid "Server Info"
381
  msgstr ""
382
 
383
+ #: admin/menu.php:102
384
  msgid "For more information:"
385
  msgstr ""
386
 
387
+ #: admin/menu.php:104
388
  msgid "Support Forums"
389
  msgstr ""
390
 
391
+ #: admin/menu.php:105
392
  msgid "Help with translation"
393
  msgstr ""
394
 
398
  "directory%2$s."
399
  msgstr ""
400
 
401
+ #: admin/schedule-form-excludes.php:6
402
  msgid "Currently Excluded"
403
  msgstr ""
404
 
405
+ #: admin/schedule-form-excludes.php:9
406
+ msgid ""
407
+ "We automatically detect and ignore common <abbr title=\"Version Control "
408
+ "Systems\">VCS</abbr> folders and other backup plugin folders."
409
  msgstr ""
410
 
411
  #: admin/schedule-form-excludes.php:44
412
+ msgid "Default rule"
413
  msgstr ""
414
 
415
  #: admin/schedule-form-excludes.php:48
416
+ msgid "Defined in wp-config.php"
417
+ msgstr ""
418
+
419
+ #: admin/schedule-form-excludes.php:55
420
  msgid "Stop excluding"
421
  msgstr ""
422
 
423
+ #: admin/schedule-form-excludes.php:71
424
  msgid "Directory Listing"
425
  msgstr ""
426
 
427
+ #: admin/schedule-form-excludes.php:73
428
  msgid ""
429
  "Here's a directory listing of all files on your site, you can browse "
430
  "through and exclude files or folders that you don't want included in your "
431
  "backup."
432
  msgstr ""
433
 
434
+ #: admin/schedule-form-excludes.php:104
435
  msgid "Name"
436
  msgstr ""
437
 
438
+ #: admin/schedule-form-excludes.php:106
439
  msgid "Permissions"
440
  msgstr ""
441
 
442
+ #: admin/schedule-form-excludes.php:108
443
  msgid "Status"
444
  msgstr ""
445
 
446
+ #: admin/schedule-form-excludes.php:168 admin/schedule-form-excludes.php:284
447
  msgid "Refresh"
448
  msgstr ""
449
 
450
+ #: admin/schedule-form-excludes.php:185 admin/schedule-form-excludes.php:309
451
  msgid "Symlink"
452
  msgstr ""
453
 
454
+ #: admin/schedule-form-excludes.php:189 admin/schedule-form-excludes.php:313
455
  msgid "Folder"
456
  msgstr ""
457
 
458
+ #: admin/schedule-form-excludes.php:282
459
  msgid "Recalculate the size of this directory"
460
  msgstr ""
461
 
462
+ #: admin/schedule-form-excludes.php:317
463
  msgid "File"
464
  msgstr ""
465
 
466
+ #: admin/schedule-form-excludes.php:328
467
  msgid "Unreadable files won't be backed up."
468
  msgstr ""
469
 
470
+ #: admin/schedule-form-excludes.php:328
471
  msgid "Unreadable"
472
  msgstr ""
473
 
474
+ #: admin/schedule-form-excludes.php:332
475
  msgid "Excluded"
476
  msgstr ""
477
 
478
+ #: admin/schedule-form-excludes.php:348
479
  msgid "Exclude &rarr;"
480
  msgstr ""
481
 
482
+ #: admin/schedule-form-excludes.php:366 admin/schedule-form.php:192
483
  #: admin/schedule-settings.php:88
484
  msgid "Done"
485
  msgstr ""
512
  msgid "Manual Only"
513
  msgstr ""
514
 
515
+ #: admin/schedule-form.php:92
516
  msgid "Start Day"
517
  msgstr ""
518
 
519
+ #: admin/schedule-form.php:100
520
  msgid "Monday"
521
  msgstr ""
522
 
523
+ #: admin/schedule-form.php:101
524
  msgid "Tuesday"
525
  msgstr ""
526
 
527
+ #: admin/schedule-form.php:102
528
  msgid "Wednesday"
529
  msgstr ""
530
 
531
+ #: admin/schedule-form.php:103
532
  msgid "Thursday"
533
  msgstr ""
534
 
535
+ #: admin/schedule-form.php:104
536
  msgid "Friday"
537
  msgstr ""
538
 
539
+ #: admin/schedule-form.php:105
540
  msgid "Saturday"
541
  msgstr ""
542
 
543
+ #: admin/schedule-form.php:106
544
  msgid "Sunday"
545
  msgstr ""
546
 
547
+ #: admin/schedule-form.php:124
548
  msgid "Start Day of Month"
549
  msgstr ""
550
 
551
+ #: admin/schedule-form.php:136
552
  msgid "Start Time"
553
  msgstr ""
554
 
555
+ #: admin/schedule-form.php:145
556
  msgid "Hours"
557
  msgstr ""
558
 
559
+ #: admin/schedule-form.php:149
560
  msgid "Minutes"
561
  msgstr ""
562
 
563
+ #: admin/schedule-form.php:152
564
+ msgid "Please use 24 hour format for hours"
565
+ msgstr ""
566
+
567
+ #: admin/schedule-form.php:153
568
  msgid "The second backup will run 12 hours after the first"
569
  msgstr ""
570
 
571
+ #: admin/schedule-form.php:162
572
  msgid "Number of backups to store on this server"
573
  msgstr ""
574
 
575
+ #: admin/schedule-form.php:171
576
  msgid "Past this limit older backups will be deleted automatically."
577
  msgstr ""
578
 
579
+ #: admin/schedule-form.php:174
580
  msgid "This schedule will store a maximum of %s of backups."
581
  msgstr ""
582
 
640
  msgid "Send a copy of each backup to %s."
641
  msgstr ""
642
 
643
+ #: admin/schedule-sentence.php:156
644
  msgid "Backups will be compressed and should be smaller than this."
645
  msgstr ""
646
 
647
+ #: admin/schedule-sentence.php:160
648
  msgid "this shouldn't take long&hellip;"
649
  msgstr ""
650
 
651
+ #: admin/schedule-sentence.php:160
652
  msgid "calculating the size of your backup&hellip;"
653
  msgstr ""
654
 
678
  "Destinations &amp; Unlimited Sites)%4$s"
679
  msgstr ""
680
 
681
+ #: backupwordpress.php:48
 
 
 
 
 
 
 
 
682
  msgid ""
683
+ "BackUpWordPress will not work on this site. ( PHP Version %s is unsupported "
684
+ ")"
685
  msgstr ""
686
 
687
+ #: backupwordpress.php:48
688
+ msgid "BackUpWordPress Error"
 
 
 
 
 
 
 
 
 
689
  msgstr ""
690
 
691
+ #: classes/class-backup.php:386
 
 
 
 
 
 
 
692
  msgid "archive filename must be a non empty string"
693
  msgstr ""
694
 
695
+ #: classes/class-backup.php:390
696
  msgid "invalid file extension for archive filename <code>%s</code>"
697
  msgstr ""
698
 
699
+ #: classes/class-backup.php:431
700
  msgid "database dump filename must be a non empty string"
701
  msgstr ""
702
 
703
+ #: classes/class-backup.php:435
704
  msgid "invalid file extension for database dump filename <code>%s</code>"
705
  msgstr ""
706
 
707
+ #: classes/class-backup.php:469
708
  msgid "Invalid root path <code>%s</code> must be a valid directory path"
709
  msgstr ""
710
 
711
+ #: classes/class-backup.php:495
712
  msgid ""
713
  "Invalid existing archive filepath <code>%s</code> must be a non empty "
714
  "(string)"
715
  msgstr ""
716
 
717
+ #: classes/class-backup.php:550
718
  msgid ""
719
  "Invalid backup type <code>%s</code> must be one of (string) file, database "
720
  "or complete"
823
  msgid "This %s file ensures that other people cannot download your backup files."
824
  msgstr ""
825
 
826
+ #: classes/class-plugin.php:219
827
+ msgid "Update"
828
+ msgstr ""
829
+
830
+ #: classes/class-plugin.php:220
831
+ msgid "Cancel"
832
+ msgstr ""
833
+
834
+ #: classes/class-plugin.php:221
835
+ msgid ""
836
+ "Are you sure you want to delete this schedule? All of it's backups will "
837
+ "also be deleted."
838
+ msgstr ""
839
+
840
+ #: classes/class-plugin.php:221 classes/class-plugin.php:222
841
+ #: classes/class-plugin.php:223 classes/class-plugin.php:224
842
+ msgid "'Cancel' to go back, 'OK' to delete."
843
+ msgstr ""
844
+
845
+ #: classes/class-plugin.php:222
846
+ msgid "Are you sure you want to delete this backup?"
847
+ msgstr ""
848
+
849
+ #: classes/class-plugin.php:223
850
+ msgid "Are you sure you want to remove this exclude rule?"
851
+ msgstr ""
852
+
853
+ #: classes/class-plugin.php:224
854
+ msgid ""
855
+ "Reducing the number of backups that are stored on this server will cause "
856
+ "some of your existing backups to be deleted, are you sure that's what you "
857
+ "want?"
858
+ msgstr ""
859
+
860
+ #: classes/class-schedule.php:151
861
  msgid "Invalid Option Name"
862
  msgstr ""
863
 
864
+ #: classes/class-schedule.php:264
865
  msgid "Argument 1 for %s must be a valid integer"
866
  msgstr ""
867
 
868
+ #: classes/class-schedule.php:612
869
  msgid "Argument 1 for %s must be a valid future timestamp"
870
  msgstr ""
871
 
872
+ #: classes/class-schedule.php:649
873
  msgid "Argument 1 for %s must be a valid cron reoccurrence or \"manually\""
874
  msgstr ""
875
 
876
+ #: classes/class-schedule.php:778 functions/interface.php:251
877
  msgid "Starting Backup"
878
  msgstr ""
879
 
880
+ #: classes/class-schedule.php:865
881
  msgid "Error writing to file. (%s)"
882
  msgstr ""
883
 
884
+ #: classes/class-schedule.php:913
885
  msgid "Dumping Database %s"
886
  msgstr ""
887
 
888
+ #: classes/class-schedule.php:918
889
  msgid "Verifying Database Dump %s"
890
  msgstr ""
891
 
892
+ #: classes/class-schedule.php:923
893
  msgid "Creating zip archive %s"
894
  msgstr ""
895
 
896
+ #: classes/class-schedule.php:928
897
  msgid "Verifying Zip Archive %s"
898
  msgstr ""
899
 
900
+ #: classes/class-schedule.php:933
901
  msgid "Finishing Backup"
902
  msgstr ""
903
 
904
+ #: classes/class-schedule.php:984
905
  msgid "An unexpected error occured"
906
  msgstr ""
907
 
908
+ #: classes/class-schedule.php:1047
909
  #. translators: min=minute
910
  msgid "%s min"
911
  msgid_plural "%s mins"
912
  msgstr[0] ""
913
  msgstr[1] ""
914
 
915
+ #: classes/class-schedule.php:1057
916
  msgid "%s hour"
917
  msgid_plural "%s hours"
918
  msgstr[0] ""
919
  msgstr[1] ""
920
 
921
+ #: classes/class-schedule.php:1119
922
  msgid "Argument 1 for %s must be a non empty string"
923
  msgstr ""
924
 
925
+ #: classes/class-schedule.php:1124
926
  msgid "%s doesn't exist"
927
  msgstr ""
928
 
929
+ #: classes/class-schedule.php:1129
930
  msgid "That backup wasn't created by this schedule"
931
  msgstr ""
932
 
946
  msgid "BackUpWordPress"
947
  msgstr ""
948
 
949
+ #: classes/class-setup.php:154
950
  msgid ""
951
  "BackUpWordPress requires PHP version %1$s or later and WordPress version "
952
  "%2$s or later to run. It has not been activated. %3$s%4$s%5$sLearn more%6$s"
956
  msgid "Error: %s"
957
  msgstr ""
958
 
959
+ #: functions/core.php:326
960
  msgid "BackUpWordPress has setup your default schedules."
961
  msgstr ""
962
 
963
+ #: functions/core.php:326
964
  msgid ""
965
  "By default BackUpWordPress performs a daily backup of your database and a "
966
  "weekly backup of your database &amp; files. You can modify these schedules."
967
  msgstr ""
968
 
969
+ #: functions/core.php:341
970
  msgid "Once Hourly"
971
  msgstr ""
972
 
973
+ #: functions/core.php:342
974
  msgid "Twice Daily"
975
  msgstr ""
976
 
977
+ #: functions/core.php:343
978
  msgid "Once Daily"
979
  msgstr ""
980
 
981
+ #: functions/core.php:344
982
  msgid "Once Weekly"
983
  msgstr ""
984
 
985
+ #: functions/core.php:345
986
  msgid "Once Biweekly"
987
  msgstr ""
988
 
989
+ #: functions/core.php:346
990
  msgid "Once Monthly"
991
  msgstr ""
992
 
993
+ #: functions/core.php:364
994
  msgid "You can only delete directories inside your WordPress installation"
995
  msgstr ""
996
 
1058
  msgid "Your site root path %s isn't readable."
1059
  msgstr ""
1060
 
1061
+ #: functions/interface.php:220
1062
  msgid "Database and Files"
1063
  msgstr ""
1064
 
1065
+ #: functions/interface.php:224
1066
  msgid "Files"
1067
  msgstr ""
1068
 
1069
+ #: functions/interface.php:228
1070
  msgid "Database"
1071
  msgstr ""
1072
 
1073
+ #: functions/interface.php:235
1074
  msgid "Legacy"
1075
  msgstr ""
1076
 
1077
+ #: functions/interface.php:250
1078
  msgid "Started %s ago"
1079
  msgstr ""
1080
 
1081
+ #: functions/interface.php:252
1082
  msgid "cancel"
1083
  msgstr ""
1084
 
1085
+ #: functions/interface.php:300
1086
  msgid "No backups completed"
1087
  msgstr ""
1088
 
1089
+ #: functions/interface.php:311
1090
  msgid "Complete Hourly"
1091
  msgstr ""
1092
 
1093
+ #: functions/interface.php:312
1094
  msgid "File Hourly"
1095
  msgstr ""
1096
 
1097
+ #: functions/interface.php:313
1098
  msgid "Database Hourly"
1099
  msgstr ""
1100
 
1101
+ #: functions/interface.php:314
1102
  msgid "Complete Twicedaily"
1103
  msgstr ""
1104
 
1105
+ #: functions/interface.php:315
1106
  msgid "File Twicedaily"
1107
  msgstr ""
1108
 
1109
+ #: functions/interface.php:316
1110
  msgid "Database Twicedaily"
1111
  msgstr ""
1112
 
1113
+ #: functions/interface.php:317
1114
  msgid "Complete Daily"
1115
  msgstr ""
1116
 
1117
+ #: functions/interface.php:318
1118
  msgid "File Daily"
1119
  msgstr ""
1120
 
1121
+ #: functions/interface.php:319
1122
  msgid "Database Daily"
1123
  msgstr ""
1124
 
1125
+ #: functions/interface.php:320
1126
  msgid "Complete Weekly"
1127
  msgstr ""
1128
 
1129
+ #: functions/interface.php:321
1130
  msgid "File Weekly"
1131
  msgstr ""
1132
 
1133
+ #: functions/interface.php:322
1134
  msgid "Database Weekly"
1135
  msgstr ""
1136
 
1137
+ #: functions/interface.php:323
1138
  msgid "Complete Biweekly"
1139
  msgstr ""
1140
 
1141
+ #: functions/interface.php:324
1142
  msgid "File Biweekly"
1143
  msgstr ""
1144
 
1145
+ #: functions/interface.php:325
1146
  msgid "Database Biweekly"
1147
  msgstr ""
1148
 
1149
+ #: functions/interface.php:326
1150
  msgid "Complete Monthly"
1151
  msgstr ""
1152
 
1153
+ #: functions/interface.php:327
1154
  msgid "File Monthly"
1155
  msgstr ""
1156
 
1157
+ #: functions/interface.php:328
1158
  msgid "Database Monthly"
1159
  msgstr ""
1160
 
1161
+ #: functions/interface.php:329
1162
  msgid "Complete Manually"
1163
  msgstr ""
1164
 
1165
+ #: functions/interface.php:330
1166
  msgid "File Manually"
1167
  msgstr ""
1168
 
1169
+ #: functions/interface.php:331
1170
  msgid "Database Manually"
1171
  msgstr ""
1172
 
1196
  msgid "Backup my %1$s %2$s %3$s, %4$s."
1197
  msgstr ""
1198
 
1199
+ #: functions/interface.php:302
1200
  msgctxt "backups count"
1201
  msgid "One backup completed"
1202
  msgid_plural "%1$s backups completed"
readme.txt CHANGED
@@ -3,7 +3,7 @@ Contributors: humanmade, willmot, pauldewouters, joehoyle, mattheu, tcrsavage, c
3
  Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
4
  Requires at least: 3.9
5
  Tested up to: 4.2-alpha
6
- Stable tag: 3.1.4
7
 
8
  Simple automated backups of your WordPress powered website.
9
 
@@ -136,6 +136,79 @@ You can also tweet <a href="http://twitter.com/humanmadeltd">@humanmadeltd</a> o
136
 
137
  == Changelog ==
138
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
139
  ### 3.1.4 / 2015-02-24
140
 
141
  * (upgrade-options) Bump version
3
  Tags: back up, backup, backups, database, zip, db, files, archive, wp-cli, humanmade
4
  Requires at least: 3.9
5
  Tested up to: 4.2-alpha
6
+ Stable tag: 3.2.0
7
 
8
  Simple automated backups of your WordPress powered website.
9
 
136
 
137
  == Changelog ==
138
 
139
+ ### 3.2 / 2015-03-16
140
+
141
+ * (issue-698) skip mySql bug
142
+ * Use shell_exec
143
+ * Remove use statement
144
+ * Revert to using shell_exec
145
+ * Remove Process
146
+ * (cool-runnings-757) Add back session_write_close
147
+ * (issue-479) Hide hours and minutes for hourly backups
148
+ * (backupception) Only load if main site on multisite
149
+ * (all-paths-lead-to-rome) Set plugin path to main plugin file to avoid relative paths
150
+ * (socket-to-me-one-more-time) Fix paths
151
+ * Use socket if available
152
+ * Display errors
153
+ * Put the db dump in the archive first - fixes issue with large archive
154
+ * Dont wait for response
155
+ * Run schedule as a Backdrop task
156
+ * Pass array directly to function
157
+ * (issue-759) Fix require paths
158
+ * check PHP version before anything else
159
+ * Move plugin class to own file
160
+ * Skip mysql bug error
161
+ * Delete all BWP options
162
+ * Start the process
163
+ * Return and check WP_Error
164
+ * (what-time-is-backup) Extract hours and minutes from the date as an array for display
165
+ * Change plugin description if multisite
166
+ * Use wp_get_sites
167
+ * Add a comment
168
+ * We check for this on plugin instantiation
169
+ * Revert to clearing schedule and rescheduling
170
+ * Delete schedules and leftover options from subsites
171
+ * Ensure plugin only runs on main site
172
+ * Fix Too Many Schedules
173
+ * Use Symfony Process
174
+ * (fix-incorrect-type-error) File is an SPL object so get path
175
+ * Set root as default param
176
+ * Delete backdrop transient
177
+ * Force directory sizes recalculation
178
+ * Define VCS abbr
179
+ * Hide exclude patterns from Excludes list.
180
+ * Check if user can connect
181
+ * Test that the mysqldump command works
182
+ * Add a couple of mysql versions
183
+ * Automatically exclude VCS folders
184
+ * Calculate Root size correctly
185
+ * Get default rules from backup object
186
+ * Do not auto ignore dot files
187
+ * Count excluded
188
+ * Do not count excluded
189
+ * If its the root then return its size directly
190
+ * Fix typo in transient names
191
+ * Set and return class property instead
192
+ * List default excludes as such
193
+ * Require symfony finder
194
+ * Clear transients on deactivate
195
+ * Get list of files with Finder
196
+ * Load composer packages
197
+ * These are alredy filtered
198
+ * Add some default excludes
199
+ * Use absolute path for excludes added via UI
200
+ * Fix tests
201
+ * Fix conditional
202
+ * Fix syntax error in travis YML
203
+ * Run codesniffer only on pull requests
204
+ * Update tested WP versions
205
+ * Change min WP version required to match travis CI
206
+ * Fix readme changelog placement
207
+ * Add condtion for Cron and Ajax
208
+ * Fix deactivate logic
209
+ * Fixes recursive exclusion of files
210
+
211
+
212
  ### 3.1.4 / 2015-02-24
213
 
214
  * (upgrade-options) Bump version
uninstall.php CHANGED
@@ -16,12 +16,7 @@ $schedules = $wpdb->get_col( $wpdb->prepare( "SELECT option_name FROM $wpdb->opt
16
  array_map( 'delete_option', $schedules );
17
 
18
  // Remove all the options
19
-
20
- $options = array( 'hmbkp_enable_support', 'hmbkp_plugin_version', 'hmbkp_path', 'hmbkp_default_path', 'hmbkp_upsell' );
21
-
22
- array_map( 'delete_option', $options );
23
 
24
  // Delete all transients
25
- $transients = array( 'hmbkp_plugin_data', 'hmbkp_directory_filesizes', 'hmbkp_directory_filesize_running', 'timeout_hmbkp_wp_cron_test_beacon', 'hmbkp_wp_cron_test_beacon' );
26
-
27
- array_map( 'delete_transient', $transients );
16
  array_map( 'delete_option', $schedules );
17
 
18
  // Remove all the options
19
+ array_map( 'delete_option', array( 'hmbkp_enable_support', 'hmbkp_plugin_version', 'hmbkp_path', 'hmbkp_default_path', 'hmbkp_upsell' ) );
 
 
 
20
 
21
  // Delete all transients
22
+ array_map( 'delete_transient', array( 'hmbkp_plugin_data', 'hmbkp_directory_filesizes', 'hmbkp_directory_filesize_running', 'timeout_hmbkp_wp_cron_test_beacon', 'hmbkp_wp_cron_test_beacon' ) );
 
 
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 ComposerAutoloaderInitba9512989056f1653376251cbe20b82c::getLoader();
vendor/composer/ClassLoader.php ADDED
@@ -0,0 +1,386 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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 class loader
17
+ *
18
+ * See https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-0.md
19
+ *
20
+ * $loader = new \Composer\Autoload\ClassLoader();
21
+ *
22
+ * // register classes with namespaces
23
+ * $loader->add('Symfony\Component', __DIR__.'/component');
24
+ * $loader->add('Symfony', __DIR__.'/framework');
25
+ *
26
+ * // activate the autoloader
27
+ * $loader->register();
28
+ *
29
+ * // to enable searching the include path (eg. for PEAR packages)
30
+ * $loader->setUseIncludePath(true);
31
+ *
32
+ * In this example, if you try to use a class in the Symfony\Component
33
+ * namespace or one of its children (Symfony\Component\Console for instance),
34
+ * the autoloader will first look for the class under the component/
35
+ * directory, and it will then fallback to the framework/ directory if not
36
+ * found before giving up.
37
+ *
38
+ * This class is loosely based on the Symfony UniversalClassLoader.
39
+ *
40
+ * @author Fabien Potencier <fabien@symfony.com>
41
+ * @author Jordi Boggiano <j.boggiano@seld.be>
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
+
57
+ public function getPrefixes()
58
+ {
59
+ if (!empty($this->prefixesPsr0)) {
60
+ return call_user_func_array('array_merge', $this->prefixesPsr0);
61
+ }
62
+ return array();
63
+ }
64
+
65
+ public function getPrefixesPsr4()
66
+ {
67
+ return $this->prefixDirsPsr4;
68
+ }
69
+
70
+ public function getFallbackDirs()
71
+ {
72
+ return $this->fallbackDirsPsr0;
73
+ }
74
+
75
+ public function getFallbackDirsPsr4()
76
+ {
77
+ return $this->fallbackDirsPsr4;
78
+ }
79
+
80
+ public function getClassMap()
81
+ {
82
+ return $this->classMap;
83
+ }
84
+
85
+ /**
86
+ * @param array $classMap Class to filename map
87
+ */
88
+ public function addClassMap(array $classMap)
89
+ {
90
+ if ($this->classMap) {
91
+ $this->classMap = array_merge($this->classMap, $classMap);
92
+ } else {
93
+ $this->classMap = $classMap;
94
+ }
95
+ }
96
+
97
+ /**
98
+ * Registers a set of PSR-0 directories for a given prefix, either
99
+ * appending or prepending to the ones previously set for this prefix.
100
+ *
101
+ * @param string $prefix The prefix
102
+ * @param array|string $paths The PSR-0 root directories
103
+ * @param bool $prepend Whether to prepend the directories
104
+ */
105
+ public function add($prefix, $paths, $prepend = false)
106
+ {
107
+ if (!$prefix) {
108
+ if ($prepend) {
109
+ $this->fallbackDirsPsr0 = array_merge(
110
+ (array) $paths,
111
+ $this->fallbackDirsPsr0
112
+ );
113
+ } else {
114
+ $this->fallbackDirsPsr0 = array_merge(
115
+ $this->fallbackDirsPsr0,
116
+ (array) $paths
117
+ );
118
+ }
119
+
120
+ return;
121
+ }
122
+
123
+ $first = $prefix[0];
124
+ if (!isset($this->prefixesPsr0[$first][$prefix])) {
125
+ $this->prefixesPsr0[$first][$prefix] = (array) $paths;
126
+
127
+ return;
128
+ }
129
+ if ($prepend) {
130
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
131
+ (array) $paths,
132
+ $this->prefixesPsr0[$first][$prefix]
133
+ );
134
+ } else {
135
+ $this->prefixesPsr0[$first][$prefix] = array_merge(
136
+ $this->prefixesPsr0[$first][$prefix],
137
+ (array) $paths
138
+ );
139
+ }
140
+ }
141
+
142
+ /**
143
+ * Registers a set of PSR-4 directories for a given namespace, either
144
+ * appending or prepending to the ones previously set for this namespace.
145
+ *
146
+ * @param string $prefix The prefix/namespace, with trailing '\\'
147
+ * @param array|string $paths The PSR-0 base directories
148
+ * @param bool $prepend Whether to prepend the directories
149
+ *
150
+ * @throws \InvalidArgumentException
151
+ */
152
+ public function addPsr4($prefix, $paths, $prepend = false)
153
+ {
154
+ if (!$prefix) {
155
+ // Register directories for the root namespace.
156
+ if ($prepend) {
157
+ $this->fallbackDirsPsr4 = array_merge(
158
+ (array) $paths,
159
+ $this->fallbackDirsPsr4
160
+ );
161
+ } else {
162
+ $this->fallbackDirsPsr4 = array_merge(
163
+ $this->fallbackDirsPsr4,
164
+ (array) $paths
165
+ );
166
+ }
167
+ } elseif (!isset($this->prefixDirsPsr4[$prefix])) {
168
+ // Register directories for a new namespace.
169
+ $length = strlen($prefix);
170
+ if ('\\' !== $prefix[$length - 1]) {
171
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
172
+ }
173
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
174
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
175
+ } elseif ($prepend) {
176
+ // Prepend directories for an already registered namespace.
177
+ $this->prefixDirsPsr4[$prefix] = array_merge(
178
+ (array) $paths,
179
+ $this->prefixDirsPsr4[$prefix]
180
+ );
181
+ } else {
182
+ // Append directories for an already registered namespace.
183
+ $this->prefixDirsPsr4[$prefix] = array_merge(
184
+ $this->prefixDirsPsr4[$prefix],
185
+ (array) $paths
186
+ );
187
+ }
188
+ }
189
+
190
+ /**
191
+ * Registers a set of PSR-0 directories for a given prefix,
192
+ * replacing any others previously set for this prefix.
193
+ *
194
+ * @param string $prefix The prefix
195
+ * @param array|string $paths The PSR-0 base directories
196
+ */
197
+ public function set($prefix, $paths)
198
+ {
199
+ if (!$prefix) {
200
+ $this->fallbackDirsPsr0 = (array) $paths;
201
+ } else {
202
+ $this->prefixesPsr0[$prefix[0]][$prefix] = (array) $paths;
203
+ }
204
+ }
205
+
206
+ /**
207
+ * Registers a set of PSR-4 directories for a given namespace,
208
+ * replacing any others previously set for this namespace.
209
+ *
210
+ * @param string $prefix The prefix/namespace, with trailing '\\'
211
+ * @param array|string $paths The PSR-4 base directories
212
+ *
213
+ * @throws \InvalidArgumentException
214
+ */
215
+ public function setPsr4($prefix, $paths)
216
+ {
217
+ if (!$prefix) {
218
+ $this->fallbackDirsPsr4 = (array) $paths;
219
+ } else {
220
+ $length = strlen($prefix);
221
+ if ('\\' !== $prefix[$length - 1]) {
222
+ throw new \InvalidArgumentException("A non-empty PSR-4 prefix must end with a namespace separator.");
223
+ }
224
+ $this->prefixLengthsPsr4[$prefix[0]][$prefix] = $length;
225
+ $this->prefixDirsPsr4[$prefix] = (array) $paths;
226
+ }
227
+ }
228
+
229
+ /**
230
+ * Turns on searching the include path for class files.
231
+ *
232
+ * @param bool $useIncludePath
233
+ */
234
+ public function setUseIncludePath($useIncludePath)
235
+ {
236
+ $this->useIncludePath = $useIncludePath;
237
+ }
238
+
239
+ /**
240
+ * Can be used to check if the autoloader uses the include path to check
241
+ * for classes.
242
+ *
243
+ * @return bool
244
+ */
245
+ public function getUseIncludePath()
246
+ {
247
+ return $this->useIncludePath;
248
+ }
249
+
250
+ /**
251
+ * Registers this instance as an autoloader.
252
+ *
253
+ * @param bool $prepend Whether to prepend the autoloader or not
254
+ */
255
+ public function register($prepend = false)
256
+ {
257
+ spl_autoload_register(array($this, 'loadClass'), true, $prepend);
258
+ }
259
+
260
+ /**
261
+ * Unregisters this instance as an autoloader.
262
+ */
263
+ public function unregister()
264
+ {
265
+ spl_autoload_unregister(array($this, 'loadClass'));
266
+ }
267
+
268
+ /**
269
+ * Loads the given class or interface.
270
+ *
271
+ * @param string $class The name of the class
272
+ * @return bool|null True if loaded, null otherwise
273
+ */
274
+ public function loadClass($class)
275
+ {
276
+ if ($file = $this->findFile($class)) {
277
+ includeFile($file);
278
+
279
+ return true;
280
+ }
281
+ }
282
+
283
+ /**
284
+ * Finds the path to the file where the class is defined.
285
+ *
286
+ * @param string $class The name of the class
287
+ *
288
+ * @return string|false The path if found, false otherwise
289
+ */
290
+ public function findFile($class)
291
+ {
292
+ // work around for PHP 5.3.0 - 5.3.2 https://bugs.php.net/50731
293
+ if ('\\' == $class[0]) {
294
+ $class = substr($class, 1);
295
+ }
296
+
297
+ // class map lookup
298
+ if (isset($this->classMap[$class])) {
299
+ return $this->classMap[$class];
300
+ }
301
+
302
+ $file = $this->findFileWithExtension($class, '.php');
303
+
304
+ // Search for Hack files if we are running on HHVM
305
+ if ($file === null && defined('HHVM_VERSION')) {
306
+ $file = $this->findFileWithExtension($class, '.hh');
307
+ }
308
+
309
+ if ($file === null) {
310
+ // Remember that this class does not exist.
311
+ return $this->classMap[$class] = false;
312
+ }
313
+
314
+ return $file;
315
+ }
316
+
317
+ private function findFileWithExtension($class, $ext)
318
+ {
319
+ // PSR-4 lookup
320
+ $logicalPathPsr4 = strtr($class, '\\', DIRECTORY_SEPARATOR) . $ext;
321
+
322
+ $first = $class[0];
323
+ if (isset($this->prefixLengthsPsr4[$first])) {
324
+ foreach ($this->prefixLengthsPsr4[$first] as $prefix => $length) {
325
+ if (0 === strpos($class, $prefix)) {
326
+ foreach ($this->prefixDirsPsr4[$prefix] as $dir) {
327
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . substr($logicalPathPsr4, $length))) {
328
+ return $file;
329
+ }
330
+ }
331
+ }
332
+ }
333
+ }
334
+
335
+ // PSR-4 fallback dirs
336
+ foreach ($this->fallbackDirsPsr4 as $dir) {
337
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr4)) {
338
+ return $file;
339
+ }
340
+ }
341
+
342
+ // PSR-0 lookup
343
+ if (false !== $pos = strrpos($class, '\\')) {
344
+ // namespaced class name
345
+ $logicalPathPsr0 = substr($logicalPathPsr4, 0, $pos + 1)
346
+ . strtr(substr($logicalPathPsr4, $pos + 1), '_', DIRECTORY_SEPARATOR);
347
+ } else {
348
+ // PEAR-like class name
349
+ $logicalPathPsr0 = strtr($class, '_', DIRECTORY_SEPARATOR) . $ext;
350
+ }
351
+
352
+ if (isset($this->prefixesPsr0[$first])) {
353
+ foreach ($this->prefixesPsr0[$first] as $prefix => $dirs) {
354
+ if (0 === strpos($class, $prefix)) {
355
+ foreach ($dirs as $dir) {
356
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
357
+ return $file;
358
+ }
359
+ }
360
+ }
361
+ }
362
+ }
363
+
364
+ // PSR-0 fallback dirs
365
+ foreach ($this->fallbackDirsPsr0 as $dir) {
366
+ if (file_exists($file = $dir . DIRECTORY_SEPARATOR . $logicalPathPsr0)) {
367
+ return $file;
368
+ }
369
+ }
370
+
371
+ // PSR-0 include paths.
372
+ if ($this->useIncludePath && $file = stream_resolve_include_path($logicalPathPsr0)) {
373
+ return $file;
374
+ }
375
+ }
376
+ }
377
+
378
+ /**
379
+ * Scope isolated include.
380
+ *
381
+ * Prevents access to $this/self from included files.
382
+ */
383
+ function includeFile($file)
384
+ {
385
+ include $file;
386
+ }
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,10 @@
 
 
 
 
 
 
 
 
 
 
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
+ 'Symfony\\Component\\Finder\\' => array($vendorDir . '/symfony/finder'),
10
+ );
vendor/composer/autoload_psr4.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
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
+ );
vendor/composer/autoload_real.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ // autoload_real.php @generated by Composer
4
+
5
+ class ComposerAutoloaderInitba9512989056f1653376251cbe20b82c
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('ComposerAutoloaderInitba9512989056f1653376251cbe20b82c', 'loadClassLoader'), true, true);
23
+ self::$loader = $loader = new \Composer\Autoload\ClassLoader();
24
+ spl_autoload_unregister(array('ComposerAutoloaderInitba9512989056f1653376251cbe20b82c', 'loadClassLoader'));
25
+
26
+ $map = require __DIR__ . '/autoload_namespaces.php';
27
+ foreach ($map as $namespace => $path) {
28
+ $loader->set($namespace, $path);
29
+ }
30
+
31
+ $map = require __DIR__ . '/autoload_psr4.php';
32
+ foreach ($map as $namespace => $path) {
33
+ $loader->setPsr4($namespace, $path);
34
+ }
35
+
36
+ $classMap = require __DIR__ . '/autoload_classmap.php';
37
+ if ($classMap) {
38
+ $loader->addClassMap($classMap);
39
+ }
40
+
41
+ $loader->register(true);
42
+
43
+ return $loader;
44
+ }
45
+ }
46
+
47
+ function composerRequireba9512989056f1653376251cbe20b82c($file)
48
+ {
49
+ require $file;
50
+ }
vendor/composer/installed.json ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [
2
+ {
3
+ "name": "symfony/finder",
4
+ "version": "v2.6.4",
5
+ "version_normalized": "2.6.4.0",
6
+ "target-dir": "Symfony/Component/Finder",
7
+ "source": {
8
+ "type": "git",
9
+ "url": "https://github.com/symfony/Finder.git",
10
+ "reference": "16513333bca64186c01609961a2bb1b95b5e1355"
11
+ },
12
+ "dist": {
13
+ "type": "zip",
14
+ "url": "https://api.github.com/repos/symfony/Finder/zipball/16513333bca64186c01609961a2bb1b95b5e1355",
15
+ "reference": "16513333bca64186c01609961a2bb1b95b5e1355",
16
+ "shasum": ""
17
+ },
18
+ "require": {
19
+ "php": ">=5.3.3"
20
+ },
21
+ "time": "2015-01-03 08:01:59",
22
+ "type": "library",
23
+ "extra": {
24
+ "branch-alias": {
25
+ "dev-master": "2.6-dev"
26
+ }
27
+ },
28
+ "installation-source": "dist",
29
+ "autoload": {
30
+ "psr-0": {
31
+ "Symfony\\Component\\Finder\\": ""
32
+ }
33
+ },
34
+ "notification-url": "https://packagist.org/downloads/",
35
+ "license": [
36
+ "MIT"
37
+ ],
38
+ "authors": [
39
+ {
40
+ "name": "Symfony Community",
41
+ "homepage": "http://symfony.com/contributors"
42
+ },
43
+ {
44
+ "name": "Fabien Potencier",
45
+ "email": "fabien@symfony.com"
46
+ }
47
+ ],
48
+ "description": "Symfony Finder Component",
49
+ "homepage": "http://symfony.com"
50
+ }
51
+ ]
vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractAdapter.php ADDED
@@ -0,0 +1,236 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ /**
15
+ * Interface for finder engine implementations.
16
+ *
17
+ * @author Jean-François Simon <contact@jfsimon.fr>
18
+ */
19
+ abstract class AbstractAdapter implements AdapterInterface
20
+ {
21
+ protected $followLinks = false;
22
+ protected $mode = 0;
23
+ protected $minDepth = 0;
24
+ protected $maxDepth = PHP_INT_MAX;
25
+ protected $exclude = array();
26
+ protected $names = array();
27
+ protected $notNames = array();
28
+ protected $contains = array();
29
+ protected $notContains = array();
30
+ protected $sizes = array();
31
+ protected $dates = array();
32
+ protected $filters = array();
33
+ protected $sort = false;
34
+ protected $paths = array();
35
+ protected $notPaths = array();
36
+ protected $ignoreUnreadableDirs = false;
37
+
38
+ private static $areSupported = array();
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ */
43
+ public function isSupported()
44
+ {
45
+ $name = $this->getName();
46
+
47
+ if (!array_key_exists($name, self::$areSupported)) {
48
+ self::$areSupported[$name] = $this->canBeUsed();
49
+ }
50
+
51
+ return self::$areSupported[$name];
52
+ }
53
+
54
+ /**
55
+ * {@inheritdoc}
56
+ */
57
+ public function setFollowLinks($followLinks)
58
+ {
59
+ $this->followLinks = $followLinks;
60
+
61
+ return $this;
62
+ }
63
+
64
+ /**
65
+ * {@inheritdoc}
66
+ */
67
+ public function setMode($mode)
68
+ {
69
+ $this->mode = $mode;
70
+
71
+ return $this;
72
+ }
73
+
74
+ /**
75
+ * {@inheritdoc}
76
+ */
77
+ public function setDepths(array $depths)
78
+ {
79
+ $this->minDepth = 0;
80
+ $this->maxDepth = PHP_INT_MAX;
81
+
82
+ foreach ($depths as $comparator) {
83
+ switch ($comparator->getOperator()) {
84
+ case '>':
85
+ $this->minDepth = $comparator->getTarget() + 1;
86
+ break;
87
+ case '>=':
88
+ $this->minDepth = $comparator->getTarget();
89
+ break;
90
+ case '<':
91
+ $this->maxDepth = $comparator->getTarget() - 1;
92
+ break;
93
+ case '<=':
94
+ $this->maxDepth = $comparator->getTarget();
95
+ break;
96
+ default:
97
+ $this->minDepth = $this->maxDepth = $comparator->getTarget();
98
+ }
99
+ }
100
+
101
+ return $this;
102
+ }
103
+
104
+ /**
105
+ * {@inheritdoc}
106
+ */
107
+ public function setExclude(array $exclude)
108
+ {
109
+ $this->exclude = $exclude;
110
+
111
+ return $this;
112
+ }
113
+
114
+ /**
115
+ * {@inheritdoc}
116
+ */
117
+ public function setNames(array $names)
118
+ {
119
+ $this->names = $names;
120
+
121
+ return $this;
122
+ }
123
+
124
+ /**
125
+ * {@inheritdoc}
126
+ */
127
+ public function setNotNames(array $notNames)
128
+ {
129
+ $this->notNames = $notNames;
130
+
131
+ return $this;
132
+ }
133
+
134
+ /**
135
+ * {@inheritdoc}
136
+ */
137
+ public function setContains(array $contains)
138
+ {
139
+ $this->contains = $contains;
140
+
141
+ return $this;
142
+ }
143
+
144
+ /**
145
+ * {@inheritdoc}
146
+ */
147
+ public function setNotContains(array $notContains)
148
+ {
149
+ $this->notContains = $notContains;
150
+
151
+ return $this;
152
+ }
153
+
154
+ /**
155
+ * {@inheritdoc}
156
+ */
157
+ public function setSizes(array $sizes)
158
+ {
159
+ $this->sizes = $sizes;
160
+
161
+ return $this;
162
+ }
163
+
164
+ /**
165
+ * {@inheritdoc}
166
+ */
167
+ public function setDates(array $dates)
168
+ {
169
+ $this->dates = $dates;
170
+
171
+ return $this;
172
+ }
173
+
174
+ /**
175
+ * {@inheritdoc}
176
+ */
177
+ public function setFilters(array $filters)
178
+ {
179
+ $this->filters = $filters;
180
+
181
+ return $this;
182
+ }
183
+
184
+ /**
185
+ * {@inheritdoc}
186
+ */
187
+ public function setSort($sort)
188
+ {
189
+ $this->sort = $sort;
190
+
191
+ return $this;
192
+ }
193
+
194
+ /**
195
+ * {@inheritdoc}
196
+ */
197
+ public function setPath(array $paths)
198
+ {
199
+ $this->paths = $paths;
200
+
201
+ return $this;
202
+ }
203
+
204
+ /**
205
+ * {@inheritdoc}
206
+ */
207
+ public function setNotPath(array $notPaths)
208
+ {
209
+ $this->notPaths = $notPaths;
210
+
211
+ return $this;
212
+ }
213
+
214
+ /**
215
+ * {@inheritdoc}
216
+ */
217
+ public function ignoreUnreadableDirs($ignore = true)
218
+ {
219
+ $this->ignoreUnreadableDirs = (bool) $ignore;
220
+
221
+ return $this;
222
+ }
223
+
224
+ /**
225
+ * Returns whether the adapter is supported in the current environment.
226
+ *
227
+ * This method should be implemented in all adapters. Do not implement
228
+ * isSupported in the adapters as the generic implementation provides a cache
229
+ * layer.
230
+ *
231
+ * @see isSupported()
232
+ *
233
+ * @return bool Whether the adapter is supported
234
+ */
235
+ abstract protected function canBeUsed();
236
+ }
vendor/symfony/finder/Symfony/Component/Finder/Adapter/AbstractFindAdapter.php ADDED
@@ -0,0 +1,327 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ use Symfony\Component\Finder\Exception\AccessDeniedException;
15
+ use Symfony\Component\Finder\Iterator;
16
+ use Symfony\Component\Finder\Shell\Shell;
17
+ use Symfony\Component\Finder\Expression\Expression;
18
+ use Symfony\Component\Finder\Shell\Command;
19
+ use Symfony\Component\Finder\Comparator\NumberComparator;
20
+ use Symfony\Component\Finder\Comparator\DateComparator;
21
+
22
+ /**
23
+ * Shell engine implementation using GNU find command.
24
+ *
25
+ * @author Jean-François Simon <contact@jfsimon.fr>
26
+ */
27
+ abstract class AbstractFindAdapter extends AbstractAdapter
28
+ {
29
+ /**
30
+ * @var Shell
31
+ */
32
+ protected $shell;
33
+
34
+ /**
35
+ * Constructor.
36
+ */
37
+ public function __construct()
38
+ {
39
+ $this->shell = new Shell();
40
+ }
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ public function searchInDirectory($dir)
46
+ {
47
+ // having "/../" in path make find fail
48
+ $dir = realpath($dir);
49
+
50
+ // searching directories containing or not containing strings leads to no result
51
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode && ($this->contains || $this->notContains)) {
52
+ return new Iterator\FilePathsIterator(array(), $dir);
53
+ }
54
+
55
+ $command = Command::create();
56
+ $find = $this->buildFindCommand($command, $dir);
57
+
58
+ if ($this->followLinks) {
59
+ $find->add('-follow');
60
+ }
61
+
62
+ $find->add('-mindepth')->add($this->minDepth + 1);
63
+
64
+ if (PHP_INT_MAX !== $this->maxDepth) {
65
+ $find->add('-maxdepth')->add($this->maxDepth + 1);
66
+ }
67
+
68
+ if (Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES === $this->mode) {
69
+ $find->add('-type d');
70
+ } elseif (Iterator\FileTypeFilterIterator::ONLY_FILES === $this->mode) {
71
+ $find->add('-type f');
72
+ }
73
+
74
+ $this->buildNamesFiltering($find, $this->names);
75
+ $this->buildNamesFiltering($find, $this->notNames, true);
76
+ $this->buildPathsFiltering($find, $dir, $this->paths);
77
+ $this->buildPathsFiltering($find, $dir, $this->notPaths, true);
78
+ $this->buildSizesFiltering($find, $this->sizes);
79
+ $this->buildDatesFiltering($find, $this->dates);
80
+
81
+ $useGrep = $this->shell->testCommand('grep') && $this->shell->testCommand('xargs');
82
+ $useSort = is_int($this->sort) && $this->shell->testCommand('sort') && $this->shell->testCommand('cut');
83
+
84
+ if ($useGrep && ($this->contains || $this->notContains)) {
85
+ $grep = $command->ins('grep');
86
+ $this->buildContentFiltering($grep, $this->contains);
87
+ $this->buildContentFiltering($grep, $this->notContains, true);
88
+ }
89
+
90
+ if ($useSort) {
91
+ $this->buildSorting($command, $this->sort);
92
+ }
93
+
94
+ $command->setErrorHandler(
95
+ $this->ignoreUnreadableDirs
96
+ // If directory is unreadable and finder is set to ignore it, `stderr` is ignored.
97
+ ? function ($stderr) { return; }
98
+ : function ($stderr) { throw new AccessDeniedException($stderr); }
99
+ );
100
+
101
+ $paths = $this->shell->testCommand('uniq') ? $command->add('| uniq')->execute() : array_unique($command->execute());
102
+ $iterator = new Iterator\FilePathsIterator($paths, $dir);
103
+
104
+ if ($this->exclude) {
105
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
106
+ }
107
+
108
+ if (!$useGrep && ($this->contains || $this->notContains)) {
109
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
110
+ }
111
+
112
+ if ($this->filters) {
113
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
114
+ }
115
+
116
+ if (!$useSort && $this->sort) {
117
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
118
+ $iterator = $iteratorAggregate->getIterator();
119
+ }
120
+
121
+ return $iterator;
122
+ }
123
+
124
+ /**
125
+ * {@inheritdoc}
126
+ */
127
+ protected function canBeUsed()
128
+ {
129
+ return $this->shell->testCommand('find');
130
+ }
131
+
132
+ /**
133
+ * @param Command $command
134
+ * @param string $dir
135
+ *
136
+ * @return Command
137
+ */
138
+ protected function buildFindCommand(Command $command, $dir)
139
+ {
140
+ return $command
141
+ ->ins('find')
142
+ ->add('find ')
143
+ ->arg($dir)
144
+ ->add('-noleaf'); // the -noleaf option is required for filesystems that don't follow the '.' and '..' conventions
145
+ }
146
+
147
+ /**
148
+ * @param Command $command
149
+ * @param string[] $names
150
+ * @param bool $not
151
+ */
152
+ private function buildNamesFiltering(Command $command, array $names, $not = false)
153
+ {
154
+ if (0 === count($names)) {
155
+ return;
156
+ }
157
+
158
+ $command->add($not ? '-not' : null)->cmd('(');
159
+
160
+ foreach ($names as $i => $name) {
161
+ $expr = Expression::create($name);
162
+
163
+ // Find does not support expandable globs ("*.{a,b}" syntax).
164
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
165
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
166
+ }
167
+
168
+ // Fixes 'not search' and 'full path matching' regex problems.
169
+ // - Jokers '.' are replaced by [^/].
170
+ // - We add '[^/]*' before and after regex (if no ^|$ flags are present).
171
+ if ($expr->isRegex()) {
172
+ $regex = $expr->getRegex();
173
+ $regex->prepend($regex->hasStartFlag() ? '/' : '/[^/]*')
174
+ ->setStartFlag(false)
175
+ ->setStartJoker(true)
176
+ ->replaceJokers('[^/]');
177
+ if (!$regex->hasEndFlag() || $regex->hasEndJoker()) {
178
+ $regex->setEndJoker(false)->append('[^/]*');
179
+ }
180
+ }
181
+
182
+ $command
183
+ ->add($i > 0 ? '-or' : null)
184
+ ->add($expr->isRegex()
185
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
186
+ : ($expr->isCaseSensitive() ? '-name' : '-iname')
187
+ )
188
+ ->arg($expr->renderPattern());
189
+ }
190
+
191
+ $command->cmd(')');
192
+ }
193
+
194
+ /**
195
+ * @param Command $command
196
+ * @param string $dir
197
+ * @param string[] $paths
198
+ * @param bool $not
199
+ */
200
+ private function buildPathsFiltering(Command $command, $dir, array $paths, $not = false)
201
+ {
202
+ if (0 === count($paths)) {
203
+ return;
204
+ }
205
+
206
+ $command->add($not ? '-not' : null)->cmd('(');
207
+
208
+ foreach ($paths as $i => $path) {
209
+ $expr = Expression::create($path);
210
+
211
+ // Find does not support expandable globs ("*.{a,b}" syntax).
212
+ if ($expr->isGlob() && $expr->getGlob()->isExpandable()) {
213
+ $expr = Expression::create($expr->getGlob()->toRegex(false));
214
+ }
215
+
216
+ // Fixes 'not search' regex problems.
217
+ if ($expr->isRegex()) {
218
+ $regex = $expr->getRegex();
219
+ $regex->prepend($regex->hasStartFlag() ? preg_quote($dir).DIRECTORY_SEPARATOR : '.*')->setEndJoker(!$regex->hasEndFlag());
220
+ } else {
221
+ $expr->prepend('*')->append('*');
222
+ }
223
+
224
+ $command
225
+ ->add($i > 0 ? '-or' : null)
226
+ ->add($expr->isRegex()
227
+ ? ($expr->isCaseSensitive() ? '-regex' : '-iregex')
228
+ : ($expr->isCaseSensitive() ? '-path' : '-ipath')
229
+ )
230
+ ->arg($expr->renderPattern());
231
+ }
232
+
233
+ $command->cmd(')');
234
+ }
235
+
236
+ /**
237
+ * @param Command $command
238
+ * @param NumberComparator[] $sizes
239
+ */
240
+ private function buildSizesFiltering(Command $command, array $sizes)
241
+ {
242
+ foreach ($sizes as $i => $size) {
243
+ $command->add($i > 0 ? '-and' : null);
244
+
245
+ switch ($size->getOperator()) {
246
+ case '<=':
247
+ $command->add('-size -'.($size->getTarget() + 1).'c');
248
+ break;
249
+ case '>=':
250
+ $command->add('-size +'.($size->getTarget() - 1).'c');
251
+ break;
252
+ case '>':
253
+ $command->add('-size +'.$size->getTarget().'c');
254
+ break;
255
+ case '!=':
256
+ $command->add('-size -'.$size->getTarget().'c');
257
+ $command->add('-size +'.$size->getTarget().'c');
258
+ break;
259
+ case '<':
260
+ default:
261
+ $command->add('-size -'.$size->getTarget().'c');
262
+ }
263
+ }
264
+ }
265
+
266
+ /**
267
+ * @param Command $command
268
+ * @param DateComparator[] $dates
269
+ */
270
+ private function buildDatesFiltering(Command $command, array $dates)
271
+ {
272
+ foreach ($dates as $i => $date) {
273
+ $command->add($i > 0 ? '-and' : null);
274
+
275
+ $mins = (int) round((time()-$date->getTarget()) / 60);
276
+
277
+ if (0 > $mins) {
278
+ // mtime is in the future
279
+ $command->add(' -mmin -0');
280
+ // we will have no result so we don't need to continue
281
+ return;
282
+ }
283
+
284
+ switch ($date->getOperator()) {
285
+ case '<=':
286
+ $command->add('-mmin +'.($mins - 1));
287
+ break;
288
+ case '>=':
289
+ $command->add('-mmin -'.($mins + 1));
290
+ break;
291
+ case '>':
292
+ $command->add('-mmin -'.$mins);
293
+ break;
294
+ case '!=':
295
+ $command->add('-mmin +'.$mins.' -or -mmin -'.$mins);
296
+ break;
297
+ case '<':
298
+ default:
299
+ $command->add('-mmin +'.$mins);
300
+ }
301
+ }
302
+ }
303
+
304
+ /**
305
+ * @param Command $command
306
+ * @param string $sort
307
+ *
308
+ * @throws \InvalidArgumentException
309
+ */
310
+ private function buildSorting(Command $command, $sort)
311
+ {
312
+ $this->buildFormatSorting($command, $sort);
313
+ }
314
+
315
+ /**
316
+ * @param Command $command
317
+ * @param string $sort
318
+ */
319
+ abstract protected function buildFormatSorting(Command $command, $sort);
320
+
321
+ /**
322
+ * @param Command $command
323
+ * @param array $contains
324
+ * @param bool $not
325
+ */
326
+ abstract protected function buildContentFiltering(Command $command, array $contains, $not = false);
327
+ }
vendor/symfony/finder/Symfony/Component/Finder/Adapter/AdapterInterface.php ADDED
@@ -0,0 +1,144 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ interface AdapterInterface
18
+ {
19
+ /**
20
+ * @param bool $followLinks
21
+ *
22
+ * @return AdapterInterface Current instance
23
+ */
24
+ public function setFollowLinks($followLinks);
25
+
26
+ /**
27
+ * @param int $mode
28
+ *
29
+ * @return AdapterInterface Current instance
30
+ */
31
+ public function setMode($mode);
32
+
33
+ /**
34
+ * @param array $exclude
35
+ *
36
+ * @return AdapterInterface Current instance
37
+ */
38
+ public function setExclude(array $exclude);
39
+
40
+ /**
41
+ * @param array $depths
42
+ *
43
+ * @return AdapterInterface Current instance
44
+ */
45
+ public function setDepths(array $depths);
46
+
47
+ /**
48
+ * @param array $names
49
+ *
50
+ * @return AdapterInterface Current instance
51
+ */
52
+ public function setNames(array $names);
53
+
54
+ /**
55
+ * @param array $notNames
56
+ *
57
+ * @return AdapterInterface Current instance
58
+ */
59
+ public function setNotNames(array $notNames);
60
+
61
+ /**
62
+ * @param array $contains
63
+ *
64
+ * @return AdapterInterface Current instance
65
+ */
66
+ public function setContains(array $contains);
67
+
68
+ /**
69
+ * @param array $notContains
70
+ *
71
+ * @return AdapterInterface Current instance
72
+ */
73
+ public function setNotContains(array $notContains);
74
+
75
+ /**
76
+ * @param array $sizes
77
+ *
78
+ * @return AdapterInterface Current instance
79
+ */
80
+ public function setSizes(array $sizes);
81
+
82
+ /**
83
+ * @param array $dates
84
+ *
85
+ * @return AdapterInterface Current instance
86
+ */
87
+ public function setDates(array $dates);
88
+
89
+ /**
90
+ * @param array $filters
91
+ *
92
+ * @return AdapterInterface Current instance
93
+ */
94
+ public function setFilters(array $filters);
95
+
96
+ /**
97
+ * @param \Closure|int $sort
98
+ *
99
+ * @return AdapterInterface Current instance
100
+ */
101
+ public function setSort($sort);
102
+
103
+ /**
104
+ * @param array $paths
105
+ *
106
+ * @return AdapterInterface Current instance
107
+ */
108
+ public function setPath(array $paths);
109
+
110
+ /**
111
+ * @param array $notPaths
112
+ *
113
+ * @return AdapterInterface Current instance
114
+ */
115
+ public function setNotPath(array $notPaths);
116
+
117
+ /**
118
+ * @param bool $ignore
119
+ *
120
+ * @return AdapterInterface Current instance
121
+ */
122
+ public function ignoreUnreadableDirs($ignore = true);
123
+
124
+ /**
125
+ * @param string $dir
126
+ *
127
+ * @return \Iterator Result iterator
128
+ */
129
+ public function searchInDirectory($dir);
130
+
131
+ /**
132
+ * Tests adapter support for current platform.
133
+ *
134
+ * @return bool
135
+ */
136
+ public function isSupported();
137
+
138
+ /**
139
+ * Returns adapter name.
140
+ *
141
+ * @return string
142
+ */
143
+ public function getName();
144
+ }
vendor/symfony/finder/Symfony/Component/Finder/Adapter/BsdFindAdapter.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ use Symfony\Component\Finder\Shell\Shell;
15
+ use Symfony\Component\Finder\Shell\Command;
16
+ use Symfony\Component\Finder\Iterator\SortableIterator;
17
+ use Symfony\Component\Finder\Expression\Expression;
18
+
19
+ /**
20
+ * Shell engine implementation using BSD find command.
21
+ *
22
+ * @author Jean-François Simon <contact@jfsimon.fr>
23
+ */
24
+ class BsdFindAdapter extends AbstractFindAdapter
25
+ {
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public function getName()
30
+ {
31
+ return 'bsd_find';
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ protected function canBeUsed()
38
+ {
39
+ return in_array($this->shell->getType(), array(Shell::TYPE_BSD, Shell::TYPE_DARWIN)) && parent::canBeUsed();
40
+ }
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ protected function buildFormatSorting(Command $command, $sort)
46
+ {
47
+ switch ($sort) {
48
+ case SortableIterator::SORT_BY_NAME:
49
+ $command->ins('sort')->add('| sort');
50
+
51
+ return;
52
+ case SortableIterator::SORT_BY_TYPE:
53
+ $format = '%HT';
54
+ break;
55
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
56
+ $format = '%a';
57
+ break;
58
+ case SortableIterator::SORT_BY_CHANGED_TIME:
59
+ $format = '%c';
60
+ break;
61
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
62
+ $format = '%m';
63
+ break;
64
+ default:
65
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
66
+ }
67
+
68
+ $command
69
+ ->add('-print0 | xargs -0 stat -f')
70
+ ->arg($format.'%t%N')
71
+ ->add('| sort | cut -f 2');
72
+ }
73
+
74
+ /**
75
+ * {@inheritdoc}
76
+ */
77
+ protected function buildFindCommand(Command $command, $dir)
78
+ {
79
+ parent::buildFindCommand($command, $dir)->addAtIndex('-E', 1);
80
+
81
+ return $command;
82
+ }
83
+
84
+ /**
85
+ * {@inheritdoc}
86
+ */
87
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
88
+ {
89
+ foreach ($contains as $contain) {
90
+ $expr = Expression::create($contain);
91
+
92
+ // todo: avoid forking process for each $pattern by using multiple -e options
93
+ $command
94
+ ->add('| grep -v \'^$\'')
95
+ ->add('| xargs -I{} grep -I')
96
+ ->add($expr->isCaseSensitive() ? null : '-i')
97
+ ->add($not ? '-L' : '-l')
98
+ ->add('-Ee')->arg($expr->renderPattern())
99
+ ->add('{}')
100
+ ;
101
+ }
102
+ }
103
+ }
vendor/symfony/finder/Symfony/Component/Finder/Adapter/GnuFindAdapter.php ADDED
@@ -0,0 +1,104 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ use Symfony\Component\Finder\Shell\Shell;
15
+ use Symfony\Component\Finder\Shell\Command;
16
+ use Symfony\Component\Finder\Iterator\SortableIterator;
17
+ use Symfony\Component\Finder\Expression\Expression;
18
+
19
+ /**
20
+ * Shell engine implementation using GNU find command.
21
+ *
22
+ * @author Jean-François Simon <contact@jfsimon.fr>
23
+ */
24
+ class GnuFindAdapter extends AbstractFindAdapter
25
+ {
26
+ /**
27
+ * {@inheritdoc}
28
+ */
29
+ public function getName()
30
+ {
31
+ return 'gnu_find';
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ protected function buildFormatSorting(Command $command, $sort)
38
+ {
39
+ switch ($sort) {
40
+ case SortableIterator::SORT_BY_NAME:
41
+ $command->ins('sort')->add('| sort');
42
+
43
+ return;
44
+ case SortableIterator::SORT_BY_TYPE:
45
+ $format = '%y';
46
+ break;
47
+ case SortableIterator::SORT_BY_ACCESSED_TIME:
48
+ $format = '%A@';
49
+ break;
50
+ case SortableIterator::SORT_BY_CHANGED_TIME:
51
+ $format = '%C@';
52
+ break;
53
+ case SortableIterator::SORT_BY_MODIFIED_TIME:
54
+ $format = '%T@';
55
+ break;
56
+ default:
57
+ throw new \InvalidArgumentException(sprintf('Unknown sort options: %s.', $sort));
58
+ }
59
+
60
+ $command
61
+ ->get('find')
62
+ ->add('-printf')
63
+ ->arg($format.' %h/%f\\n')
64
+ ->add('| sort | cut')
65
+ ->arg('-d ')
66
+ ->arg('-f2-')
67
+ ;
68
+ }
69
+
70
+ /**
71
+ * {@inheritdoc}
72
+ */
73
+ protected function canBeUsed()
74
+ {
75
+ return $this->shell->getType() === Shell::TYPE_UNIX && parent::canBeUsed();
76
+ }
77
+
78
+ /**
79
+ * {@inheritdoc}
80
+ */
81
+ protected function buildFindCommand(Command $command, $dir)
82
+ {
83
+ return parent::buildFindCommand($command, $dir)->add('-regextype posix-extended');
84
+ }
85
+
86
+ /**
87
+ * {@inheritdoc}
88
+ */
89
+ protected function buildContentFiltering(Command $command, array $contains, $not = false)
90
+ {
91
+ foreach ($contains as $contain) {
92
+ $expr = Expression::create($contain);
93
+
94
+ // todo: avoid forking process for each $pattern by using multiple -e options
95
+ $command
96
+ ->add('| xargs -I{} -r grep -I')
97
+ ->add($expr->isCaseSensitive() ? null : '-i')
98
+ ->add($not ? '-L' : '-l')
99
+ ->add('-Ee')->arg($expr->renderPattern())
100
+ ->add('{}')
101
+ ;
102
+ }
103
+ }
104
+ }
vendor/symfony/finder/Symfony/Component/Finder/Adapter/PhpAdapter.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Adapter;
13
+
14
+ use Symfony\Component\Finder\Iterator;
15
+
16
+ /**
17
+ * PHP finder engine implementation.
18
+ *
19
+ * @author Jean-François Simon <contact@jfsimon.fr>
20
+ */
21
+ class PhpAdapter extends AbstractAdapter
22
+ {
23
+ /**
24
+ * {@inheritdoc}
25
+ */
26
+ public function searchInDirectory($dir)
27
+ {
28
+ $flags = \RecursiveDirectoryIterator::SKIP_DOTS;
29
+
30
+ if ($this->followLinks) {
31
+ $flags |= \RecursiveDirectoryIterator::FOLLOW_SYMLINKS;
32
+ }
33
+
34
+ $iterator = new \RecursiveIteratorIterator(
35
+ new Iterator\RecursiveDirectoryIterator($dir, $flags, $this->ignoreUnreadableDirs),
36
+ \RecursiveIteratorIterator::SELF_FIRST
37
+ );
38
+
39
+ if ($this->minDepth > 0 || $this->maxDepth < PHP_INT_MAX) {
40
+ $iterator = new Iterator\DepthRangeFilterIterator($iterator, $this->minDepth, $this->maxDepth);
41
+ }
42
+
43
+ if ($this->mode) {
44
+ $iterator = new Iterator\FileTypeFilterIterator($iterator, $this->mode);
45
+ }
46
+
47
+ if ($this->exclude) {
48
+ $iterator = new Iterator\ExcludeDirectoryFilterIterator($iterator, $this->exclude);
49
+ }
50
+
51
+ if ($this->names || $this->notNames) {
52
+ $iterator = new Iterator\FilenameFilterIterator($iterator, $this->names, $this->notNames);
53
+ }
54
+
55
+ if ($this->contains || $this->notContains) {
56
+ $iterator = new Iterator\FilecontentFilterIterator($iterator, $this->contains, $this->notContains);
57
+ }
58
+
59
+ if ($this->sizes) {
60
+ $iterator = new Iterator\SizeRangeFilterIterator($iterator, $this->sizes);
61
+ }
62
+
63
+ if ($this->dates) {
64
+ $iterator = new Iterator\DateRangeFilterIterator($iterator, $this->dates);
65
+ }
66
+
67
+ if ($this->filters) {
68
+ $iterator = new Iterator\CustomFilterIterator($iterator, $this->filters);
69
+ }
70
+
71
+ if ($this->sort) {
72
+ $iteratorAggregate = new Iterator\SortableIterator($iterator, $this->sort);
73
+ $iterator = $iteratorAggregate->getIterator();
74
+ }
75
+
76
+ if ($this->paths || $this->notPaths) {
77
+ $iterator = new Iterator\PathFilterIterator($iterator, $this->paths, $this->notPaths);
78
+ }
79
+
80
+ return $iterator;
81
+ }
82
+
83
+ /**
84
+ * {@inheritdoc}
85
+ */
86
+ public function getName()
87
+ {
88
+ return 'php';
89
+ }
90
+
91
+ /**
92
+ * {@inheritdoc}
93
+ */
94
+ protected function canBeUsed()
95
+ {
96
+ return true;
97
+ }
98
+ }
vendor/symfony/finder/Symfony/Component/Finder/CHANGELOG.md ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ CHANGELOG
2
+ =========
3
+
4
+ 2.5.0
5
+ -----
6
+ * added support for GLOB_BRACE in the paths passed to Finder::in()
7
+
8
+ 2.3.0
9
+ -----
10
+
11
+ * added a way to ignore unreadable directories (via Finder::ignoreUnreadableDirs())
12
+ * unified the way subfolders that are not executable are handled by always throwing an AccessDeniedException exception
13
+
14
+ 2.2.0
15
+ -----
16
+
17
+ * added Finder::path() and Finder::notPath() methods
18
+ * added finder adapters to improve performance on specific platforms
19
+ * added support for wildcard characters (glob patterns) in the paths passed
20
+ to Finder::in()
21
+
22
+ 2.1.0
23
+ -----
24
+
25
+ * added Finder::sortByAccessedTime(), Finder::sortByChangedTime(), and
26
+ Finder::sortByModifiedTime()
27
+ * added Countable to Finder
28
+ * added support for an array of directories as an argument to
29
+ Finder::exclude()
30
+ * added searching based on the file content via Finder::contains() and
31
+ Finder::notContains()
32
+ * added support for the != operator in the Comparator
33
+ * [BC BREAK] filter expressions (used for file name and content) are no more
34
+ considered as regexps but glob patterns when they are enclosed in '*' or '?'
vendor/symfony/finder/Symfony/Component/Finder/Comparator/Comparator.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Comparator;
13
+
14
+ /**
15
+ * Comparator.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class Comparator
20
+ {
21
+ private $target;
22
+ private $operator = '==';
23
+
24
+ /**
25
+ * Gets the target value.
26
+ *
27
+ * @return string The target value
28
+ */
29
+ public function getTarget()
30
+ {
31
+ return $this->target;
32
+ }
33
+
34
+ /**
35
+ * Sets the target value.
36
+ *
37
+ * @param string $target The target value
38
+ */
39
+ public function setTarget($target)
40
+ {
41
+ $this->target = $target;
42
+ }
43
+
44
+ /**
45
+ * Gets the comparison operator.
46
+ *
47
+ * @return string The operator
48
+ */
49
+ public function getOperator()
50
+ {
51
+ return $this->operator;
52
+ }
53
+
54
+ /**
55
+ * Sets the comparison operator.
56
+ *
57
+ * @param string $operator A valid operator
58
+ *
59
+ * @throws \InvalidArgumentException
60
+ */
61
+ public function setOperator($operator)
62
+ {
63
+ if (!$operator) {
64
+ $operator = '==';
65
+ }
66
+
67
+ if (!in_array($operator, array('>', '<', '>=', '<=', '==', '!='))) {
68
+ throw new \InvalidArgumentException(sprintf('Invalid operator "%s".', $operator));
69
+ }
70
+
71
+ $this->operator = $operator;
72
+ }
73
+
74
+ /**
75
+ * Tests against the target.
76
+ *
77
+ * @param mixed $test A test value
78
+ *
79
+ * @return bool
80
+ */
81
+ public function test($test)
82
+ {
83
+ switch ($this->operator) {
84
+ case '>':
85
+ return $test > $this->target;
86
+ case '>=':
87
+ return $test >= $this->target;
88
+ case '<':
89
+ return $test < $this->target;
90
+ case '<=':
91
+ return $test <= $this->target;
92
+ case '!=':
93
+ return $test != $this->target;
94
+ }
95
+
96
+ return $test == $this->target;
97
+ }
98
+ }
vendor/symfony/finder/Symfony/Component/Finder/Comparator/DateComparator.php ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Comparator;
13
+
14
+ /**
15
+ * DateCompare compiles date comparisons.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class DateComparator extends Comparator
20
+ {
21
+ /**
22
+ * Constructor.
23
+ *
24
+ * @param string $test A comparison string
25
+ *
26
+ * @throws \InvalidArgumentException If the test is not understood
27
+ */
28
+ public function __construct($test)
29
+ {
30
+ if (!preg_match('#^\s*(==|!=|[<>]=?|after|since|before|until)?\s*(.+?)\s*$#i', $test, $matches)) {
31
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a date test.', $test));
32
+ }
33
+
34
+ try {
35
+ $date = new \DateTime($matches[2]);
36
+ $target = $date->format('U');
37
+ } catch (\Exception $e) {
38
+ throw new \InvalidArgumentException(sprintf('"%s" is not a valid date.', $matches[2]));
39
+ }
40
+
41
+ $operator = isset($matches[1]) ? $matches[1] : '==';
42
+ if ('since' === $operator || 'after' === $operator) {
43
+ $operator = '>';
44
+ }
45
+
46
+ if ('until' === $operator || 'before' === $operator) {
47
+ $operator = '<';
48
+ }
49
+
50
+ $this->setOperator($operator);
51
+ $this->setTarget($target);
52
+ }
53
+ }
vendor/symfony/finder/Symfony/Component/Finder/Comparator/NumberComparator.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Comparator;
13
+
14
+ /**
15
+ * NumberComparator compiles a simple comparison to an anonymous
16
+ * subroutine, which you can call with a value to be tested again.
17
+ *
18
+ * Now this would be very pointless, if NumberCompare didn't understand
19
+ * magnitudes.
20
+ *
21
+ * The target value may use magnitudes of kilobytes (k, ki),
22
+ * megabytes (m, mi), or gigabytes (g, gi). Those suffixed
23
+ * with an i use the appropriate 2**n version in accordance with the
24
+ * IEC standard: http://physics.nist.gov/cuu/Units/binary.html
25
+ *
26
+ * Based on the Perl Number::Compare module.
27
+ *
28
+ * @author Fabien Potencier <fabien@symfony.com> PHP port
29
+ * @author Richard Clamp <richardc@unixbeard.net> Perl version
30
+ * @copyright 2004-2005 Fabien Potencier <fabien@symfony.com>
31
+ * @copyright 2002 Richard Clamp <richardc@unixbeard.net>
32
+ *
33
+ * @see http://physics.nist.gov/cuu/Units/binary.html
34
+ */
35
+ class NumberComparator extends Comparator
36
+ {
37
+ /**
38
+ * Constructor.
39
+ *
40
+ * @param string $test A comparison string
41
+ *
42
+ * @throws \InvalidArgumentException If the test is not understood
43
+ */
44
+ public function __construct($test)
45
+ {
46
+ if (!preg_match('#^\s*(==|!=|[<>]=?)?\s*([0-9\.]+)\s*([kmg]i?)?\s*$#i', $test, $matches)) {
47
+ throw new \InvalidArgumentException(sprintf('Don\'t understand "%s" as a number test.', $test));
48
+ }
49
+
50
+ $target = $matches[2];
51
+ if (!is_numeric($target)) {
52
+ throw new \InvalidArgumentException(sprintf('Invalid number "%s".', $target));
53
+ }
54
+ if (isset($matches[3])) {
55
+ // magnitude
56
+ switch (strtolower($matches[3])) {
57
+ case 'k':
58
+ $target *= 1000;
59
+ break;
60
+ case 'ki':
61
+ $target *= 1024;
62
+ break;
63
+ case 'm':
64
+ $target *= 1000000;
65
+ break;
66
+ case 'mi':
67
+ $target *= 1024*1024;
68
+ break;
69
+ case 'g':
70
+ $target *= 1000000000;
71
+ break;
72
+ case 'gi':
73
+ $target *= 1024*1024*1024;
74
+ break;
75
+ }
76
+ }
77
+
78
+ $this->setTarget($target);
79
+ $this->setOperator(isset($matches[1]) ? $matches[1] : '==');
80
+ }
81
+ }
vendor/symfony/finder/Symfony/Component/Finder/Exception/AccessDeniedException.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Exception;
13
+
14
+ /**
15
+ * @author Jean-François Simon <jeanfrancois.simon@sensiolabs.com>
16
+ */
17
+ class AccessDeniedException extends \UnexpectedValueException
18
+ {
19
+ }
vendor/symfony/finder/Symfony/Component/Finder/Exception/AdapterFailureException.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Exception;
13
+
14
+ use Symfony\Component\Finder\Adapter\AdapterInterface;
15
+
16
+ /**
17
+ * Base exception for all adapter failures.
18
+ *
19
+ * @author Jean-François Simon <contact@jfsimon.fr>
20
+ */
21
+ class AdapterFailureException extends \RuntimeException implements ExceptionInterface
22
+ {
23
+ /**
24
+ * @var \Symfony\Component\Finder\Adapter\AdapterInterface
25
+ */
26
+ private $adapter;
27
+
28
+ /**
29
+ * @param AdapterInterface $adapter
30
+ * @param string|null $message
31
+ * @param \Exception|null $previous
32
+ */
33
+ public function __construct(AdapterInterface $adapter, $message = null, \Exception $previous = null)
34
+ {
35
+ $this->adapter = $adapter;
36
+ parent::__construct($message ?: 'Search failed with "'.$adapter->getName().'" adapter.', $previous);
37
+ }
38
+
39
+ /**
40
+ * {@inheritdoc}
41
+ */
42
+ public function getAdapter()
43
+ {
44
+ return $this->adapter;
45
+ }
46
+ }
vendor/symfony/finder/Symfony/Component/Finder/Exception/ExceptionInterface.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Exception;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ interface ExceptionInterface
18
+ {
19
+ /**
20
+ * @return \Symfony\Component\Finder\Adapter\AdapterInterface
21
+ */
22
+ public function getAdapter();
23
+ }
vendor/symfony/finder/Symfony/Component/Finder/Exception/OperationNotPermitedException.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Exception;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class OperationNotPermitedException extends AdapterFailureException
18
+ {
19
+ }
vendor/symfony/finder/Symfony/Component/Finder/Exception/ShellCommandFailureException.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Exception;
13
+
14
+ use Symfony\Component\Finder\Adapter\AdapterInterface;
15
+ use Symfony\Component\Finder\Shell\Command;
16
+
17
+ /**
18
+ * @author Jean-François Simon <contact@jfsimon.fr>
19
+ */
20
+ class ShellCommandFailureException extends AdapterFailureException
21
+ {
22
+ /**
23
+ * @var Command
24
+ */
25
+ private $command;
26
+
27
+ /**
28
+ * @param AdapterInterface $adapter
29
+ * @param Command $command
30
+ * @param \Exception|null $previous
31
+ */
32
+ public function __construct(AdapterInterface $adapter, Command $command, \Exception $previous = null)
33
+ {
34
+ $this->command = $command;
35
+ parent::__construct($adapter, 'Shell command failed: "'.$command->join().'".', $previous);
36
+ }
37
+
38
+ /**
39
+ * @return Command
40
+ */
41
+ public function getCommand()
42
+ {
43
+ return $this->command;
44
+ }
45
+ }
vendor/symfony/finder/Symfony/Component/Finder/Expression/Expression.php ADDED
@@ -0,0 +1,146 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Expression;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class Expression implements ValueInterface
18
+ {
19
+ const TYPE_REGEX = 1;
20
+ const TYPE_GLOB = 2;
21
+
22
+ /**
23
+ * @var ValueInterface
24
+ */
25
+ private $value;
26
+
27
+ /**
28
+ * @param string $expr
29
+ *
30
+ * @return Expression
31
+ */
32
+ public static function create($expr)
33
+ {
34
+ return new self($expr);
35
+ }
36
+
37
+ /**
38
+ * @param string $expr
39
+ */
40
+ public function __construct($expr)
41
+ {
42
+ try {
43
+ $this->value = Regex::create($expr);
44
+ } catch (\InvalidArgumentException $e) {
45
+ $this->value = new Glob($expr);
46
+ }
47
+ }
48
+
49
+ /**
50
+ * @return string
51
+ */
52
+ public function __toString()
53
+ {
54
+ return $this->render();
55
+ }
56
+
57
+ /**
58
+ * {@inheritdoc}
59
+ */
60
+ public function render()
61
+ {
62
+ return $this->value->render();
63
+ }
64
+
65
+ /**
66
+ * {@inheritdoc}
67
+ */
68
+ public function renderPattern()
69
+ {
70
+ return $this->value->renderPattern();
71
+ }
72
+
73
+ /**
74
+ * @return bool
75
+ */
76
+ public function isCaseSensitive()
77
+ {
78
+ return $this->value->isCaseSensitive();
79
+ }
80
+
81
+ /**
82
+ * @return int
83
+ */
84
+ public function getType()
85
+ {
86
+ return $this->value->getType();
87
+ }
88
+
89
+ /**
90
+ * {@inheritdoc}
91
+ */
92
+ public function prepend($expr)
93
+ {
94
+ $this->value->prepend($expr);
95
+
96
+ return $this;
97
+ }
98
+
99
+ /**
100
+ * {@inheritdoc}
101
+ */
102
+ public function append($expr)
103
+ {
104
+ $this->value->append($expr);
105
+
106
+ return $this;
107
+ }
108
+
109
+ /**
110
+ * @return bool
111
+ */
112
+ public function isRegex()
113
+ {
114
+ return self::TYPE_REGEX === $this->value->getType();
115
+ }
116
+
117
+ /**
118
+ * @return bool
119
+ */
120
+ public function isGlob()
121
+ {
122
+ return self::TYPE_GLOB === $this->value->getType();
123
+ }
124
+
125
+ /**
126
+ * @throws \LogicException
127
+ *
128
+ * @return Glob
129
+ */
130
+ public function getGlob()
131
+ {
132
+ if (self::TYPE_GLOB !== $this->value->getType()) {
133
+ throw new \LogicException('Regex can\'t be transformed to glob.');
134
+ }
135
+
136
+ return $this->value;
137
+ }
138
+
139
+ /**
140
+ * @return Regex
141
+ */
142
+ public function getRegex()
143
+ {
144
+ return self::TYPE_REGEX === $this->value->getType() ? $this->value : $this->value->toRegex();
145
+ }
146
+ }
vendor/symfony/finder/Symfony/Component/Finder/Expression/Glob.php ADDED
@@ -0,0 +1,157 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Expression;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class Glob implements ValueInterface
18
+ {
19
+ /**
20
+ * @var string
21
+ */
22
+ private $pattern;
23
+
24
+ /**
25
+ * @param string $pattern
26
+ */
27
+ public function __construct($pattern)
28
+ {
29
+ $this->pattern = $pattern;
30
+ }
31
+
32
+ /**
33
+ * {@inheritdoc}
34
+ */
35
+ public function render()
36
+ {
37
+ return $this->pattern;
38
+ }
39
+
40
+ /**
41
+ * {@inheritdoc}
42
+ */
43
+ public function renderPattern()
44
+ {
45
+ return $this->pattern;
46
+ }
47
+
48
+ /**
49
+ * {@inheritdoc}
50
+ */
51
+ public function getType()
52
+ {
53
+ return Expression::TYPE_GLOB;
54
+ }
55
+
56
+ /**
57
+ * {@inheritdoc}
58
+ */
59
+ public function isCaseSensitive()
60
+ {
61
+ return true;
62
+ }
63
+
64
+ /**
65
+ * {@inheritdoc}
66
+ */
67
+ public function prepend($expr)
68
+ {
69
+ $this->pattern = $expr.$this->pattern;
70
+
71
+ return $this;
72
+ }
73
+
74
+ /**
75
+ * {@inheritdoc}
76
+ */
77
+ public function append($expr)
78
+ {
79
+ $this->pattern .= $expr;
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Tests if glob is expandable ("*.{a,b}" syntax).
86
+ *
87
+ * @return bool
88
+ */
89
+ public function isExpandable()
90
+ {
91
+ return false !== strpos($this->pattern, '{')
92
+ && false !== strpos($this->pattern, '}');
93
+ }
94
+
95
+ /**
96
+ * @param bool $strictLeadingDot
97
+ * @param bool $strictWildcardSlash
98
+ *
99
+ * @return Regex
100
+ */
101
+ public function toRegex($strictLeadingDot = true, $strictWildcardSlash = true)
102
+ {
103
+ $firstByte = true;
104
+ $escaping = false;
105
+ $inCurlies = 0;
106
+ $regex = '';
107
+ $sizeGlob = strlen($this->pattern);
108
+ for ($i = 0; $i < $sizeGlob; $i++) {
109
+ $car = $this->pattern[$i];
110
+ if ($firstByte) {
111
+ if ($strictLeadingDot && '.' !== $car) {
112
+ $regex .= '(?=[^\.])';
113
+ }
114
+
115
+ $firstByte = false;
116
+ }
117
+
118
+ if ('/' === $car) {
119
+ $firstByte = true;
120
+ }
121
+
122
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
123
+ $regex .= "\\$car";
124
+ } elseif ('*' === $car) {
125
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
126
+ } elseif ('?' === $car) {
127
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
128
+ } elseif ('{' === $car) {
129
+ $regex .= $escaping ? '\\{' : '(';
130
+ if (!$escaping) {
131
+ ++$inCurlies;
132
+ }
133
+ } elseif ('}' === $car && $inCurlies) {
134
+ $regex .= $escaping ? '}' : ')';
135
+ if (!$escaping) {
136
+ --$inCurlies;
137
+ }
138
+ } elseif (',' === $car && $inCurlies) {
139
+ $regex .= $escaping ? ',' : '|';
140
+ } elseif ('\\' === $car) {
141
+ if ($escaping) {
142
+ $regex .= '\\\\';
143
+ $escaping = false;
144
+ } else {
145
+ $escaping = true;
146
+ }
147
+
148
+ continue;
149
+ } else {
150
+ $regex .= $car;
151
+ }
152
+ $escaping = false;
153
+ }
154
+
155
+ return new Regex('^'.$regex.'$');
156
+ }
157
+ }
vendor/symfony/finder/Symfony/Component/Finder/Expression/Regex.php ADDED
@@ -0,0 +1,321 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Expression;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class Regex implements ValueInterface
18
+ {
19
+ const START_FLAG = '^';
20
+ const END_FLAG = '$';
21
+ const BOUNDARY = '~';
22
+ const JOKER = '.*';
23
+ const ESCAPING = '\\';
24
+
25
+ /**
26
+ * @var string
27
+ */
28
+ private $pattern;
29
+
30
+ /**
31
+ * @var array
32
+ */
33
+ private $options;
34
+
35
+ /**
36
+ * @var bool
37
+ */
38
+ private $startFlag;
39
+
40
+ /**
41
+ * @var bool
42
+ */
43
+ private $endFlag;
44
+
45
+ /**
46
+ * @var bool
47
+ */
48
+ private $startJoker;
49
+
50
+ /**
51
+ * @var bool
52
+ */
53
+ private $endJoker;
54
+
55
+ /**
56
+ * @param string $expr
57
+ *
58
+ * @return Regex
59
+ *
60
+ * @throws \InvalidArgumentException
61
+ */
62
+ public static function create($expr)
63
+ {
64
+ if (preg_match('/^(.{3,}?)([imsxuADU]*)$/', $expr, $m)) {
65
+ $start = substr($m[1], 0, 1);
66
+ $end = substr($m[1], -1);
67
+
68
+ if (
69
+ ($start === $end && !preg_match('/[*?[:alnum:] \\\\]/', $start))
70
+ || ($start === '{' && $end === '}')
71
+ || ($start === '(' && $end === ')')
72
+ ) {
73
+ return new self(substr($m[1], 1, -1), $m[2], $end);
74
+ }
75
+ }
76
+
77
+ throw new \InvalidArgumentException('Given expression is not a regex.');
78
+ }
79
+
80
+ /**
81
+ * @param string $pattern
82
+ * @param string $options
83
+ * @param string $delimiter
84
+ */
85
+ public function __construct($pattern, $options = '', $delimiter = null)
86
+ {
87
+ if (null !== $delimiter) {
88
+ // removes delimiter escaping
89
+ $pattern = str_replace('\\'.$delimiter, $delimiter, $pattern);
90
+ }
91
+
92
+ $this->parsePattern($pattern);
93
+ $this->options = $options;
94
+ }
95
+
96
+ /**
97
+ * @return string
98
+ */
99
+ public function __toString()
100
+ {
101
+ return $this->render();
102
+ }
103
+
104
+ /**
105
+ * {@inheritdoc}
106
+ */
107
+ public function render()
108
+ {
109
+ return self::BOUNDARY
110
+ .$this->renderPattern()
111
+ .self::BOUNDARY
112
+ .$this->options;
113
+ }
114
+
115
+ /**
116
+ * {@inheritdoc}
117
+ */
118
+ public function renderPattern()
119
+ {
120
+ return ($this->startFlag ? self::START_FLAG : '')
121
+ .($this->startJoker ? self::JOKER : '')
122
+ .str_replace(self::BOUNDARY, '\\'.self::BOUNDARY, $this->pattern)
123
+ .($this->endJoker ? self::JOKER : '')
124
+ .($this->endFlag ? self::END_FLAG : '');
125
+ }
126
+
127
+ /**
128
+ * {@inheritdoc}
129
+ */
130
+ public function isCaseSensitive()
131
+ {
132
+ return !$this->hasOption('i');
133
+ }
134
+
135
+ /**
136
+ * {@inheritdoc}
137
+ */
138
+ public function getType()
139
+ {
140
+ return Expression::TYPE_REGEX;
141
+ }
142
+
143
+ /**
144
+ * {@inheritdoc}
145
+ */
146
+ public function prepend($expr)
147
+ {
148
+ $this->pattern = $expr.$this->pattern;
149
+
150
+ return $this;
151
+ }
152
+
153
+ /**
154
+ * {@inheritdoc}
155
+ */
156
+ public function append($expr)
157
+ {
158
+ $this->pattern .= $expr;
159
+
160
+ return $this;
161
+ }
162
+
163
+ /**
164
+ * @param string $option
165
+ *
166
+ * @return bool
167
+ */
168
+ public function hasOption($option)
169
+ {
170
+ return false !== strpos($this->options, $option);
171
+ }
172
+
173
+ /**
174
+ * @param string $option
175
+ *
176
+ * @return Regex
177
+ */
178
+ public function addOption($option)
179
+ {
180
+ if (!$this->hasOption($option)) {
181
+ $this->options .= $option;
182
+ }
183
+
184
+ return $this;
185
+ }
186
+
187
+ /**
188
+ * @param string $option
189
+ *
190
+ * @return Regex
191
+ */
192
+ public function removeOption($option)
193
+ {
194
+ $this->options = str_replace($option, '', $this->options);
195
+
196
+ return $this;
197
+ }
198
+
199
+ /**
200
+ * @param bool $startFlag
201
+ *
202
+ * @return Regex
203
+ */
204
+ public function setStartFlag($startFlag)
205
+ {
206
+ $this->startFlag = $startFlag;
207
+
208
+ return $this;
209
+ }
210
+
211
+ /**
212
+ * @return bool
213
+ */
214
+ public function hasStartFlag()
215
+ {
216
+ return $this->startFlag;
217
+ }
218
+
219
+ /**
220
+ * @param bool $endFlag
221
+ *
222
+ * @return Regex
223
+ */
224
+ public function setEndFlag($endFlag)
225
+ {
226
+ $this->endFlag = (bool) $endFlag;
227
+
228
+ return $this;
229
+ }
230
+
231
+ /**
232
+ * @return bool
233
+ */
234
+ public function hasEndFlag()
235
+ {
236
+ return $this->endFlag;
237
+ }
238
+
239
+ /**
240
+ * @param bool $startJoker
241
+ *
242
+ * @return Regex
243
+ */
244
+ public function setStartJoker($startJoker)
245
+ {
246
+ $this->startJoker = $startJoker;
247
+
248
+ return $this;
249
+ }
250
+
251
+ /**
252
+ * @return bool
253
+ */
254
+ public function hasStartJoker()
255
+ {
256
+ return $this->startJoker;
257
+ }
258
+
259
+ /**
260
+ * @param bool $endJoker
261
+ *
262
+ * @return Regex
263
+ */
264
+ public function setEndJoker($endJoker)
265
+ {
266
+ $this->endJoker = (bool) $endJoker;
267
+
268
+ return $this;
269
+ }
270
+
271
+ /**
272
+ * @return bool
273
+ */
274
+ public function hasEndJoker()
275
+ {
276
+ return $this->endJoker;
277
+ }
278
+
279
+ /**
280
+ * @param array $replacement
281
+ *
282
+ * @return Regex
283
+ */
284
+ public function replaceJokers($replacement)
285
+ {
286
+ $replace = function ($subject) use ($replacement) {
287
+ $subject = $subject[0];
288
+ $replace = 0 === substr_count($subject, '\\') % 2;
289
+
290
+ return $replace ? str_replace('.', $replacement, $subject) : $subject;
291
+ };
292
+
293
+ $this->pattern = preg_replace_callback('~[\\\\]*\\.~', $replace, $this->pattern);
294
+
295
+ return $this;
296
+ }
297
+
298
+ /**
299
+ * @param string $pattern
300
+ */
301
+ private function parsePattern($pattern)
302
+ {
303
+ if ($this->startFlag = self::START_FLAG === substr($pattern, 0, 1)) {
304
+ $pattern = substr($pattern, 1);
305
+ }
306
+
307
+ if ($this->startJoker = self::JOKER === substr($pattern, 0, 2)) {
308
+ $pattern = substr($pattern, 2);
309
+ }
310
+
311
+ if ($this->endFlag = (self::END_FLAG === substr($pattern, -1) && self::ESCAPING !== substr($pattern, -2, -1))) {
312
+ $pattern = substr($pattern, 0, -1);
313
+ }
314
+
315
+ if ($this->endJoker = (self::JOKER === substr($pattern, -2) && self::ESCAPING !== substr($pattern, -3, -2))) {
316
+ $pattern = substr($pattern, 0, -2);
317
+ }
318
+
319
+ $this->pattern = $pattern;
320
+ }
321
+ }
vendor/symfony/finder/Symfony/Component/Finder/Expression/ValueInterface.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Expression;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ interface ValueInterface
18
+ {
19
+ /**
20
+ * Renders string representation of expression.
21
+ *
22
+ * @return string
23
+ */
24
+ public function render();
25
+
26
+ /**
27
+ * Renders string representation of pattern.
28
+ *
29
+ * @return string
30
+ */
31
+ public function renderPattern();
32
+
33
+ /**
34
+ * Returns value case sensitivity.
35
+ *
36
+ * @return bool
37
+ */
38
+ public function isCaseSensitive();
39
+
40
+ /**
41
+ * Returns expression type.
42
+ *
43
+ * @return int
44
+ */
45
+ public function getType();
46
+
47
+ /**
48
+ * @param string $expr
49
+ *
50
+ * @return ValueInterface
51
+ */
52
+ public function prepend($expr);
53
+
54
+ /**
55
+ * @param string $expr
56
+ *
57
+ * @return ValueInterface
58
+ */
59
+ public function append($expr);
60
+ }
vendor/symfony/finder/Symfony/Component/Finder/Finder.php ADDED
@@ -0,0 +1,840 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder;
13
+
14
+ use Symfony\Component\Finder\Adapter\AdapterInterface;
15
+ use Symfony\Component\Finder\Adapter\GnuFindAdapter;
16
+ use Symfony\Component\Finder\Adapter\BsdFindAdapter;
17
+ use Symfony\Component\Finder\Adapter\PhpAdapter;
18
+ use Symfony\Component\Finder\Comparator\DateComparator;
19
+ use Symfony\Component\Finder\Comparator\NumberComparator;
20
+ use Symfony\Component\Finder\Exception\ExceptionInterface;
21
+ use Symfony\Component\Finder\Iterator\CustomFilterIterator;
22
+ use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
23
+ use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
24
+ use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
25
+ use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
26
+ use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
27
+ use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
28
+ use Symfony\Component\Finder\Iterator\SortableIterator;
29
+
30
+ /**
31
+ * Finder allows to build rules to find files and directories.
32
+ *
33
+ * It is a thin wrapper around several specialized iterator classes.
34
+ *
35
+ * All rules may be invoked several times.
36
+ *
37
+ * All methods return the current Finder object to allow easy chaining:
38
+ *
39
+ * $finder = Finder::create()->files()->name('*.php')->in(__DIR__);
40
+ *
41
+ * @author Fabien Potencier <fabien@symfony.com>
42
+ *
43
+ * @api
44
+ */
45
+ class Finder implements \IteratorAggregate, \Countable
46
+ {
47
+ const IGNORE_VCS_FILES = 1;
48
+ const IGNORE_DOT_FILES = 2;
49
+
50
+ private $mode = 0;
51
+ private $names = array();
52
+ private $notNames = array();
53
+ private $exclude = array();
54
+ private $filters = array();
55
+ private $depths = array();
56
+ private $sizes = array();
57
+ private $followLinks = false;
58
+ private $sort = false;
59
+ private $ignore = 0;
60
+ private $dirs = array();
61
+ private $dates = array();
62
+ private $iterators = array();
63
+ private $contains = array();
64
+ private $notContains = array();
65
+ private $adapters = array();
66
+ private $paths = array();
67
+ private $notPaths = array();
68
+ private $ignoreUnreadableDirs = false;
69
+
70
+ private static $vcsPatterns = array('.svn', '_svn', 'CVS', '_darcs', '.arch-params', '.monotone', '.bzr', '.git', '.hg');
71
+
72
+ /**
73
+ * Constructor.
74
+ */
75
+ public function __construct()
76
+ {
77
+ $this->ignore = static::IGNORE_VCS_FILES | static::IGNORE_DOT_FILES;
78
+
79
+ $this
80
+ ->addAdapter(new GnuFindAdapter())
81
+ ->addAdapter(new BsdFindAdapter())
82
+ ->addAdapter(new PhpAdapter(), -50)
83
+ ->setAdapter('php')
84
+ ;
85
+ }
86
+
87
+ /**
88
+ * Creates a new Finder.
89
+ *
90
+ * @return Finder A new Finder instance
91
+ *
92
+ * @api
93
+ */
94
+ public static function create()
95
+ {
96
+ return new static();
97
+ }
98
+
99
+ /**
100
+ * Registers a finder engine implementation.
101
+ *
102
+ * @param AdapterInterface $adapter An adapter instance
103
+ * @param int $priority Highest is selected first
104
+ *
105
+ * @return Finder The current Finder instance
106
+ */
107
+ public function addAdapter(AdapterInterface $adapter, $priority = 0)
108
+ {
109
+ $this->adapters[$adapter->getName()] = array(
110
+ 'adapter' => $adapter,
111
+ 'priority' => $priority,
112
+ 'selected' => false,
113
+ );
114
+
115
+ return $this->sortAdapters();
116
+ }
117
+
118
+ /**
119
+ * Sets the selected adapter to the best one according to the current platform the code is run on.
120
+ *
121
+ * @return Finder The current Finder instance
122
+ */
123
+ public function useBestAdapter()
124
+ {
125
+ $this->resetAdapterSelection();
126
+
127
+ return $this->sortAdapters();
128
+ }
129
+
130
+ /**
131
+ * Selects the adapter to use.
132
+ *
133
+ * @param string $name
134
+ *
135
+ * @throws \InvalidArgumentException
136
+ *
137
+ * @return Finder The current Finder instance
138
+ */
139
+ public function setAdapter($name)
140
+ {
141
+ if (!isset($this->adapters[$name])) {
142
+ throw new \InvalidArgumentException(sprintf('Adapter "%s" does not exist.', $name));
143
+ }
144
+
145
+ $this->resetAdapterSelection();
146
+ $this->adapters[$name]['selected'] = true;
147
+
148
+ return $this->sortAdapters();
149
+ }
150
+
151
+ /**
152
+ * Removes all adapters registered in the finder.
153
+ *
154
+ * @return Finder The current Finder instance
155
+ */
156
+ public function removeAdapters()
157
+ {
158
+ $this->adapters = array();
159
+
160
+ return $this;
161
+ }
162
+
163
+ /**
164
+ * Returns registered adapters ordered by priority without extra information.
165
+ *
166
+ * @return AdapterInterface[]
167
+ */
168
+ public function getAdapters()
169
+ {
170
+ return array_values(array_map(function (array $adapter) {
171
+ return $adapter['adapter'];
172
+ }, $this->adapters));
173
+ }
174
+
175
+ /**
176
+ * Restricts the matching to directories only.
177
+ *
178
+ * @return Finder The current Finder instance
179
+ *
180
+ * @api
181
+ */
182
+ public function directories()
183
+ {
184
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_DIRECTORIES;
185
+
186
+ return $this;
187
+ }
188
+
189
+ /**
190
+ * Restricts the matching to files only.
191
+ *
192
+ * @return Finder The current Finder instance
193
+ *
194
+ * @api
195
+ */
196
+ public function files()
197
+ {
198
+ $this->mode = Iterator\FileTypeFilterIterator::ONLY_FILES;
199
+
200
+ return $this;
201
+ }
202
+
203
+ /**
204
+ * Adds tests for the directory depth.
205
+ *
206
+ * Usage:
207
+ *
208
+ * $finder->depth('> 1') // the Finder will start matching at level 1.
209
+ * $finder->depth('< 3') // the Finder will descend at most 3 levels of directories below the starting point.
210
+ *
211
+ * @param int $level The depth level expression
212
+ *
213
+ * @return Finder The current Finder instance
214
+ *
215
+ * @see DepthRangeFilterIterator
216
+ * @see NumberComparator
217
+ *
218
+ * @api
219
+ */
220
+ public function depth($level)
221
+ {
222
+ $this->depths[] = new Comparator\NumberComparator($level);
223
+
224
+ return $this;
225
+ }
226
+
227
+ /**
228
+ * Adds tests for file dates (last modified).
229
+ *
230
+ * The date must be something that strtotime() is able to parse:
231
+ *
232
+ * $finder->date('since yesterday');
233
+ * $finder->date('until 2 days ago');
234
+ * $finder->date('> now - 2 hours');
235
+ * $finder->date('>= 2005-10-15');
236
+ *
237
+ * @param string $date A date rage string
238
+ *
239
+ * @return Finder The current Finder instance
240
+ *
241
+ * @see strtotime
242
+ * @see DateRangeFilterIterator
243
+ * @see DateComparator
244
+ *
245
+ * @api
246
+ */
247
+ public function date($date)
248
+ {
249
+ $this->dates[] = new Comparator\DateComparator($date);
250
+
251
+ return $this;
252
+ }
253
+
254
+ /**
255
+ * Adds rules that files must match.
256
+ *
257
+ * You can use patterns (delimited with / sign), globs or simple strings.
258
+ *
259
+ * $finder->name('*.php')
260
+ * $finder->name('/\.php$/') // same as above
261
+ * $finder->name('test.php')
262
+ *
263
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
264
+ *
265
+ * @return Finder The current Finder instance
266
+ *
267
+ * @see FilenameFilterIterator
268
+ *
269
+ * @api
270
+ */
271
+ public function name($pattern)
272
+ {
273
+ $this->names[] = $pattern;
274
+
275
+ return $this;
276
+ }
277
+
278
+ /**
279
+ * Adds rules that files must not match.
280
+ *
281
+ * @param string $pattern A pattern (a regexp, a glob, or a string)
282
+ *
283
+ * @return Finder The current Finder instance
284
+ *
285
+ * @see FilenameFilterIterator
286
+ *
287
+ * @api
288
+ */
289
+ public function notName($pattern)
290
+ {
291
+ $this->notNames[] = $pattern;
292
+
293
+ return $this;
294
+ }
295
+
296
+ /**
297
+ * Adds tests that file contents must match.
298
+ *
299
+ * Strings or PCRE patterns can be used:
300
+ *
301
+ * $finder->contains('Lorem ipsum')
302
+ * $finder->contains('/Lorem ipsum/i')
303
+ *
304
+ * @param string $pattern A pattern (string or regexp)
305
+ *
306
+ * @return Finder The current Finder instance
307
+ *
308
+ * @see FilecontentFilterIterator
309
+ */
310
+ public function contains($pattern)
311
+ {
312
+ $this->contains[] = $pattern;
313
+
314
+ return $this;
315
+ }
316
+
317
+ /**
318
+ * Adds tests that file contents must not match.
319
+ *
320
+ * Strings or PCRE patterns can be used:
321
+ *
322
+ * $finder->notContains('Lorem ipsum')
323
+ * $finder->notContains('/Lorem ipsum/i')
324
+ *
325
+ * @param string $pattern A pattern (string or regexp)
326
+ *
327
+ * @return Finder The current Finder instance
328
+ *
329
+ * @see FilecontentFilterIterator
330
+ */
331
+ public function notContains($pattern)
332
+ {
333
+ $this->notContains[] = $pattern;
334
+
335
+ return $this;
336
+ }
337
+
338
+ /**
339
+ * Adds rules that filenames must match.
340
+ *
341
+ * You can use patterns (delimited with / sign) or simple strings.
342
+ *
343
+ * $finder->path('some/special/dir')
344
+ * $finder->path('/some\/special\/dir/') // same as above
345
+ *
346
+ * Use only / as dirname separator.
347
+ *
348
+ * @param string $pattern A pattern (a regexp or a string)
349
+ *
350
+ * @return Finder The current Finder instance
351
+ *
352
+ * @see FilenameFilterIterator
353
+ */
354
+ public function path($pattern)
355
+ {
356
+ $this->paths[] = $pattern;
357
+
358
+ return $this;
359
+ }
360
+
361
+ /**
362
+ * Adds rules that filenames must not match.
363
+ *
364
+ * You can use patterns (delimited with / sign) or simple strings.
365
+ *
366
+ * $finder->notPath('some/special/dir')
367
+ * $finder->notPath('/some\/special\/dir/') // same as above
368
+ *
369
+ * Use only / as dirname separator.
370
+ *
371
+ * @param string $pattern A pattern (a regexp or a string)
372
+ *
373
+ * @return Finder The current Finder instance
374
+ *
375
+ * @see FilenameFilterIterator
376
+ */
377
+ public function notPath($pattern)
378
+ {
379
+ $this->notPaths[] = $pattern;
380
+
381
+ return $this;
382
+ }
383
+
384
+ /**
385
+ * Adds tests for file sizes.
386
+ *
387
+ * $finder->size('> 10K');
388
+ * $finder->size('<= 1Ki');
389
+ * $finder->size(4);
390
+ *
391
+ * @param string $size A size range string
392
+ *
393
+ * @return Finder The current Finder instance
394
+ *
395
+ * @see SizeRangeFilterIterator
396
+ * @see NumberComparator
397
+ *
398
+ * @api
399
+ */
400
+ public function size($size)
401
+ {
402
+ $this->sizes[] = new Comparator\NumberComparator($size);
403
+
404
+ return $this;
405
+ }
406
+
407
+ /**
408
+ * Excludes directories.
409
+ *
410
+ * @param string|array $dirs A directory path or an array of directories
411
+ *
412
+ * @return Finder The current Finder instance
413
+ *
414
+ * @see ExcludeDirectoryFilterIterator
415
+ *
416
+ * @api
417
+ */
418
+ public function exclude($dirs)
419
+ {
420
+ $this->exclude = array_merge($this->exclude, (array) $dirs);
421
+
422
+ return $this;
423
+ }
424
+
425
+ /**
426
+ * Excludes "hidden" directories and files (starting with a dot).
427
+ *
428
+ * @param bool $ignoreDotFiles Whether to exclude "hidden" files or not
429
+ *
430
+ * @return Finder The current Finder instance
431
+ *
432
+ * @see ExcludeDirectoryFilterIterator
433
+ *
434
+ * @api
435
+ */
436
+ public function ignoreDotFiles($ignoreDotFiles)
437
+ {
438
+ if ($ignoreDotFiles) {
439
+ $this->ignore = $this->ignore | static::IGNORE_DOT_FILES;
440
+ } else {
441
+ $this->ignore = $this->ignore & ~static::IGNORE_DOT_FILES;
442
+ }
443
+
444
+ return $this;
445
+ }
446
+
447
+ /**
448
+ * Forces the finder to ignore version control directories.
449
+ *
450
+ * @param bool $ignoreVCS Whether to exclude VCS files or not
451
+ *
452
+ * @return Finder The current Finder instance
453
+ *
454
+ * @see ExcludeDirectoryFilterIterator
455
+ *
456
+ * @api
457
+ */
458
+ public function ignoreVCS($ignoreVCS)
459
+ {
460
+ if ($ignoreVCS) {
461
+ $this->ignore = $this->ignore | static::IGNORE_VCS_FILES;
462
+ } else {
463
+ $this->ignore = $this->ignore & ~static::IGNORE_VCS_FILES;
464
+ }
465
+
466
+ return $this;
467
+ }
468
+
469
+ /**
470
+ * Adds VCS patterns.
471
+ *
472
+ * @see ignoreVCS()
473
+ *
474
+ * @param string|string[] $pattern VCS patterns to ignore
475
+ */
476
+ public static function addVCSPattern($pattern)
477
+ {
478
+ foreach ((array) $pattern as $p) {
479
+ self::$vcsPatterns[] = $p;
480
+ }
481
+
482
+ self::$vcsPatterns = array_unique(self::$vcsPatterns);
483
+ }
484
+
485
+ /**
486
+ * Sorts files and directories by an anonymous function.
487
+ *
488
+ * The anonymous function receives two \SplFileInfo instances to compare.
489
+ *
490
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
491
+ *
492
+ * @param \Closure $closure An anonymous function
493
+ *
494
+ * @return Finder The current Finder instance
495
+ *
496
+ * @see SortableIterator
497
+ *
498
+ * @api
499
+ */
500
+ public function sort(\Closure $closure)
501
+ {
502
+ $this->sort = $closure;
503
+
504
+ return $this;
505
+ }
506
+
507
+ /**
508
+ * Sorts files and directories by name.
509
+ *
510
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
511
+ *
512
+ * @return Finder The current Finder instance
513
+ *
514
+ * @see SortableIterator
515
+ *
516
+ * @api
517
+ */
518
+ public function sortByName()
519
+ {
520
+ $this->sort = Iterator\SortableIterator::SORT_BY_NAME;
521
+
522
+ return $this;
523
+ }
524
+
525
+ /**
526
+ * Sorts files and directories by type (directories before files), then by name.
527
+ *
528
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
529
+ *
530
+ * @return Finder The current Finder instance
531
+ *
532
+ * @see SortableIterator
533
+ *
534
+ * @api
535
+ */
536
+ public function sortByType()
537
+ {
538
+ $this->sort = Iterator\SortableIterator::SORT_BY_TYPE;
539
+
540
+ return $this;
541
+ }
542
+
543
+ /**
544
+ * Sorts files and directories by the last accessed time.
545
+ *
546
+ * This is the time that the file was last accessed, read or written to.
547
+ *
548
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
549
+ *
550
+ * @return Finder The current Finder instance
551
+ *
552
+ * @see SortableIterator
553
+ *
554
+ * @api
555
+ */
556
+ public function sortByAccessedTime()
557
+ {
558
+ $this->sort = Iterator\SortableIterator::SORT_BY_ACCESSED_TIME;
559
+
560
+ return $this;
561
+ }
562
+
563
+ /**
564
+ * Sorts files and directories by the last inode changed time.
565
+ *
566
+ * This is the time that the inode information was last modified (permissions, owner, group or other metadata).
567
+ *
568
+ * On Windows, since inode is not available, changed time is actually the file creation time.
569
+ *
570
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
571
+ *
572
+ * @return Finder The current Finder instance
573
+ *
574
+ * @see SortableIterator
575
+ *
576
+ * @api
577
+ */
578
+ public function sortByChangedTime()
579
+ {
580
+ $this->sort = Iterator\SortableIterator::SORT_BY_CHANGED_TIME;
581
+
582
+ return $this;
583
+ }
584
+
585
+ /**
586
+ * Sorts files and directories by the last modified time.
587
+ *
588
+ * This is the last time the actual contents of the file were last modified.
589
+ *
590
+ * This can be slow as all the matching files and directories must be retrieved for comparison.
591
+ *
592
+ * @return Finder The current Finder instance
593
+ *
594
+ * @see SortableIterator
595
+ *
596
+ * @api
597
+ */
598
+ public function sortByModifiedTime()
599
+ {
600
+ $this->sort = Iterator\SortableIterator::SORT_BY_MODIFIED_TIME;
601
+
602
+ return $this;
603
+ }
604
+
605
+ /**
606
+ * Filters the iterator with an anonymous function.
607
+ *
608
+ * The anonymous function receives a \SplFileInfo and must return false
609
+ * to remove files.
610
+ *
611
+ * @param \Closure $closure An anonymous function
612
+ *
613
+ * @return Finder The current Finder instance
614
+ *
615
+ * @see CustomFilterIterator
616
+ *
617
+ * @api
618
+ */
619
+ public function filter(\Closure $closure)
620
+ {
621
+ $this->filters[] = $closure;
622
+
623
+ return $this;
624
+ }
625
+
626
+ /**
627
+ * Forces the following of symlinks.
628
+ *
629
+ * @return Finder The current Finder instance
630
+ *
631
+ * @api
632
+ */
633
+ public function followLinks()
634
+ {
635
+ $this->followLinks = true;
636
+
637
+ return $this;
638
+ }
639
+
640
+ /**
641
+ * Tells finder to ignore unreadable directories.
642
+ *
643
+ * By default, scanning unreadable directories content throws an AccessDeniedException.
644
+ *
645
+ * @param bool $ignore
646
+ *
647
+ * @return Finder The current Finder instance
648
+ */
649
+ public function ignoreUnreadableDirs($ignore = true)
650
+ {
651
+ $this->ignoreUnreadableDirs = (bool) $ignore;
652
+
653
+ return $this;
654
+ }
655
+
656
+ /**
657
+ * Searches files and directories which match defined rules.
658
+ *
659
+ * @param string|array $dirs A directory path or an array of directories
660
+ *
661
+ * @return Finder The current Finder instance
662
+ *
663
+ * @throws \InvalidArgumentException if one of the directories does not exist
664
+ *
665
+ * @api
666
+ */
667
+ public function in($dirs)
668
+ {
669
+ $resolvedDirs = array();
670
+
671
+ foreach ((array) $dirs as $dir) {
672
+ if (is_dir($dir)) {
673
+ $resolvedDirs[] = $dir;
674
+ } elseif ($glob = glob($dir, GLOB_BRACE | GLOB_ONLYDIR)) {
675
+ $resolvedDirs = array_merge($resolvedDirs, $glob);
676
+ } else {
677
+ throw new \InvalidArgumentException(sprintf('The "%s" directory does not exist.', $dir));
678
+ }
679
+ }
680
+
681
+ $this->dirs = array_merge($this->dirs, $resolvedDirs);
682
+
683
+ return $this;
684
+ }
685
+
686
+ /**
687
+ * Returns an Iterator for the current Finder configuration.
688
+ *
689
+ * This method implements the IteratorAggregate interface.
690
+ *
691
+ * @return \Iterator An iterator
692
+ *
693
+ * @throws \LogicException if the in() method has not been called
694
+ */
695
+ public function getIterator()
696
+ {
697
+ if (0 === count($this->dirs) && 0 === count($this->iterators)) {
698
+ throw new \LogicException('You must call one of in() or append() methods before iterating over a Finder.');
699
+ }
700
+
701
+ if (1 === count($this->dirs) && 0 === count($this->iterators)) {
702
+ return $this->searchInDirectory($this->dirs[0]);
703
+ }
704
+
705
+ $iterator = new \AppendIterator();
706
+ foreach ($this->dirs as $dir) {
707
+ $iterator->append($this->searchInDirectory($dir));
708
+ }
709
+
710
+ foreach ($this->iterators as $it) {
711
+ $iterator->append($it);
712
+ }
713
+
714
+ return $iterator;
715
+ }
716
+
717
+ /**
718
+ * Appends an existing set of files/directories to the finder.
719
+ *
720
+ * The set can be another Finder, an Iterator, an IteratorAggregate, or even a plain array.
721
+ *
722
+ * @param mixed $iterator
723
+ *
724
+ * @return Finder The finder
725
+ *
726
+ * @throws \InvalidArgumentException When the given argument is not iterable.
727
+ */
728
+ public function append($iterator)
729
+ {
730
+ if ($iterator instanceof \IteratorAggregate) {
731
+ $this->iterators[] = $iterator->getIterator();
732
+ } elseif ($iterator instanceof \Iterator) {
733
+ $this->iterators[] = $iterator;
734
+ } elseif ($iterator instanceof \Traversable || is_array($iterator)) {
735
+ $it = new \ArrayIterator();
736
+ foreach ($iterator as $file) {
737
+ $it->append($file instanceof \SplFileInfo ? $file : new \SplFileInfo($file));
738
+ }
739
+ $this->iterators[] = $it;
740
+ } else {
741
+ throw new \InvalidArgumentException('Finder::append() method wrong argument type.');
742
+ }
743
+
744
+ return $this;
745
+ }
746
+
747
+ /**
748
+ * Counts all the results collected by the iterators.
749
+ *
750
+ * @return int
751
+ */
752
+ public function count()
753
+ {
754
+ return iterator_count($this->getIterator());
755
+ }
756
+
757
+ /**
758
+ * @return Finder The current Finder instance
759
+ */
760
+ private function sortAdapters()
761
+ {
762
+ uasort($this->adapters, function (array $a, array $b) {
763
+ if ($a['selected'] || $b['selected']) {
764
+ return $a['selected'] ? -1 : 1;
765
+ }
766
+
767
+ return $a['priority'] > $b['priority'] ? -1 : 1;
768
+ });
769
+
770
+ return $this;
771
+ }
772
+
773
+ /**
774
+ * @param $dir
775
+ *
776
+ * @return \Iterator
777
+ *
778
+ * @throws \RuntimeException When none of the adapters are supported
779
+ */
780
+ private function searchInDirectory($dir)
781
+ {
782
+ if (static::IGNORE_VCS_FILES === (static::IGNORE_VCS_FILES & $this->ignore)) {
783
+ $this->exclude = array_merge($this->exclude, self::$vcsPatterns);
784
+ }
785
+
786
+ if (static::IGNORE_DOT_FILES === (static::IGNORE_DOT_FILES & $this->ignore)) {
787
+ $this->notPaths[] = '#(^|/)\..+(/|$)#';
788
+ }
789
+
790
+ foreach ($this->adapters as $adapter) {
791
+ if ($adapter['adapter']->isSupported()) {
792
+ try {
793
+ return $this
794
+ ->buildAdapter($adapter['adapter'])
795
+ ->searchInDirectory($dir);
796
+ } catch (ExceptionInterface $e) {
797
+ }
798
+ }
799
+ }
800
+
801
+ throw new \RuntimeException('No supported adapter found.');
802
+ }
803
+
804
+ /**
805
+ * @param AdapterInterface $adapter
806
+ *
807
+ * @return AdapterInterface
808
+ */
809
+ private function buildAdapter(AdapterInterface $adapter)
810
+ {
811
+ return $adapter
812
+ ->setFollowLinks($this->followLinks)
813
+ ->setDepths($this->depths)
814
+ ->setMode($this->mode)
815
+ ->setExclude($this->exclude)
816
+ ->setNames($this->names)
817
+ ->setNotNames($this->notNames)
818
+ ->setContains($this->contains)
819
+ ->setNotContains($this->notContains)
820
+ ->setSizes($this->sizes)
821
+ ->setDates($this->dates)
822
+ ->setFilters($this->filters)
823
+ ->setSort($this->sort)
824
+ ->setPath($this->paths)
825
+ ->setNotPath($this->notPaths)
826
+ ->ignoreUnreadableDirs($this->ignoreUnreadableDirs);
827
+ }
828
+
829
+ /**
830
+ * Unselects all adapters.
831
+ */
832
+ private function resetAdapterSelection()
833
+ {
834
+ $this->adapters = array_map(function (array $properties) {
835
+ $properties['selected'] = false;
836
+
837
+ return $properties;
838
+ }, $this->adapters);
839
+ }
840
+ }
vendor/symfony/finder/Symfony/Component/Finder/Glob.php ADDED
@@ -0,0 +1,103 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder;
13
+
14
+ /**
15
+ * Glob matches globbing patterns against text.
16
+ *
17
+ * if match_glob("foo.*", "foo.bar") echo "matched\n";
18
+ *
19
+ * // prints foo.bar and foo.baz
20
+ * $regex = glob_to_regex("foo.*");
21
+ * for (array('foo.bar', 'foo.baz', 'foo', 'bar') as $t)
22
+ * {
23
+ * if (/$regex/) echo "matched: $car\n";
24
+ * }
25
+ *
26
+ * Glob implements glob(3) style matching that can be used to match
27
+ * against text, rather than fetching names from a filesystem.
28
+ *
29
+ * Based on the Perl Text::Glob module.
30
+ *
31
+ * @author Fabien Potencier <fabien@symfony.com> PHP port
32
+ * @author Richard Clamp <richardc@unixbeard.net> Perl version
33
+ * @copyright 2004-2005 Fabien Potencier <fabien@symfony.com>
34
+ * @copyright 2002 Richard Clamp <richardc@unixbeard.net>
35
+ */
36
+ class Glob
37
+ {
38
+ /**
39
+ * Returns a regexp which is the equivalent of the glob pattern.
40
+ *
41
+ * @param string $glob The glob pattern
42
+ * @param bool $strictLeadingDot
43
+ * @param bool $strictWildcardSlash
44
+ *
45
+ * @return string regex The regexp
46
+ */
47
+ public static function toRegex($glob, $strictLeadingDot = true, $strictWildcardSlash = true)
48
+ {
49
+ $firstByte = true;
50
+ $escaping = false;
51
+ $inCurlies = 0;
52
+ $regex = '';
53
+ $sizeGlob = strlen($glob);
54
+ for ($i = 0; $i < $sizeGlob; $i++) {
55
+ $car = $glob[$i];
56
+ if ($firstByte) {
57
+ if ($strictLeadingDot && '.' !== $car) {
58
+ $regex .= '(?=[^\.])';
59
+ }
60
+
61
+ $firstByte = false;
62
+ }
63
+
64
+ if ('/' === $car) {
65
+ $firstByte = true;
66
+ }
67
+
68
+ if ('.' === $car || '(' === $car || ')' === $car || '|' === $car || '+' === $car || '^' === $car || '$' === $car) {
69
+ $regex .= "\\$car";
70
+ } elseif ('*' === $car) {
71
+ $regex .= $escaping ? '\\*' : ($strictWildcardSlash ? '[^/]*' : '.*');
72
+ } elseif ('?' === $car) {
73
+ $regex .= $escaping ? '\\?' : ($strictWildcardSlash ? '[^/]' : '.');
74
+ } elseif ('{' === $car) {
75
+ $regex .= $escaping ? '\\{' : '(';
76
+ if (!$escaping) {
77
+ ++$inCurlies;
78
+ }
79
+ } elseif ('}' === $car && $inCurlies) {
80
+ $regex .= $escaping ? '}' : ')';
81
+ if (!$escaping) {
82
+ --$inCurlies;
83
+ }
84
+ } elseif (',' === $car && $inCurlies) {
85
+ $regex .= $escaping ? ',' : '|';
86
+ } elseif ('\\' === $car) {
87
+ if ($escaping) {
88
+ $regex .= '\\\\';
89
+ $escaping = false;
90
+ } else {
91
+ $escaping = true;
92
+ }
93
+
94
+ continue;
95
+ } else {
96
+ $regex .= $car;
97
+ }
98
+ $escaping = false;
99
+ }
100
+
101
+ return '#^'.$regex.'$#';
102
+ }
103
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/CustomFilterIterator.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * CustomFilterIterator filters files by applying anonymous functions.
16
+ *
17
+ * The anonymous function receives a \SplFileInfo and must return false
18
+ * to remove files.
19
+ *
20
+ * @author Fabien Potencier <fabien@symfony.com>
21
+ */
22
+ class CustomFilterIterator extends FilterIterator
23
+ {
24
+ private $filters = array();
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @param \Iterator $iterator The Iterator to filter
30
+ * @param array $filters An array of PHP callbacks
31
+ *
32
+ * @throws \InvalidArgumentException
33
+ */
34
+ public function __construct(\Iterator $iterator, array $filters)
35
+ {
36
+ foreach ($filters as $filter) {
37
+ if (!is_callable($filter)) {
38
+ throw new \InvalidArgumentException('Invalid PHP callback.');
39
+ }
40
+ }
41
+ $this->filters = $filters;
42
+
43
+ parent::__construct($iterator);
44
+ }
45
+
46
+ /**
47
+ * Filters the iterator values.
48
+ *
49
+ * @return bool true if the value should be kept, false otherwise
50
+ */
51
+ public function accept()
52
+ {
53
+ $fileinfo = $this->current();
54
+
55
+ foreach ($this->filters as $filter) {
56
+ if (false === call_user_func($filter, $fileinfo)) {
57
+ return false;
58
+ }
59
+ }
60
+
61
+ return true;
62
+ }
63
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/DateRangeFilterIterator.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\Comparator\DateComparator;
15
+
16
+ /**
17
+ * DateRangeFilterIterator filters out files that are not in the given date range (last modified dates).
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ class DateRangeFilterIterator extends FilterIterator
22
+ {
23
+ private $comparators = array();
24
+
25
+ /**
26
+ * Constructor.
27
+ *
28
+ * @param \Iterator $iterator The Iterator to filter
29
+ * @param DateComparator[] $comparators An array of DateComparator instances
30
+ */
31
+ public function __construct(\Iterator $iterator, array $comparators)
32
+ {
33
+ $this->comparators = $comparators;
34
+
35
+ parent::__construct($iterator);
36
+ }
37
+
38
+ /**
39
+ * Filters the iterator values.
40
+ *
41
+ * @return bool true if the value should be kept, false otherwise
42
+ */
43
+ public function accept()
44
+ {
45
+ $fileinfo = $this->current();
46
+
47
+ if (!file_exists($fileinfo->getRealPath())) {
48
+ return false;
49
+ }
50
+
51
+ $filedate = $fileinfo->getMTime();
52
+ foreach ($this->comparators as $compare) {
53
+ if (!$compare->test($filedate)) {
54
+ return false;
55
+ }
56
+ }
57
+
58
+ return true;
59
+ }
60
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/DepthRangeFilterIterator.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * DepthRangeFilterIterator limits the directory depth.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class DepthRangeFilterIterator extends FilterIterator
20
+ {
21
+ private $minDepth = 0;
22
+
23
+ /**
24
+ * Constructor.
25
+ *
26
+ * @param \RecursiveIteratorIterator $iterator The Iterator to filter
27
+ * @param int $minDepth The min depth
28
+ * @param int $maxDepth The max depth
29
+ */
30
+ public function __construct(\RecursiveIteratorIterator $iterator, $minDepth = 0, $maxDepth = PHP_INT_MAX)
31
+ {
32
+ $this->minDepth = $minDepth;
33
+ $iterator->setMaxDepth(PHP_INT_MAX === $maxDepth ? -1 : $maxDepth);
34
+
35
+ parent::__construct($iterator);
36
+ }
37
+
38
+ /**
39
+ * Filters the iterator values.
40
+ *
41
+ * @return bool true if the value should be kept, false otherwise
42
+ */
43
+ public function accept()
44
+ {
45
+ return $this->getInnerIterator()->getDepth() >= $this->minDepth;
46
+ }
47
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/ExcludeDirectoryFilterIterator.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * ExcludeDirectoryFilterIterator filters out directories.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class ExcludeDirectoryFilterIterator extends FilterIterator
20
+ {
21
+ private $patterns = array();
22
+
23
+ /**
24
+ * Constructor.
25
+ *
26
+ * @param \Iterator $iterator The Iterator to filter
27
+ * @param array $directories An array of directories to exclude
28
+ */
29
+ public function __construct(\Iterator $iterator, array $directories)
30
+ {
31
+ foreach ($directories as $directory) {
32
+ $this->patterns[] = '#(^|/)'.preg_quote($directory, '#').'(/|$)#';
33
+ }
34
+
35
+ parent::__construct($iterator);
36
+ }
37
+
38
+ /**
39
+ * Filters the iterator values.
40
+ *
41
+ * @return bool true if the value should be kept, false otherwise
42
+ */
43
+ public function accept()
44
+ {
45
+ $path = $this->isDir() ? $this->current()->getRelativePathname() : $this->current()->getRelativePath();
46
+ $path = strtr($path, '\\', '/');
47
+ foreach ($this->patterns as $pattern) {
48
+ if (preg_match($pattern, $path)) {
49
+ return false;
50
+ }
51
+ }
52
+
53
+ return true;
54
+ }
55
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilePathsIterator.php ADDED
@@ -0,0 +1,131 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\SplFileInfo;
15
+
16
+ /**
17
+ * Iterate over shell command result.
18
+ *
19
+ * @author Jean-François Simon <contact@jfsimon.fr>
20
+ */
21
+ class FilePathsIterator extends \ArrayIterator
22
+ {
23
+ /**
24
+ * @var string
25
+ */
26
+ private $baseDir;
27
+
28
+ /**
29
+ * @var int
30
+ */
31
+ private $baseDirLength;
32
+
33
+ /**
34
+ * @var string
35
+ */
36
+ private $subPath;
37
+
38
+ /**
39
+ * @var string
40
+ */
41
+ private $subPathname;
42
+
43
+ /**
44
+ * @var SplFileInfo
45
+ */
46
+ private $current;
47
+
48
+ /**
49
+ * @param array $paths List of paths returned by shell command
50
+ * @param string $baseDir Base dir for relative path building
51
+ */
52
+ public function __construct(array $paths, $baseDir)
53
+ {
54
+ $this->baseDir = $baseDir;
55
+ $this->baseDirLength = strlen($baseDir);
56
+
57
+ parent::__construct($paths);
58
+ }
59
+
60
+ /**
61
+ * @param string $name
62
+ * @param array $arguments
63
+ *
64
+ * @return mixed
65
+ */
66
+ public function __call($name, array $arguments)
67
+ {
68
+ return call_user_func_array(array($this->current(), $name), $arguments);
69
+ }
70
+
71
+ /**
72
+ * Return an instance of SplFileInfo with support for relative paths.
73
+ *
74
+ * @return SplFileInfo File information
75
+ */
76
+ public function current()
77
+ {
78
+ return $this->current;
79
+ }
80
+
81
+ /**
82
+ * @return string
83
+ */
84
+ public function key()
85
+ {
86
+ return $this->current->getPathname();
87
+ }
88
+
89
+ public function next()
90
+ {
91
+ parent::next();
92
+ $this->buildProperties();
93
+ }
94
+
95
+ public function rewind()
96
+ {
97
+ parent::rewind();
98
+ $this->buildProperties();
99
+ }
100
+
101
+ /**
102
+ * @return string
103
+ */
104
+ public function getSubPath()
105
+ {
106
+ return $this->subPath;
107
+ }
108
+
109
+ /**
110
+ * @return string
111
+ */
112
+ public function getSubPathname()
113
+ {
114
+ return $this->subPathname;
115
+ }
116
+
117
+ private function buildProperties()
118
+ {
119
+ $absolutePath = parent::current();
120
+
121
+ if ($this->baseDir === substr($absolutePath, 0, $this->baseDirLength)) {
122
+ $this->subPathname = ltrim(substr($absolutePath, $this->baseDirLength), '/\\');
123
+ $dir = dirname($this->subPathname);
124
+ $this->subPath = '.' === $dir ? '' : $dir;
125
+ } else {
126
+ $this->subPath = $this->subPathname = '';
127
+ }
128
+
129
+ $this->current = new SplFileInfo(parent::current(), $this->subPath, $this->subPathname);
130
+ }
131
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/FileTypeFilterIterator.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * FileTypeFilterIterator only keeps files, directories, or both.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class FileTypeFilterIterator extends FilterIterator
20
+ {
21
+ const ONLY_FILES = 1;
22
+ const ONLY_DIRECTORIES = 2;
23
+
24
+ private $mode;
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @param \Iterator $iterator The Iterator to filter
30
+ * @param int $mode The mode (self::ONLY_FILES or self::ONLY_DIRECTORIES)
31
+ */
32
+ public function __construct(\Iterator $iterator, $mode)
33
+ {
34
+ $this->mode = $mode;
35
+
36
+ parent::__construct($iterator);
37
+ }
38
+
39
+ /**
40
+ * Filters the iterator values.
41
+ *
42
+ * @return bool true if the value should be kept, false otherwise
43
+ */
44
+ public function accept()
45
+ {
46
+ $fileinfo = $this->current();
47
+ if (self::ONLY_DIRECTORIES === (self::ONLY_DIRECTORIES & $this->mode) && $fileinfo->isFile()) {
48
+ return false;
49
+ } elseif (self::ONLY_FILES === (self::ONLY_FILES & $this->mode) && $fileinfo->isDir()) {
50
+ return false;
51
+ }
52
+
53
+ return true;
54
+ }
55
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilecontentFilterIterator.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * FilecontentFilterIterator filters files by their contents using patterns (regexps or strings).
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
19
+ */
20
+ class FilecontentFilterIterator extends MultiplePcreFilterIterator
21
+ {
22
+ /**
23
+ * Filters the iterator values.
24
+ *
25
+ * @return bool true if the value should be kept, false otherwise
26
+ */
27
+ public function accept()
28
+ {
29
+ if (!$this->matchRegexps && !$this->noMatchRegexps) {
30
+ return true;
31
+ }
32
+
33
+ $fileinfo = $this->current();
34
+
35
+ if ($fileinfo->isDir() || !$fileinfo->isReadable()) {
36
+ return false;
37
+ }
38
+
39
+ $content = $fileinfo->getContents();
40
+ if (!$content) {
41
+ return false;
42
+ }
43
+
44
+ // should at least not match one rule to exclude
45
+ foreach ($this->noMatchRegexps as $regex) {
46
+ if (preg_match($regex, $content)) {
47
+ return false;
48
+ }
49
+ }
50
+
51
+ // should at least match one rule
52
+ $match = true;
53
+ if ($this->matchRegexps) {
54
+ $match = false;
55
+ foreach ($this->matchRegexps as $regex) {
56
+ if (preg_match($regex, $content)) {
57
+ return true;
58
+ }
59
+ }
60
+ }
61
+
62
+ return $match;
63
+ }
64
+
65
+ /**
66
+ * Converts string to regexp if necessary.
67
+ *
68
+ * @param string $str Pattern: string or regexp
69
+ *
70
+ * @return string regexp corresponding to a given string or regexp
71
+ */
72
+ protected function toRegex($str)
73
+ {
74
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
75
+ }
76
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilenameFilterIterator.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\Expression\Expression;
15
+
16
+ /**
17
+ * FilenameFilterIterator filters files by patterns (a regexp, a glob, or a string).
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ class FilenameFilterIterator extends MultiplePcreFilterIterator
22
+ {
23
+ /**
24
+ * Filters the iterator values.
25
+ *
26
+ * @return bool true if the value should be kept, false otherwise
27
+ */
28
+ public function accept()
29
+ {
30
+ $filename = $this->current()->getFilename();
31
+
32
+ // should at least not match one rule to exclude
33
+ foreach ($this->noMatchRegexps as $regex) {
34
+ if (preg_match($regex, $filename)) {
35
+ return false;
36
+ }
37
+ }
38
+
39
+ // should at least match one rule
40
+ $match = true;
41
+ if ($this->matchRegexps) {
42
+ $match = false;
43
+ foreach ($this->matchRegexps as $regex) {
44
+ if (preg_match($regex, $filename)) {
45
+ return true;
46
+ }
47
+ }
48
+ }
49
+
50
+ return $match;
51
+ }
52
+
53
+ /**
54
+ * Converts glob to regexp.
55
+ *
56
+ * PCRE patterns are left unchanged.
57
+ * Glob strings are transformed with Glob::toRegex().
58
+ *
59
+ * @param string $str Pattern: glob or regexp
60
+ *
61
+ * @return string regexp corresponding to a given glob or regexp
62
+ */
63
+ protected function toRegex($str)
64
+ {
65
+ return Expression::create($str)->getRegex()->render();
66
+ }
67
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/FilterIterator.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * This iterator just overrides the rewind method in order to correct a PHP bug.
16
+ *
17
+ * @see https://bugs.php.net/bug.php?id=49104
18
+ *
19
+ * @author Alex Bogomazov
20
+ */
21
+ abstract class FilterIterator extends \FilterIterator
22
+ {
23
+ /**
24
+ * This is a workaround for the problem with \FilterIterator leaving inner \FilesystemIterator in wrong state after
25
+ * rewind in some cases.
26
+ *
27
+ * @see FilterIterator::rewind()
28
+ */
29
+ public function rewind()
30
+ {
31
+ $iterator = $this;
32
+ while ($iterator instanceof \OuterIterator) {
33
+ $innerIterator = $iterator->getInnerIterator();
34
+
35
+ if ($innerIterator instanceof RecursiveDirectoryIterator) {
36
+ if ($innerIterator->isRewindable()) {
37
+ $innerIterator->next();
38
+ $innerIterator->rewind();
39
+ }
40
+ } elseif ($iterator->getInnerIterator() instanceof \FilesystemIterator) {
41
+ $iterator->getInnerIterator()->next();
42
+ $iterator->getInnerIterator()->rewind();
43
+ }
44
+ $iterator = $iterator->getInnerIterator();
45
+ }
46
+
47
+ parent::rewind();
48
+ }
49
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/MultiplePcreFilterIterator.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\Expression\Expression;
15
+
16
+ /**
17
+ * MultiplePcreFilterIterator filters files using patterns (regexps, globs or strings).
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ abstract class MultiplePcreFilterIterator extends FilterIterator
22
+ {
23
+ protected $matchRegexps = array();
24
+ protected $noMatchRegexps = array();
25
+
26
+ /**
27
+ * Constructor.
28
+ *
29
+ * @param \Iterator $iterator The Iterator to filter
30
+ * @param array $matchPatterns An array of patterns that need to match
31
+ * @param array $noMatchPatterns An array of patterns that need to not match
32
+ */
33
+ public function __construct(\Iterator $iterator, array $matchPatterns, array $noMatchPatterns)
34
+ {
35
+ foreach ($matchPatterns as $pattern) {
36
+ $this->matchRegexps[] = $this->toRegex($pattern);
37
+ }
38
+
39
+ foreach ($noMatchPatterns as $pattern) {
40
+ $this->noMatchRegexps[] = $this->toRegex($pattern);
41
+ }
42
+
43
+ parent::__construct($iterator);
44
+ }
45
+
46
+ /**
47
+ * Checks whether the string is a regex.
48
+ *
49
+ * @param string $str
50
+ *
51
+ * @return bool Whether the given string is a regex
52
+ */
53
+ protected function isRegex($str)
54
+ {
55
+ return Expression::create($str)->isRegex();
56
+ }
57
+
58
+ /**
59
+ * Converts string into regexp.
60
+ *
61
+ * @param string $str Pattern
62
+ *
63
+ * @return string regexp corresponding to a given string
64
+ */
65
+ abstract protected function toRegex($str);
66
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/PathFilterIterator.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * PathFilterIterator filters files by path patterns (e.g. some/special/dir).
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ * @author Włodzimierz Gajda <gajdaw@gajdaw.pl>
19
+ */
20
+ class PathFilterIterator extends MultiplePcreFilterIterator
21
+ {
22
+ /**
23
+ * Filters the iterator values.
24
+ *
25
+ * @return bool true if the value should be kept, false otherwise
26
+ */
27
+ public function accept()
28
+ {
29
+ $filename = $this->current()->getRelativePathname();
30
+
31
+ if ('\\' === DIRECTORY_SEPARATOR) {
32
+ $filename = strtr($filename, '\\', '/');
33
+ }
34
+
35
+ // should at least not match one rule to exclude
36
+ foreach ($this->noMatchRegexps as $regex) {
37
+ if (preg_match($regex, $filename)) {
38
+ return false;
39
+ }
40
+ }
41
+
42
+ // should at least match one rule
43
+ $match = true;
44
+ if ($this->matchRegexps) {
45
+ $match = false;
46
+ foreach ($this->matchRegexps as $regex) {
47
+ if (preg_match($regex, $filename)) {
48
+ return true;
49
+ }
50
+ }
51
+ }
52
+
53
+ return $match;
54
+ }
55
+
56
+ /**
57
+ * Converts strings to regexp.
58
+ *
59
+ * PCRE patterns are left unchanged.
60
+ *
61
+ * Default conversion:
62
+ * 'lorem/ipsum/dolor' ==> 'lorem\/ipsum\/dolor/'
63
+ *
64
+ * Use only / as directory separator (on Windows also).
65
+ *
66
+ * @param string $str Pattern: regexp or dirname.
67
+ *
68
+ * @return string regexp corresponding to a given string or regexp
69
+ */
70
+ protected function toRegex($str)
71
+ {
72
+ return $this->isRegex($str) ? $str : '/'.preg_quote($str, '/').'/';
73
+ }
74
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/RecursiveDirectoryIterator.php ADDED
@@ -0,0 +1,126 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\Exception\AccessDeniedException;
15
+ use Symfony\Component\Finder\SplFileInfo;
16
+
17
+ /**
18
+ * Extends the \RecursiveDirectoryIterator to support relative paths.
19
+ *
20
+ * @author Victor Berchet <victor@suumit.com>
21
+ */
22
+ class RecursiveDirectoryIterator extends \RecursiveDirectoryIterator
23
+ {
24
+ /**
25
+ * @var bool
26
+ */
27
+ private $ignoreUnreadableDirs;
28
+
29
+ /**
30
+ * @var bool
31
+ */
32
+ private $rewindable;
33
+
34
+ /**
35
+ * Constructor.
36
+ *
37
+ * @param string $path
38
+ * @param int $flags
39
+ * @param bool $ignoreUnreadableDirs
40
+ *
41
+ * @throws \RuntimeException
42
+ */
43
+ public function __construct($path, $flags, $ignoreUnreadableDirs = false)
44
+ {
45
+ if ($flags & (self::CURRENT_AS_PATHNAME | self::CURRENT_AS_SELF)) {
46
+ throw new \RuntimeException('This iterator only support returning current as fileinfo.');
47
+ }
48
+
49
+ parent::__construct($path, $flags);
50
+ $this->ignoreUnreadableDirs = $ignoreUnreadableDirs;
51
+ }
52
+
53
+ /**
54
+ * Return an instance of SplFileInfo with support for relative paths.
55
+ *
56
+ * @return SplFileInfo File information
57
+ */
58
+ public function current()
59
+ {
60
+ return new SplFileInfo(parent::current()->getPathname(), $this->getSubPath(), $this->getSubPathname());
61
+ }
62
+
63
+ /**
64
+ * @return \RecursiveIterator
65
+ *
66
+ * @throws AccessDeniedException
67
+ */
68
+ public function getChildren()
69
+ {
70
+ try {
71
+ $children = parent::getChildren();
72
+
73
+ if ($children instanceof self) {
74
+ // parent method will call the constructor with default arguments, so unreadable dirs won't be ignored anymore
75
+ $children->ignoreUnreadableDirs = $this->ignoreUnreadableDirs;
76
+ }
77
+
78
+ return $children;
79
+ } catch (\UnexpectedValueException $e) {
80
+ if ($this->ignoreUnreadableDirs) {
81
+ // If directory is unreadable and finder is set to ignore it, a fake empty content is returned.
82
+ return new \RecursiveArrayIterator(array());
83
+ } else {
84
+ throw new AccessDeniedException($e->getMessage(), $e->getCode(), $e);
85
+ }
86
+ }
87
+ }
88
+
89
+ /**
90
+ * Do nothing for non rewindable stream.
91
+ */
92
+ public function rewind()
93
+ {
94
+ if (false === $this->isRewindable()) {
95
+ return;
96
+ }
97
+
98
+ // @see https://bugs.php.net/bug.php?id=49104
99
+ parent::next();
100
+
101
+ parent::rewind();
102
+ }
103
+
104
+ /**
105
+ * Checks if the stream is rewindable.
106
+ *
107
+ * @return bool true when the stream is rewindable, false otherwise
108
+ */
109
+ public function isRewindable()
110
+ {
111
+ if (null !== $this->rewindable) {
112
+ return $this->rewindable;
113
+ }
114
+
115
+ if (false !== $stream = @opendir($this->getPath())) {
116
+ $infos = stream_get_meta_data($stream);
117
+ closedir($stream);
118
+
119
+ if ($infos['seekable']) {
120
+ return $this->rewindable = true;
121
+ }
122
+ }
123
+
124
+ return $this->rewindable = false;
125
+ }
126
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/SizeRangeFilterIterator.php ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ use Symfony\Component\Finder\Comparator\NumberComparator;
15
+
16
+ /**
17
+ * SizeRangeFilterIterator filters out files that are not in the given size range.
18
+ *
19
+ * @author Fabien Potencier <fabien@symfony.com>
20
+ */
21
+ class SizeRangeFilterIterator extends FilterIterator
22
+ {
23
+ private $comparators = array();
24
+
25
+ /**
26
+ * Constructor.
27
+ *
28
+ * @param \Iterator $iterator The Iterator to filter
29
+ * @param NumberComparator[] $comparators An array of NumberComparator instances
30
+ */
31
+ public function __construct(\Iterator $iterator, array $comparators)
32
+ {
33
+ $this->comparators = $comparators;
34
+
35
+ parent::__construct($iterator);
36
+ }
37
+
38
+ /**
39
+ * Filters the iterator values.
40
+ *
41
+ * @return bool true if the value should be kept, false otherwise
42
+ */
43
+ public function accept()
44
+ {
45
+ $fileinfo = $this->current();
46
+ if (!$fileinfo->isFile()) {
47
+ return true;
48
+ }
49
+
50
+ $filesize = $fileinfo->getSize();
51
+ foreach ($this->comparators as $compare) {
52
+ if (!$compare->test($filesize)) {
53
+ return false;
54
+ }
55
+ }
56
+
57
+ return true;
58
+ }
59
+ }
vendor/symfony/finder/Symfony/Component/Finder/Iterator/SortableIterator.php ADDED
@@ -0,0 +1,82 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Iterator;
13
+
14
+ /**
15
+ * SortableIterator applies a sort on a given Iterator.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class SortableIterator implements \IteratorAggregate
20
+ {
21
+ const SORT_BY_NAME = 1;
22
+ const SORT_BY_TYPE = 2;
23
+ const SORT_BY_ACCESSED_TIME = 3;
24
+ const SORT_BY_CHANGED_TIME = 4;
25
+ const SORT_BY_MODIFIED_TIME = 5;
26
+
27
+ private $iterator;
28
+ private $sort;
29
+
30
+ /**
31
+ * Constructor.
32
+ *
33
+ * @param \Traversable $iterator The Iterator to filter
34
+ * @param int|callable $sort The sort type (SORT_BY_NAME, SORT_BY_TYPE, or a PHP callback)
35
+ *
36
+ * @throws \InvalidArgumentException
37
+ */
38
+ public function __construct(\Traversable $iterator, $sort)
39
+ {
40
+ $this->iterator = $iterator;
41
+
42
+ if (self::SORT_BY_NAME === $sort) {
43
+ $this->sort = function ($a, $b) {
44
+ return strcmp($a->getRealpath(), $b->getRealpath());
45
+ };
46
+ } elseif (self::SORT_BY_TYPE === $sort) {
47
+ $this->sort = function ($a, $b) {
48
+ if ($a->isDir() && $b->isFile()) {
49
+ return -1;
50
+ } elseif ($a->isFile() && $b->isDir()) {
51
+ return 1;
52
+ }
53
+
54
+ return strcmp($a->getRealpath(), $b->getRealpath());
55
+ };
56
+ } elseif (self::SORT_BY_ACCESSED_TIME === $sort) {
57
+ $this->sort = function ($a, $b) {
58
+ return ($a->getATime() - $b->getATime());
59
+ };
60
+ } elseif (self::SORT_BY_CHANGED_TIME === $sort) {
61
+ $this->sort = function ($a, $b) {
62
+ return ($a->getCTime() - $b->getCTime());
63
+ };
64
+ } elseif (self::SORT_BY_MODIFIED_TIME === $sort) {
65
+ $this->sort = function ($a, $b) {
66
+ return ($a->getMTime() - $b->getMTime());
67
+ };
68
+ } elseif (is_callable($sort)) {
69
+ $this->sort = $sort;
70
+ } else {
71
+ throw new \InvalidArgumentException('The SortableIterator takes a PHP callable or a valid built-in sort algorithm as an argument.');
72
+ }
73
+ }
74
+
75
+ public function getIterator()
76
+ {
77
+ $array = iterator_to_array($this->iterator, true);
78
+ uasort($array, $this->sort);
79
+
80
+ return new \ArrayIterator($array);
81
+ }
82
+ }
vendor/symfony/finder/Symfony/Component/Finder/LICENSE ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Copyright (c) 2004-2015 Fabien Potencier
2
+
3
+ Permission is hereby granted, free of charge, to any person obtaining a copy
4
+ of this software and associated documentation files (the "Software"), to deal
5
+ in the Software without restriction, including without limitation the rights
6
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7
+ copies of the Software, and to permit persons to whom the Software is furnished
8
+ to do so, subject to the following conditions:
9
+
10
+ The above copyright notice and this permission notice shall be included in all
11
+ copies or substantial portions of the Software.
12
+
13
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19
+ THE SOFTWARE.
vendor/symfony/finder/Symfony/Component/Finder/README.md ADDED
@@ -0,0 +1,53 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ Finder Component
2
+ ================
3
+
4
+ Finder finds files and directories via an intuitive fluent interface.
5
+
6
+ ```php
7
+ use Symfony\Component\Finder\Finder;
8
+
9
+ $finder = new Finder();
10
+
11
+ $iterator = $finder
12
+ ->files()
13
+ ->name('*.php')
14
+ ->depth(0)
15
+ ->size('>= 1K')
16
+ ->in(__DIR__);
17
+
18
+ foreach ($iterator as $file) {
19
+ print $file->getRealpath()."\n";
20
+ }
21
+ ```
22
+
23
+ The iterator returns instances of [Symfony\Component\Finder\SplFileInfo\SplFileInfo][1].
24
+ Besides the build-in methods inherited from [\SplFileInfo][2] (`getPerms()`, `getSize()`, ...),
25
+ you can also use `getRelativePath()` and `getRelativePathname()`. Read the
26
+ [official documentation][3] for more information.
27
+
28
+ But you can also use it to find files stored remotely like in this example where
29
+ we are looking for files on Amazon S3:
30
+
31
+ ```php
32
+ $s3 = new \Zend_Service_Amazon_S3($key, $secret);
33
+ $s3->registerStreamWrapper("s3");
34
+
35
+ $finder = new Finder();
36
+ $finder->name('photos*')->size('< 100K')->date('since 1 hour ago');
37
+ foreach ($finder->in('s3://bucket-name') as $file) {
38
+ print $file->getFilename()."\n";
39
+ }
40
+ ```
41
+
42
+ Resources
43
+ ---------
44
+
45
+ You can run the unit tests with the following command:
46
+
47
+ $ cd path/to/Symfony/Component/Finder/
48
+ $ composer.phar install
49
+ $ phpunit
50
+
51
+ [1]: http://api.symfony.com/2.5/Symfony/Component/Finder/SplFileInfo.html
52
+ [2]: http://php.net/splfileinfo
53
+ [3]: http://symfony.com/doc/current/components/finder.html#usage
vendor/symfony/finder/Symfony/Component/Finder/Shell/Command.php ADDED
@@ -0,0 +1,294 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Shell;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class Command
18
+ {
19
+ /**
20
+ * @var Command|null
21
+ */
22
+ private $parent;
23
+
24
+ /**
25
+ * @var array
26
+ */
27
+ private $bits = array();
28
+
29
+ /**
30
+ * @var array
31
+ */
32
+ private $labels = array();
33
+
34
+ /**
35
+ * @var \Closure|null
36
+ */
37
+ private $errorHandler;
38
+
39
+ /**
40
+ * Constructor.
41
+ *
42
+ * @param Command|null $parent Parent command
43
+ */
44
+ public function __construct(Command $parent = null)
45
+ {
46
+ $this->parent = $parent;
47
+ }
48
+
49
+ /**
50
+ * Returns command as string.
51
+ *
52
+ * @return string
53
+ */
54
+ public function __toString()
55
+ {
56
+ return $this->join();
57
+ }
58
+
59
+ /**
60
+ * Creates a new Command instance.
61
+ *
62
+ * @param Command|null $parent Parent command
63
+ *
64
+ * @return Command New Command instance
65
+ */
66
+ public static function create(Command $parent = null)
67
+ {
68
+ return new self($parent);
69
+ }
70
+
71
+ /**
72
+ * Escapes special chars from input.
73
+ *
74
+ * @param string $input A string to escape
75
+ *
76
+ * @return string The escaped string
77
+ */
78
+ public static function escape($input)
79
+ {
80
+ return escapeshellcmd($input);
81
+ }
82
+
83
+ /**
84
+ * Quotes input.
85
+ *
86
+ * @param string $input An argument string
87
+ *
88
+ * @return string The quoted string
89
+ */
90
+ public static function quote($input)
91
+ {
92
+ return escapeshellarg($input);
93
+ }
94
+
95
+ /**
96
+ * Appends a string or a Command instance.
97
+ *
98
+ * @param string|Command $bit
99
+ *
100
+ * @return Command The current Command instance
101
+ */
102
+ public function add($bit)
103
+ {
104
+ $this->bits[] = $bit;
105
+
106
+ return $this;
107
+ }
108
+
109
+ /**
110
+ * Prepends a string or a command instance.
111
+ *
112
+ * @param string|Command $bit
113
+ *
114
+ * @return Command The current Command instance
115
+ */
116
+ public function top($bit)
117
+ {
118
+ array_unshift($this->bits, $bit);
119
+
120
+ foreach ($this->labels as $label => $index) {
121
+ $this->labels[$label] += 1;
122
+ }
123
+
124
+ return $this;
125
+ }
126
+
127
+ /**
128
+ * Appends an argument, will be quoted.
129
+ *
130
+ * @param string $arg
131
+ *
132
+ * @return Command The current Command instance
133
+ */
134
+ public function arg($arg)
135
+ {
136
+ $this->bits[] = self::quote($arg);
137
+
138
+ return $this;
139
+ }
140
+
141
+ /**
142
+ * Appends escaped special command chars.
143
+ *
144
+ * @param string $esc
145
+ *
146
+ * @return Command The current Command instance
147
+ */
148
+ public function cmd($esc)
149
+ {
150
+ $this->bits[] = self::escape($esc);
151
+
152
+ return $this;
153
+ }
154
+
155
+ /**
156
+ * Inserts a labeled command to feed later.
157
+ *
158
+ * @param string $label The unique label
159
+ *
160
+ * @return Command The current Command instance
161
+ *
162
+ * @throws \RuntimeException If label already exists
163
+ */
164
+ public function ins($label)
165
+ {
166
+ if (isset($this->labels[$label])) {
167
+ throw new \RuntimeException(sprintf('Label "%s" already exists.', $label));
168
+ }
169
+
170
+ $this->bits[] = self::create($this);
171
+ $this->labels[$label] = count($this->bits)-1;
172
+
173
+ return $this->bits[$this->labels[$label]];
174
+ }
175
+
176
+ /**
177
+ * Retrieves a previously labeled command.
178
+ *
179
+ * @param string $label
180
+ *
181
+ * @return Command The labeled command
182
+ *
183
+ * @throws \RuntimeException
184
+ */
185
+ public function get($label)
186
+ {
187
+ if (!isset($this->labels[$label])) {
188
+ throw new \RuntimeException(sprintf('Label "%s" does not exist.', $label));
189
+ }
190
+
191
+ return $this->bits[$this->labels[$label]];
192
+ }
193
+
194
+ /**
195
+ * Returns parent command (if any).
196
+ *
197
+ * @return Command Parent command
198
+ *
199
+ * @throws \RuntimeException If command has no parent
200
+ */
201
+ public function end()
202
+ {
203
+ if (null === $this->parent) {
204
+ throw new \RuntimeException('Calling end on root command doesn\'t make sense.');
205
+ }
206
+
207
+ return $this->parent;
208
+ }
209
+
210
+ /**
211
+ * Counts bits stored in command.
212
+ *
213
+ * @return int The bits count
214
+ */
215
+ public function length()
216
+ {
217
+ return count($this->bits);
218
+ }
219
+
220
+ /**
221
+ * @param \Closure $errorHandler
222
+ *
223
+ * @return Command
224
+ */
225
+ public function setErrorHandler(\Closure $errorHandler)
226
+ {
227
+ $this->errorHandler = $errorHandler;
228
+
229
+ return $this;
230
+ }
231
+
232
+ /**
233
+ * @return \Closure|null
234
+ */
235
+ public function getErrorHandler()
236
+ {
237
+ return $this->errorHandler;
238
+ }
239
+
240
+ /**
241
+ * Executes current command.
242
+ *
243
+ * @return array The command result
244
+ *
245
+ * @throws \RuntimeException
246
+ */
247
+ public function execute()
248
+ {
249
+ if (null === $errorHandler = $this->errorHandler) {
250
+ exec($this->join(), $output);
251
+ } else {
252
+ $process = proc_open($this->join(), array(0 => array('pipe', 'r'), 1 => array('pipe', 'w'), 2 => array('pipe', 'w')), $pipes);
253
+ $output = preg_split('~(\r\n|\r|\n)~', stream_get_contents($pipes[1]), -1, PREG_SPLIT_NO_EMPTY);
254
+
255
+ if ($error = stream_get_contents($pipes[2])) {
256
+ $errorHandler($error);
257
+ }
258
+
259
+ proc_close($process);
260
+ }
261
+
262
+ return $output ?: array();
263
+ }
264
+
265
+ /**
266
+ * Joins bits.
267
+ *
268
+ * @return string
269
+ */
270
+ public function join()
271
+ {
272
+ return implode(' ', array_filter(
273
+ array_map(function ($bit) {
274
+ return $bit instanceof Command ? $bit->join() : ($bit ?: null);
275
+ }, $this->bits),
276
+ function ($bit) { return null !== $bit; }
277
+ ));
278
+ }
279
+
280
+ /**
281
+ * Insert a string or a Command instance before the bit at given position $index (index starts from 0).
282
+ *
283
+ * @param string|Command $bit
284
+ * @param int $index
285
+ *
286
+ * @return Command The current Command instance
287
+ */
288
+ public function addAtIndex($bit, $index)
289
+ {
290
+ array_splice($this->bits, $index, 0, $bit);
291
+
292
+ return $this;
293
+ }
294
+ }
vendor/symfony/finder/Symfony/Component/Finder/Shell/Shell.php ADDED
@@ -0,0 +1,97 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Shell;
13
+
14
+ /**
15
+ * @author Jean-François Simon <contact@jfsimon.fr>
16
+ */
17
+ class Shell
18
+ {
19
+ const TYPE_UNIX = 1;
20
+ const TYPE_DARWIN = 2;
21
+ const TYPE_CYGWIN = 3;
22
+ const TYPE_WINDOWS = 4;
23
+ const TYPE_BSD = 5;
24
+
25
+ /**
26
+ * @var string|null
27
+ */
28
+ private $type;
29
+
30
+ /**
31
+ * Returns guessed OS type.
32
+ *
33
+ * @return int
34
+ */
35
+ public function getType()
36
+ {
37
+ if (null === $this->type) {
38
+ $this->type = $this->guessType();
39
+ }
40
+
41
+ return $this->type;
42
+ }
43
+
44
+ /**
45
+ * Tests if a command is available.
46
+ *
47
+ * @param string $command
48
+ *
49
+ * @return bool
50
+ */
51
+ public function testCommand($command)
52
+ {
53
+ if (!function_exists('exec')) {
54
+ return false;
55
+ }
56
+
57
+ // todo: find a better way (command could not be available)
58
+ $testCommand = 'which ';
59
+ if (self::TYPE_WINDOWS === $this->type) {
60
+ $testCommand = 'where ';
61
+ }
62
+
63
+ $command = escapeshellcmd($command);
64
+
65
+ exec($testCommand.$command, $output, $code);
66
+
67
+ return 0 === $code && count($output) > 0;
68
+ }
69
+
70
+ /**
71
+ * Guesses OS type.
72
+ *
73
+ * @return int
74
+ */
75
+ private function guessType()
76
+ {
77
+ $os = strtolower(PHP_OS);
78
+
79
+ if (false !== strpos($os, 'cygwin')) {
80
+ return self::TYPE_CYGWIN;
81
+ }
82
+
83
+ if (false !== strpos($os, 'darwin')) {
84
+ return self::TYPE_DARWIN;
85
+ }
86
+
87
+ if (false !== strpos($os, 'bsd')) {
88
+ return self::TYPE_BSD;
89
+ }
90
+
91
+ if (0 === strpos($os, 'win')) {
92
+ return self::TYPE_WINDOWS;
93
+ }
94
+
95
+ return self::TYPE_UNIX;
96
+ }
97
+ }
vendor/symfony/finder/Symfony/Component/Finder/SplFileInfo.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder;
13
+
14
+ /**
15
+ * Extends \SplFileInfo to support relative paths.
16
+ *
17
+ * @author Fabien Potencier <fabien@symfony.com>
18
+ */
19
+ class SplFileInfo extends \SplFileInfo
20
+ {
21
+ private $relativePath;
22
+ private $relativePathname;
23
+
24
+ /**
25
+ * Constructor.
26
+ *
27
+ * @param string $file The file name
28
+ * @param string $relativePath The relative path
29
+ * @param string $relativePathname The relative path name
30
+ */
31
+ public function __construct($file, $relativePath, $relativePathname)
32
+ {
33
+ parent::__construct($file);
34
+ $this->relativePath = $relativePath;
35
+ $this->relativePathname = $relativePathname;
36
+ }
37
+
38
+ /**
39
+ * Returns the relative path.
40
+ *
41
+ * @return string the relative path
42
+ */
43
+ public function getRelativePath()
44
+ {
45
+ return $this->relativePath;
46
+ }
47
+
48
+ /**
49
+ * Returns the relative path name.
50
+ *
51
+ * @return string the relative path name
52
+ */
53
+ public function getRelativePathname()
54
+ {
55
+ return $this->relativePathname;
56
+ }
57
+
58
+ /**
59
+ * Returns the contents of the file.
60
+ *
61
+ * @return string the contents of the file
62
+ *
63
+ * @throws \RuntimeException
64
+ */
65
+ public function getContents()
66
+ {
67
+ $level = error_reporting(0);
68
+ $content = file_get_contents($this->getPathname());
69
+ error_reporting($level);
70
+ if (false === $content) {
71
+ $error = error_get_last();
72
+ throw new \RuntimeException($error['message']);
73
+ }
74
+
75
+ return $content;
76
+ }
77
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/ComparatorTest.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Comparator;
13
+
14
+ use Symfony\Component\Finder\Comparator\Comparator;
15
+
16
+ class ComparatorTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ public function testGetSetOperator()
19
+ {
20
+ $comparator = new Comparator();
21
+ try {
22
+ $comparator->setOperator('foo');
23
+ $this->fail('->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
24
+ } catch (\Exception $e) {
25
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->setOperator() throws an \InvalidArgumentException if the operator is not valid.');
26
+ }
27
+
28
+ $comparator = new Comparator();
29
+ $comparator->setOperator('>');
30
+ $this->assertEquals('>', $comparator->getOperator(), '->getOperator() returns the current operator');
31
+ }
32
+
33
+ public function testGetSetTarget()
34
+ {
35
+ $comparator = new Comparator();
36
+ $comparator->setTarget(8);
37
+ $this->assertEquals(8, $comparator->getTarget(), '->getTarget() returns the target');
38
+ }
39
+
40
+ /**
41
+ * @dataProvider getTestData
42
+ */
43
+ public function testTest($operator, $target, $match, $noMatch)
44
+ {
45
+ $c = new Comparator();
46
+ $c->setOperator($operator);
47
+ $c->setTarget($target);
48
+
49
+ foreach ($match as $m) {
50
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
51
+ }
52
+
53
+ foreach ($noMatch as $m) {
54
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
55
+ }
56
+ }
57
+
58
+ public function getTestData()
59
+ {
60
+ return array(
61
+ array('<', '1000', array('500', '999'), array('1000', '1500')),
62
+ );
63
+ }
64
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/DateComparatorTest.php ADDED
@@ -0,0 +1,63 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Comparator;
13
+
14
+ use Symfony\Component\Finder\Comparator\DateComparator;
15
+
16
+ class DateComparatorTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ public function testConstructor()
19
+ {
20
+ try {
21
+ new DateComparator('foobar');
22
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
23
+ } catch (\Exception $e) {
24
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
25
+ }
26
+
27
+ try {
28
+ new DateComparator('');
29
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
30
+ } catch (\Exception $e) {
31
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
32
+ }
33
+ }
34
+
35
+ /**
36
+ * @dataProvider getTestData
37
+ */
38
+ public function testTest($test, $match, $noMatch)
39
+ {
40
+ $c = new DateComparator($test);
41
+
42
+ foreach ($match as $m) {
43
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
44
+ }
45
+
46
+ foreach ($noMatch as $m) {
47
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
48
+ }
49
+ }
50
+
51
+ public function getTestData()
52
+ {
53
+ return array(
54
+ array('< 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
55
+ array('until 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
56
+ array('before 2005-10-10', array(strtotime('2005-10-09')), array(strtotime('2005-10-15'))),
57
+ array('> 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
58
+ array('after 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
59
+ array('since 2005-10-10', array(strtotime('2005-10-15')), array(strtotime('2005-10-09'))),
60
+ array('!= 2005-10-10', array(strtotime('2005-10-11')), array(strtotime('2005-10-10'))),
61
+ );
62
+ }
63
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Comparator/NumberComparatorTest.php ADDED
@@ -0,0 +1,107 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Comparator;
13
+
14
+ use Symfony\Component\Finder\Comparator\NumberComparator;
15
+
16
+ class NumberComparatorTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @dataProvider getConstructorTestData
20
+ */
21
+ public function testConstructor($successes, $failures)
22
+ {
23
+ foreach ($successes as $s) {
24
+ new NumberComparator($s);
25
+ }
26
+
27
+ foreach ($failures as $f) {
28
+ try {
29
+ new NumberComparator($f);
30
+ $this->fail('__construct() throws an \InvalidArgumentException if the test expression is not valid.');
31
+ } catch (\Exception $e) {
32
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException if the test expression is not valid.');
33
+ }
34
+ }
35
+ }
36
+
37
+ /**
38
+ * @dataProvider getTestData
39
+ */
40
+ public function testTest($test, $match, $noMatch)
41
+ {
42
+ $c = new NumberComparator($test);
43
+
44
+ foreach ($match as $m) {
45
+ $this->assertTrue($c->test($m), '->test() tests a string against the expression');
46
+ }
47
+
48
+ foreach ($noMatch as $m) {
49
+ $this->assertFalse($c->test($m), '->test() tests a string against the expression');
50
+ }
51
+ }
52
+
53
+ public function getTestData()
54
+ {
55
+ return array(
56
+ array('< 1000', array('500', '999'), array('1000', '1500')),
57
+
58
+ array('< 1K', array('500', '999'), array('1000', '1500')),
59
+ array('<1k', array('500', '999'), array('1000', '1500')),
60
+ array(' < 1 K ', array('500', '999'), array('1000', '1500')),
61
+ array('<= 1K', array('1000'), array('1001')),
62
+ array('> 1K', array('1001'), array('1000')),
63
+ array('>= 1K', array('1000'), array('999')),
64
+
65
+ array('< 1KI', array('500', '1023'), array('1024', '1500')),
66
+ array('<= 1KI', array('1024'), array('1025')),
67
+ array('> 1KI', array('1025'), array('1024')),
68
+ array('>= 1KI', array('1024'), array('1023')),
69
+
70
+ array('1KI', array('1024'), array('1023', '1025')),
71
+ array('==1KI', array('1024'), array('1023', '1025')),
72
+
73
+ array('==1m', array('1000000'), array('999999', '1000001')),
74
+ array('==1mi', array(1024*1024), array(1024*1024-1, 1024*1024+1)),
75
+
76
+ array('==1g', array('1000000000'), array('999999999', '1000000001')),
77
+ array('==1gi', array(1024*1024*1024), array(1024*1024*1024-1, 1024*1024*1024+1)),
78
+
79
+ array('!= 1000', array('500', '999'), array('1000')),
80
+ );
81
+ }
82
+
83
+ public function getConstructorTestData()
84
+ {
85
+ return array(
86
+ array(
87
+ array(
88
+ '1', '0',
89
+ '3.5', '33.55', '123.456', '123456.78',
90
+ '.1', '.123',
91
+ '.0', '0.0',
92
+ '1.', '0.', '123.',
93
+ '==1', '!=1', '<1', '>1', '<=1', '>=1',
94
+ '==1k', '==1ki', '==1m', '==1mi', '==1g', '==1gi',
95
+ '1k', '1ki', '1m', '1mi', '1g', '1gi',
96
+ ),
97
+ array(
98
+ false, null, '',
99
+ ' ', 'foobar',
100
+ '=1', '===1',
101
+ '0 . 1', '123 .45', '234. 567',
102
+ '..', '.0.', '0.1.2',
103
+ ),
104
+ ),
105
+ );
106
+ }
107
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/ExpressionTest.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Expression;
13
+
14
+ use Symfony\Component\Finder\Expression\Expression;
15
+
16
+ class ExpressionTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @dataProvider getTypeGuesserData
20
+ */
21
+ public function testTypeGuesser($expr, $type)
22
+ {
23
+ $this->assertEquals($type, Expression::create($expr)->getType());
24
+ }
25
+
26
+ /**
27
+ * @dataProvider getCaseSensitiveData
28
+ */
29
+ public function testCaseSensitive($expr, $isCaseSensitive)
30
+ {
31
+ $this->assertEquals($isCaseSensitive, Expression::create($expr)->isCaseSensitive());
32
+ }
33
+
34
+ /**
35
+ * @dataProvider getRegexRenderingData
36
+ */
37
+ public function testRegexRendering($expr, $body)
38
+ {
39
+ $this->assertEquals($body, Expression::create($expr)->renderPattern());
40
+ }
41
+
42
+ public function getTypeGuesserData()
43
+ {
44
+ return array(
45
+ array('{foo}', Expression::TYPE_REGEX),
46
+ array('/foo/', Expression::TYPE_REGEX),
47
+ array('foo', Expression::TYPE_GLOB),
48
+ array('foo*', Expression::TYPE_GLOB),
49
+ );
50
+ }
51
+
52
+ public function getCaseSensitiveData()
53
+ {
54
+ return array(
55
+ array('{foo}m', true),
56
+ array('/foo/i', false),
57
+ array('foo*', true),
58
+ );
59
+ }
60
+
61
+ public function getRegexRenderingData()
62
+ {
63
+ return array(
64
+ array('{foo}m', 'foo'),
65
+ array('/foo/i', 'foo'),
66
+ );
67
+ }
68
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/GlobTest.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Expression;
13
+
14
+ use Symfony\Component\Finder\Expression\Expression;
15
+
16
+ class GlobTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @dataProvider getToRegexData
20
+ */
21
+ public function testGlobToRegex($glob, $match, $noMatch)
22
+ {
23
+ foreach ($match as $m) {
24
+ $this->assertRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
25
+ }
26
+
27
+ foreach ($noMatch as $m) {
28
+ $this->assertNotRegExp(Expression::create($glob)->getRegex()->render(), $m, '::toRegex() converts a glob to a regexp');
29
+ }
30
+ }
31
+
32
+ public function getToRegexData()
33
+ {
34
+ return array(
35
+ array('', array(''), array('f', '/')),
36
+ array('*', array('foo'), array('foo/', '/foo')),
37
+ array('foo.*', array('foo.php', 'foo.a', 'foo.'), array('fooo.php', 'foo.php/foo')),
38
+ array('fo?', array('foo', 'fot'), array('fooo', 'ffoo', 'fo/')),
39
+ array('fo{o,t}', array('foo', 'fot'), array('fob', 'fo/')),
40
+ array('foo(bar|foo)', array('foo(bar|foo)'), array('foobar', 'foofoo')),
41
+ array('foo,bar', array('foo,bar'), array('foo', 'bar')),
42
+ array('fo{o,\\,}', array('foo', 'fo,'), array()),
43
+ array('fo{o,\\\\}', array('foo', 'fo\\'), array()),
44
+ array('/foo', array('/foo'), array('foo')),
45
+ );
46
+ }
47
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Expression/RegexTest.php ADDED
@@ -0,0 +1,143 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Expression;
13
+
14
+ use Symfony\Component\Finder\Expression\Expression;
15
+
16
+ class RegexTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @dataProvider getHasFlagsData
20
+ */
21
+ public function testHasFlags($regex, $start, $end)
22
+ {
23
+ $expr = new Expression($regex);
24
+
25
+ $this->assertEquals($start, $expr->getRegex()->hasStartFlag());
26
+ $this->assertEquals($end, $expr->getRegex()->hasEndFlag());
27
+ }
28
+
29
+ /**
30
+ * @dataProvider getHasJokersData
31
+ */
32
+ public function testHasJokers($regex, $start, $end)
33
+ {
34
+ $expr = new Expression($regex);
35
+
36
+ $this->assertEquals($start, $expr->getRegex()->hasStartJoker());
37
+ $this->assertEquals($end, $expr->getRegex()->hasEndJoker());
38
+ }
39
+
40
+ /**
41
+ * @dataProvider getSetFlagsData
42
+ */
43
+ public function testSetFlags($regex, $start, $end, $expected)
44
+ {
45
+ $expr = new Expression($regex);
46
+ $expr->getRegex()->setStartFlag($start)->setEndFlag($end);
47
+
48
+ $this->assertEquals($expected, $expr->render());
49
+ }
50
+
51
+ /**
52
+ * @dataProvider getSetJokersData
53
+ */
54
+ public function testSetJokers($regex, $start, $end, $expected)
55
+ {
56
+ $expr = new Expression($regex);
57
+ $expr->getRegex()->setStartJoker($start)->setEndJoker($end);
58
+
59
+ $this->assertEquals($expected, $expr->render());
60
+ }
61
+
62
+ public function testOptions()
63
+ {
64
+ $expr = new Expression('~abc~is');
65
+ $expr->getRegex()->removeOption('i')->addOption('m');
66
+
67
+ $this->assertEquals('~abc~sm', $expr->render());
68
+ }
69
+
70
+ public function testMixFlagsAndJokers()
71
+ {
72
+ $expr = new Expression('~^.*abc.*$~is');
73
+
74
+ $expr->getRegex()->setStartFlag(false)->setEndFlag(false)->setStartJoker(false)->setEndJoker(false);
75
+ $this->assertEquals('~abc~is', $expr->render());
76
+
77
+ $expr->getRegex()->setStartFlag(true)->setEndFlag(true)->setStartJoker(true)->setEndJoker(true);
78
+ $this->assertEquals('~^.*abc.*$~is', $expr->render());
79
+ }
80
+
81
+ /**
82
+ * @dataProvider getReplaceJokersTestData
83
+ */
84
+ public function testReplaceJokers($regex, $expected)
85
+ {
86
+ $expr = new Expression($regex);
87
+ $expr = $expr->getRegex()->replaceJokers('@');
88
+
89
+ $this->assertEquals($expected, $expr->renderPattern());
90
+ }
91
+
92
+ public function getHasFlagsData()
93
+ {
94
+ return array(
95
+ array('~^abc~', true, false),
96
+ array('~abc$~', false, true),
97
+ array('~abc~', false, false),
98
+ array('~^abc$~', true, true),
99
+ array('~^abc\\$~', true, false),
100
+ );
101
+ }
102
+
103
+ public function getHasJokersData()
104
+ {
105
+ return array(
106
+ array('~.*abc~', true, false),
107
+ array('~abc.*~', false, true),
108
+ array('~abc~', false, false),
109
+ array('~.*abc.*~', true, true),
110
+ array('~.*abc\\.*~', true, false),
111
+ );
112
+ }
113
+
114
+ public function getSetFlagsData()
115
+ {
116
+ return array(
117
+ array('~abc~', true, false, '~^abc~'),
118
+ array('~abc~', false, true, '~abc$~'),
119
+ array('~abc~', false, false, '~abc~'),
120
+ array('~abc~', true, true, '~^abc$~'),
121
+ );
122
+ }
123
+
124
+ public function getSetJokersData()
125
+ {
126
+ return array(
127
+ array('~abc~', true, false, '~.*abc~'),
128
+ array('~abc~', false, true, '~abc.*~'),
129
+ array('~abc~', false, false, '~abc~'),
130
+ array('~abc~', true, true, '~.*abc.*~'),
131
+ );
132
+ }
133
+
134
+ public function getReplaceJokersTestData()
135
+ {
136
+ return array(
137
+ array('~.abc~', '@abc'),
138
+ array('~\\.abc~', '\\.abc'),
139
+ array('~\\\\.abc~', '\\\\@abc'),
140
+ array('~\\\\\\.abc~', '\\\\\\.abc'),
141
+ );
142
+ }
143
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/DummyAdapter.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\FakeAdapter;
13
+
14
+ use Symfony\Component\Finder\Adapter\AbstractAdapter;
15
+
16
+ /**
17
+ * @author Jean-François Simon <contact@jfsimon.fr>
18
+ */
19
+ class DummyAdapter extends AbstractAdapter
20
+ {
21
+ /**
22
+ * @var \Iterator
23
+ */
24
+ private $iterator;
25
+
26
+ /**
27
+ * @param \Iterator $iterator
28
+ */
29
+ public function __construct(\Iterator $iterator)
30
+ {
31
+ $this->iterator = $iterator;
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ public function searchInDirectory($dir)
38
+ {
39
+ return $this->iterator;
40
+ }
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ public function getName()
46
+ {
47
+ return 'yes';
48
+ }
49
+
50
+ /**
51
+ * {@inheritdoc}
52
+ */
53
+ protected function canBeUsed()
54
+ {
55
+ return true;
56
+ }
57
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/FailingAdapter.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\FakeAdapter;
13
+
14
+ use Symfony\Component\Finder\Adapter\AbstractAdapter;
15
+ use Symfony\Component\Finder\Exception\AdapterFailureException;
16
+
17
+ /**
18
+ * @author Jean-François Simon <contact@jfsimon.fr>
19
+ */
20
+ class FailingAdapter extends AbstractAdapter
21
+ {
22
+ /**
23
+ * {@inheritdoc}
24
+ */
25
+ public function searchInDirectory($dir)
26
+ {
27
+ throw new AdapterFailureException($this);
28
+ }
29
+
30
+ /**
31
+ * {@inheritdoc}
32
+ */
33
+ public function getName()
34
+ {
35
+ return 'failing';
36
+ }
37
+
38
+ /**
39
+ * {@inheritdoc}
40
+ */
41
+ protected function canBeUsed()
42
+ {
43
+ return true;
44
+ }
45
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/NamedAdapter.php ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\FakeAdapter;
13
+
14
+ use Symfony\Component\Finder\Adapter\AbstractAdapter;
15
+
16
+ /**
17
+ * @author Jean-François Simon <contact@jfsimon.fr>
18
+ */
19
+ class NamedAdapter extends AbstractAdapter
20
+ {
21
+ /**
22
+ * @var string
23
+ */
24
+ private $name;
25
+
26
+ /**
27
+ * @param string $name
28
+ */
29
+ public function __construct($name)
30
+ {
31
+ $this->name = $name;
32
+ }
33
+
34
+ /**
35
+ * {@inheritdoc}
36
+ */
37
+ public function searchInDirectory($dir)
38
+ {
39
+ return new \ArrayIterator(array());
40
+ }
41
+
42
+ /**
43
+ * {@inheritdoc}
44
+ */
45
+ public function getName()
46
+ {
47
+ return $this->name;
48
+ }
49
+
50
+ /**
51
+ * {@inheritdoc}
52
+ */
53
+ protected function canBeUsed()
54
+ {
55
+ return true;
56
+ }
57
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/FakeAdapter/UnsupportedAdapter.php ADDED
@@ -0,0 +1,44 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\FakeAdapter;
13
+
14
+ use Symfony\Component\Finder\Adapter\AbstractAdapter;
15
+
16
+ /**
17
+ * @author Jean-François Simon <contact@jfsimon.fr>
18
+ */
19
+ class UnsupportedAdapter extends AbstractAdapter
20
+ {
21
+ /**
22
+ * {@inheritdoc}
23
+ */
24
+ public function searchInDirectory($dir)
25
+ {
26
+ return new \ArrayIterator(array());
27
+ }
28
+
29
+ /**
30
+ * {@inheritdoc}
31
+ */
32
+ public function getName()
33
+ {
34
+ return 'unsupported';
35
+ }
36
+
37
+ /**
38
+ * {@inheritdoc}
39
+ */
40
+ protected function canBeUsed()
41
+ {
42
+ return false;
43
+ }
44
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/FinderTest.php ADDED
@@ -0,0 +1,869 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests;
13
+
14
+ use Symfony\Component\Finder\Finder;
15
+ use Symfony\Component\Finder\Adapter;
16
+
17
+ class FinderTest extends Iterator\RealIteratorTestCase
18
+ {
19
+ public function testCreate()
20
+ {
21
+ $this->assertInstanceOf('Symfony\Component\Finder\Finder', Finder::create());
22
+ }
23
+
24
+ /**
25
+ * @dataProvider getAdaptersTestData
26
+ */
27
+ public function testDirectories($adapter)
28
+ {
29
+ $finder = $this->buildFinder($adapter);
30
+ $this->assertSame($finder, $finder->directories());
31
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
32
+
33
+ $finder = $this->buildFinder($adapter);
34
+ $finder->directories();
35
+ $finder->files();
36
+ $finder->directories();
37
+ $this->assertIterator($this->toAbsolute(array('foo', 'toto')), $finder->in(self::$tmpDir)->getIterator());
38
+ }
39
+
40
+ /**
41
+ * @dataProvider getAdaptersTestData
42
+ */
43
+ public function testFiles($adapter)
44
+ {
45
+ $finder = $this->buildFinder($adapter);
46
+ $this->assertSame($finder, $finder->files());
47
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
48
+
49
+ $finder = $this->buildFinder($adapter);
50
+ $finder->files();
51
+ $finder->directories();
52
+ $finder->files();
53
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'test.py', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
54
+ }
55
+
56
+ /**
57
+ * @dataProvider getAdaptersTestData
58
+ */
59
+ public function testDepth($adapter)
60
+ {
61
+ $finder = $this->buildFinder($adapter);
62
+ $this->assertSame($finder, $finder->depth('< 1'));
63
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
64
+
65
+ $finder = $this->buildFinder($adapter);
66
+ $this->assertSame($finder, $finder->depth('<= 0'));
67
+ $this->assertIterator($this->toAbsolute(array('foo', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
68
+
69
+ $finder = $this->buildFinder($adapter);
70
+ $this->assertSame($finder, $finder->depth('>= 1'));
71
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp')), $finder->in(self::$tmpDir)->getIterator());
72
+
73
+ $finder = $this->buildFinder($adapter);
74
+ $finder->depth('< 1')->depth('>= 1');
75
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
76
+ }
77
+
78
+ /**
79
+ * @dataProvider getAdaptersTestData
80
+ */
81
+ public function testName($adapter)
82
+ {
83
+ $finder = $this->buildFinder($adapter);
84
+ $this->assertSame($finder, $finder->name('*.php'));
85
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
86
+
87
+ $finder = $this->buildFinder($adapter);
88
+ $finder->name('test.ph*');
89
+ $finder->name('test.py');
90
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
91
+
92
+ $finder = $this->buildFinder($adapter);
93
+ $finder->name('~^test~i');
94
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
95
+
96
+ $finder = $this->buildFinder($adapter);
97
+ $finder->name('~\\.php$~i');
98
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
99
+
100
+ $finder = $this->buildFinder($adapter);
101
+ $finder->name('test.p{hp,y}');
102
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
103
+ }
104
+
105
+ /**
106
+ * @dataProvider getAdaptersTestData
107
+ */
108
+ public function testNotName($adapter)
109
+ {
110
+ $finder = $this->buildFinder($adapter);
111
+ $this->assertSame($finder, $finder->notName('*.php'));
112
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
113
+
114
+ $finder = $this->buildFinder($adapter);
115
+ $finder->notName('*.php');
116
+ $finder->notName('*.py');
117
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
118
+
119
+ $finder = $this->buildFinder($adapter);
120
+ $finder->name('test.ph*');
121
+ $finder->name('test.py');
122
+ $finder->notName('*.php');
123
+ $finder->notName('*.py');
124
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
125
+
126
+ $finder = $this->buildFinder($adapter);
127
+ $finder->name('test.ph*');
128
+ $finder->name('test.py');
129
+ $finder->notName('*.p{hp,y}');
130
+ $this->assertIterator(array(), $finder->in(self::$tmpDir)->getIterator());
131
+ }
132
+
133
+ /**
134
+ * @dataProvider getRegexNameTestData
135
+ *
136
+ * @group regexName
137
+ */
138
+ public function testRegexName($adapter, $regex)
139
+ {
140
+ $finder = $this->buildFinder($adapter);
141
+ $finder->name($regex);
142
+ $this->assertIterator($this->toAbsolute(array('test.py', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
143
+ }
144
+
145
+ /**
146
+ * @dataProvider getAdaptersTestData
147
+ */
148
+ public function testSize($adapter)
149
+ {
150
+ $finder = $this->buildFinder($adapter);
151
+ $this->assertSame($finder, $finder->files()->size('< 1K')->size('> 500'));
152
+ $this->assertIterator($this->toAbsolute(array('test.php')), $finder->in(self::$tmpDir)->getIterator());
153
+ }
154
+
155
+ /**
156
+ * @dataProvider getAdaptersTestData
157
+ */
158
+ public function testDate($adapter)
159
+ {
160
+ $finder = $this->buildFinder($adapter);
161
+ $this->assertSame($finder, $finder->files()->date('until last month'));
162
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php')), $finder->in(self::$tmpDir)->getIterator());
163
+ }
164
+
165
+ /**
166
+ * @dataProvider getAdaptersTestData
167
+ */
168
+ public function testExclude($adapter)
169
+ {
170
+ $finder = $this->buildFinder($adapter);
171
+ $this->assertSame($finder, $finder->exclude('foo'));
172
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
173
+ }
174
+
175
+ /**
176
+ * @dataProvider getAdaptersTestData
177
+ */
178
+ public function testIgnoreVCS($adapter)
179
+ {
180
+ $finder = $this->buildFinder($adapter);
181
+ $this->assertSame($finder, $finder->ignoreVCS(false)->ignoreDotFiles(false));
182
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
183
+
184
+ $finder = $this->buildFinder($adapter);
185
+ $finder->ignoreVCS(false)->ignoreVCS(false)->ignoreDotFiles(false);
186
+ $this->assertIterator($this->toAbsolute(array('.git', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
187
+
188
+ $finder = $this->buildFinder($adapter);
189
+ $this->assertSame($finder, $finder->ignoreVCS(true)->ignoreDotFiles(false));
190
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
191
+ }
192
+
193
+ /**
194
+ * @dataProvider getAdaptersTestData
195
+ */
196
+ public function testIgnoreDotFiles($adapter)
197
+ {
198
+ $finder = $this->buildFinder($adapter);
199
+ $this->assertSame($finder, $finder->ignoreDotFiles(false)->ignoreVCS(false));
200
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
201
+
202
+ $finder = $this->buildFinder($adapter);
203
+ $finder->ignoreDotFiles(false)->ignoreDotFiles(false)->ignoreVCS(false);
204
+ $this->assertIterator($this->toAbsolute(array('.git', '.bar', '.foo', '.foo/.bar', '.foo/bar', 'foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
205
+
206
+ $finder = $this->buildFinder($adapter);
207
+ $this->assertSame($finder, $finder->ignoreDotFiles(true)->ignoreVCS(false));
208
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
209
+ }
210
+
211
+ /**
212
+ * @dataProvider getAdaptersTestData
213
+ */
214
+ public function testSortByName($adapter)
215
+ {
216
+ $finder = $this->buildFinder($adapter);
217
+ $this->assertSame($finder, $finder->sortByName());
218
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
219
+ }
220
+
221
+ /**
222
+ * @dataProvider getAdaptersTestData
223
+ */
224
+ public function testSortByType($adapter)
225
+ {
226
+ $finder = $this->buildFinder($adapter);
227
+ $this->assertSame($finder, $finder->sortByType());
228
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'toto', 'foo/bar.tmp', 'test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
229
+ }
230
+
231
+ /**
232
+ * @dataProvider getAdaptersTestData
233
+ */
234
+ public function testSortByAccessedTime($adapter)
235
+ {
236
+ $finder = $this->buildFinder($adapter);
237
+ $this->assertSame($finder, $finder->sortByAccessedTime());
238
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
239
+ }
240
+
241
+ /**
242
+ * @dataProvider getAdaptersTestData
243
+ */
244
+ public function testSortByChangedTime($adapter)
245
+ {
246
+ $finder = $this->buildFinder($adapter);
247
+ $this->assertSame($finder, $finder->sortByChangedTime());
248
+ $this->assertIterator($this->toAbsolute(array('toto', 'test.py', 'test.php', 'foo/bar.tmp', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
249
+ }
250
+
251
+ /**
252
+ * @dataProvider getAdaptersTestData
253
+ */
254
+ public function testSortByModifiedTime($adapter)
255
+ {
256
+ $finder = $this->buildFinder($adapter);
257
+ $this->assertSame($finder, $finder->sortByModifiedTime());
258
+ $this->assertIterator($this->toAbsolute(array('foo/bar.tmp', 'test.php', 'toto', 'test.py', 'foo', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
259
+ }
260
+
261
+ /**
262
+ * @dataProvider getAdaptersTestData
263
+ */
264
+ public function testSort($adapter)
265
+ {
266
+ $finder = $this->buildFinder($adapter);
267
+ $this->assertSame($finder, $finder->sort(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }));
268
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo bar', 'foo/bar.tmp', 'test.php', 'test.py', 'toto')), $finder->in(self::$tmpDir)->getIterator());
269
+ }
270
+
271
+ /**
272
+ * @dataProvider getAdaptersTestData
273
+ */
274
+ public function testFilter($adapter)
275
+ {
276
+ $finder = $this->buildFinder($adapter);
277
+ $this->assertSame($finder, $finder->filter(function (\SplFileInfo $f) { return preg_match('/test/', $f) > 0; }));
278
+ $this->assertIterator($this->toAbsolute(array('test.php', 'test.py')), $finder->in(self::$tmpDir)->getIterator());
279
+ }
280
+
281
+ /**
282
+ * @dataProvider getAdaptersTestData
283
+ */
284
+ public function testFollowLinks($adapter)
285
+ {
286
+ if ('\\' == DIRECTORY_SEPARATOR) {
287
+ return;
288
+ }
289
+
290
+ $finder = $this->buildFinder($adapter);
291
+ $this->assertSame($finder, $finder->followLinks());
292
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto', 'foo bar')), $finder->in(self::$tmpDir)->getIterator());
293
+ }
294
+
295
+ /**
296
+ * @dataProvider getAdaptersTestData
297
+ */
298
+ public function testIn($adapter)
299
+ {
300
+ $finder = $this->buildFinder($adapter);
301
+ try {
302
+ $finder->in('foobar');
303
+ $this->fail('->in() throws a \InvalidArgumentException if the directory does not exist');
304
+ } catch (\Exception $e) {
305
+ $this->assertInstanceOf('InvalidArgumentException', $e, '->in() throws a \InvalidArgumentException if the directory does not exist');
306
+ }
307
+
308
+ $finder = $this->buildFinder($adapter);
309
+ $iterator = $finder->files()->name('*.php')->depth('< 1')->in(array(self::$tmpDir, __DIR__))->getIterator();
310
+
311
+ $this->assertIterator(array(self::$tmpDir.DIRECTORY_SEPARATOR.'test.php', __DIR__.DIRECTORY_SEPARATOR.'FinderTest.php'), $iterator);
312
+ }
313
+
314
+ /**
315
+ * @dataProvider getAdaptersTestData
316
+ */
317
+ public function testInWithGlob($adapter)
318
+ {
319
+ $finder = $this->buildFinder($adapter);
320
+ $finder->in(array(__DIR__.'/Fixtures/*/B/C', __DIR__.'/Fixtures/*/*/B/C'))->getIterator();
321
+
322
+ $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
323
+ }
324
+
325
+ /**
326
+ * @dataProvider getAdaptersTestData
327
+ * @expectedException \InvalidArgumentException
328
+ */
329
+ public function testInWithNonDirectoryGlob($adapter)
330
+ {
331
+ $finder = $this->buildFinder($adapter);
332
+ $finder->in(__DIR__.'/Fixtures/A/a*');
333
+ }
334
+
335
+ /**
336
+ * @dataProvider getAdaptersTestData
337
+ */
338
+ public function testInWithGlobBrace($adapter)
339
+ {
340
+ $finder = $this->buildFinder($adapter);
341
+ $finder->in(array(__DIR__.'/Fixtures/{A,copy/A}/B/C'))->getIterator();
342
+
343
+ $this->assertIterator($this->toAbsoluteFixtures(array('A/B/C/abc.dat', 'copy/A/B/C/abc.dat.copy')), $finder);
344
+ }
345
+
346
+ /**
347
+ * @dataProvider getAdaptersTestData
348
+ */
349
+ public function testGetIterator($adapter)
350
+ {
351
+ $finder = $this->buildFinder($adapter);
352
+ try {
353
+ $finder->getIterator();
354
+ $this->fail('->getIterator() throws a \LogicException if the in() method has not been called');
355
+ } catch (\Exception $e) {
356
+ $this->assertInstanceOf('LogicException', $e, '->getIterator() throws a \LogicException if the in() method has not been called');
357
+ }
358
+
359
+ $finder = $this->buildFinder($adapter);
360
+ $dirs = array();
361
+ foreach ($finder->directories()->in(self::$tmpDir) as $dir) {
362
+ $dirs[] = (string) $dir;
363
+ }
364
+
365
+ $expected = $this->toAbsolute(array('foo', 'toto'));
366
+
367
+ sort($dirs);
368
+ sort($expected);
369
+
370
+ $this->assertEquals($expected, $dirs, 'implements the \IteratorAggregate interface');
371
+
372
+ $finder = $this->buildFinder($adapter);
373
+ $this->assertEquals(2, iterator_count($finder->directories()->in(self::$tmpDir)), 'implements the \IteratorAggregate interface');
374
+
375
+ $finder = $this->buildFinder($adapter);
376
+ $a = iterator_to_array($finder->directories()->in(self::$tmpDir));
377
+ $a = array_values(array_map(function ($a) { return (string) $a; }, $a));
378
+ sort($a);
379
+ $this->assertEquals($expected, $a, 'implements the \IteratorAggregate interface');
380
+ }
381
+
382
+ /**
383
+ * @dataProvider getAdaptersTestData
384
+ */
385
+ public function testRelativePath($adapter)
386
+ {
387
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
388
+
389
+ $paths = array();
390
+
391
+ foreach ($finder as $file) {
392
+ $paths[] = $file->getRelativePath();
393
+ }
394
+
395
+ $ref = array("", "", "", "", "foo", "");
396
+
397
+ sort($ref);
398
+ sort($paths);
399
+
400
+ $this->assertEquals($ref, $paths);
401
+ }
402
+
403
+ /**
404
+ * @dataProvider getAdaptersTestData
405
+ */
406
+ public function testRelativePathname($adapter)
407
+ {
408
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir)->sortByName();
409
+
410
+ $paths = array();
411
+
412
+ foreach ($finder as $file) {
413
+ $paths[] = $file->getRelativePathname();
414
+ }
415
+
416
+ $ref = array("test.php", "toto", "test.py", "foo", "foo".DIRECTORY_SEPARATOR."bar.tmp", "foo bar");
417
+
418
+ sort($paths);
419
+ sort($ref);
420
+
421
+ $this->assertEquals($ref, $paths);
422
+ }
423
+
424
+ /**
425
+ * @dataProvider getAdaptersTestData
426
+ */
427
+ public function testAppendWithAFinder($adapter)
428
+ {
429
+ $finder = $this->buildFinder($adapter);
430
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
431
+
432
+ $finder1 = $this->buildFinder($adapter);
433
+ $finder1->directories()->in(self::$tmpDir);
434
+
435
+ $finder = $finder->append($finder1);
436
+
437
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
438
+ }
439
+
440
+ /**
441
+ * @dataProvider getAdaptersTestData
442
+ */
443
+ public function testAppendWithAnArray($adapter)
444
+ {
445
+ $finder = $this->buildFinder($adapter);
446
+ $finder->files()->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
447
+
448
+ $finder->append($this->toAbsolute(array('foo', 'toto')));
449
+
450
+ $this->assertIterator($this->toAbsolute(array('foo', 'foo/bar.tmp', 'toto')), $finder->getIterator());
451
+ }
452
+
453
+ /**
454
+ * @dataProvider getAdaptersTestData
455
+ */
456
+ public function testAppendReturnsAFinder($adapter)
457
+ {
458
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\Finder', $this->buildFinder($adapter)->append(array()));
459
+ }
460
+
461
+ /**
462
+ * @dataProvider getAdaptersTestData
463
+ */
464
+ public function testAppendDoesNotRequireIn($adapter)
465
+ {
466
+ $finder = $this->buildFinder($adapter);
467
+ $finder->in(self::$tmpDir.DIRECTORY_SEPARATOR.'foo');
468
+
469
+ $finder1 = Finder::create()->append($finder);
470
+
471
+ $this->assertIterator(iterator_to_array($finder->getIterator()), $finder1->getIterator());
472
+ }
473
+
474
+ public function testCountDirectories()
475
+ {
476
+ $directory = Finder::create()->directories()->in(self::$tmpDir);
477
+ $i = 0;
478
+
479
+ foreach ($directory as $dir) {
480
+ $i++;
481
+ }
482
+
483
+ $this->assertCount($i, $directory);
484
+ }
485
+
486
+ public function testCountFiles()
487
+ {
488
+ $files = Finder::create()->files()->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures');
489
+ $i = 0;
490
+
491
+ foreach ($files as $file) {
492
+ $i++;
493
+ }
494
+
495
+ $this->assertCount($i, $files);
496
+ }
497
+
498
+ /**
499
+ * @expectedException \LogicException
500
+ */
501
+ public function testCountWithoutIn()
502
+ {
503
+ $finder = Finder::create()->files();
504
+ count($finder);
505
+ }
506
+
507
+ /**
508
+ * @dataProvider getContainsTestData
509
+ * @group grep
510
+ */
511
+ public function testContains($adapter, $matchPatterns, $noMatchPatterns, $expected)
512
+ {
513
+ $finder = $this->buildFinder($adapter);
514
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
515
+ ->name('*.txt')->sortByName()
516
+ ->contains($matchPatterns)
517
+ ->notContains($noMatchPatterns);
518
+
519
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
520
+ }
521
+
522
+ /**
523
+ * @dataProvider getAdaptersTestData
524
+ */
525
+ public function testContainsOnDirectory(Adapter\AdapterInterface $adapter)
526
+ {
527
+ $finder = $this->buildFinder($adapter);
528
+ $finder->in(__DIR__)
529
+ ->directories()
530
+ ->name('Fixtures')
531
+ ->contains('abc');
532
+ $this->assertIterator(array(), $finder);
533
+ }
534
+
535
+ /**
536
+ * @dataProvider getAdaptersTestData
537
+ */
538
+ public function testNotContainsOnDirectory(Adapter\AdapterInterface $adapter)
539
+ {
540
+ $finder = $this->buildFinder($adapter);
541
+ $finder->in(__DIR__)
542
+ ->directories()
543
+ ->name('Fixtures')
544
+ ->notContains('abc');
545
+ $this->assertIterator(array(), $finder);
546
+ }
547
+
548
+ /**
549
+ * Searching in multiple locations involves AppendIterator which does an unnecessary rewind which leaves FilterIterator
550
+ * with inner FilesystemIterator in an invalid state.
551
+ *
552
+ * @see https://bugs.php.net/bug.php?id=49104
553
+ *
554
+ * @dataProvider getAdaptersTestData
555
+ */
556
+ public function testMultipleLocations(Adapter\AdapterInterface $adapter)
557
+ {
558
+ $locations = array(
559
+ self::$tmpDir.'/',
560
+ self::$tmpDir.'/toto/',
561
+ );
562
+
563
+ // it is expected that there are test.py test.php in the tmpDir
564
+ $finder = $this->buildFinder($adapter);
565
+ $finder->in($locations)->depth('< 1')->name('test.php');
566
+
567
+ $this->assertCount(1, $finder);
568
+ }
569
+
570
+ /**
571
+ * Iterator keys must be the file pathname.
572
+ *
573
+ * @dataProvider getAdaptersTestData
574
+ */
575
+ public function testIteratorKeys(Adapter\AdapterInterface $adapter)
576
+ {
577
+ $finder = $this->buildFinder($adapter)->in(self::$tmpDir);
578
+ foreach ($finder as $key => $file) {
579
+ $this->assertEquals($file->getPathname(), $key);
580
+ }
581
+ }
582
+
583
+ /**
584
+ * @dataProvider getAdaptersTestData
585
+ */
586
+ public function testRegexSpecialCharsLocationWithPathRestrictionContainingStartFlag(Adapter\AdapterInterface $adapter)
587
+ {
588
+ $finder = $this->buildFinder($adapter);
589
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.'r+e.gex[c]a(r)s')
590
+ ->path('/^dir/');
591
+
592
+ $expected = array('r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir',
593
+ 'r+e.gex[c]a(r)s'.DIRECTORY_SEPARATOR.'dir'.DIRECTORY_SEPARATOR.'bar.dat',);
594
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
595
+ }
596
+
597
+ public function testAdaptersOrdering()
598
+ {
599
+ $finder = Finder::create()
600
+ ->removeAdapters()
601
+ ->addAdapter(new FakeAdapter\NamedAdapter('a'), 0)
602
+ ->addAdapter(new FakeAdapter\NamedAdapter('b'), -50)
603
+ ->addAdapter(new FakeAdapter\NamedAdapter('c'), 50)
604
+ ->addAdapter(new FakeAdapter\NamedAdapter('d'), -25)
605
+ ->addAdapter(new FakeAdapter\NamedAdapter('e'), 25);
606
+
607
+ $this->assertEquals(
608
+ array('c', 'e', 'a', 'd', 'b'),
609
+ array_map(function (Adapter\AdapterInterface $adapter) {
610
+ return $adapter->getName();
611
+ }, $finder->getAdapters())
612
+ );
613
+ }
614
+
615
+ public function testAdaptersChaining()
616
+ {
617
+ $iterator = new \ArrayIterator(array());
618
+ $filenames = $this->toAbsolute(array('foo', 'foo/bar.tmp', 'test.php', 'test.py', 'toto'));
619
+ foreach ($filenames as $file) {
620
+ $iterator->append(new \Symfony\Component\Finder\SplFileInfo($file, null, null));
621
+ }
622
+
623
+ $finder = Finder::create()
624
+ ->removeAdapters()
625
+ ->addAdapter(new FakeAdapter\UnsupportedAdapter(), 3)
626
+ ->addAdapter(new FakeAdapter\FailingAdapter(), 2)
627
+ ->addAdapter(new FakeAdapter\DummyAdapter($iterator), 1);
628
+
629
+ $this->assertIterator($filenames, $finder->in(sys_get_temp_dir())->getIterator());
630
+ }
631
+
632
+ public function getAdaptersTestData()
633
+ {
634
+ return array_map(
635
+ function ($adapter) { return array($adapter); },
636
+ $this->getValidAdapters()
637
+ );
638
+ }
639
+
640
+ public function getContainsTestData()
641
+ {
642
+ $tests = array(
643
+ array('', '', array()),
644
+ array('foo', 'bar', array()),
645
+ array('', 'foobar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
646
+ array('lorem ipsum dolor sit amet', 'foobar', array('lorem.txt')),
647
+ array('sit', 'bar', array('dolor.txt', 'ipsum.txt', 'lorem.txt')),
648
+ array('dolor sit amet', '@^L@m', array('dolor.txt', 'ipsum.txt')),
649
+ array('/^lorem ipsum dolor sit amet$/m', 'foobar', array('lorem.txt')),
650
+ array('lorem', 'foobar', array('lorem.txt')),
651
+ array('', 'lorem', array('dolor.txt', 'ipsum.txt')),
652
+ array('ipsum dolor sit amet', '/^IPSUM/m', array('lorem.txt')),
653
+ );
654
+
655
+ return $this->buildTestData($tests);
656
+ }
657
+
658
+ public function getRegexNameTestData()
659
+ {
660
+ $tests = array(
661
+ array('~.+\\.p.+~i'),
662
+ array('~t.*s~i'),
663
+ );
664
+
665
+ return $this->buildTestData($tests);
666
+ }
667
+
668
+ /**
669
+ * @dataProvider getTestPathData
670
+ */
671
+ public function testPath(Adapter\AdapterInterface $adapter, $matchPatterns, $noMatchPatterns, array $expected)
672
+ {
673
+ $finder = $this->buildFinder($adapter);
674
+ $finder->in(__DIR__.DIRECTORY_SEPARATOR.'Fixtures')
675
+ ->path($matchPatterns)
676
+ ->notPath($noMatchPatterns);
677
+
678
+ $this->assertIterator($this->toAbsoluteFixtures($expected), $finder);
679
+ }
680
+
681
+ public function testAdapterSelection()
682
+ {
683
+ // test that by default, PhpAdapter is selected
684
+ $adapters = Finder::create()->getAdapters();
685
+ $this->assertTrue($adapters[0] instanceof Adapter\PhpAdapter);
686
+
687
+ // test another adapter selection
688
+ $adapters = Finder::create()->setAdapter('gnu_find')->getAdapters();
689
+ $this->assertTrue($adapters[0] instanceof Adapter\GnuFindAdapter);
690
+
691
+ // test that useBestAdapter method removes selection
692
+ $adapters = Finder::create()->useBestAdapter()->getAdapters();
693
+ $this->assertFalse($adapters[0] instanceof Adapter\PhpAdapter);
694
+ }
695
+
696
+ public function getTestPathData()
697
+ {
698
+ $tests = array(
699
+ array('', '', array()),
700
+ array('/^A\/B\/C/', '/C$/',
701
+ array('A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat'),
702
+ ),
703
+ array('/^A\/B/', 'foobar',
704
+ array(
705
+ 'A'.DIRECTORY_SEPARATOR.'B',
706
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
707
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
708
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
709
+ ),
710
+ ),
711
+ array('A/B/C', 'foobar',
712
+ array(
713
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
714
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
715
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
716
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
717
+ ),
718
+ ),
719
+ array('A/B', 'foobar',
720
+ array(
721
+ //dirs
722
+ 'A'.DIRECTORY_SEPARATOR.'B',
723
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
724
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B',
725
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C',
726
+ //files
727
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
728
+ 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
729
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat.copy',
730
+ 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat.copy',
731
+ ),
732
+ ),
733
+ array('/^with space\//', 'foobar',
734
+ array(
735
+ 'with space'.DIRECTORY_SEPARATOR.'foo.txt',
736
+ ),
737
+ ),
738
+ );
739
+
740
+ return $this->buildTestData($tests);
741
+ }
742
+
743
+ /**
744
+ * @dataProvider getAdaptersTestData
745
+ */
746
+ public function testAccessDeniedException(Adapter\AdapterInterface $adapter)
747
+ {
748
+ if ('\\' === DIRECTORY_SEPARATOR) {
749
+ $this->markTestSkipped('chmod is not supported on Windows');
750
+ }
751
+
752
+ $finder = $this->buildFinder($adapter);
753
+ $finder->files()->in(self::$tmpDir);
754
+
755
+ // make 'foo' directory non-readable
756
+ $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
757
+ chmod($testDir, 0333);
758
+
759
+ if (false === $couldRead = is_readable($testDir)) {
760
+ try {
761
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
762
+ $this->fail('Finder should throw an exception when opening a non-readable directory.');
763
+ } catch (\Exception $e) {
764
+ $expectedExceptionClass = 'Symfony\\Component\\Finder\\Exception\\AccessDeniedException';
765
+ if ($e instanceof \PHPUnit_Framework_ExpectationFailedException) {
766
+ $this->fail(sprintf("Expected exception:\n%s\nGot:\n%s\nWith comparison failure:\n%s", $expectedExceptionClass, 'PHPUnit_Framework_ExpectationFailedException', $e->getComparisonFailure()->getExpectedAsString()));
767
+ }
768
+
769
+ $this->assertInstanceOf($expectedExceptionClass, $e);
770
+ }
771
+ }
772
+
773
+ // restore original permissions
774
+ chmod($testDir, 0777);
775
+ clearstatcache($testDir);
776
+
777
+ if ($couldRead) {
778
+ $this->markTestSkipped('could read test files while test requires unreadable');
779
+ }
780
+ }
781
+
782
+ /**
783
+ * @dataProvider getAdaptersTestData
784
+ */
785
+ public function testIgnoredAccessDeniedException(Adapter\AdapterInterface $adapter)
786
+ {
787
+ if ('\\' === DIRECTORY_SEPARATOR) {
788
+ $this->markTestSkipped('chmod is not supported on Windows');
789
+ }
790
+
791
+ $finder = $this->buildFinder($adapter);
792
+ $finder->files()->ignoreUnreadableDirs()->in(self::$tmpDir);
793
+
794
+ // make 'foo' directory non-readable
795
+ $testDir = self::$tmpDir.DIRECTORY_SEPARATOR.'foo';
796
+ chmod($testDir, 0333);
797
+
798
+ if (false === ($couldRead = is_readable($testDir))) {
799
+ $this->assertIterator($this->toAbsolute(array('foo bar', 'test.php', 'test.py')), $finder->getIterator());
800
+ }
801
+
802
+ // restore original permissions
803
+ chmod($testDir, 0777);
804
+ clearstatcache($testDir);
805
+
806
+ if ($couldRead) {
807
+ $this->markTestSkipped('could read test files while test requires unreadable');
808
+ }
809
+ }
810
+
811
+ private function buildTestData(array $tests)
812
+ {
813
+ $data = array();
814
+ foreach ($this->getValidAdapters() as $adapter) {
815
+ foreach ($tests as $test) {
816
+ $data[] = array_merge(array($adapter), $test);
817
+ }
818
+ }
819
+
820
+ return $data;
821
+ }
822
+
823
+ private function buildFinder(Adapter\AdapterInterface $adapter)
824
+ {
825
+ return Finder::create()
826
+ ->removeAdapters()
827
+ ->addAdapter($adapter);
828
+ }
829
+
830
+ private function getValidAdapters()
831
+ {
832
+ return array_filter(
833
+ array(
834
+ new Adapter\BsdFindAdapter(),
835
+ new Adapter\GnuFindAdapter(),
836
+ new Adapter\PhpAdapter(),
837
+ ),
838
+ function (Adapter\AdapterInterface $adapter) {
839
+ return $adapter->isSupported();
840
+ }
841
+ );
842
+ }
843
+
844
+ /**
845
+ * Searching in multiple locations with sub directories involves
846
+ * AppendIterator which does an unnecessary rewind which leaves
847
+ * FilterIterator with inner FilesystemIterator in an invalid state.
848
+ *
849
+ * @see https://bugs.php.net/bug.php?id=49104
850
+ */
851
+ public function testMultipleLocationsWithSubDirectories()
852
+ {
853
+ $locations = array(
854
+ __DIR__.'/Fixtures/one',
855
+ self::$tmpDir.DIRECTORY_SEPARATOR.'toto',
856
+ );
857
+
858
+ $finder = new Finder();
859
+ $finder->in($locations)->depth('< 10')->name('*.neon');
860
+
861
+ $expected = array(
862
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'c.neon',
863
+ __DIR__.'/Fixtures/one'.DIRECTORY_SEPARATOR.'b'.DIRECTORY_SEPARATOR.'d.neon',
864
+ );
865
+
866
+ $this->assertIterator($expected, $finder);
867
+ $this->assertIteratorInForeach($expected, $finder);
868
+ }
869
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/C/abc.dat ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/B/ab.dat ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/A/a.dat ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/C/abc.dat.copy ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/B/ab.dat.copy ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/copy/A/a.dat.copy ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/dolor.txt ADDED
@@ -0,0 +1,2 @@
 
 
1
+ dolor sit amet
2
+ DOLOR SIT AMET
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/ipsum.txt ADDED
@@ -0,0 +1,2 @@
 
 
1
+ ipsum dolor sit amet
2
+ IPSUM DOLOR SIT AMET
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/lorem.txt ADDED
@@ -0,0 +1,2 @@
 
 
1
+ lorem ipsum dolor sit amet
2
+ LOREM IPSUM DOLOR SIT AMET
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/a ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/c.neon ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/one/b/d.neon ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/r+e.gex[c]a(r)s/dir/bar.dat ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Fixtures/with space/foo.txt ADDED
File without changes
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/CustomFilterIteratorTest.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\CustomFilterIterator;
15
+
16
+ class CustomFilterIteratorTest extends IteratorTestCase
17
+ {
18
+ /**
19
+ * @expectedException \InvalidArgumentException
20
+ */
21
+ public function testWithInvalidFilter()
22
+ {
23
+ new CustomFilterIterator(new Iterator(), array('foo'));
24
+ }
25
+
26
+ /**
27
+ * @dataProvider getAcceptData
28
+ */
29
+ public function testAccept($filters, $expected)
30
+ {
31
+ $inner = new Iterator(array('test.php', 'test.py', 'foo.php'));
32
+
33
+ $iterator = new CustomFilterIterator($inner, $filters);
34
+
35
+ $this->assertIterator($expected, $iterator);
36
+ }
37
+
38
+ public function getAcceptData()
39
+ {
40
+ return array(
41
+ array(array(function (\SplFileInfo $fileinfo) { return false; }), array()),
42
+ array(array(function (\SplFileInfo $fileinfo) { return preg_match('/^test/', $fileinfo) > 0; }), array('test.php', 'test.py')),
43
+ array(array('is_dir'), array()),
44
+ );
45
+ }
46
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DateRangeFilterIteratorTest.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\DateRangeFilterIterator;
15
+ use Symfony\Component\Finder\Comparator\DateComparator;
16
+
17
+ class DateRangeFilterIteratorTest extends RealIteratorTestCase
18
+ {
19
+ /**
20
+ * @dataProvider getAcceptData
21
+ */
22
+ public function testAccept($size, $expected)
23
+ {
24
+ $files = self::$files;
25
+ $files[] = self::toAbsolute('doesnotexist');
26
+ $inner = new Iterator($files);
27
+
28
+ $iterator = new DateRangeFilterIterator($inner, $size);
29
+
30
+ $this->assertIterator($expected, $iterator);
31
+ }
32
+
33
+ public function getAcceptData()
34
+ {
35
+ $since20YearsAgo = array(
36
+ '.git',
37
+ 'test.py',
38
+ 'foo',
39
+ 'foo/bar.tmp',
40
+ 'test.php',
41
+ 'toto',
42
+ '.bar',
43
+ '.foo',
44
+ '.foo/.bar',
45
+ 'foo bar',
46
+ '.foo/bar',
47
+ );
48
+
49
+ $since2MonthsAgo = array(
50
+ '.git',
51
+ 'test.py',
52
+ 'foo',
53
+ 'toto',
54
+ '.bar',
55
+ '.foo',
56
+ '.foo/.bar',
57
+ 'foo bar',
58
+ '.foo/bar',
59
+ );
60
+
61
+ $untilLastMonth = array(
62
+ 'foo/bar.tmp',
63
+ 'test.php',
64
+ );
65
+
66
+ return array(
67
+ array(array(new DateComparator('since 20 years ago')), $this->toAbsolute($since20YearsAgo)),
68
+ array(array(new DateComparator('since 2 months ago')), $this->toAbsolute($since2MonthsAgo)),
69
+ array(array(new DateComparator('until last month')), $this->toAbsolute($untilLastMonth)),
70
+ );
71
+ }
72
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/DepthRangeFilterIteratorTest.php ADDED
@@ -0,0 +1,80 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\DepthRangeFilterIterator;
15
+
16
+ class DepthRangeFilterIteratorTest extends RealIteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getAcceptData
20
+ */
21
+ public function testAccept($minDepth, $maxDepth, $expected)
22
+ {
23
+ $inner = new \RecursiveIteratorIterator(new \RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
24
+
25
+ $iterator = new DepthRangeFilterIterator($inner, $minDepth, $maxDepth);
26
+
27
+ $actual = array_keys(iterator_to_array($iterator));
28
+ sort($expected);
29
+ sort($actual);
30
+ $this->assertEquals($expected, $actual);
31
+ }
32
+
33
+ public function getAcceptData()
34
+ {
35
+ $lessThan1 = array(
36
+ '.git',
37
+ 'test.py',
38
+ 'foo',
39
+ 'test.php',
40
+ 'toto',
41
+ '.foo',
42
+ '.bar',
43
+ 'foo bar',
44
+ );
45
+
46
+ $lessThanOrEqualTo1 = array(
47
+ '.git',
48
+ 'test.py',
49
+ 'foo',
50
+ 'foo/bar.tmp',
51
+ 'test.php',
52
+ 'toto',
53
+ '.foo',
54
+ '.foo/.bar',
55
+ '.bar',
56
+ 'foo bar',
57
+ '.foo/bar',
58
+ );
59
+
60
+ $graterThanOrEqualTo1 = array(
61
+ 'foo/bar.tmp',
62
+ '.foo/.bar',
63
+ '.foo/bar',
64
+ );
65
+
66
+ $equalTo1 = array(
67
+ 'foo/bar.tmp',
68
+ '.foo/.bar',
69
+ '.foo/bar',
70
+ );
71
+
72
+ return array(
73
+ array(0, 0, $this->toAbsolute($lessThan1)),
74
+ array(0, 1, $this->toAbsolute($lessThanOrEqualTo1)),
75
+ array(2, PHP_INT_MAX, array()),
76
+ array(1, PHP_INT_MAX, $this->toAbsolute($graterThanOrEqualTo1)),
77
+ array(1, 1, $this->toAbsolute($equalTo1)),
78
+ );
79
+ }
80
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/ExcludeDirectoryFilterIteratorTest.php ADDED
@@ -0,0 +1,64 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\ExcludeDirectoryFilterIterator;
15
+ use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
16
+
17
+ class ExcludeDirectoryFilterIteratorTest extends RealIteratorTestCase
18
+ {
19
+ /**
20
+ * @dataProvider getAcceptData
21
+ */
22
+ public function testAccept($directories, $expected)
23
+ {
24
+ $inner = new \RecursiveIteratorIterator(new RecursiveDirectoryIterator($this->toAbsolute(), \FilesystemIterator::SKIP_DOTS), \RecursiveIteratorIterator::SELF_FIRST);
25
+
26
+ $iterator = new ExcludeDirectoryFilterIterator($inner, $directories);
27
+
28
+ $this->assertIterator($expected, $iterator);
29
+ }
30
+
31
+ public function getAcceptData()
32
+ {
33
+ $foo = array(
34
+ '.bar',
35
+ '.foo',
36
+ '.foo/.bar',
37
+ '.foo/bar',
38
+ '.git',
39
+ 'test.py',
40
+ 'test.php',
41
+ 'toto',
42
+ 'foo bar',
43
+ );
44
+
45
+ $fo = array(
46
+ '.bar',
47
+ '.foo',
48
+ '.foo/.bar',
49
+ '.foo/bar',
50
+ '.git',
51
+ 'test.py',
52
+ 'foo',
53
+ 'foo/bar.tmp',
54
+ 'test.php',
55
+ 'toto',
56
+ 'foo bar',
57
+ );
58
+
59
+ return array(
60
+ array(array('foo'), $this->toAbsolute($foo)),
61
+ array(array('fo'), $this->toAbsolute($fo)),
62
+ );
63
+ }
64
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilePathsIteratorTest.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\FilePathsIterator;
15
+
16
+ class FilePathsIteratorTest extends RealIteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getSubPathData
20
+ */
21
+ public function testSubPath($baseDir, array $paths, array $subPaths, array $subPathnames)
22
+ {
23
+ $iterator = new FilePathsIterator($paths, $baseDir);
24
+
25
+ foreach ($iterator as $index => $file) {
26
+ $this->assertEquals($paths[$index], $file->getPathname());
27
+ $this->assertEquals($subPaths[$index], $iterator->getSubPath());
28
+ $this->assertEquals($subPathnames[$index], $iterator->getSubPathname());
29
+ }
30
+ }
31
+
32
+ public function getSubPathData()
33
+ {
34
+ $tmpDir = sys_get_temp_dir().'/symfony_finder';
35
+
36
+ return array(
37
+ array(
38
+ $tmpDir,
39
+ array( // paths
40
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => $tmpDir.DIRECTORY_SEPARATOR.'.git',
41
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => $tmpDir.DIRECTORY_SEPARATOR.'test.py',
42
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => $tmpDir.DIRECTORY_SEPARATOR.'foo',
43
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
44
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => $tmpDir.DIRECTORY_SEPARATOR.'test.php',
45
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => $tmpDir.DIRECTORY_SEPARATOR.'toto',
46
+ ),
47
+ array( // subPaths
48
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '',
49
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => '',
50
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => '',
51
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo',
52
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => '',
53
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => '',
54
+ ),
55
+ array( // subPathnames
56
+ $tmpDir.DIRECTORY_SEPARATOR.'.git' => '.git',
57
+ $tmpDir.DIRECTORY_SEPARATOR.'test.py' => 'test.py',
58
+ $tmpDir.DIRECTORY_SEPARATOR.'foo' => 'foo',
59
+ $tmpDir.DIRECTORY_SEPARATOR.'foo'.DIRECTORY_SEPARATOR.'bar.tmp' => 'foo'.DIRECTORY_SEPARATOR.'bar.tmp',
60
+ $tmpDir.DIRECTORY_SEPARATOR.'test.php' => 'test.php',
61
+ $tmpDir.DIRECTORY_SEPARATOR.'toto' => 'toto',
62
+ ),
63
+ ),
64
+ );
65
+ }
66
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FileTypeFilterIteratorTest.php ADDED
@@ -0,0 +1,72 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\FileTypeFilterIterator;
15
+
16
+ class FileTypeFilterIteratorTest extends RealIteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getAcceptData
20
+ */
21
+ public function testAccept($mode, $expected)
22
+ {
23
+ $inner = new InnerTypeIterator(self::$files);
24
+
25
+ $iterator = new FileTypeFilterIterator($inner, $mode);
26
+
27
+ $this->assertIterator($expected, $iterator);
28
+ }
29
+
30
+ public function getAcceptData()
31
+ {
32
+ $onlyFiles = array(
33
+ 'test.py',
34
+ 'foo/bar.tmp',
35
+ 'test.php',
36
+ '.bar',
37
+ '.foo/.bar',
38
+ '.foo/bar',
39
+ 'foo bar',
40
+ );
41
+
42
+ $onlyDirectories = array(
43
+ '.git',
44
+ 'foo',
45
+ 'toto',
46
+ '.foo',
47
+ );
48
+
49
+ return array(
50
+ array(FileTypeFilterIterator::ONLY_FILES, $this->toAbsolute($onlyFiles)),
51
+ array(FileTypeFilterIterator::ONLY_DIRECTORIES, $this->toAbsolute($onlyDirectories)),
52
+ );
53
+ }
54
+ }
55
+
56
+ class InnerTypeIterator extends \ArrayIterator
57
+ {
58
+ public function current()
59
+ {
60
+ return new \SplFileInfo(parent::current());
61
+ }
62
+
63
+ public function isFile()
64
+ {
65
+ return $this->current()->isFile();
66
+ }
67
+
68
+ public function isDir()
69
+ {
70
+ return $this->current()->isDir();
71
+ }
72
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilecontentFilterIteratorTest.php ADDED
@@ -0,0 +1,86 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\FilecontentFilterIterator;
15
+
16
+ class FilecontentFilterIteratorTest extends IteratorTestCase
17
+ {
18
+ public function testAccept()
19
+ {
20
+ $inner = new MockFileListIterator(array('test.txt'));
21
+ $iterator = new FilecontentFilterIterator($inner, array(), array());
22
+ $this->assertIterator(array('test.txt'), $iterator);
23
+ }
24
+
25
+ public function testDirectory()
26
+ {
27
+ $inner = new MockFileListIterator(array('directory'));
28
+ $iterator = new FilecontentFilterIterator($inner, array('directory'), array());
29
+ $this->assertIterator(array(), $iterator);
30
+ }
31
+
32
+ public function testUnreadableFile()
33
+ {
34
+ $inner = new MockFileListIterator(array('file r-'));
35
+ $iterator = new FilecontentFilterIterator($inner, array('file r-'), array());
36
+ $this->assertIterator(array(), $iterator);
37
+ }
38
+
39
+ /**
40
+ * @dataProvider getTestFilterData
41
+ */
42
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
43
+ {
44
+ $iterator = new FilecontentFilterIterator($inner, $matchPatterns, $noMatchPatterns);
45
+ $this->assertIterator($resultArray, $iterator);
46
+ }
47
+
48
+ public function getTestFilterData()
49
+ {
50
+ $inner = new MockFileListIterator();
51
+
52
+ $inner[] = new MockSplFileInfo(array(
53
+ 'name' => 'a.txt',
54
+ 'contents' => 'Lorem ipsum...',
55
+ 'type' => 'file',
56
+ 'mode' => 'r+', )
57
+ );
58
+
59
+ $inner[] = new MockSplFileInfo(array(
60
+ 'name' => 'b.yml',
61
+ 'contents' => 'dolor sit...',
62
+ 'type' => 'file',
63
+ 'mode' => 'r+', )
64
+ );
65
+
66
+ $inner[] = new MockSplFileInfo(array(
67
+ 'name' => 'some/other/dir/third.php',
68
+ 'contents' => 'amet...',
69
+ 'type' => 'file',
70
+ 'mode' => 'r+', )
71
+ );
72
+
73
+ $inner[] = new MockSplFileInfo(array(
74
+ 'name' => 'unreadable-file.txt',
75
+ 'contents' => false,
76
+ 'type' => 'file',
77
+ 'mode' => 'r+', )
78
+ );
79
+
80
+ return array(
81
+ array($inner, array('.'), array(), array('a.txt', 'b.yml', 'some/other/dir/third.php')),
82
+ array($inner, array('ipsum'), array(), array('a.txt')),
83
+ array($inner, array('i', 'amet'), array('Lorem', 'amet'), array('b.yml')),
84
+ );
85
+ }
86
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilenameFilterIteratorTest.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\FilenameFilterIterator;
15
+
16
+ class FilenameFilterIteratorTest extends IteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getAcceptData
20
+ */
21
+ public function testAccept($matchPatterns, $noMatchPatterns, $expected)
22
+ {
23
+ $inner = new InnerNameIterator(array('test.php', 'test.py', 'foo.php'));
24
+
25
+ $iterator = new FilenameFilterIterator($inner, $matchPatterns, $noMatchPatterns);
26
+
27
+ $this->assertIterator($expected, $iterator);
28
+ }
29
+
30
+ public function getAcceptData()
31
+ {
32
+ return array(
33
+ array(array('test.*'), array(), array('test.php', 'test.py')),
34
+ array(array(), array('test.*'), array('foo.php')),
35
+ array(array('*.php'), array('test.*'), array('foo.php')),
36
+ array(array('*.php', '*.py'), array('foo.*'), array('test.php', 'test.py')),
37
+ array(array('/\.php$/'), array(), array('test.php', 'foo.php')),
38
+ array(array(), array('/\.php$/'), array('test.py')),
39
+ );
40
+ }
41
+ }
42
+
43
+ class InnerNameIterator extends \ArrayIterator
44
+ {
45
+ public function current()
46
+ {
47
+ return new \SplFileInfo(parent::current());
48
+ }
49
+
50
+ public function getFilename()
51
+ {
52
+ return parent::current();
53
+ }
54
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/FilterIteratorTest.php ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ /**
15
+ * @author Alex Bogomazov
16
+ */
17
+ class FilterIteratorTest extends RealIteratorTestCase
18
+ {
19
+ public function testFilterFilesystemIterators()
20
+ {
21
+ $i = new \FilesystemIterator($this->toAbsolute());
22
+
23
+ // it is expected that there are test.py test.php in the tmpDir
24
+ $i = $this->getMockForAbstractClass('Symfony\Component\Finder\Iterator\FilterIterator', array($i));
25
+ $i->expects($this->any())
26
+ ->method('accept')
27
+ ->will($this->returnCallback(function () use ($i) {
28
+ return (bool) preg_match('/\.php/', (string) $i->current());
29
+ })
30
+ );
31
+
32
+ $c = 0;
33
+ foreach ($i as $item) {
34
+ $c++;
35
+ }
36
+
37
+ $this->assertEquals(1, $c);
38
+
39
+ $i->rewind();
40
+
41
+ $c = 0;
42
+ foreach ($i as $item) {
43
+ $c++;
44
+ }
45
+
46
+ // This would fail with \FilterIterator but works with Symfony\Component\Finder\Iterator\FilterIterator
47
+ // see https://bugs.php.net/bug.php?id=49104
48
+ $this->assertEquals(1, $c);
49
+ }
50
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/Iterator.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ class Iterator implements \Iterator
15
+ {
16
+ protected $values = array();
17
+
18
+ public function __construct(array $values = array())
19
+ {
20
+ foreach ($values as $value) {
21
+ $this->attach(new \SplFileInfo($value));
22
+ }
23
+ $this->rewind();
24
+ }
25
+
26
+ public function attach(\SplFileInfo $fileinfo)
27
+ {
28
+ $this->values[] = $fileinfo;
29
+ }
30
+
31
+ public function rewind()
32
+ {
33
+ reset($this->values);
34
+ }
35
+
36
+ public function valid()
37
+ {
38
+ return false !== $this->current();
39
+ }
40
+
41
+ public function next()
42
+ {
43
+ next($this->values);
44
+ }
45
+
46
+ public function current()
47
+ {
48
+ return current($this->values);
49
+ }
50
+
51
+ public function key()
52
+ {
53
+ return key($this->values);
54
+ }
55
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/IteratorTestCase.php ADDED
@@ -0,0 +1,98 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ abstract class IteratorTestCase extends \PHPUnit_Framework_TestCase
15
+ {
16
+ protected function assertIterator($expected, \Traversable $iterator)
17
+ {
18
+ // set iterator_to_array $use_key to false to avoid values merge
19
+ // this made FinderTest::testAppendWithAnArray() failed with GnuFinderAdapter
20
+ $values = array_map(function (\SplFileInfo $fileinfo) { return str_replace('/', DIRECTORY_SEPARATOR, $fileinfo->getPathname()); }, iterator_to_array($iterator, false));
21
+
22
+ $expected = array_map(function ($path) { return str_replace('/', DIRECTORY_SEPARATOR, $path); }, $expected);
23
+
24
+ sort($values);
25
+ sort($expected);
26
+
27
+ $this->assertEquals($expected, array_values($values));
28
+ }
29
+
30
+ protected function assertOrderedIterator($expected, \Traversable $iterator)
31
+ {
32
+ $values = array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator));
33
+
34
+ $this->assertEquals($expected, array_values($values));
35
+ }
36
+
37
+ /**
38
+ * Same as assertOrderedIterator, but checks the order of groups of
39
+ * array elements.
40
+ *
41
+ * @param array $expected - an array of arrays. For any two subarrays
42
+ * $a and $b such that $a goes before $b in $expected, the method
43
+ * asserts that any element of $a goes before any element of $b
44
+ * in the sequence generated by $iterator
45
+ * @param \Traversable $iterator
46
+ */
47
+ protected function assertOrderedIteratorForGroups($expected, \Traversable $iterator)
48
+ {
49
+ $values = array_values(array_map(function (\SplFileInfo $fileinfo) { return $fileinfo->getPathname(); }, iterator_to_array($iterator)));
50
+
51
+ foreach ($expected as $subarray) {
52
+ $temp = array();
53
+ while (count($values) && count($temp) < count($subarray)) {
54
+ array_push($temp, array_shift($values));
55
+ }
56
+ sort($temp);
57
+ sort($subarray);
58
+ $this->assertEquals($subarray, $temp);
59
+ }
60
+ }
61
+
62
+ /**
63
+ * Same as IteratorTestCase::assertIterator with foreach usage.
64
+ *
65
+ * @param array $expected
66
+ * @param \Traversable $iterator
67
+ */
68
+ protected function assertIteratorInForeach($expected, \Traversable $iterator)
69
+ {
70
+ $values = array();
71
+ foreach ($iterator as $file) {
72
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
73
+ $values[] = $file->getPathname();
74
+ }
75
+
76
+ sort($values);
77
+ sort($expected);
78
+
79
+ $this->assertEquals($expected, array_values($values));
80
+ }
81
+
82
+ /**
83
+ * Same as IteratorTestCase::assertOrderedIterator with foreach usage.
84
+ *
85
+ * @param array $expected
86
+ * @param \Traversable $iterator
87
+ */
88
+ protected function assertOrderedIteratorInForeach($expected, \Traversable $iterator)
89
+ {
90
+ $values = array();
91
+ foreach ($iterator as $file) {
92
+ $this->assertInstanceOf('Symfony\\Component\\Finder\\SplFileInfo', $file);
93
+ $values[] = $file->getPathname();
94
+ }
95
+
96
+ $this->assertEquals($expected, array_values($values));
97
+ }
98
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockFileListIterator.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ class MockFileListIterator extends \ArrayIterator
15
+ {
16
+ public function __construct(array $filesArray = array())
17
+ {
18
+ $files = array_map(function ($file) { return new MockSplFileInfo($file); }, $filesArray);
19
+ parent::__construct($files);
20
+ }
21
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MockSplFileInfo.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ class MockSplFileInfo extends \SplFileInfo
15
+ {
16
+ const TYPE_DIRECTORY = 1;
17
+ const TYPE_FILE = 2;
18
+ const TYPE_UNKNOWN = 3;
19
+
20
+ private $contents = null;
21
+ private $mode = null;
22
+ private $type = null;
23
+ private $relativePath = null;
24
+ private $relativePathname = null;
25
+
26
+ public function __construct($param)
27
+ {
28
+ if (is_string($param)) {
29
+ parent::__construct($param);
30
+ } elseif (is_array($param)) {
31
+ $defaults = array(
32
+ 'name' => 'file.txt',
33
+ 'contents' => null,
34
+ 'mode' => null,
35
+ 'type' => null,
36
+ 'relativePath' => null,
37
+ 'relativePathname' => null,
38
+ );
39
+ $defaults = array_merge($defaults, $param);
40
+ parent::__construct($defaults['name']);
41
+ $this->setContents($defaults['contents']);
42
+ $this->setMode($defaults['mode']);
43
+ $this->setType($defaults['type']);
44
+ $this->setRelativePath($defaults['relativePath']);
45
+ $this->setRelativePathname($defaults['relativePathname']);
46
+ } else {
47
+ throw new \RuntimeException(sprintf('Incorrect parameter "%s"', $param));
48
+ }
49
+ }
50
+
51
+ public function isFile()
52
+ {
53
+ if (null === $this->type) {
54
+ return preg_match('/file/', $this->getFilename());
55
+ };
56
+
57
+ return self::TYPE_FILE === $this->type;
58
+ }
59
+
60
+ public function isDir()
61
+ {
62
+ if (null === $this->type) {
63
+ return preg_match('/directory/', $this->getFilename());
64
+ }
65
+
66
+ return self::TYPE_DIRECTORY === $this->type;
67
+ }
68
+
69
+ public function isReadable()
70
+ {
71
+ if (null === $this->mode) {
72
+ return preg_match('/r\+/', $this->getFilename());
73
+ }
74
+
75
+ return preg_match('/r\+/', $this->mode);
76
+ }
77
+
78
+ public function getContents()
79
+ {
80
+ return $this->contents;
81
+ }
82
+
83
+ public function setContents($contents)
84
+ {
85
+ $this->contents = $contents;
86
+ }
87
+
88
+ public function setMode($mode)
89
+ {
90
+ $this->mode = $mode;
91
+ }
92
+
93
+ public function setType($type)
94
+ {
95
+ if (is_string($type)) {
96
+ switch ($type) {
97
+ case 'directory':
98
+ $this->type = self::TYPE_DIRECTORY;
99
+ case 'd':
100
+ $this->type = self::TYPE_DIRECTORY;
101
+ break;
102
+ case 'file':
103
+ $this->type = self::TYPE_FILE;
104
+ case 'f':
105
+ $this->type = self::TYPE_FILE;
106
+ break;
107
+ default:
108
+ $this->type = self::TYPE_UNKNOWN;
109
+ }
110
+ } else {
111
+ $this->type = $type;
112
+ }
113
+ }
114
+
115
+ public function setRelativePath($relativePath)
116
+ {
117
+ $this->relativePath = $relativePath;
118
+ }
119
+
120
+ public function setRelativePathname($relativePathname)
121
+ {
122
+ $this->relativePathname = $relativePathname;
123
+ }
124
+
125
+ public function getRelativePath()
126
+ {
127
+ return $this->relativePath;
128
+ }
129
+
130
+ public function getRelativePathname()
131
+ {
132
+ return $this->relativePathname;
133
+ }
134
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/MultiplePcreFilterIteratorTest.php ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\MultiplePcreFilterIterator;
15
+
16
+ class MultiplePcreFilterIteratorTest extends \PHPUnit_Framework_TestCase
17
+ {
18
+ /**
19
+ * @dataProvider getIsRegexFixtures
20
+ */
21
+ public function testIsRegex($string, $isRegex, $message)
22
+ {
23
+ $testIterator = new TestMultiplePcreFilterIterator();
24
+ $this->assertEquals($isRegex, $testIterator->isRegex($string), $message);
25
+ }
26
+
27
+ public function getIsRegexFixtures()
28
+ {
29
+ return array(
30
+ array('foo', false, 'string'),
31
+ array(' foo ', false, '" " is not a valid delimiter'),
32
+ array('\\foo\\', false, '"\\" is not a valid delimiter'),
33
+ array('afooa', false, '"a" is not a valid delimiter'),
34
+ array('//', false, 'the pattern should contain at least 1 character'),
35
+ array('/a/', true, 'valid regex'),
36
+ array('/foo/', true, 'valid regex'),
37
+ array('/foo/i', true, 'valid regex with a single modifier'),
38
+ array('/foo/imsxu', true, 'valid regex with multiple modifiers'),
39
+ array('#foo#', true, '"#" is a valid delimiter'),
40
+ array('{foo}', true, '"{,}" is a valid delimiter pair'),
41
+ array('*foo.*', false, '"*" is not considered as a valid delimiter'),
42
+ array('?foo.?', false, '"?" is not considered as a valid delimiter'),
43
+ );
44
+ }
45
+ }
46
+
47
+ class TestMultiplePcreFilterIterator extends MultiplePcreFilterIterator
48
+ {
49
+ public function __construct()
50
+ {
51
+ }
52
+
53
+ public function accept()
54
+ {
55
+ throw new \BadFunctionCallException('Not implemented');
56
+ }
57
+
58
+ public function isRegex($str)
59
+ {
60
+ return parent::isRegex($str);
61
+ }
62
+
63
+ public function toRegex($str)
64
+ {
65
+ throw new \BadFunctionCallException('Not implemented');
66
+ }
67
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/PathFilterIteratorTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\PathFilterIterator;
15
+
16
+ class PathFilterIteratorTest extends IteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getTestFilterData
20
+ */
21
+ public function testFilter(\Iterator $inner, array $matchPatterns, array $noMatchPatterns, array $resultArray)
22
+ {
23
+ $iterator = new PathFilterIterator($inner, $matchPatterns, $noMatchPatterns);
24
+ $this->assertIterator($resultArray, $iterator);
25
+ }
26
+
27
+ public function getTestFilterData()
28
+ {
29
+ $inner = new MockFileListIterator();
30
+
31
+ //PATH: A/B/C/abc.dat
32
+ $inner[] = new MockSplFileInfo(array(
33
+ 'name' => 'abc.dat',
34
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
35
+ ));
36
+
37
+ //PATH: A/B/ab.dat
38
+ $inner[] = new MockSplFileInfo(array(
39
+ 'name' => 'ab.dat',
40
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
41
+ ));
42
+
43
+ //PATH: A/a.dat
44
+ $inner[] = new MockSplFileInfo(array(
45
+ 'name' => 'a.dat',
46
+ 'relativePathname' => 'A'.DIRECTORY_SEPARATOR.'a.dat',
47
+ ));
48
+
49
+ //PATH: copy/A/B/C/abc.dat.copy
50
+ $inner[] = new MockSplFileInfo(array(
51
+ 'name' => 'abc.dat.copy',
52
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'C'.DIRECTORY_SEPARATOR.'abc.dat',
53
+ ));
54
+
55
+ //PATH: copy/A/B/ab.dat.copy
56
+ $inner[] = new MockSplFileInfo(array(
57
+ 'name' => 'ab.dat.copy',
58
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'B'.DIRECTORY_SEPARATOR.'ab.dat',
59
+ ));
60
+
61
+ //PATH: copy/A/a.dat.copy
62
+ $inner[] = new MockSplFileInfo(array(
63
+ 'name' => 'a.dat.copy',
64
+ 'relativePathname' => 'copy'.DIRECTORY_SEPARATOR.'A'.DIRECTORY_SEPARATOR.'a.dat',
65
+ ));
66
+
67
+ return array(
68
+ array($inner, array('/^A/'), array(), array('abc.dat', 'ab.dat', 'a.dat')),
69
+ array($inner, array('/^A\/B/'), array(), array('abc.dat', 'ab.dat')),
70
+ array($inner, array('/^A\/B\/C/'), array(), array('abc.dat')),
71
+ array($inner, array('/A\/B\/C/'), array(), array('abc.dat', 'abc.dat.copy')),
72
+
73
+ array($inner, array('A'), array(), array('abc.dat', 'ab.dat', 'a.dat', 'abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
74
+ array($inner, array('A/B'), array(), array('abc.dat', 'ab.dat', 'abc.dat.copy', 'ab.dat.copy')),
75
+ array($inner, array('A/B/C'), array(), array('abc.dat', 'abc.dat.copy')),
76
+
77
+ array($inner, array('copy/A'), array(), array('abc.dat.copy', 'ab.dat.copy', 'a.dat.copy')),
78
+ array($inner, array('copy/A/B'), array(), array('abc.dat.copy', 'ab.dat.copy')),
79
+ array($inner, array('copy/A/B/C'), array(), array('abc.dat.copy')),
80
+
81
+ );
82
+ }
83
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RealIteratorTestCase.php ADDED
@@ -0,0 +1,109 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ abstract class RealIteratorTestCase extends IteratorTestCase
15
+ {
16
+ protected static $tmpDir;
17
+ protected static $files;
18
+
19
+ public static function setUpBeforeClass()
20
+ {
21
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';
22
+
23
+ self::$files = array(
24
+ '.git/',
25
+ '.foo/',
26
+ '.foo/.bar',
27
+ '.foo/bar',
28
+ '.bar',
29
+ 'test.py',
30
+ 'foo/',
31
+ 'foo/bar.tmp',
32
+ 'test.php',
33
+ 'toto/',
34
+ 'foo bar',
35
+ );
36
+
37
+ self::$files = self::toAbsolute(self::$files);
38
+
39
+ if (is_dir(self::$tmpDir)) {
40
+ self::tearDownAfterClass();
41
+ } else {
42
+ mkdir(self::$tmpDir);
43
+ }
44
+
45
+ foreach (self::$files as $file) {
46
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
47
+ mkdir($file);
48
+ } else {
49
+ touch($file);
50
+ }
51
+ }
52
+
53
+ file_put_contents(self::toAbsolute('test.php'), str_repeat(' ', 800));
54
+ file_put_contents(self::toAbsolute('test.py'), str_repeat(' ', 2000));
55
+
56
+ touch(self::toAbsolute('foo/bar.tmp'), strtotime('2005-10-15'));
57
+ touch(self::toAbsolute('test.php'), strtotime('2005-10-15'));
58
+ }
59
+
60
+ public static function tearDownAfterClass()
61
+ {
62
+ foreach (array_reverse(self::$files) as $file) {
63
+ if (DIRECTORY_SEPARATOR === $file[strlen($file) - 1]) {
64
+ @rmdir($file);
65
+ } else {
66
+ @unlink($file);
67
+ }
68
+ }
69
+ }
70
+
71
+ protected static function toAbsolute($files = null)
72
+ {
73
+ /*
74
+ * Without the call to setUpBeforeClass() property can be null.
75
+ */
76
+ if (!self::$tmpDir) {
77
+ self::$tmpDir = realpath(sys_get_temp_dir()).DIRECTORY_SEPARATOR.'symfony_finder';
78
+ }
79
+
80
+ if (is_array($files)) {
81
+ $f = array();
82
+ foreach ($files as $file) {
83
+ if (is_array($file)) {
84
+ $f[] = self::toAbsolute($file);
85
+ } else {
86
+ $f[] = self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $file);
87
+ }
88
+ }
89
+
90
+ return $f;
91
+ }
92
+
93
+ if (is_string($files)) {
94
+ return self::$tmpDir.DIRECTORY_SEPARATOR.str_replace('/', DIRECTORY_SEPARATOR, $files);
95
+ }
96
+
97
+ return self::$tmpDir;
98
+ }
99
+
100
+ protected static function toAbsoluteFixtures($files)
101
+ {
102
+ $f = array();
103
+ foreach ($files as $file) {
104
+ $f[] = realpath(__DIR__.DIRECTORY_SEPARATOR.'..'.DIRECTORY_SEPARATOR.'Fixtures'.DIRECTORY_SEPARATOR.$file);
105
+ }
106
+
107
+ return $f;
108
+ }
109
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/RecursiveDirectoryIteratorTest.php ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\RecursiveDirectoryIterator;
15
+
16
+ class RecursiveDirectoryIteratorTest extends IteratorTestCase
17
+ {
18
+ /**
19
+ * @dataProvider getPaths
20
+ *
21
+ * @param string $path
22
+ * @param bool $seekable
23
+ * @param array $contains
24
+ * @param string $message
25
+ */
26
+ public function testRewind($path, $seekable, $contains, $message = null)
27
+ {
28
+ try {
29
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
30
+ } catch (\UnexpectedValueException $e) {
31
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
32
+ }
33
+
34
+ $i->rewind();
35
+
36
+ $this->assertTrue(true, $message);
37
+ }
38
+
39
+ /**
40
+ * @dataProvider getPaths
41
+ *
42
+ * @param string $path
43
+ * @param bool $seekable
44
+ * @param array $contains
45
+ * @param string $message
46
+ */
47
+ public function testSeek($path, $seekable, $contains, $message = null)
48
+ {
49
+ try {
50
+ $i = new RecursiveDirectoryIterator($path, \RecursiveDirectoryIterator::SKIP_DOTS);
51
+ } catch (\UnexpectedValueException $e) {
52
+ $this->markTestSkipped(sprintf('Unsupported stream "%s".', $path));
53
+ }
54
+
55
+ $actual = array();
56
+
57
+ $i->seek(0);
58
+ $actual[] = $i->getPathname();
59
+
60
+ $i->seek(1);
61
+ $actual[] = $i->getPathname();
62
+
63
+ $i->seek(2);
64
+ $actual[] = $i->getPathname();
65
+
66
+ $this->assertEquals($contains, $actual);
67
+ }
68
+
69
+ public function getPaths()
70
+ {
71
+ $data = array();
72
+
73
+ // ftp
74
+ $contains = array(
75
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'README',
76
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'index.html',
77
+ 'ftp://ftp.mozilla.org'.DIRECTORY_SEPARATOR.'pub',
78
+ );
79
+ $data[] = array('ftp://ftp.mozilla.org/', false, $contains);
80
+
81
+ return $data;
82
+ }
83
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SizeRangeFilterIteratorTest.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\SizeRangeFilterIterator;
15
+ use Symfony\Component\Finder\Comparator\NumberComparator;
16
+
17
+ class SizeRangeFilterIteratorTest extends RealIteratorTestCase
18
+ {
19
+ /**
20
+ * @dataProvider getAcceptData
21
+ */
22
+ public function testAccept($size, $expected)
23
+ {
24
+ $inner = new InnerSizeIterator(self::$files);
25
+
26
+ $iterator = new SizeRangeFilterIterator($inner, $size);
27
+
28
+ $this->assertIterator($expected, $iterator);
29
+ }
30
+
31
+ public function getAcceptData()
32
+ {
33
+ $lessThan1KGreaterThan05K = array(
34
+ '.foo',
35
+ '.git',
36
+ 'foo',
37
+ 'test.php',
38
+ 'toto',
39
+ );
40
+
41
+ return array(
42
+ array(array(new NumberComparator('< 1K'), new NumberComparator('> 0.5K')), $this->toAbsolute($lessThan1KGreaterThan05K)),
43
+ );
44
+ }
45
+ }
46
+
47
+ class InnerSizeIterator extends \ArrayIterator
48
+ {
49
+ public function current()
50
+ {
51
+ return new \SplFileInfo(parent::current());
52
+ }
53
+
54
+ public function getFilename()
55
+ {
56
+ return parent::current();
57
+ }
58
+
59
+ public function isFile()
60
+ {
61
+ return $this->current()->isFile();
62
+ }
63
+
64
+ public function getSize()
65
+ {
66
+ return $this->current()->getSize();
67
+ }
68
+ }
vendor/symfony/finder/Symfony/Component/Finder/Tests/Iterator/SortableIteratorTest.php ADDED
@@ -0,0 +1,169 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /*
4
+ * This file is part of the Symfony package.
5
+ *
6
+ * (c) Fabien Potencier <fabien@symfony.com>
7
+ *
8
+ * For the full copyright and license information, please view the LICENSE
9
+ * file that was distributed with this source code.
10
+ */
11
+
12
+ namespace Symfony\Component\Finder\Tests\Iterator;
13
+
14
+ use Symfony\Component\Finder\Iterator\SortableIterator;
15
+
16
+ class SortableIteratorTest extends RealIteratorTestCase
17
+ {
18
+ public function testConstructor()
19
+ {
20
+ try {
21
+ new SortableIterator(new Iterator(array()), 'foobar');
22
+ $this->fail('__construct() throws an \InvalidArgumentException exception if the mode is not valid');
23
+ } catch (\Exception $e) {
24
+ $this->assertInstanceOf('InvalidArgumentException', $e, '__construct() throws an \InvalidArgumentException exception if the mode is not valid');
25
+ }
26
+ }
27
+
28
+ /**
29
+ * @dataProvider getAcceptData
30
+ */
31
+ public function testAccept($mode, $expected)
32
+ {
33
+ if (!is_callable($mode)) {
34
+ switch ($mode) {
35
+ case SortableIterator::SORT_BY_ACCESSED_TIME :
36
+ file_get_contents(self::toAbsolute('.git'));
37
+ sleep(1);
38
+ file_get_contents(self::toAbsolute('.bar'));
39
+ break;
40
+ case SortableIterator::SORT_BY_CHANGED_TIME :
41
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
42
+ sleep(1);
43
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
44
+ break;
45
+ case SortableIterator::SORT_BY_MODIFIED_TIME :
46
+ file_put_contents(self::toAbsolute('test.php'), 'foo');
47
+ sleep(1);
48
+ file_put_contents(self::toAbsolute('test.py'), 'foo');
49
+ break;
50
+ }
51
+ }
52
+
53
+ $inner = new Iterator(self::$files);
54
+
55
+ $iterator = new SortableIterator($inner, $mode);
56
+
57
+ if ($mode === SortableIterator::SORT_BY_ACCESSED_TIME
58
+ || $mode === SortableIterator::SORT_BY_CHANGED_TIME
59
+ || $mode === SortableIterator::SORT_BY_MODIFIED_TIME) {
60
+ $this->assertOrderedIteratorForGroups($expected, $iterator);
61
+ } else {
62
+ $this->assertOrderedIterator($expected, $iterator);
63
+ }
64
+ }
65
+
66
+ public function getAcceptData()
67
+ {
68
+ $sortByName = array(
69
+ '.bar',
70
+ '.foo',
71
+ '.foo/.bar',
72
+ '.foo/bar',
73
+ '.git',
74
+ 'foo',
75
+ 'foo bar',
76
+ 'foo/bar.tmp',
77
+ 'test.php',
78
+ 'test.py',
79
+ 'toto',
80
+ );
81
+
82
+ $sortByType = array(
83
+ '.foo',
84
+ '.git',
85
+ 'foo',
86
+ 'toto',
87
+ '.bar',
88
+ '.foo/.bar',
89
+ '.foo/bar',
90
+ 'foo bar',
91
+ 'foo/bar.tmp',
92
+ 'test.php',
93
+ 'test.py',
94
+ );
95
+
96
+ $customComparison = array(
97
+ '.bar',
98
+ '.foo',
99
+ '.foo/.bar',
100
+ '.foo/bar',
101
+ '.git',
102
+ 'foo',
103
+ 'foo bar',
104
+ 'foo/bar.tmp',
105
+ 'test.php',
106
+ 'test.py',
107
+ 'toto',
108
+ );
109
+
110
+ $sortByAccessedTime = array(
111
+ // For these two files the access time was set to 2005-10-15
112
+ array('foo/bar.tmp', 'test.php'),
113
+ // These files were created more or less at the same time
114
+ array(
115
+ '.git',
116
+ '.foo',
117
+ '.foo/.bar',
118
+ '.foo/bar',
119
+ 'test.py',
120
+ 'foo',
121
+ 'toto',
122
+ 'foo bar',
123
+ ),
124
+ // This file was accessed after sleeping for 1 sec
125
+ array('.bar'),
126
+ );
127
+
128
+ $sortByChangedTime = array(
129
+ array(
130
+ '.git',
131
+ '.foo',
132
+ '.foo/.bar',
133
+ '.foo/bar',
134
+ '.bar',
135
+ 'foo',
136
+ 'foo/bar.tmp',
137
+ 'toto',
138
+ 'foo bar',
139
+ ),
140
+ array('test.php'),
141
+ array('test.py'),
142
+ );
143
+
144
+ $sortByModifiedTime = array(
145
+ array(
146
+ '.git',
147
+ '.foo',
148
+ '.foo/.bar',
149
+ '.foo/bar',
150
+ '.bar',
151
+ 'foo',
152
+ 'foo/bar.tmp',
153
+ 'toto',
154
+ 'foo bar',
155
+ ),
156
+ array('test.php'),
157
+ array('test.py'),
158
+ );
159
+
160
+ return array(
161
+ array(SortableIterator::SORT_BY_NAME, $this->toAbsolute($sortByName)),
162
+ array(SortableIterator::SORT_BY_TYPE, $this->toAbsolute($sortByType)),
163
+ array(SortableIterator::SORT_BY_ACCESSED_TIME, $this->toAbsolute($sortByAccessedTime)),
164
+ array(SortableIterator::SORT_BY_CHANGED_TIME, $this->toAbsolute($sortByChangedTime)),
165
+ array(SortableIterator::SORT_BY_MODIFIED_TIME, $this->toAbsolute($sortByModifiedTime)),
166
+ array(function (\SplFileInfo $a, \SplFileInfo $b) { return strcmp($a->getRealpath(), $b->getRealpath()); }, $this->toAbsolute($customComparison)),
167
+ );
168
+ }
169
+ }
vendor/symfony/finder/Symfony/Component/Finder/composer.json ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "name": "symfony/finder",
3
+ "type": "library",
4
+ "description": "Symfony Finder Component",
5
+ "keywords": [],
6
+ "homepage": "http://symfony.com",
7
+ "license": "MIT",
8
+ "authors": [
9
+ {
10
+ "name": "Fabien Potencier",
11
+ "email": "fabien@symfony.com"
12
+ },
13
+ {
14
+ "name": "Symfony Community",
15
+ "homepage": "http://symfony.com/contributors"
16
+ }
17
+ ],
18
+ "require": {
19
+ "php": ">=5.3.3"
20
+ },
21
+ "autoload": {
22
+ "psr-0": { "Symfony\\Component\\Finder\\": "" }
23
+ },
24
+ "target-dir": "Symfony/Component/Finder",
25
+ "minimum-stability": "dev",
26
+ "extra": {
27
+ "branch-alias": {
28
+ "dev-master": "2.6-dev"
29
+ }
30
+ }
31
+ }
vendor/symfony/finder/Symfony/Component/Finder/phpunit.xml.dist ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4
+ xsi:noNamespaceSchemaLocation="http://schema.phpunit.de/4.1/phpunit.xsd"
5
+ backupGlobals="false"
6
+ colors="true"
7
+ bootstrap="vendor/autoload.php"
8
+ >
9
+ <php>
10
+ <!-- Silence E_USER_DEPRECATED (-16385 == -1 & ~E_USER_DEPRECATED) -->
11
+ <ini name="error_reporting" value="-16385"/>
12
+ </php>
13
+ <testsuites>
14
+ <testsuite name="Symfony Finder Component Test Suite">
15
+ <directory>./Tests/</directory>
16
+ </testsuite>
17
+ </testsuites>
18
+
19
+ <filter>
20
+ <whitelist>
21
+ <directory>./</directory>
22
+ <exclude>
23
+ <directory>./Tests</directory>
24
+ <directory>./vendor</directory>
25
+ </exclude>
26
+ </whitelist>
27
+ </filter>
28
+ </phpunit>