142 Commits

Author SHA1 Message Date
Fonata
c7375dea8e Added authors and web links to source and issues 2018-08-09 13:48:06 +02:00
Fonata
6ce4550eed Merge pull request #147 from parsecsv/file_get_contents
Replace fread with file_get_contents to avoid the 8192 byte limit
2018-08-08 21:02:26 +02:00
Fonata
55890da647 Replace fread with file_get_contents to avoid the 8192 byte limit
This can happen when using streams.

Specific problem occurred with a file uploaded with Drupal's ``managed_file``
Form API element.

See https://secure.php.net/manual/en/function.fread.php
2018-07-31 21:59:04 +02:00
Fonata
21953ab6be Merge pull request #146 from parsecsv/waiver-test
Added test for issue 145, couldn't reproduce it
2018-05-22 09:01:01 +02:00
Fonata
1d8e6808bc Added test for issue #145, couldn't reproduce it 2018-05-21 21:56:54 +02:00
Fonata
063a812732 Merge pull request #142 from parsecsv/issue-141-multiple-empty-lines
Ignore entirely empty lines at the end of files
2018-05-11 09:03:36 +02:00
Fonata
4504f4b158 Converted function names to camelCase for PSR karma points 2018-04-29 11:21:00 +02:00
Fonata
b82ad03bd5 Ignore entirely empty lines at the end of files
Closes #141
2018-04-29 11:08:40 +02:00
Fonata
23a1b0a4b3 Merge pull request #138 from geminorum/master
min php on composer.json
2018-04-11 08:47:06 +02:00
Fonata
51d878a9a1 Merge pull request #137 from parsecsv/new-unparse-test
Added new test for unparse with parameters
2018-04-11 08:31:33 +02:00
Fonata
7d39b80fca Merge pull request #140 from susgo/patch-1
Update README.md: corrected function name getTotalDataRowCount()
2018-04-11 08:30:21 +02:00
susgo
8c7eba6815 Update README.md 2018-04-05 16:32:44 +02:00
Nasser Rafie
c41c559ac2 min php on composer.json 2018-04-02 18:36:16 +04:30
Fonata
e1ecf9302e Advertised getCollection in ChangeLog.txt 2018-04-02 15:11:17 +02:00
Fonata
de8e792ef4 Merge branch 'feature-datacollections'
Conflicts:
	src/Csv.php
2018-04-02 14:40:32 +02:00
Fonata
60d6458080 PHPUnit: prevent output from download.php to leak 2018-04-02 14:38:03 +02:00
William Knauss
406e1e415f added getCollection method that returns a Illuminate\Support\Collection object - useful for using the mapping functions 2018-04-02 14:32:17 +02:00
Fonata
2e40a2eb1c Added new test for unparse with parameters 2018-03-28 15:45:44 +02:00
Fonata
927e785891 Merge pull request #133 from parsecsv/fixing-132-output-with-fields
Bug fix: calling ->output() with $fields parameter set
2018-03-28 13:25:05 +02:00
Fonata
e6ba24b47a Dropping PHP 5.4 support (#131)
Also removed special treatment of PHP 5.4, as we don't support it anymore
2018-03-20 11:12:22 +01:00
Fonata
f24e5bf3a3 Merge branch 'offset-comment-and-tests' 2018-03-17 12:44:02 +01:00
Fonata
bdd4e5ef25 Merge branch 'master' into offset-comment-and-tests
Conflicts:
	tests/methods/ParseTest.php
2018-03-17 12:42:18 +01:00
Fonata
42b5d30d66 Improved OldRequireTest: explanation and new test added (#128) 2018-03-17 12:37:54 +01:00
Fonata
93f177a396 Merged two ifs in _validate_row_condition to prevent
This is to a sane count of zero PhpStorm inspections. In particular,
this is NestedPositiveIfStatementsInspection from EA Extended.
2018-03-17 12:17:25 +01:00
Fonata
f5ff7332a4 Set $data field on unparse. This fixes issue #132. 2018-03-17 12:16:39 +01:00
Fonata
07846d33c1 Added OutputTest to verify issue #132 is a bug. 2018-03-17 12:07:12 +01:00
Fonata
4b60d38fb0 Tell PhpStorm not to complain about reference mismatch
http://blog.jpauli.tech/2014/06/27/references-mismatch.html#what-is-a-reference-mismatch
2018-03-17 12:05:01 +01:00
Fonata
c8d15557cb Fixed parse()'s return value: return true only if $data is useful 2018-03-17 12:05:01 +01:00
Fonata
10895788c8 Slightly simplified getTotalDataRowCount, added test
The brackets () in the pattern were not needed, as only
$matches[0] was accessed, not $matches[1].

The @var is useful for PhpStorm's Php Inspections (EA Extended).
More details here: https://github.com/kalessil/phpinspectionsea/blob/master/docs/types-compatibility.md#foreach-source-to-iterate-over
2018-03-17 12:05:01 +01:00
Fonata
ffed7ffdc0 Only improved PHPDoc blocks, including sentance for output() 2018-03-17 12:05:01 +01:00
Fonata
7498a963ac _validate_fields_for_unparse: more info in UnexpectedValueException 2018-03-17 11:42:44 +01:00
Fonata
49728a74bb Only reformatted the source code 2018-03-17 10:31:09 +01:00
susgo
e4c9fed6cf Update README.md for old and new functions (#129)
* Update README.md
2018-03-12 08:28:25 +01:00
Susann Sgorzaly
5bc6d09b5e fixes bug on _validate_fields_for_unparse() if titles property is used instead of fields parameter for changing the titles for unparsing 2018-03-12 08:25:42 +01:00
susgo
b7f2075efc Fix #41: output order and subset (#126)
* init unparse tests for ordering and subseting by fields
* added one test for heading=false
* implements functionality of this issue
2018-03-11 11:14:53 +01:00
Christian Bläul
3cc20fbb47 Merge remote-tracking branch 'itexia/auto-detect-file-has-heading'
# Conflicts:
#	tests/methods/ParseTest.php
2018-03-10 12:46:36 +01:00
Christian Bläul
086cd15b44 Added requires to keep Composer-free environments working 2018-03-07 09:51:50 +01:00
Christian Bläul
03bc946b98 Sorted uses alphabetically, removed version
The repo is no longer on version 1.0.0. The ChangeLog.txt file is a
more obvious place for people to see which version includes what.
2018-03-07 09:45:48 +01:00
Christian Bläul
8f431aa7a4 Merge remote-tracking branch 'itexia/refactoring-constants' 2018-03-07 09:43:22 +01:00
Christian Bläul
7168cb15e3 ChangeLog.txt: Added new feature 2018-03-07 09:40:43 +01:00
Fonata
1142ef2611 Merge pull request #124 from itexia/new-enums-for-docu
New Enum class for file processing (save + unparse) + Documentation
2018-03-07 09:35:01 +01:00
Fonata
80a4954a3a Merge pull request #122 from itexia/get-total-row-count
New feature: get total row count - useful if $limit is set.
2018-03-07 09:30:36 +01:00
Christian Bläul
9c14bc2f30 Updated ChangeLog.txt with new features 2018-03-03 12:01:45 +01:00
Christian Bläul
4b6b7ee0b8 Removed -rc.2 from version, as it is officially released now 2018-03-03 11:55:57 +01:00
Christian Bläul
a80a6f1862 Moved features section up because library selection comes before install 2018-03-03 11:55:06 +01:00
Christian Bläul
da70838698 Only improved ChangeLog to include the output() change 2018-03-02 17:52:26 +01:00
Christian Bläul
9d7ccab20f Improved comment and test data to show how the offset is counted. 2018-03-02 17:50:01 +01:00
Christian Bläul
abecaf1b5d Only re-formated source code slightly 2018-03-02 17:25:38 +01:00
Christian Bläul
3af94399e6 Semantic versioning: Marked the current state of the repo as 1.0.0-rc.2 2018-03-02 17:15:31 +01:00
Christian Bläul
499088b3b2 Slightly improved README.md 2018-03-02 17:15:31 +01:00
Christian Bläul
fd63ff4a26 Removed examples from class file as they are also in the README.md 2018-03-02 17:15:31 +01:00
Christian Bläul
d250c9034b Further improved ChangeLog.txt and README.txt 2018-03-02 17:15:31 +01:00
Christian Bläul
bfc2c0901b Improved installation section of README.md; added Travid badge. 2018-03-02 17:15:31 +01:00
Christian Bläul
a0336f02ee Prepared new release in ChangeLog.txt 2018-03-02 17:15:31 +01:00
Christian Bläul
ea78f38e26 ConstructTest: undo directory change to be on the safe side. 2018-03-02 17:15:31 +01:00
Christian Bläul
c9e7997643 Don't break people's code just because they don't have Composer 2018-03-02 17:15:31 +01:00
Christian Bläul
68239d6859 No code changes, just cleaned up comments a bit 2018-03-02 17:15:31 +01:00
Christian Bläul
d05577d303 output(): Use better mime type for \t separator.
Fixes #79
2018-03-02 17:13:45 +01:00
Fonata
eedbffc375 Merge pull request #125 from itexia/42-Heading-and-offset
Fixed issue 42: heading and offset; added tests
2018-03-02 17:06:22 +01:00
Susann Sgorzaly
fb9325884d small code improvement 2018-02-28 13:47:38 +01:00
Susann Sgorzaly
11b20a3144 fixes #42. If csv has heading and offset is set, first row will always be parsed 2018-02-27 15:10:55 +01:00
Susann Sgorzaly
7766bf7c3b added two tests for reproducing the heading and offset bug. test with heading fails at the moment. if this one is green, bug would be solved 2018-02-27 15:00:14 +01:00
Susann Sgorzaly
5daa422aca new test for setting new headers before save (comments #82) 2018-02-27 14:33:26 +01:00
Susann Sgorzaly
48a3cdbc5c new enum for file processing mode. extended documentation (comments #112) 2018-02-27 14:18:00 +01:00
Susann Sgorzaly
fbe5263bca only code improvements 2018-02-27 13:22:11 +01:00
Susann Sgorzaly
5b1002a677 test correction 2018-02-26 10:06:59 +01:00
Susann Sgorzaly
4bbc928f09 added dependency for test 2018-02-26 10:00:52 +01:00
Susann Sgorzaly
951fc68886 new feature: auto detect if parsed file has heading 2018-02-26 09:46:44 +01:00
Susann Sgorzaly
68b849a37b corrected regex to fit all given enclosures. Added test for single enclosure 2018-02-26 08:55:51 +01:00
Susann Sgorzaly
aaefe2a480 introduces new local variable that holds the data 2018-02-26 08:50:35 +01:00
Susann Sgorzaly
611b1a92e8 use strpos instead of preg_match 2018-02-26 08:46:41 +01:00
Susann Sgorzaly
e5eccf1fc1 put tests into new file 2018-02-26 08:38:08 +01:00
Susann Sgorzaly
9e5c97328d renamed function to getTotalDataRowCount 2018-02-26 08:33:09 +01:00
Susann Sgorzaly
b6247c367c reformat code; only extended comment for new function 2018-02-26 08:31:46 +01:00
Susann Sgorzaly
ba4cc0672a reformat code 2018-02-26 06:57:40 +01:00
Susann Sgorzaly
c9cc9697ef new feature: getting total data row count without parsing all data 2018-02-24 16:55:45 +01:00
Susann Sgorzaly
f8fe4cad03 change accessibility of parse_file and parse_string 2018-02-23 10:37:12 +01:00
Susann Sgorzaly
95521cde87 reset file property if input is string 2018-02-23 10:17:09 +01:00
Susann Sgorzaly
249e5a24ac readded missing return statement in parse-function 2018-02-23 10:14:01 +01:00
Susann Sgorzaly
343c683077 corrected test for default sort type. Is set to regular now 2018-02-23 10:02:13 +01:00
Susann Sgorzaly
cf91bf40ff now compatible with old sorting values 2018-02-23 08:11:56 +01:00
Susann Sgorzaly
958af1027e small code improvements 2018-02-22 21:34:39 +01:00
Susann Sgorzaly
7a3120dd28 added test for sort enums (todo: handle exception on test) 2018-02-22 21:15:00 +01:00
Susann Sgorzaly
a74736d4da init implementation of abstract enum class 2018-02-22 21:01:06 +01:00
Susann Sgorzaly
657cec4b4e added enum for sort 2018-02-22 20:41:03 +01:00
susgo
ef44ea3989 Merge pull request #7 from parsecsv/master
update
2018-02-22 14:55:40 +01:00
Christian Bläul
2ac9f450f1 Check if output contains HTML table cells
They should if the _books.csv file is found
2018-02-21 19:25:39 +01:00
Christian Bläul
3968659b9f Make sure the code examples run without syntax or runtime errors. 2018-02-21 19:22:45 +01:00
Christian Bläul
d3a084d973 Added namespace support for further tests 2018-02-21 19:04:00 +01:00
Christian Bläul
b0355be96a Re-added the parsecsv.lib.php file for compatibility 2018-02-21 19:00:41 +01:00
Christian Bläul
b753d9c694 Repaired examples: there was a require missing. 2018-02-21 18:45:50 +01:00
Christian Bläul
2b95ec5aa1 Merge remote-tracking branch 'origin/Tests-for-sort-and-cond' into pull-test
# Conflicts:
#	tests/Bootstrap.php
#	tests/methods/ParseTest.php
#	tests/properties/worthless_test.php
2018-02-21 18:41:45 +01:00
Susann Sgorzaly
3f595dfd3b only renamed variable 2018-02-21 12:55:26 +01:00
susgo
081949339b Merge pull request #6 from parsecsv/itexia-fixed-remaining-test
Fixed remaining test
2018-02-21 08:36:24 +01:00
Christian Bläul
a60aae47a4 getDatatypes: Documented the need for PHP 5.5 or higher 2018-02-20 22:16:49 +01:00
Christian Bläul
4cba97ad51 Allow PhpStorm to understand the code better
(I followed suggestions from PhpStorm's inspections)
2018-02-20 22:07:08 +01:00
Christian Bläul
2206ec1e7c only reformatted source code to match the rest of the project 2018-02-20 22:06:06 +01:00
Christian Bläul
d188921ab6 composer.json: Only allow to load tests in dev environment 2018-02-20 21:50:52 +01:00
Christian Bläul
85cc0d9cfc Updated README.md to new name & namespace 2018-02-20 21:50:45 +01:00
Christian Bläul
a7f2bbb7bc Throw more specific exception 2018-02-20 21:40:48 +01:00
Christian Bläul
d484f3e9e3 The workaround for array_count_values was wrong and unnecessary. 2018-02-20 21:37:39 +01:00
Christian Bläul
f8b2fe274a Added missing letter in function name 2018-02-20 21:35:21 +01:00
susgo
17bfd9496a Merge pull request #5 from parsecsv/itexia-repair-tests
Repair tests (somewhat)
2018-02-20 08:22:59 +01:00
Christian Bläul
ec7b1c1d55 PHPUnit: Better class names with modern naming scheme 2018-02-19 23:01:31 +01:00
Christian Bläul
ba9eae17d4 Bootstrap: Improved the conditions under which the test wrapper loads 2018-02-19 23:00:57 +01:00
Christian Bläul
8f26ce6ea3 Force Travis to output which PHPUnit version it uses 2018-02-19 22:49:43 +01:00
Christian Bläul
913dc94e2c Keep sorting keys compatible: Moved array_values call to PHPUnit.
This commit partially reverts adcd258ea2.
2018-02-19 22:08:59 +01:00
Christian Bläul
5ced1f4212 Added conditions to SortByTest because otherwise different PHP versions...
yielded different sort orders (that's sort of ok, as rating is ambiguous).

See https://travis-ci.org/parsecsv/parsecsv-for-php/jobs/336540118
2018-02-19 22:08:59 +01:00
Christian Bläul
ca84469950 Moved ConditionsTest to properties subfolder 2018-02-19 22:08:59 +01:00
Christian Bläul
75902f4a22 Added PHPUnit test for sorting; I could not get the rows in the right...
order without calling array_values - maybe this helps just PHPUnit. I
consider the risk of breaking library users' code unlikely.
2018-02-19 22:08:59 +01:00
Christian Bläul
7470d2b804 PHPUnit: Repaired file paths in autoQuotesDataProvider() 2018-02-19 22:08:59 +01:00
Christian Bläul
01f0891cfb Test some conditions 2018-02-19 22:08:59 +01:00
Susann Sgorzaly
52a9b61b97 added DatatypeEnum tests; repaired the other test for local execution; small bug fixes 2018-02-19 21:36:31 +01:00
susgo
5660be3373 Merge pull request #1 from itexia/introduce-namespaces
init introduce namespaces and enums
2018-02-19 14:22:46 +01:00
Susann Sgorzaly
70b6fe4bd8 Merge branch 'introduce-namespaces' of https://github.com/itexia/parsecsv-for-php into introduce-namespaces 2018-02-19 14:10:10 +01:00
Susann Sgorzaly
f1a89127c2 regex updated according to merge conflict 2018-02-19 14:09:30 +01:00
susgo
31dba0411e Merge pull request #4 from parsecsv/test-helper-for-itexia-with-namespaces
Test helper for ITEXIA fork with namespaces
2018-02-19 14:05:14 +01:00
susgo
6da0537197 Merge branch 'introduce-namespaces' into test-helper-for-itexia-with-namespaces 2018-02-19 14:04:37 +01:00
susgo
91091ac933 Merge pull request #2 from itexia/new-enom-datatype
init enum for data type
2018-02-19 12:08:38 +01:00
susgo
2c7c552515 Update DatatypeTrait.php 2018-02-19 12:07:32 +01:00
Susann Sgorzaly
52e87953a4 corrected datatype count 2018-02-19 12:02:48 +01:00
Christian Bläul
2b6e38734c Merge remote-tracking branch 'origin/test-helper-for-itexia-master' into delete_this_branch 2018-02-18 19:41:38 +01:00
Christian Bläul
af7368378c Changed tests to work now that we have a namespace 2018-02-18 19:40:21 +01:00
Christian Bläul
f2fb7c81bd Absolute path in require do stop PhpStorm from nagging
(PhpStorm couldn't find the file)
2018-02-18 19:34:32 +01:00
Christian Bläul
92653c99c5 Force predictable working dir; create autoloader file if it doesn't exist 2018-02-18 19:32:39 +01:00
Christian Bläul
d4f9c9f020 Updated worthless_test to allow for more fields 2018-02-18 19:04:16 +01:00
Christian Bläul
2b17f01a0a Removed additional column to make expected data fit to fixture 2018-02-18 19:03:23 +01:00
Christian Bläul
9551862a95 Allow current working dir to be different when running tests
...By using an absolute path
2018-02-18 19:02:37 +01:00
Christian Bläul
736bc489e6 getDatatypes: throw more meaningful exception if no data is present 2018-02-18 19:01:47 +01:00
Christian Bläul
f702ca93fe Float regex: Don't allow double dot; do allow 'e' for exponentials 2018-02-18 19:00:24 +01:00
Susann Sgorzaly
48cec20f4f namespace change 2018-02-18 12:45:33 +01:00
Susann Sgorzaly
c266ef9fbc Merge branch 'introduce-namespaces' of https://github.com/itexia/parsecsv-for-php into new-enom-datatype 2018-02-18 12:43:45 +01:00
Susann Sgorzaly
76a0406eff updated examples for using new classname 2018-02-18 12:43:19 +01:00
Susann Sgorzaly
17ac1dee1a renamed namespace 2018-02-18 12:42:53 +01:00
Susann Sgorzaly
f6bd414ae7 init enum for data type 2018-02-18 00:09:22 +01:00
Susann Sgorzaly
a7a0bc34a4 init introduce namespaces 2018-02-17 23:41:03 +01:00
Susann Sgorzaly
0e5afb209e test for method getDatatypes added 2018-02-17 22:24:50 +01:00
Susann Sgorzaly
f8c68a6cd7 test improvements 2018-02-17 22:24:19 +01:00
Susann Sgorzaly
5babb55879 review changes 2018-02-14 14:03:00 +01:00
Susann Sgorzaly
8ec87126dc load files from extensions folder for tests; added new property in worthless_test 2018-02-14 12:12:53 +01:00
Susann Sgorzaly
d788135bbe exclude datatype detection in its own trait 2018-02-14 12:12:01 +01:00
Susann Sgorzaly
301f6da3e6 init new functionality to identify datatypes of columns 2018-02-13 17:18:01 +01:00
36 changed files with 1663 additions and 512 deletions

View File

@@ -6,9 +6,9 @@ php:
- 7.0
- 5.6
- 5.5
- 5.4
script:
- phpunit --version
- phpunit --configuration tests/phpunit.xml
notifications:

View File

@@ -1,266 +1,288 @@
ParseCsvForPhp 1.0.0-rc.1
-----------------------------------
Date: unreleased
- Renamed class from parseCSV to ParseCsvForPhp
- Added support for MS Excel's "sep=" to detect the
delimiter (Issue #60).
- MIME: output() sends correct MIME type to browser
if the separator is a tab tab (Issue #79)
- Added support for mb_convert_encoding() instead of
iconv() (Issue #109)
- A number of minor bug fixes - see GitHub issues
-----------------------------------
parseCSV 0.4.3 beta
-----------------------------------
Date: 1-July-2008
- Issue #4. Added an option for setting sorting
type behavior when sorting data.
Simply set $csv->sort_type to "regular", "numeric",
or "string".
- Issue #6. Raw loaded file data is now cleared from
file_data property when it has been successfully
parsed to keep parseCSV's memory footprint to a
minimum. Specifically handy when using multiple
instances of parseCSV to process large files.
-----------------------------------
parseCSV 0.4.2 beta
-----------------------------------
Date: 31-May-2008
- IMPORTANT! If you're using the output(),
method please note that the first parameter
has been completely removed as it was
technically just useless. Instead, the second
parameter (filename) doubles as its replacement.
Simply put, if filename is not set or null, the
output() method will not output a downloadable
file. Please update your existing code
when using 0.4.2 and later :)
- Small fix to the headers sent by the output()
method.
- Added a download example using the output()
method to the examples folder.
-----------------------------------
parseCSV 0.4.1 beta
-----------------------------------
Date: 29-May-2008
- Fixed a small bug in how the output() method
handles input data.
-----------------------------------
parseCSV 0.4 beta
-----------------------------------
Date: 11-Apr-2008
- Error reporting for files/data which is corrupt
or has formatting errors like using double
quotes in a field without enclosing quotes. Or
not escaping double quotes with a second one.
- parse() method does not require input anymore
if the "$object->file" property has been set.
I'm calling this a beta release due to the heavy
modifications to the core parsing logic required
for error reporting to work. I have tested the
new code quite extensively, I'm fairly confident
that it still parses exactly as it always has.
The second reason I'm calling it a beta release
is cause I'm sure the error reporting code will
need more refinements and tweaks to detect more
types of errors, as it's only picking two types
or syntax errors right now. However, it seems
these two are the most common errors that you
would be likely to come across.
-----------------------------------
parseCSV 0.3.2
-----------------------------------
Date: 1-Apr-2008
This is primarily a bug-fix release for a critical
bug which was brought to my attention.
- Fixed a critical bug in conditions parsing which
would generate corrupt matching patterns causing
the condition(s) to not work at all in some
situations.
- Fixed a small code error which would cause PHP to
generate a invalid offset notice when zero length
values were fed into the unparse() method to
generate CSV data from an array.
Notice: If you have been using the "parsecsv-stable"
branch as an external in any of your projects,
please use the "stable/parsecsv" branch from this
point on as I will eventually remove the former due
to it's stupid naming.
-----------------------------------
parseCSV 0.3.1
-----------------------------------
Date: 1-Sep-2007
- Small change to default output settings to
conform with RFC 4180 (http://rfc.net/rfc4180.html).
Only the LF (line feed) character was used
by default to separate rows, rather than
CRLF (carriage return & line feed).
-----------------------------------
parseCSV 0.3.0
-----------------------------------
Date: 9-Aug-2007
- Changed to the MIT license.
- Added offset and limit options.
- Added SQL-like conditions for quickly
filtering out entries. Documentation on the
condition syntax is forthcoming.
- Small parsing modification to comply
with some recent changes to the specifications
outlined on Wikipedia's Comma-separated values
article.
- Minor changes and optimizations, and a few
spelling corrections. Oops :)
- Included more complex code examples in the
parseCSV download.
-----------------------------------
parseCSV 0.2.1
-----------------------------------
Date: 8-Aug-2007
- Fixed stupid code which caused auto function
to not work in some situations.
-----------------------------------
parseCSV 0.2.0 beta
-----------------------------------
Date: 2-Jan-2007
- Added auto() function to automatically detect
delimiter character.
Useful for user upload in case delimiter is
comma (,), tab, or semi-colon (;). Some
versions of MS Excel for Windows use
semi-colons instead of commas when saving to
CSV files.
It uses a process of elimination to eliminate
characters that can not be the delimiter,
so it should work on all CSV-structured files
almost no matter what the delimiter is.
- Generally updated some of the core workings
to increase performance, and offer better
support for large (1MB and up) files.
- Added code examples to header comment.
-----------------------------------
parseCSV 0.1.6 beta
-----------------------------------
Date: 22-Dec-2006
- Updated output() function.
-----------------------------------
parseCSV 0.1.5 beta
-----------------------------------
Date: 22-Dec-2006
- Added output() function for easy output to
browser, for downloading features for example.
-----------------------------------
parseCSV 0.1.4 beta
-----------------------------------
Date: 17-Dec-2006
- Minor changes and fixes
-----------------------------------
parseCSV 0.1.3 beta
-----------------------------------
Date: 17-Dec-2006
- Added GPL v2.0 license.
-----------------------------------
parseCSV 0.1.2 beta
-----------------------------------
Date: 17-Dec-2006
- Added encoding() function for easier character
encoding configuration.
-----------------------------------
parseCSV 0.1.1 beta
-----------------------------------
Date: 24-Nov-2006
- Added support for a PHP die command on first
line of csv files if they have a .php extension
to protect secure data from being displayed
directly to the browser.
-----------------------------------
parseCSV 0.1 beta
-----------------------------------
Date: 23-Nov-2006
- Initial release
-----------------------------------
ParseCSV dev-master
-----------------------------------
Date: unreleased
- New function getTotalDataRowCount() - useful if
$limit is set - see pull request #122.
- Dropped support for PHP 5.4
- Added support for Laravel-style collections via the
new getCollection() function - see
https://github.com/parsecsv/parsecsv-for-php/pull/134
-----------------------------------
ParseCSV 1.0.0
-----------------------------------
Date: 3-March-2018
- Renamed class from parseCSV to Csv and added name-
space "ParseCsv" for PSR compliance.
- Added support for MS Excel's "sep=" to detect the
delimiter (Issue #60).
- Added data type detection - function getDatatypes()
guesses the type of each column.
- MIME: output() sends correct MIME type to browser
if the separator is a tab char (Issue #79).
- Added support for mb_convert_encoding() instead of
iconv() - see issue #109.
- A number of minor bug fixes - see GitHub issues.
- Added many more unit tests.
-----------------------------------
parseCSV 0.4.3 beta
-----------------------------------
Date: 1-July-2008
- Issue #4. Added an option for setting sorting
type behavior when sorting data.
Simply set $csv->sort_type to "regular", "numeric",
or "string".
- Issue #6. Raw loaded file data is now cleared from
file_data property when it has been successfully
parsed to keep parseCSV's memory footprint to a
minimum. Specifically handy when using multiple
instances of parseCSV to process large files.
-----------------------------------
parseCSV 0.4.2 beta
-----------------------------------
Date: 31-May-2008
- IMPORTANT! If you're using the output(),
method please note that the first parameter
has been completely removed as it was
technically just useless. Instead, the second
parameter (filename) doubles as its replacement.
Simply put, if filename is not set or null, the
output() method will not output a downloadable
file. Please update your existing code
when using 0.4.2 and later :)
- Small fix to the headers sent by the output()
method.
- Added a download example using the output()
method to the examples folder.
-----------------------------------
parseCSV 0.4.1 beta
-----------------------------------
Date: 29-May-2008
- Fixed a small bug in how the output() method
handles input data.
-----------------------------------
parseCSV 0.4 beta
-----------------------------------
Date: 11-Apr-2008
- Error reporting for files/data which is corrupt
or has formatting errors like using double
quotes in a field without enclosing quotes. Or
not escaping double quotes with a second one.
- parse() method does not require input anymore
if the "$object->file" property has been set.
I'm calling this a beta release due to the heavy
modifications to the core parsing logic required
for error reporting to work. I have tested the
new code quite extensively, I'm fairly confident
that it still parses exactly as it always has.
The second reason I'm calling it a beta release
is cause I'm sure the error reporting code will
need more refinements and tweaks to detect more
types of errors, as it's only picking two types
or syntax errors right now. However, it seems
these two are the most common errors that you
would be likely to come across.
-----------------------------------
parseCSV 0.3.2
-----------------------------------
Date: 1-Apr-2008
This is primarily a bug-fix release for a critical
bug which was brought to my attention.
- Fixed a critical bug in conditions parsing which
would generate corrupt matching patterns causing
the condition(s) to not work at all in some
situations.
- Fixed a small code error which would cause PHP to
generate a invalid offset notice when zero length
values were fed into the unparse() method to
generate CSV data from an array.
Notice: If you have been using the "parsecsv-stable"
branch as an external in any of your projects,
please use the "stable/parsecsv" branch from this
point on as I will eventually remove the former due
to it's stupid naming.
-----------------------------------
parseCSV 0.3.1
-----------------------------------
Date: 1-Sep-2007
- Small change to default output settings to
conform with RFC 4180 (http://rfc.net/rfc4180.html).
Only the LF (line feed) character was used
by default to separate rows, rather than
CRLF (carriage return & line feed).
-----------------------------------
parseCSV 0.3.0
-----------------------------------
Date: 9-Aug-2007
- Changed to the MIT license.
- Added offset and limit options.
- Added SQL-like conditions for quickly
filtering out entries. Documentation on the
condition syntax is forthcoming.
- Small parsing modification to comply
with some recent changes to the specifications
outlined on Wikipedia's Comma-separated values
article.
- Minor changes and optimizations, and a few
spelling corrections. Oops :)
- Included more complex code examples in the
parseCSV download.
-----------------------------------
parseCSV 0.2.1
-----------------------------------
Date: 8-Aug-2007
- Fixed stupid code which caused auto function
to not work in some situations.
-----------------------------------
parseCSV 0.2.0 beta
-----------------------------------
Date: 2-Jan-2007
- Added auto() function to automatically detect
delimiter character.
Useful for user upload in case delimiter is
comma (,), tab, or semi-colon (;). Some
versions of MS Excel for Windows use
semi-colons instead of commas when saving to
CSV files.
It uses a process of elimination to eliminate
characters that can not be the delimiter,
so it should work on all CSV-structured files
almost no matter what the delimiter is.
- Generally updated some of the core workings
to increase performance, and offer better
support for large (1MB and up) files.
- Added code examples to header comment.
-----------------------------------
parseCSV 0.1.6 beta
-----------------------------------
Date: 22-Dec-2006
- Updated output() function.
-----------------------------------
parseCSV 0.1.5 beta
-----------------------------------
Date: 22-Dec-2006
- Added output() function for easy output to
browser, for downloading features for example.
-----------------------------------
parseCSV 0.1.4 beta
-----------------------------------
Date: 17-Dec-2006
- Minor changes and fixes
-----------------------------------
parseCSV 0.1.3 beta
-----------------------------------
Date: 17-Dec-2006
- Added GPL v2.0 license.
-----------------------------------
parseCSV 0.1.2 beta
-----------------------------------
Date: 17-Dec-2006
- Added encoding() function for easier character
encoding configuration.
-----------------------------------
parseCSV 0.1.1 beta
-----------------------------------
Date: 24-Nov-2006
- Added support for a PHP die command on first
line of csv files if they have a .php extension
to protect secure data from being displayed
directly to the browser.
-----------------------------------
parseCSV 0.1 beta
-----------------------------------
Date: 23-Nov-2006
- Initial release
-----------------------------------

View File

@@ -1,30 +1,20 @@
# ParseCsvForPhp
# ParseCsv
This is an easy-to-use PHP class that reads and writes CSV data properly. It
ParseCsv is an easy-to-use PHP class that reads and writes CSV data properly. It
fully conforms to the specifications outlined on the on the
[Wikipedia article][CSV] (and thus RFC 4180). It has many advanced features which help make your
life easier when dealing with CSV data.
You may not need a library at all: before using ParseCsvForPhp, please make sure if PHP's own `str_getcsv()`, ``fgetcvs()`` or `fputcsv()` meets your needs.
You may not need a library at all: before using ParseCsv, please make sure if PHP's own `str_getcsv()`, ``fgetcvs()`` or `fputcsv()` meets your needs.
This library was originally created in early 2007 by [jimeh](https://github.com/jimeh) due to the lack of built-in
and third-party support for handling CSV data in PHP.
[csv]: http://en.wikipedia.org/wiki/Comma-separated_values
## Installation
Installation is easy using Composer. Include the following in your composer.json
```
"parsecsv/php-parsecsv": "1.0.0"
```
You may also manually include the ParseCsvForPhp.php file
```php
require_once 'ParseCsvForPhp.php';
```
## Features
* ParseCsv is a complete and fully featured CSV solution for PHP
* Supports enclosed values, enclosed commas, double quotes and new lines.
* Automatic delimiter character detection.
* Sort data by specific fields/columns.
@@ -34,25 +24,45 @@ require_once 'ParseCsvForPhp.php';
* Error detection for incorrectly formatted input. It attempts to be
intelligent, but can not be trusted 100% due to the structure of CSV, and
how different programs like Excel for example outputs CSV data.
* Support for character encoding conversion using PHP's
`iconv()` and `mb_convert_encoding()` functions (requires PHP 5).
* Supports PHP 5.4 and higher.
* Support for character encoding conversion using PHP's
`iconv()` and `mb_convert_encoding()` functions.
* Supports PHP 5.5 and higher.
It certainly works with PHP 7.2 and all versions in between.
## Installation
Installation is easy using Composer. Just run the following on the
command line:
```
composer require parsecsv/php-parsecsv
```
If you don't use a framework such as Drupal, Laravel, Symfony, Yii etc.,
you may have to manually include Composer's autoloader file in your PHP
script:
```php
require_once __DIR__ . '/vendor/autoload.php';
```
#### Without composer
Not recommended, but technically possible: you can also clone the
repository or extract the
[ZIP](https://github.com/parsecsv/parsecsv-for-php/archive/master.zip).
To use ParseCSV, you then have to add a `require 'parsecsv.lib.php';` line.
## Example Usage
**General**
```php
$csv = new ParseCsvForPhp('data.csv');
$csv = new ParseCsv\Csv('data.csv');
print_r($csv->data);
```
**Tab delimited, and encoding conversion**
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
@@ -62,15 +72,49 @@ print_r($csv->data);
**Auto-detect delimiter character**
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->auto('data.csv');
print_r($csv->data);
```
**Parse data with offset**
* ignoring the first X (e.g. two) rows
```php
$csv = new ParseCsv\Csv();
$csv->offset = 2;
$csv->parse('data.csv');
print_r($csv->data);
```
**Limit the number of returned data rows**
```php
$csv = new ParseCsv\Csv();
$csv->limit = 5;
$csv->parse('data.csv');
print_r($csv->data);
```
**Get total number of data rows without parsing whole data**
* Excluding heading line if present (see $csv->header property)
```php
$csv = new ParseCsv\Csv();
$csv->load_data('data.csv');
$count = $csv->getTotalDataRowCount();
print_r($count);
```
**Get most common data type for each column (Requires PHP >= 5.5)**
```php
$csv = new ParseCsv\Csv('data.csv');
$csv->getDatatypes()
print_r($csv->data_types);
```
**Modify data in a CSV file**
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->sort_by = 'id';
$csv->parse('data.csv');
# "4" is the value of the "id" column of the CSV row
@@ -81,7 +125,7 @@ $csv->save();
**Replace field names or set ones if missing**
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->fields = ['id', 'name', 'category']
$csv->parse('data.csv');
```
@@ -91,7 +135,7 @@ $csv->parse('data.csv');
_Only recommended when you know the exact structure of the file._
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
```
@@ -99,7 +143,7 @@ $csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
a file and download it**
```php
$csv = new ParseCsvForPhp();
$csv = new ParseCsv\Csv();
$csv->output('movies.csv', $array, array('field 1', 'field 2'), ',');
```
@@ -107,7 +151,7 @@ For more complex examples, see the ``tests`` and `examples` directories.
## Credits
* ParseCsvForPhp is based on the concept of [Ming Hong Ng][ming]'s [CsvFileParser][]
* ParseCsv is based on the concept of [Ming Hong Ng][ming]'s [CsvFileParser][]
class.
[ming]: http://minghong.blogspot.com/
@@ -145,3 +189,5 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
[![Build Status](https://travis-ci.org/parsecsv/parsecsv-for-php.svg?branch=master)](https://travis-ci.org/parsecsv/parsecsv-for-php)

View File

@@ -10,14 +10,38 @@
{
"name": "William Knauss",
"email": "will.knauss@gmail.com"
},
{
"name": "Susann Sgorzaly",
"homepage": "https://github.com/susgo"
},
{
"name": "Christian Bläul",
"homepage": "https://github.com/Fonata"
}
],
"autoload": {
"classmap": [
"."
]
"autoload":{
"psr-4":{
"ParseCsv\\": "src",
"ParseCsv\\extensions\\": "src\\extensions"
}
},
"autoload-dev":{
"psr-4":{
"ParseCsv\\tests\\": "tests"
}
},
"require": {
"php": ">=5.5"
},
"require-dev": {
"phpunit/phpunit": "4.1.*"
},
"suggest": {
"illuminate/support": "Fluent array interface for map functions"
},
"support": {
"issues": "https://github.com/parsecsv/parsecsv-for-php/issues",
"source": "https://github.com/parsecsv/parsecsv-for-php"
}
}

View File

@@ -1,13 +1,13 @@
<pre>
<?php
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# create new object.
$csv = new ParseCsvForPhp();
# create new parseCSV object.
$csv = new Csv();
# Parse '_books.csv' using automatic delimiter detection...

View File

@@ -2,12 +2,13 @@
<?php
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# create new object.
$csv = new ParseCsvForPhp();
# create new parseCSV object.
$csv = new Csv();
# Example conditions:

View File

@@ -1,12 +1,13 @@
<?php
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# create new object.
$csv = new ParseCsvForPhp();
# create new parseCSV object.
$csv = new Csv();
# Parse '_books.csv' using automatic delimiter detection...

View File

@@ -2,12 +2,13 @@
<?php
# include class.
require_once('../ParseCsvForPhp.php');
# include parseCSV class.
require __DIR__ . '/../vendor/autoload.php';
use ParseCsv\Csv;
# create new object.
$csv = new ParseCsvForPhp();
# create new parseCSV object.
$csv = new Csv();
# if sorting is enabled, the whole CSV file

24
parsecsv.lib.php Normal file
View File

@@ -0,0 +1,24 @@
<?php
// This file should not be used at all! Instead, please use Composer's autoload.
// It purely exists to reduce the maintenance burden for existing code using
// this repository.
// Check if people used Composer to include this project in theirs
if (!file_exists(__DIR__ . '/vendor/autoload.php')) {
require __DIR__ . '/src/enums/AbstractEnum.php';
require __DIR__ . '/src/enums/DatatypeEnum.php';
require __DIR__ . '/src/enums/FileProcessingModeEnum.php';
require __DIR__ . '/src/enums/SortEnum.php';
require __DIR__ . '/src/extensions/DatatypeTrait.php';
require __DIR__ . '/src/Csv.php';
} else {
require __DIR__ . '/vendor/autoload.php';
}
// This wrapper class should not be used by new projects. Please look at the
// examples to find the up-to-date way of using this repo.
class parseCSV extends ParseCsv\Csv {
}

View File

@@ -1,9 +1,15 @@
<?php
class ParseCsvForPhp {
namespace ParseCsv;
use Illuminate\Support\Collection;
use ParseCsv\enums\FileProcessingModeEnum;
use ParseCsv\enums\SortEnum;
use ParseCsv\extensions\DatatypeTrait;
class Csv {
/*
Class: ParseCsvForPhp 1.0.0-rc.1
https://github.com/parsecsv/parsecsv-for-php
Fully conforms to the specifications lined out on Wikipedia:
@@ -12,7 +18,6 @@ class ParseCsvForPhp {
Based on the concept of Ming Hong Ng's CsvFileParser class:
- http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
(The MIT license)
Copyright (c) 2014 Jim Myhrberg.
@@ -35,43 +40,7 @@ class ParseCsvForPhp {
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
Code Examples
----------------
# general usage
$csv = new ParseCsvForPhp('data.csv');
print_r($csv->data);
----------------
# tab delimited, and encoding conversion
$csv = new ParseCsvForPhp();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
print_r($csv->data);
----------------
# auto-detect delimiter character
$csv = new ParseCsvForPhp();
$csv->auto('data.csv');
print_r($csv->data);
----------------
# modify data in a csv file
$csv = new ParseCsvForPhp();
$csv->sort_by = 'id';
$csv->parse('data.csv');
# "4" is the value of the "id" column of the CSV row
$csv->data[4] = array('firstname' => 'John', 'lastname' => 'Doe', 'email' => 'john@doe.com');
$csv->save();
----------------
# add row/entry to end of CSV file
# - only recommended when you know the exact structure of the file
$csv = new ParseCsvForPhp();
$csv->save('data.csv', array(array('1986', 'Home', 'Nowhere', '')), true);
----------------
# convert 2D array to csv data and send headers
# to browser to treat output as a file and download it
$csv = new ParseCsvForPhp();
$csv->output('movies.csv', $array, array('field 1', 'field 2'), ',');
----------------
For code examples, please read the files within the 'examples' dir.
*/
/**
@@ -121,7 +90,7 @@ class ParseCsvForPhp {
*
* @var string|null
*/
public $sort_type = null;
public $sort_type = SortEnum::SORT_TYPE_REGULAR;
/**
* Delimiter
@@ -157,7 +126,9 @@ class ParseCsvForPhp {
/**
* Offset
* Number of rows to ignore from beginning of data
* Number of rows to ignore from beginning of data. If present, the heading
* row is also counted (if $this->heading == true). In other words,
* $offset == 1 and $offset == 0 have the same meaning in that situation.
*
* @var int|null
*/
@@ -322,17 +293,43 @@ class ParseCsvForPhp {
*/
public $data = array();
use DatatypeTrait;
/**
* Constructor
* Class constructor
*
* @param string|null $input The CSV string or a direct filepath
* @param integer|null $offset Number of rows to ignore from the beginning of the data
* @param integer|null $limit Limits the number of returned rows to specified amount
* @param string|null $conditions Basic SQL-like conditions for row matching
* @param null|true $keep_file_data Keep raw file data in memory after successful parsing (useful for debugging)
* @param integer|null $offset Number of rows to ignore from the
* beginning of the data
* @param integer|null $limit Limits the number of returned rows
* to specified amount
* @param string|null $conditions Basic SQL-like conditions for row
* matching
* @param null|true $keep_file_data Keep raw file data in memory after
* successful parsing
* (useful for debugging)
*/
public function __construct($input = null, $offset = null, $limit = null, $conditions = null, $keep_file_data = null) {
$this->init($offset, $limit, $conditions, $keep_file_data);
if (!empty($input)) {
$this->parse($input);
}
}
/**
* @param integer|null $offset Number of rows to ignore from the
* beginning of the data
* @param integer|null $limit Limits the number of returned rows
* to specified amount
* @param string|null $conditions Basic SQL-like conditions for row
* matching
* @param null|true $keep_file_data Keep raw file data in memory after
* successful parsing
* (useful for debugging)
*/
public function init($offset = null, $limit = null, $conditions = null, $keep_file_data = null) {
if (!is_null($offset)) {
$this->offset = $offset;
}
@@ -348,10 +345,6 @@ class ParseCsvForPhp {
if (!is_null($keep_file_data)) {
$this->keep_file_data = $keep_file_data;
}
if (!empty($input)) {
$this->parse($input);
}
}
// ==============================================
@@ -363,9 +356,12 @@ class ParseCsvForPhp {
* Parse a CSV file or string
*
* @param string|null $input The CSV string or a direct filepath
* @param integer $offset Number of rows to ignore from the beginning of the data
* @param integer $limit Limits the number of returned rows to specified amount
* @param string $conditions Basic SQL-like conditions for row matching
* @param integer $offset Number of rows to ignore from the
* beginning of the data
* @param integer $limit Limits the number of returned rows to
* specified amount
* @param string $conditions Basic SQL-like conditions for row
* matching
*
* @return bool True on success
*/
@@ -374,32 +370,22 @@ class ParseCsvForPhp {
$input = $this->file;
}
if (!empty($input)) {
if (!is_null($offset)) {
$this->offset = $offset;
}
if (!is_null($limit)) {
$this->limit = $limit;
}
if (!is_null($conditions)) {
$this->conditions = $conditions;
}
if (strlen($input) <= PHP_MAXPATHLEN && is_readable($input)) {
$this->data = $this->parse_file($input);
} else {
$this->file_data = &$input;
$this->data = $this->parse_string();
}
if ($this->data === false) {
return false;
}
if (empty($input)) {
return false;
}
return true;
$this->init($offset, $limit, $conditions);
if (strlen($input) <= PHP_MAXPATHLEN && is_readable($input)) {
$this->file = $input;
$this->data = $this->parse_file();
} else {
$this->file = null;
$this->file_data = &$input;
$this->data = $this->parse_string();
}
return $this->data !== false;
}
/**
@@ -408,17 +394,19 @@ class ParseCsvForPhp {
*
* @param string $file File location to save to
* @param array $data 2D array of data
* @param bool $append Append current data to end of target CSV, if file exists
* @param array $fields Field names
* @param bool $append Append current data to end of target CSV, if file
* exists
* @param array $fields Field names. Sets the header. If it is not set
* $this->titles would be used instead.
*
* @return bool
*/
public function save($file = '', $data = array(), $append = false, $fields = array()) {
public function save($file = '', $data = array(), $append = FileProcessingModeEnum::MODE_FILE_OVERWRITE, $fields = array()) {
if (empty($file)) {
$file = &$this->file;
}
$mode = $append ? 'ab' : 'wb';
$mode = FileProcessingModeEnum::getAppendMode($append);
$is_php = preg_match('/\.php$/i', $file) ? true : false;
return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
@@ -431,7 +419,10 @@ class ParseCsvForPhp {
* @param string|null $filename If a filename is specified here or in the
* object, headers and data will be output
* directly to browser as a downloadable
* file.
* file. This file doesn't have to exist on
* the server; the parameter only affects
* how the download is called to the
* browser.
* @param array[] $data 2D array with data
* @param array $fields Field names
* @param string|null $delimiter character used to separate data
@@ -470,8 +461,8 @@ class ParseCsvForPhp {
* Encoding
* Convert character encoding
*
* @param [string] $input Input character encoding, uses default if left blank
* @param [string] $output Output character encoding, uses default if left blank
* @param string $input Input character encoding, uses default if left blank
* @param string $output Output character encoding, uses default if left blank
*/
public function encoding($input = null, $output = null) {
$this->convert_encoding = true;
@@ -538,6 +529,44 @@ class ParseCsvForPhp {
return $this->delimiter;
}
/**
* Get total number of data rows (exclusive heading line if present) in CSV
* without parsing the whole data string.
*
* @return bool|int
*/
public function getTotalDataRowCount() {
if (empty($this->file_data)) {
return false;
}
$data = $this->file_data;
$this->_detect_and_remove_sep_row_from_data($data);
$pattern = sprintf('/%1$s[^%1$s]*%1$s/i', $this->enclosure);
preg_match_all($pattern, $data, $matches);
/** @var array[] $matches */
foreach ($matches[0] as $match) {
if (empty($match) || (strpos($match, $this->enclosure) === false)) {
continue;
}
$replace = str_replace(["\r", "\n"], '', $match);
$data = str_replace($match, $replace, $data);
}
$headingRow = $this->heading ? 1 : 0;
$count = substr_count($data, "\r")
+ substr_count($data, "\n")
- substr_count($data, "\r\n")
- $headingRow;
return $count;
}
// ==============================================
// ----- [ Core Functions ] ---------------------
// ==============================================
@@ -550,7 +579,7 @@ class ParseCsvForPhp {
*
* @return array|bool
*/
public function parse_file($file = null) {
protected function parse_file($file = null) {
if (is_null($file)) {
$file = $this->file;
}
@@ -573,7 +602,7 @@ class ParseCsvForPhp {
*
* @return array|false - 2D array with CSV data, or false on failure
*/
public function parse_string($data = null) {
protected function parse_string($data = null) {
if (empty($data)) {
if ($this->_check_data()) {
$data = &$this->file_data;
@@ -724,18 +753,9 @@ class ParseCsvForPhp {
$this->titles = $head;
if (!empty($this->sort_by)) {
$sort_type = SORT_REGULAR;
if ($this->sort_type == 'numeric') {
$sort_type = SORT_NUMERIC;
} elseif ($this->sort_type == 'string') {
$sort_type = SORT_STRING;
}
$sort_type = SortEnum::getSorting($this->sort_type);
$this->sort_reverse ? krsort($rows, $sort_type) : ksort($rows, $sort_type);
// Avoid issues with mixing string and integer keys:
$rows = array_values($rows);
if ($this->offset !== null || $this->limit !== null) {
$rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset), $this->limit, true);
}
@@ -761,9 +781,12 @@ class ParseCsvForPhp {
*
* @return string CSV data
*/
public function unparse($data = array(), $fields = array(), $append = false, $is_php = false, $delimiter = null) {
public function unparse($data = array(), $fields = array(), $append = FileProcessingModeEnum::MODE_FILE_OVERWRITE, $is_php = false, $delimiter = null) {
if (!is_array($data) || empty($data)) {
$data = &$this->data;
} else {
/** @noinspection ReferenceMismatchInspection */
$this->data = $data;
}
if (!is_array($fields) || empty($fields)) {
@@ -778,8 +801,16 @@ class ParseCsvForPhp {
$entry = array();
// create heading
/** @noinspection ReferenceMismatchInspection */
$fieldOrder = $this->_validate_fields_for_unparse($fields);
if (!$fieldOrder && !empty($data)) {
$column_count = count($data[0]);
$columns = range(0, $column_count - 1, 1);
$fieldOrder = array_combine($columns, $columns);
}
if ($this->heading && !$append && !empty($fields)) {
foreach ($fields as $key => $column_name) {
foreach ($fieldOrder as $column_name) {
$entry[] = $this->_enclose_value($column_name, $delimiter);
}
@@ -789,7 +820,8 @@ class ParseCsvForPhp {
// create data
foreach ($data as $key => $row) {
foreach ($row as $cell_value) {
foreach (array_keys($fieldOrder) as $index) {
$cell_value = $row[$index];
$entry[] = $this->_enclose_value($cell_value, $delimiter);
}
@@ -804,6 +836,46 @@ class ParseCsvForPhp {
return $string;
}
private function _validate_fields_for_unparse($fields) {
if (empty($fields)) {
$fields = $this->titles;
}
if (empty($fields)) {
return array();
}
// this is needed because sometime titles property is overwritten instead of using fields parameter!
$titlesOnParse = !empty($this->data) ? array_keys($this->data[0]) : array();
// both are identical, also in ordering
if (array_values($fields) === array_values($titlesOnParse)) {
return array_combine($fields, $fields);
}
// if renaming given by: $oldName => $newName (maybe with reorder and / or subset):
// todo: this will only work if titles are unique
$fieldOrder = array_intersect(array_flip($fields), $titlesOnParse);
if (!empty($fieldOrder)) {
return array_flip($fieldOrder);
}
$fieldOrder = array_intersect($fields, $titlesOnParse);
if (!empty($fieldOrder)) {
return array_combine($fieldOrder, $fieldOrder);
}
// original titles are not given in fields. that is okay if count is okay.
if (count($fields) != count($titlesOnParse)) {
throw new \UnexpectedValueException(
"The specified fields do not match any titles and do not match column count.\n" .
"\$fields was " . print_r($fields, true) .
"\$titlesOnParse was " . print_r($titlesOnParse, true));
}
return array_combine($titlesOnParse, $fields);
}
/**
* Load local file or string
*
@@ -916,12 +988,19 @@ class ParseCsvForPhp {
*/
protected function _validate_row_condition($row, $condition) {
$operators = array(
'=', 'equals', 'is',
'!=', 'is not',
'<', 'is less than',
'>', 'is greater than',
'<=', 'is less than or equals',
'>=', 'is greater than or equals',
'=',
'equals',
'is',
'!=',
'is not',
'<',
'is less than',
'>',
'is greater than',
'<=',
'is less than or equals',
'>=',
'is greater than or equals',
'contains',
'does not contain',
);
@@ -939,16 +1018,14 @@ class ParseCsvForPhp {
$op = $capture[2];
$value = $capture[3];
if (preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/', $value, $capture)) {
if ($capture[1] == $capture[3]) {
$value = strtr($capture[2], array(
"\\n" => "\n",
"\\r" => "\r",
"\\t" => "\t",
));
if (preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/', $value, $capture) && $capture[1] == $capture[3]) {
$value = strtr($capture[2], array(
"\\n" => "\n",
"\\r" => "\r",
"\\t" => "\t",
));
$value = stripslashes($value);
}
$value = stripslashes($value);
}
if (array_key_exists($field, $row)) {
@@ -988,7 +1065,8 @@ class ParseCsvForPhp {
return
$this->sort_by !== null ||
$this->offset === null ||
$current_row >= $this->offset;
$current_row >= $this->offset ||
($this->heading && $current_row == 0);
}
/**
@@ -1078,21 +1156,19 @@ class ParseCsvForPhp {
}
/**
* Read local file
* Read local file.
*
* @param string|null $file local filename
* @param string $file local filename
*
* @return string|false Data from file, or false on failure
*/
protected function _rfile($file = null) {
protected function _rfile($file) {
if (is_readable($file)) {
if (!($fh = fopen($file, 'r'))) {
$data = file_get_contents($file);
if ($data === false) {
return false;
}
$data = fread($fh, filesize($file));
fclose($fh);
return $data;
return rtrim($data, "\r\n");
}
return false;
@@ -1127,7 +1203,7 @@ class ParseCsvForPhp {
* first line containing only "sep=;", where the last character is the
* separator. Microsoft Excel is able to open such files.
*
* @param string $data    file data
* @param string $data file data
*
* @return string|false detected delimiter, or false if none found
*/
@@ -1145,7 +1221,7 @@ class ParseCsvForPhp {
/**
* Support for Excel-compatible sep=? row.
*
* @param string $data_string    file data to be updated
* @param string $data_string file data to be updated
*
* @return bool TRUE if sep= line was found at the very beginning of the file
*/
@@ -1241,4 +1317,29 @@ class ParseCsvForPhp {
ksort($filtered);
$this->delimiter = reset($filtered);
}
/**
* getCollection
* Returns a Illuminate/Collection object
* This may prove to be helpful to people who want to
* create macros, and or use map functions
*
* @access public
* @link https://laravel.com/docs/5.6/collections
*
* @throws \ErrorException - If the Illuminate\Support\Collection class is not found
*
* @return Collection
*/
public function getCollection() {
//does the Illuminate\Support\Collection class exists?
//this uses the autoloader to try to determine
//@see http://php.net/manual/en/function.class-exists.php
if (class_exists('Illuminate\Support\Collection', true) == false) {
throw new \ErrorException('It would appear you have not installed the illuminate/support package!');
}
//return the collection
return new Collection($this->data);
}
}

View File

@@ -0,0 +1,40 @@
<?php
namespace ParseCsv\enums;
use ReflectionClass;
abstract class AbstractEnum {
/**
* Creates a new value of some type
*
* @param mixed $value
*
* @throws \UnexpectedValueException if incompatible type is given.
*/
public function __construct($value)
{
if (!$this->isValid($value)) {
throw new \UnexpectedValueException("Value '$value' is not part of the enum " . get_called_class());
}
$this->value = $value;
}
public static function getConstants(){
$class = get_called_class();
$reflection = new \ReflectionClass($class);
return $reflection->getConstants();
}
/**
* Check if enum value is valid
*
* @param $value
*
* @return bool
*/
public static function isValid($value)
{
return in_array($value, static::getConstants(), true);
}
}

120
src/enums/DatatypeEnum.php Normal file
View File

@@ -0,0 +1,120 @@
<?php
namespace ParseCsv\enums;
/**
* Class DatatypeEnum
*
* @package ParseCsv\enums
*
* todo: needs a basic parent enum class for error handling.
*/
class DatatypeEnum extends AbstractEnum {
const __DEFAULT = self::TYPE_STRING;
const TYPE_STRING = 'string';
const TYPE_FLOAT = 'float';
const TYPE_INT = 'integer';
const TYPE_BOOL = 'boolean';
const TYPE_DATE = 'date';
const REGEX_FLOAT = '/(^[+-]?$)|(^[+-]?[0-9]+([,.][0-9])?[0-9]*(e[+-]?[0-9]+)?$)/';
const REGEX_INT = '/^[-+]?[0-9]\d*$/';
const REGEX_BOOL = '/^(?i:true|false)$/';
/**
* Define validator functions here.
*
* @var array
*
* @uses isValidFloat
* @uses isValidInteger
* @uses isValidBoolean
* @uses isValidDate
*/
private static $validators = array(
self::TYPE_STRING => null,
self::TYPE_INT => 'isValidInteger',
self::TYPE_BOOL => 'isValidBoolean',
self::TYPE_FLOAT => 'isValidFloat',
self::TYPE_DATE => 'isValidDate',
);
/**
* Checks data type for given string.
*
* @param string $value
*
* @return bool|string
*/
public static function getValidTypeFromSample($value) {
$value = trim((string) $value);
if (empty($value)) {
return false;
}
foreach (self::$validators as $type => $validator) {
if ($validator === null) {
continue;
}
if (method_exists(__CLASS__, $validator) && self::$validator($value)) {
return $type;
}
}
return self::__DEFAULT;
}
/**
* Check if string is float value.
*
* @param string $value
*
* @return bool
*/
private static function isValidFloat($value) {
return (bool) preg_match(self::REGEX_FLOAT, $value);
}
/**
* Check if string is integer value.
*
* @param string $value
*
* @return bool
*/
private static function isValidInteger($value) {
return (bool) preg_match(self::REGEX_INT, $value);
}
/**
* Check if string is boolean.
*
* @param string $value
*
* @return bool
*/
private static function isValidBoolean($value) {
return (bool) preg_match(self::REGEX_BOOL, $value);
}
/**
* Check if string is date.
*
* @param string $value
*
* @return bool
*/
private static function isValidDate($value) {
return (bool) strtotime($value);
}
}

View File

@@ -0,0 +1,28 @@
<?php
namespace ParseCsv\enums;
/**
* Class FileProcessingEnum
*
* @package ParseCsv\enums
*
* todo extends a basic enum class after merging #121
*/
class FileProcessingModeEnum {
const __default = self::MODE_FILE_OVERWRITE;
const MODE_FILE_APPEND = true;
const MODE_FILE_OVERWRITE = false;
public static function getAppendMode($mode) {
if ($mode == self::MODE_FILE_APPEND){
return 'ab';
}
return 'wb';
}
}

28
src/enums/SortEnum.php Normal file
View File

@@ -0,0 +1,28 @@
<?php
namespace ParseCsv\enums;
class SortEnum extends AbstractEnum {
const __DEFAULT = self::SORT_TYPE_REGULAR;
const SORT_TYPE_REGULAR = 'regular';
const SORT_TYPE_NUMERIC = 'numeric';
const SORT_TYPE_STRING = 'string';
private static $sorting = array(
self::SORT_TYPE_REGULAR => SORT_REGULAR,
self::SORT_TYPE_STRING => SORT_STRING,
self::SORT_TYPE_NUMERIC => SORT_NUMERIC
);
public static function getSorting($type){
if (array_key_exists($type, self::$sorting)){
return self::$sorting[$type];
}
return self::$sorting[self::__DEFAULT];
}
}

View File

@@ -0,0 +1,113 @@
<?php
namespace ParseCsv\extensions;
use ParseCsv\enums\DatatypeEnum;
trait DatatypeTrait {
/**
* Datatypes
* Datatypes of CSV data-columns
*
* @access public
* @var array
*/
public $data_types = [];
/**
* Check data type for one column.
* Check for most commonly data type for one column.
*
* @access private
*
* @param array $datatypes
*
* @return string|false
*/
private function getMostFrequentDatatypeForColumn($datatypes) {
// remove 'false' from array (can happen if CSV cell is empty)
$typesFiltered = array_filter($datatypes);
if (empty($typesFiltered)) {
return false;
}
$typesFreq = array_count_values($typesFiltered);
arsort($typesFreq);
reset($typesFreq);
return key($typesFreq);
}
/**
* Check data type foreach Column
* Check data type for each column and returns the most commonly.
*
* Requires PHP >= 5.5
*
* @access public
*
* @uses DatatypeEnum::getValidTypeFromSample
*
* @return array|bool
*/
public function getDatatypes() {
if (empty($this->data)) {
$this->data = $this->parse_string();
}
if (!is_array($this->data)) {
throw new \UnexpectedValueException('No data set yet.');
}
$result = [];
foreach ($this->titles as $cName) {
$column = array_column($this->data, $cName);
$cDatatypes = array_map(DatatypeEnum::class . '::getValidTypeFromSample', $column);
$result[$cName] = $this->getMostFrequentDatatypeForColumn($cDatatypes);
}
$this->data_types = $result;
return !empty($this->data_types) ? $this->data_types : [];
}
/**
* Check data type of titles / first row for auto detecting if this could be
* a heading line.
*
* Requires PHP >= 5.5
*
* @access public
*
* @uses DatatypeEnum::getValidTypeFromSample
*
* @return bool
*/
public function autoDetectFileHasHeading(){
if (empty($this->data)){
throw new \UnexpectedValueException('No data set yet.');
}
if ($this->heading){
$firstRow = $this->titles;
} else {
$firstRow = $this->data[0];
}
$firstRow = array_filter($firstRow);
if (empty($firstRow)){
return false;
}
$firstRowDatatype = array_map(DatatypeEnum::class . '::getValidTypeFromSample', $firstRow);
if ($this->getMostFrequentDatatypeForColumn($firstRowDatatype) !== DatatypeEnum::TYPE_STRING){
return false;
}
return true;
}
}

View File

@@ -1,13 +1,13 @@
<?php
chdir(__DIR__ . '/..');
if (!file_exists('vendor/autoload.php')) {
`composer dump-autoload`;
}
$dir = realpath(__DIR__);
defined('BASE') OR define('BASE', dirname($dir) . '/');
require __DIR__ . '/../vendor/autoload.php';
require_once BASE . 'ParseCsvForPhp.php';
if (!class_exists('PHPUnit\Framework\TestCase')) {
if (!class_exists('PHPUnit\Framework\TestCase') && class_exists('PHPUnit_Framework_TestCase')) {
// we run on an older PHPUnit version without namespaces.
require_once __DIR__ . '/PHPUnit_Framework_TestCase.inc.php';
}
require_once BASE . 'tests/properties/BaseClass.php';

View File

@@ -0,0 +1,22 @@
ID,dID,createdAt,else1,else2,else3,else4,else5,user,else6,else7,else8,else9,else10,else11,else12,else13,else14,else15,else16,else17,else18,else19,else20,else21,else22,else23,else24,else25,else26,else27,else28,else29,else30,else31,else32,else33,else34,else35,else36,else37,else38
418,0,2017-05-16,,,2018-01-22,22.01.2018 10:00:09,,admin,Ja,,10001,Abweichung,,10001,v1,1,ddd,100,1000,,HH,,v1,0,401,1,2,H1,,-1,10,1,111,Ja,2017-01-01,,12,0,11109,HH-100,default
419,0,2017-05-16,,,2017-05-16,14.07.2017 09:58:09,,admin,Ja,,,Abweichung,,10002,v2,1,ddd,200,500,DD,DD,,v2,1,402,2,4,H2,,-2,100,1,1111,Ja,2017-01-01,1,13,1,11109,DD-200,default
438,0,2017-05-16,,,2017-05-16,14.07.2017 09:58:29,,admin,Ja,,10021,Abweichung,,10021,v3,4,ddd,300,400,DD,DD,,v3,0,421,1,,H3,,-1,106,1,111,Ja,2017-05-08,,2,1,11109,DD-300,default
440,0,2017-05-16,,,,14.07.2017 09:58:53,,admin,Ja,,,Alt,,10023,v4,3,,400,500,BE,DD,,v4,1,423,3,,H4,,-3,143,1,1111,Ja,2017-01-01,1,33,1,11108,BE-400,default
441,0,2017-05-16,,,,14.07.2017 09:59:19,,admin,Ja,,,Fehlt,,10024,v5,3,,500,,BE,,,v5,2,424,4,,H5,,0,1435,0,111,Ja,2017-01-01,,12,1,0,BE-500,default
442,0,2017-05-16,,,,14.07.2017 10:00:46,,admin,Ja,,,Neu,,10025,v6,3,,100,,DD,,,v6,435,425,1,,H6,,0,10,0,1111,Ja,2017-01-01,,102,1,0,DD-100,default
443,0,2017-05-16,,,2017-07-04,14.07.2017 10:01:12,,admin,Ja,,,OK,,10026,v7,3,,200,200,DD,DD,,v7,32,426,2,2,H7,,0,100,0,111,Ja,2017-01-01,,77,1,0,DD-200,default
444,0,2017-05-16,,,,14.07.2017 10:02:13,,admin,Ja,,,Fehlt,,10027,v8,3,,300,,BE,,,v8,45,427,3,,H8,,0,200,0,1111,Ja,2017-01-01,,44,3,0,BE-300,default
445,0,2017-05-16,,,,14.07.2017 10:02:38,,admin,Ja,,,Fehlt,,10028,v9,3,,100,,BE,,,v9,45,428,4,,H9,,0,400,0,111,Ja,2017-01-01,,44,1,0,BE-100,default
446,0,2017-05-16,,,,14.07.2017 10:03:01,,admin,Ja,,,Fehlt,,10029,v10,3,,,400,,DD,,v10,45,429,,,H10,,0,1124,0,1111,Ja,2017-01-01,,89,1,0,,default
1 ID dID createdAt else1 else2 else3 else4 else5 user else6 else7 else8 else9 else10 else11 else12 else13 else14 else15 else16 else17 else18 else19 else20 else21 else22 else23 else24 else25 else26 else27 else28 else29 else30 else31 else32 else33 else34 else35 else36 else37 else38
2 418 0 2017-05-16 2018-01-22 22.01.2018 10:00:09 admin Ja 10001 Abweichung 10001 v1 1 ddd 100 1000 HH v1 0 401 1 2 H1 -1 10 1 111 Ja 2017-01-01 12 0 11109 HH-100 default
3 419 0 2017-05-16 2017-05-16 14.07.2017 09:58:09 admin Ja Abweichung 10002 v2 1 ddd 200 500 DD DD v2 1 402 2 4 H2 -2 100 1 1111 Ja 2017-01-01 1 13 1 11109 DD-200 default
4 438 0 2017-05-16 2017-05-16 14.07.2017 09:58:29 admin Ja 10021 Abweichung 10021 v3 4 ddd 300 400 DD DD v3 0 421 1 H3 -1 106 1 111 Ja 2017-05-08 2 1 11109 DD-300 default
5 440 0 2017-05-16 14.07.2017 09:58:53 admin Ja Alt 10023 v4 3 400 500 BE DD v4 1 423 3 H4 -3 143 1 1111 Ja 2017-01-01 1 33 1 11108 BE-400 default
6 441 0 2017-05-16 14.07.2017 09:59:19 admin Ja Fehlt 10024 v5 3 500 BE v5 2 424 4 H5 0 1435 0 111 Ja 2017-01-01 12 1 0 BE-500 default
7 442 0 2017-05-16 14.07.2017 10:00:46 admin Ja Neu 10025 v6 3 100 DD v6 435 425 1 H6 0 10 0 1111 Ja 2017-01-01 102 1 0 DD-100 default
8 443 0 2017-05-16 2017-07-04 14.07.2017 10:01:12 admin Ja OK 10026 v7 3 200 200 DD DD v7 32 426 2 2 H7 0 100 0 111 Ja 2017-01-01 77 1 0 DD-200 default
9 444 0 2017-05-16 14.07.2017 10:02:13 admin Ja Fehlt 10027 v8 3 300 BE v8 45 427 3 H8 0 200 0 1111 Ja 2017-01-01 44 3 0 BE-300 default
10 445 0 2017-05-16 14.07.2017 10:02:38 admin Ja Fehlt 10028 v9 3 100 BE v9 45 428 4 H9 0 400 0 111 Ja 2017-01-01 44 1 0 BE-100 default
11 446 0 2017-05-16 14.07.2017 10:03:01 admin Ja Fehlt 10029 v10 3 400 DD v10 45 429 H10 0 1124 0 1111 Ja 2017-01-01 89 1 0 default

View File

@@ -0,0 +1,6 @@
keyword
liability waiver
release of liability form
release of liability
sample waiver
sample waiver form
1 keyword
2 liability waiver
3 release of liability form
4 release of liability
5 sample waiver
6 sample waiver form

View File

@@ -1,45 +1,68 @@
<?php
class ConstructTest extends PHPUnit\Framework\TestCase {
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class ConstructTest extends TestCase {
/**
* @access protected
* @var ParseCsvForPhp object
* @var Csv object
*/
protected $csv = null;
public function test_offset_param() {
$offset = 10;
$this->csv = new ParseCsvForPhp(null, $offset);
$this->csv = new Csv(null, $offset);
$this->assertTrue(is_numeric($this->csv->offset));
$this->assertEquals($offset, $this->csv->offset);
}
public function test_limit_param() {
$limit = 10;
$this->csv = new ParseCsvForPhp(null, null, $limit);
$this->csv = new Csv(null, null, $limit);
$this->assertTrue(is_numeric($this->csv->limit));
$this->assertEquals($limit, $this->csv->limit);
}
public function test_conditions_param() {
$conditions = 'some column NOT value';
$this->csv = new ParseCsvForPhp(null, null, null, $conditions);
$this->csv = new Csv(null, null, null, $conditions);
$this->assertTrue(is_string($this->csv->conditions));
$this->assertEquals($conditions, $this->csv->conditions);
}
public function test_keep_file_data_param() {
$keep = true;
$this->csv = new ParseCsvForPhp(null, null, null, null, $keep);
$this->csv = new Csv(null, null, null, null, $keep);
$this->assertTrue(is_bool($this->csv->keep_file_data));
$this->assertEquals($keep, $this->csv->keep_file_data);
}
public function test_input_param() {
$csv = "col1,col2,col3\r\nval1,val2,val3\r\nval1A,val2A,val3A\r\n";
$this->csv = new ParseCsvForPhp($csv, null, null, null, true);
$this->csv = new Csv($csv, null, null, null, true);
$this->assertTrue(is_string($this->csv->file_data));
$this->assertEquals($csv, $this->csv->file_data);
}
/**
* @runInSeparateProcess because download.php uses header()
*
* @see https://github.com/sebastianbergmann/phpunit/issues/720#issuecomment-10421092
*/
public function testCodeExamples() {
chdir('examples');
foreach (glob('*.php') as $script_file) {
ob_start();
/** @noinspection PhpIncludeInspection */
require $script_file;
$ob_get_clean = ob_get_clean();
if ($script_file != 'download.php') {
$this->assertContains('<td>', $ob_get_clean);
}
}
chdir('..');
}
}

View File

@@ -0,0 +1,82 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class DataRowCountTest extends TestCase {
/**
* CSV
* The CSV object
*
* @access protected
* @var Csv
*/
protected $csv;
/**
* Setup
* Setup our test environment objects
*
* @access public
*/
public function setUp() {
$this->csv = new Csv();
}
public function countRowsProvider() {
return [
'auto-double-enclosure' => [
'auto-double-enclosure.csv',
2,
],
'auto-single-enclosure' => [
'auto-single-enclosure.csv',
2,
],
'UTF-8_sep_row' => [
'datatype.csv',
3,
],
];
}
/**
* @dataProvider countRowsProvider
*
* @param string $file
* @param int $expectedRows
*/
public function testGetTotalRowCountFromFile($file, $expectedRows) {
$this->csv->heading = true;
$this->csv->load_data(__DIR__ . '/fixtures/' . $file);
$this->assertEquals($expectedRows, $this->csv->getTotalDataRowCount());
}
public function testGetTotalRowCountMissingEndingLineBreak() {
$this->csv->heading = false;
$this->csv->enclosure = '"';
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\"";
$this->csv->load_data($sInput);
$this->assertEquals(3, $this->csv->getTotalDataRowCount());
}
public function testGetTotalRowCountSingleEnclosure() {
$this->csv->heading = false;
$this->csv->enclosure = "'";
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\'c\r\nd\'";
$this->csv->load_data($sInput);
$this->assertEquals(3, $this->csv->getTotalDataRowCount());
}
public function testGetTotalRowCountSingleRow() {
$this->csv->heading = false;
$this->csv->enclosure = "'";
$sInput = "86545235689";
$this->csv->load_data($sInput);
$this->assertEquals(1, $this->csv->getTotalDataRowCount());
}
}

View File

@@ -0,0 +1,69 @@
<?php
/**
* Created by PhpStorm.
* User: sgorzaly
* Date: 19.02.18
* Time: 20:52
*/
namespace ParseCsv\tests\methods;
use PHPUnit\Framework\TestCase;
use ParseCsv\enums\DatatypeEnum;
class DatatypeTest extends TestCase
{
public function testSampleIsValidInteger(){
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1'));
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('+1'));
$this->assertEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('-1'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('--1'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('test'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1.0'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1,0'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('1,1'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('0.1'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('true'));
$this->assertNotEquals(DatatypeEnum::TYPE_INT, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
}
public function testSampleIsValidBool(){
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('true'));
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('TRUE'));
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('false'));
$this->assertEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('FALSE'));
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('FALS'));
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('test'));
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('0'));
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('1'));
$this->assertNotEquals(DatatypeEnum::TYPE_BOOL, DatatypeEnum::getValidTypeFromSample('0.1'));
}
public function testSampleIsValidFloat(){
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1.0'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('-1.1'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('+1,1'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,1'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,1'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1e-03'));
$this->assertEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1e+03'));
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1'));
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('test'));
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1,,1'));
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('1..1'));
$this->assertNotEquals(DatatypeEnum::TYPE_FLOAT, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
}
public function testSampleIsValidDate(){
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('2018-02-19'));
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('18-2-19'));
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('01.02.2018'));
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1.2.18'));
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('07/31/2018'));
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('31/07/2018'));
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1-2'));
$this->assertEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('1.2.'));
$this->assertNotEquals(DatatypeEnum::TYPE_DATE, DatatypeEnum::getValidTypeFromSample('test'));
}
}

View File

@@ -0,0 +1,45 @@
<?php
namespace ParseCsv\tests\methods;
use PHPUnit\Framework\TestCase;
/**
* This test checks for backwards compatibility: Does it work to
* - require the old "parsecsv.lib.php" instead of composer autoloading?
* - use the old class name "parseCSV"?
*/
class OldRequireTest extends TestCase {
protected function setUp() {
rename('vendor/autoload.php', '__autoload');
}
protected function tearDown() {
rename('__autoload', 'vendor/autoload.php');
}
/**
* @runInSeparateProcess so that disabled autoloading has an effect
*/
public function testOldLibWithoutComposer() {
file_put_contents('__eval.php', '<?php require "parsecsv.lib.php"; new \ParseCsv\Csv;');
exec("php __eval.php", $output, $return_var);
unlink('__eval.php');
$this->assertEquals($output, []);
$this->assertEquals(0, $return_var);
}
/**
* @runInSeparateProcess so that disabled autoloading has an effect
*/
public function testOldLibWithOldClassName() {
file_put_contents('__eval.php', '<?php require "parsecsv.lib.php"; new parseCSV;');
exec("php __eval.php", $output, $return_var);
unlink('__eval.php');
$this->assertEquals($output, []);
$this->assertEquals(0, $return_var);
}
}

View File

@@ -0,0 +1,21 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class OutputTest extends TestCase {
/**
* @runInSeparateProcess because download.php uses header()
*/
public function testOutputWithFourParameters() {
$csv = new Csv();
$data = [0 => ['a', 'b', 'c'], 1 => ['d', 'e', 'f']];
$fields = ['col1', 'col2', 'col3'];
$output = $csv->output('test.csv', $data, $fields, ',');
$expected = "col1,col2,col3\ra,b,c\rd,e,f\r";
self::assertEquals($expected, $output);
}
}

View File

@@ -1,10 +1,14 @@
<?php
class ParseTest extends PHPUnit\Framework\TestCase {
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class ParseTest extends TestCase {
/**
* @access protected
* @var ParseCsvForPhp
* @var Csv object
*/
protected $csv;
@@ -15,16 +19,16 @@ class ParseTest extends PHPUnit\Framework\TestCase {
* @access public
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
$this->csv = new Csv();
}
public function test_parse() {
public function testParse() {
// can we trick 'is_readable' into whining? See #67.
$this->parse_repetitive_string('c:/looks/like/a/path');
$this->parse_repetitive_string('http://looks/like/an/url');
$this->parseRepetitiveString('c:/looks/like/a/path');
$this->parseRepetitiveString('http://looks/like/an/url');
}
private function parse_repetitive_string($content) {
private function parseRepetitiveString($content) {
$this->csv->delimiter = ';';
$this->csv->heading = false;
$success = $this->csv->parse(str_repeat($content . ';', 500));
@@ -36,9 +40,28 @@ class ParseTest extends PHPUnit\Framework\TestCase {
$this->assertEquals($expected_data, $row);
}
public function test_sep_row_auto_detection_UTF8_no_BOM() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-8_sep_row_but_no_BOM.csv');
/**
* @depends testParse
*
* @dataProvider autoDetectionProvider
*
* @param string $file
*/
public function testSepRowAutoDetection($file) {
// This file (parse_test.php) is encoded in UTF-8, hence comparison will
// fail unless we to this:
$this->csv->output_encoding = 'UTF-8';
$this->csv->auto($file);
$this->assertEquals($this->_get_magazines_data(), $this->csv->data);
}
public function autoDetectionProvider() {
return [
'UTF8_no_BOM' => [__DIR__ . '/../example_files/UTF-8_sep_row_but_no_BOM.csv'],
'UTF8' => [__DIR__ . '/../example_files/UTF-8_with_BOM_and_sep_row.csv'],
'UTF16' => [__DIR__ . '/../example_files/UTF-16LE_with_BOM_and_sep_row.csv'],
];
}
public function testSingleColumnWithZeros() {
@@ -64,7 +87,8 @@ class ParseTest extends PHPUnit\Framework\TestCase {
$this->csv->enclosure = '"';
$sInput = "86545235689,a\r\n34365587654,b\r\n13469874576,\"c\r\nd\"";
$expected_data = [86545235689, 34365587654, 13469874576];
$actual_data = $this->csv->parse_string($sInput);
$actual_data = $this->invokeMethod($this->csv, 'parse_string', array($sInput));
$actual_column = array_map('reset', $actual_data);
$this->assertEquals($expected_data, $actual_column);
$this->assertEquals([
@@ -74,26 +98,7 @@ class ParseTest extends PHPUnit\Framework\TestCase {
], array_map('next', $actual_data));
}
public function test_sep_row_auto_detection_UTF8() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-8_with_BOM_and_sep_row.csv');
}
public function test_sep_row_auto_detection_UTF16() {
$this->_autoparse_magazine_file(
__DIR__ . '/../example_files/UTF-16LE_with_BOM_and_sep_row.csv');
}
protected function _autoparse_magazine_file($file) {
// This file (parse_test.php) is encoded in UTF-8, hence comparison will
// fail unless we to this:
$this->csv->output_encoding = 'UTF-8';
$this->csv->auto($file);
$this->assertEquals($this->_get_magazines_data(), $this->csv->data);
}
public function test_single_column() {
public function testSingleColumn() {
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
$expected = [
['SMS' => '0444'],
@@ -104,11 +109,8 @@ class ParseTest extends PHPUnit\Framework\TestCase {
$this->assertEquals($expected, $this->csv->data);
}
public function test_Piwik_data() {
if (!function_exists('array_column')) {
// function only available in PHP >= 5.5
return;
}
public function testMatomoData() {
// Matomo (Piwik) export cannot be read with
$this->csv->use_mb_convert_encoding = true;
$this->csv->output_encoding = 'UTF-8';
$this->csv->auto(__DIR__ . '/../example_files/Piwik_API_download.csv');
@@ -127,6 +129,65 @@ class ParseTest extends PHPUnit\Framework\TestCase {
], $aCity);
}
public function testWithMultipleNewlines() {
$this->csv->auto(__DIR__ . '/../example_files/multiple_empty_lines.csv');
$aElse9 = array_column($this->csv->data, 'else9');
/** @noinspection SpellCheckingInspection */
$this->assertEquals([
'Abweichung',
'Abweichung',
'Abweichung',
'Alt',
'Fehlt',
'Neu',
'OK',
'Fehlt',
'Fehlt',
'Fehlt',
], $aElse9);
}
/**
* @depends testSepRowAutoDetection
*/
public function testGetColumnDatatypes() {
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
$this->csv->getDatatypes();
$expected = [
'title' => 'string',
'isbn' => 'string',
'publishedAt' => 'date',
'published' => 'boolean',
'count' => 'integer',
'price' => 'float',
];
$this->assertEquals($expected, $this->csv->data_types);
}
/**
* @depends testSepRowAutoDetection
*/
public function testAutoDetectFileHasHeading() {
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
$this->assertTrue($this->csv->autoDetectFileHasHeading());
$this->csv->heading = false;
$this->csv->auto(__DIR__ . '/fixtures/datatype.csv');
$this->assertTrue($this->csv->autoDetectFileHasHeading());
$this->csv->heading = false;
$sInput = "86545235689\r\n34365587654\r\n13469874576";
$this->csv->auto($sInput);
$this->assertFalse($this->csv->autoDetectFileHasHeading());
$this->csv->heading = true;
$sInput = "86545235689\r\n34365587654\r\n13469874576";
$this->csv->auto($sInput);
$this->assertFalse($this->csv->autoDetectFileHasHeading());
}
protected function _get_magazines_data() {
return [
[
@@ -155,15 +216,47 @@ class ParseTest extends PHPUnit\Framework\TestCase {
}
/**
* @depends testSepRowAutoDetection
*
* @dataProvider autoQuotesDataProvider
*
* @param string $file
* @param string $enclosure
*/
public function testAutoQuotes($file, $enclosure) {
$csv = new ParseCsvForPhp();
$csv->auto(__DIR__ . '/../example_files/' . $file, true, null, null, $enclosure);
$csv = new Csv();
$csv->auto(__DIR__ . '/fixtures/' . $file, true, null, null, $enclosure);
$this->assertArrayHasKey('column1', $csv->data[0], 'Data parsed incorrectly with enclosure ' . $enclosure);
$this->assertEquals('value1', $csv->data[0]['column1'], 'Data parsed incorrectly with enclosure ' . $enclosure);
}
/**
* Call protected/private method of a class.
*
* @param object &$object Instantiated object that we will run method on.
* @param string $methodName Method name to call
* @param array $parameters Array of parameters to pass into method.
*
* @return mixed Method return.
*/
private function invokeMethod(&$object, $methodName, array $parameters = array()) {
$reflection = new \ReflectionClass(get_class($object));
$method = $reflection->getMethod($methodName);
$method->setAccessible(true);
return $method->invokeArgs($object, $parameters);
}
public function testWaiverFieldSeparator() {
$this->assertSame(false, $this->csv->auto(__DIR__ . '/../example_files/waiver_field_separator.csv'));
$expected = [
'liability waiver',
'release of liability form',
'release of liability',
'sample waiver',
'sample waiver form',
];
$actual = array_column($this->csv->data, 'keyword');
$this->assertSame($expected, $actual);
}
}

View File

@@ -1,8 +1,13 @@
<?php
namespace ParseCsv\tests\methods;
class SaveTest extends PHPUnit\Framework\TestCase {
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
/** @var ParseCsvForPhp */
class SaveTest extends TestCase
{
/** @var Csv */
private $csv;
private $temp_filename;
@@ -11,7 +16,7 @@ class SaveTest extends PHPUnit\Framework\TestCase {
* Setup our test environment objects; will be called before each test.
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
$this->csv = new Csv();
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
// Remove last 2 lines to simplify comparison
@@ -44,6 +49,13 @@ class SaveTest extends PHPUnit\Framework\TestCase {
$this->saveAndCompare($expected);
}
public function testSaveWithNewHeader() {
$this->csv->linefeed = "\n";
$this->csv->titles = array("NewTitle");
$expected = "NewTitle\n0444\n5555\n";
$this->saveAndCompare($expected);
}
public function testSaveWithoutHeader() {
$this->csv->linefeed = "\n";
$this->csv->heading = false;

View File

@@ -0,0 +1,83 @@
<?php
namespace ParseCsv\tests\methods;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class UnparseTest extends Testcase {
/** @var Csv */
private $csv;
/**
* Setup our test environment objects; will be called before each test.
*/
public function setUp() {
$this->csv = new Csv();
$this->csv->auto(__DIR__ . '/fixtures/auto-double-enclosure.csv');
}
public function testUnparseWithParameters() {
$fields = array('a' => 'AA', 'b' => 'BB');
$data = [['a' => 'value1', 'b' => 'value2']];
$csv_object = new Csv();
$csv_string = $csv_object->unparse($data, $fields);
$this->assertEquals("AA,BB\rvalue1,value2\r", $csv_string);
$csv_object = new Csv();
$csv_object->linefeed = "\n";
$csv_string = $csv_object->unparse([[55, 66]]);
$this->assertEquals("55,66\n", $csv_string);
$csv_object = new Csv();
$data2 = [['a' => "multi\rline", 'b' => 'value2']];
$csv_object->enclosure = "'";
$csv_string = $csv_object->unparse($data2, $fields);
$this->assertEquals("AA,BB\r'multi\rline',value2\r", $csv_string);
}
public function testUnparseDefault() {
$expected = "column1,column2\rvalue1,value2\rvalue3,value4\r";
$this->unparseAndCompare($expected);
}
public function testUnparseDefaultWithoutHeading() {
$this->csv->heading = false;
$this->csv->auto(__DIR__ . '/fixtures/auto-double-enclosure.csv');
$expected = "column1,column2\rvalue1,value2\rvalue3,value4\r";
$this->unparseAndCompare($expected);
}
public function testUnparseRenameFields() {
$expected = "C1,C2\rvalue1,value2\rvalue3,value4\r";
$this->unparseAndCompare($expected, array("C1", "C2"));
}
public function testReorderFields() {
$expected = "column2,column1\rvalue2,value1\rvalue4,value3\r";
$this->unparseAndCompare($expected, array("column2", "column1"));
}
public function testSubsetFields() {
$expected = "column1\rvalue1\rvalue3\r";
$this->unparseAndCompare($expected, array("column1"));
}
public function testReorderAndRenameFields() {
$fields = array(
'column2' => 'C2',
'column1' => 'C1',
);
$expected = "C2,C1\rvalue2,value1\rvalue4,value3\r";
$this->unparseAndCompare($expected, $fields);
}
private function unparseAndCompare($expected, $fields = array()) {
$str = $this->csv->unparse($this->csv->data, $fields);
$this->assertEquals($expected, $str);
}
}

View File

@@ -0,0 +1,5 @@
sep=;
title;isbn;publishedAt;published;count;price
Красивая кулинария;5454-5587-3210;21.05.2011;true;1;10.99
The Wine Connoisseurs;2547-8548-2541;12.12.2011;TRUE;;20.33
Weißwein;1313-4545-8875;23.02.2012;false;10;10
1 sep=;
2 title;isbn;publishedAt;published;count;price
3 Красивая кулинария;5454-5587-3210;21.05.2011;true;1;10.99
4 The Wine Connoisseurs;2547-8548-2541;12.12.2011;TRUE;;20.33
5 Weißwein;1313-4545-8875;23.02.2012;false;10;10

View File

@@ -10,7 +10,7 @@
stopOnIncomplete="true"
stopOnSkipped="false">
<testsuites>
<testsuite name="ParseCsvForPhp Test Suite">
<testsuite name="parseCSV Test Suite">
<directory suffix="est.php">properties/</directory>
<directory suffix="est.php">methods/</directory>
</testsuite>

View File

@@ -1,10 +1,18 @@
<?php
class BaseClass extends PHPUnit\Framework\TestCase {
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class BaseClass extends TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var ParseCsvForPhp object
* @var Csv
*/
protected $csv;
@@ -15,7 +23,7 @@ class BaseClass extends PHPUnit\Framework\TestCase {
* @access public
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
$this->csv = new Csv();
}
protected function _compareWithExpected($expected) {
@@ -23,6 +31,6 @@ class BaseClass extends PHPUnit\Framework\TestCase {
$actual = array_map(function ($row) {
return $row['title'];
}, $this->csv->data);
$this->assertEquals($expected, $actual);
$this->assertEquals($expected, array_values($actual));
}
}

View File

@@ -1,5 +1,7 @@
<?php
namespace ParseCsv\tests\properties;
class ConditionsTest extends BaseClass {
public function testNotDanBrown() {

View File

@@ -1,10 +1,18 @@
<?php
class default_values_properties_Test extends PHPUnit\Framework\TestCase {
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use PHPUnit\Framework\TestCase;
class DefaultValuesPropertiesTest extends TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var ParseCsvForPhp object
* @var Csv
*/
protected $csv = null;
@@ -16,7 +24,17 @@ class default_values_properties_Test extends PHPUnit\Framework\TestCase {
*/
public function setUp() {
//setup parse CSV
$this->csv = new ParseCsvForPhp();
$this->csv = new Csv();
}
/**
* Tear down
* Tear down our test environment objects
*
* @access public
*/
public function tearDown() {
$this->csv = null;
}
public function test_heading_default() {
@@ -39,7 +57,7 @@ class default_values_properties_Test extends PHPUnit\Framework\TestCase {
}
public function test_sort_type_default() {
$this->assertNull($this->csv->sort_type);
$this->assertEquals('regular', $this->csv->sort_type);
}
public function test_delimiter_default() {

View File

@@ -0,0 +1,78 @@
<?php
namespace ParseCsv\tests\properties;
/**
* Tests related to the $offset property
*/
class OffsetTest extends BaseClass {
public function testOffsetOfOne() {
$this->csv->offset = 1;
$this->csv->auto(__DIR__ . '/../methods/fixtures/datatype.csv');
$this->assertCount(3, $this->csv->data);
if (!function_exists('array_column')) {
// function only available in PHP >= 5.5
return;
}
$expected = [
'Красивая кулинария',
'The Wine Connoisseurs',
'Weißwein',
];
$actual = array_column($this->csv->data, 'title');
$this->assertEquals($expected, $actual);
}
public function numberRangeZeroToFourProvider() {
return array_map(function ($number) {
return [$number];
}, range(0, 4));
}
/**
* @dataProvider numberRangeZeroToFourProvider
*
* @param integer $offset
*/
public function testOffsetOfOneNoHeader($offset) {
$this->csv->offset = $offset;
$this->csv->heading = false;
$this->csv->auto(__DIR__ . '/../methods/fixtures/datatype.csv');
$this->assertCount(4 - $offset, $this->csv->data);
}
public function testDataArrayKeysWhenSettingOffsetWithHeading() {
$this->csv->offset = 2;
$this->csv->auto(__DIR__ . '/../methods/fixtures/datatype.csv');
$expected = [
[
'title' => 'The Wine Connoisseurs',
'isbn' => '2547-8548-2541',
'publishedAt' => '12.12.2011',
'published' => 'TRUE',
'count' => '',
'price' => 20.33,
],
[
'title' => 'Weißwein',
'isbn' => '1313-4545-8875',
'publishedAt' => '23.02.2012',
'published' => 'false',
'count' => 10,
'price' => 10,
],
];
$this->assertEquals($expected, $this->csv->data);
}
public function testDataArrayKeysWhenSettingOffsetWithoutHeading() {
$this->csv->heading = false;
$this->csv->offset = 2;
$this->csv->auto(__DIR__ . '/../methods/fixtures/datatype.csv');
$expected = range(0, 5, 1);
$this->assertEquals($expected, array_keys($this->csv->data[0]));
}
}

View File

@@ -1,10 +1,19 @@
<?php
class worthless_properties_Test extends PHPUnit\Framework\TestCase {
namespace ParseCsv\tests\properties;
use ParseCsv\Csv;
use ParseCsv\enums\SortEnum;
use PHPUnit\Framework\TestCase;
class PublicPropertiesTest extends TestCase {
/**
* CSV
* The parseCSV object
*
* @access protected
* @var ParseCsvForPhp
* @var Csv
*/
protected $csv = null;
@@ -13,7 +22,7 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
* The reflection class object
*
* @access protected
* @var ReflectionClass
* @var \ReflectionClass
*/
protected $reflection = null;
@@ -21,8 +30,8 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
* Reflection Properties
* The reflected class properties
*
* @var \ReflectionProperty[]
* @access protected
* @var ReflectionProperty[]
*/
protected $properties = null;
@@ -34,10 +43,10 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
*/
public function setUp() {
//setup parse CSV
$this->csv = new ParseCsvForPhp();
$this->csv = new Csv();
//setup the reflection class
$this->reflection = new ReflectionClass($this->csv);
$this->reflection = new \ReflectionClass($this->csv);
//setup the reflected class properties
$this->properties = $this->reflection->getProperties();
@@ -63,7 +72,7 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
* @access public
*/
public function test_propertiesCount() {
$this->assertCount(28, $this->properties);
$this->assertCount(29, $this->properties);
}
/**
@@ -106,10 +115,11 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
'error_info',
'titles',
'data',
'data_types',
);
// Find our real properties
$real_properties = array_map(function (ReflectionProperty $property) {
$real_properties = array_map(function (\ReflectionProperty $property) {
return $property->getName();
}, $this->properties);
@@ -127,7 +137,8 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
public function test_count_public_properties() {
$counter = 0;
for ($a = count($this->properties) - 1; $a >= 0; $a--) {
$propertiesCount = count($this->properties);
for ($a = 0; $a < $propertiesCount; $a++) {
if ($this->properties[$a]->isPublic() === true) {
$counter++;
}
@@ -135,4 +146,26 @@ class worthless_properties_Test extends PHPUnit\Framework\TestCase {
$this->assertCount($counter, $this->properties);
}
public function testDefaultSortTypeIsRegular(){
$this->assertEquals(SortEnum::SORT_TYPE_REGULAR, $this->csv->sort_type);
}
public function testSetSortType(){
$this->csv->sort_type = 'numeric';
$this->assertEquals(SortEnum::SORT_TYPE_NUMERIC, $this->csv->sort_type);
$this->csv->sort_type = 'string';
$this->assertEquals(SortEnum::SORT_TYPE_STRING, $this->csv->sort_type);
}
public function testGetSorting(){
$this->csv->sort_type = 'numeric';
$sorting = SortEnum::getSorting($this->csv->sort_type);
$this->assertEquals(SORT_NUMERIC, $sorting);
$this->csv->sort_type = 'string';
$sorting = SortEnum::getSorting($this->csv->sort_type);
$this->assertEquals(SORT_STRING, $sorting);
}
}

View File

@@ -1,5 +1,7 @@
<?php
namespace ParseCsv\tests\properties;
class SortByTest extends BaseClass {
public function testSortByRating() {