219 Commits

Author SHA1 Message Date
Christian Bläul
02a8c1995d Semantic versioning: Marked the current state of the repo as 1.0.0-rc.1 2018-02-23 15:03:57 +01:00
Christian Bläul
72a7c29ed6 Updated remaining occurrences for old class/project name. 2018-02-02 17:31:26 +01:00
Christian Bläul
c905c9abfd Updated README.md 2018-02-02 17:26:13 +01:00
Christian Bläul
221c175217 Further improved ChangeLog.txt 2018-02-02 17:22:35 +01:00
Christian Bläul
4376cc8bd6 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-02 14:28:51 +01:00
Christian Bläul
5c157efbc3 output(): Use better mime type for \t separator.
Fixes #79
2018-02-02 13:49:57 +01:00
Christian Bläul
387a0f5761 Renamed class to follow the PHP community guidelines such as:
- https://svn.apache.org/repos/asf/shindig/attic/php/docs/style-guide.html:
  "Acryonyms are treated as normal words."

- https://softwareengineering.stackexchange.com/a/149321/80632
  Overview of class naming conventions of PHP frameworks

- https://github.com/php-fig/fig-standards/blob/master/accepted/PSR-4-autoloader.md
  No .lib allowed: "The class name corresponds to a file name ending in .php"

See issue #50
2018-02-02 13:22:58 +01:00
Christian Bläul
7a9d55dd1e Prepared new release in ChangeLog.txt 2018-02-02 12:27:12 +01:00
Christian Bläul
979e9ed0cd Moved ConditionsTest to properties subfolder 2018-02-02 12:26:06 +01:00
Christian Bläul
adcd258ea2 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-02 12:22:23 +01:00
Christian Bläul
34d28f7435 PHPUnit: Repaired file paths in autoQuotesDataProvider() 2018-02-02 12:10:25 +01:00
Christian Bläul
5cdec32466 Test some conditions 2018-02-02 11:14:41 +01:00
Christian Bläul
b9721a9aff Slightly improved PHPDoc comments 2018-02-02 11:13:49 +01:00
Christian Bläul
3c31b70724 Added accidentally removed regex modifier i 2018-02-02 11:13:49 +01:00
Christian Bläul
823f51c4f0 Added PHPUnit test to save without header 2018-02-02 11:13:49 +01:00
Christian Bläul
488b8f9d9b Prevent an "Uninitialized string offset" error
Got triggered by testMissingEndingLineBreak.
2018-02-02 11:13:49 +01:00
Christian Bläul
b004911218 $this->auto_non_chars didn't work the way I would have expected:
The "-" was taken literally, and thus 0 was forbidden, but 1 was allowed.

Fixes #55.
Also see #61
2018-02-02 11:13:49 +01:00
Christian Bläul
47f691ce33 Added new testSingleColumnWithZeros.
Proves that issue #61 is indeed fixed.
2018-02-02 11:13:49 +01:00
Christian Bläul
ab6b3d19e0 Added line to send people to the other examples within the repo. 2018-02-02 11:13:49 +01:00
Christian Bläul
2d7ab4b2f0 Added documentation to parse_string()
Fixes #76
2018-02-02 11:13:49 +01:00
Christian Bläul
2bf4a2d0cd Added reference to RFC 4180 to make the goal of this project a little clearer.
Fixes #64
2018-02-02 11:13:49 +01:00
Christian Bläul
f41a18b1c0 Added support for DOS double line endings
Fixed GitHub issue #75
2018-02-02 11:13:49 +01:00
Christian Bläul
003e98e8ff Added SaveTest for coverage of writing files 2018-02-02 11:13:49 +01:00
Christian Bläul
d8aefa792e Made PhpStorm inspections happy:
- avoid empty for-loop bodies as they are unusual and look a bit like
  forgotten implementations
- removed 'i' modifier from regular expressions that contain no letters
- replaced consecutive 'str_replace' calls by single 'strtr' call
- introduced new variable $is_newline to make the intend of a complex
  'if' more obvious and get rid of the operator precedence inspection
2018-02-02 11:13:49 +01:00
Christian Bläul
a92506d078 Prevent quoting of sinlge-column file. Needed because auto() with...
...single-column file will not set field delimiter. This commit is a bug fix.

For a test see testSaveWithDefaultSettings.
2018-02-02 11:13:49 +01:00
Christian Bläul
54e846ee30 Construct array key just once instead for better readability 2018-02-02 11:13:49 +01:00
Christian Bläul
63932f67a4 ParseTest: skip 'test_Piwik_data' in PHP 5.4 2018-02-02 11:13:49 +01:00
Christian Bläul
44ff705a23 Improved README.md: spelling, mention native PHP functions 2018-02-02 11:13:49 +01:00
Christian Bläul
6432ba2ced Added test for new field 'use_mb_convert_encoding' 2018-02-02 11:13:49 +01:00
Christian Bläul
8ae09c604b Added support for mb_convert_encoding() instead of iconv()
See issue #109 at GitHub
2018-02-02 11:13:49 +01:00
Christian Bläul
5ea1d95f31 Also run test files ending with Test.php (capital letter) 2018-02-02 11:13:49 +01:00
Christian Bläul
af549dc47e Updated .travis.yml to test with PHP 7.2 2018-02-02 11:13:49 +01:00
Christian Bläul
12aec86bf7 Merge branch 'alex-vlasov-single_quote_auto_detection'
See #74
2018-01-21 21:48:13 +01:00
Christian Bläul
38944ba221 Moved testAutoQuotes into existing test infrastructure 2018-01-21 21:47:28 +01:00
Alexander Vlasov
5a9a10aeed Incorrect parsing with single quote during auto-detection delimiter. 2018-01-21 21:43:42 +01:00
Christian Bläul
631fae5191 Improved PHPDoc of _check_count; Refactored vars in _guess_delimiter
This commit does not contain functional changes.
2018-01-21 01:15:56 +01:00
Christian Bläul
18ddde98c0 Comparison in _enclose_value: put least expensive condition first 2018-01-21 01:15:56 +01:00
Christian Bläul
a07de14bba Slightly more meaningful variable names in 'unparse' function 2018-01-21 01:15:56 +01:00
Christian Bläul
e87a5ae0e6 Improved source code formatting (no functional change) 2018-01-21 01:15:56 +01:00
Christian Bläul
c04fc89c43 Removed @access PHPDoc because it doesn't add value.
Today's phpDocumentor detects visiblity from the PHP keywords.
2018-01-21 01:15:56 +01:00
Christian Bläul
cc908fd096 _detect_and_remove_sep_row_from_data: improved comments to make it more ...
obvious that $data given is changed.
2018-01-21 01:15:56 +01:00
Christian Bläul
155c50ad7a Slightly improved code quality, no functionality changes
E.g.:
- Improved PHPDoc to reflect/include actual types
- Removed unnecessary brackets in ternary statements
- _check_count: Added return statement (code smell)
- added type-safe comparison where it doesn't change results
2018-01-21 01:15:56 +01:00
Christian Bläul
98edcbfec3 Ignore *.bak files that WinMerge leaves behind
I don't want to accidentally add them to the repo.
2018-01-21 01:15:56 +01:00
Christian Bläul
378353eb79 Added PHIVE files to .gitignore 2018-01-21 01:15:56 +01:00
Christian Bläul
e4ca0062f6 Added .idea folder to .gitignore; if you want my PHPStorm settings, go ...
...to GitHub issue #101: https://github.com/parsecsv/parsecsv-for-php/issues/101
2018-01-21 01:15:56 +01:00
Christian Bläul
e419663679 Improved name of files and classes within tests/methods folder
This follows PHP best practices for classes.
2018-01-21 01:15:56 +01:00
Christian Bläul
0ecaa80222 Added .editorconfig to tell others about spaces and tabs
Also:
- formated source code according to these rules;
- added spaces after commas in test code

See GitHub issue #101
2017-12-21 09:33:23 +01:00
Christian Bläul
0ac5064d58 Only call iconv if input and output encoding differ.
This saves some headache if characters are invalid according to iconv.
2017-12-21 09:33:23 +01:00
Christian Bläul
4d011827f5 When we find a BOM, we know the input encoding. Let's use it!
Also: UTF tests not failing anymore because we are specifying
the output encoding now.
2017-12-21 09:33:23 +01:00
Christian Bläul
c818fff81a Only improved spelling in source code comments 2017-12-21 09:33:23 +01:00
Matthew de Marillac
ccad5c8360 Remove BOM from UTF files.
Implementation similar to suggestion from, and thus closes #83
2017-12-21 09:33:23 +01:00
Christian Bläul
b082849b17 Added tests for files starting with a byte order mark (BOM) 2017-12-21 09:33:23 +01:00
Christian Bläul
7536d55f27 PHPUnit: Prevent 'Cannot redeclare class' error
The Travis environments of PHP 5.4 and 5.6 contained both the
namespaced and the global version of the TestCase class :-/
2017-12-06 02:25:54 +01:00
Christian Bläul
db1e242d07 PHPUnit: made compatible with v6, which is now namespaced. 2017-12-06 02:25:54 +01:00
Christian Bläul
fd5fb96bce PHPUnit: simplified Bootstrap.php without changing functionality.
Notes:
- Using / on Windows is safe.
- __DIR__ is identical to dirname(__FILE)
2017-12-06 02:25:54 +01:00
Christian Bläul
4f08cbb561 PHPUnit: added test for UTF-8 and sep= row
Thanks to https://github.com/blaubaer! Some things in the CSV file
originate from java-kata-1 by Gregor Noczinski
2017-12-06 02:25:54 +01:00
Christian Bläul
0d14ca01be Improved sep= detection and added it to auto() 2017-12-06 02:25:54 +01:00
Christian Bläul
a4a0dfa2fd Extracted the long detection algorithm from 'auto()' into new function.
Also removed unnecessary brackets () in ternary on the way.
2017-12-06 02:25:54 +01:00
Christian Bläul
95ad7c315a PHPUnit: told Travis to also run tests on PHP 7 2017-12-06 02:25:54 +01:00
Christian Bläul
0e50aec3b9 Renamed example file 'single_row', as it containes a single column. 2017-12-06 02:25:54 +01:00
Christian Bläul
f5851ba9ac Only improved comments in source code 2017-12-06 02:25:54 +01:00
Jan Piskvor Martinec
fad5ebcdc8 Added function to detect delimiter using sep= file header 2017-12-06 02:25:54 +01:00
Christian Bläul
bd2031582d Added 'single_row' test data for issue #99
Took example documented in #100. Thanks, @tunecino!
2017-11-16 15:29:17 +01:00
Christian Bläul
1db4b02e9e ChangeLog: corrected spelling mistake 2017-11-16 15:29:17 +01:00
Christian Bläul
07f2306a9c Travis configuration: removed hhvm and PHP 5.3
They seem unsupported by GitHub at this point.
2017-11-16 15:29:17 +01:00
Christian Bläul
7eb6daa6fb Added file parse_test.php to check for 'is_readable' warning
As documented in pull request #67
2017-11-16 15:29:17 +01:00
Christian Bläul
240fa0ce23 construct_test.php: only reformatted the code 2017-11-16 15:29:17 +01:00
Salem Ouerdani
1321c3b693 Should fix #99 (zeros breaking lines)
see https://github.com/parsecsv/parsecsv-for-php/issues/99
2017-11-03 21:35:58 +01:00
Christian Bläul
b9cf7cb0c1 Improved PHPDoc blocks
Added missing parameters, wrapped at 80 characters, added types.
2017-11-03 20:25:56 +01:00
Christian Bläul
4bae0d2bcf Re-added the code to grap object-level filename in output()
Follow-up on pull request #88: No breaking compatibality with
older parsecsv versions.

If no output to browser is desired, set $output_filename to null,
or use unparse() function.
2017-11-03 20:23:12 +01:00
Jan Piskvor Martinec
189746405f Do not force filename if not set explicitly
Per docblock, the function output() is supposed to output to browser
    only if filename is passed into it.
    If not, it should return the CSV as a string, not auto-set filename.
2017-11-03 11:30:55 -06:00
Fonata
2ae35c26ff Merge pull request #78 from lbajsarowicz/patch-1
Documentation: added example usage of fields variable
2017-11-03 11:13:47 -06:00
Fonata
2d1b7cebde Merge pull request #67 from BreyndotEchse/patch-1
Suppress file name too long warning
2017-11-02 15:09:33 -06:00
Lukasz Bajsarowicz
b33cc6c667 Example usage of field variable 2016-02-08 00:08:17 +01:00
Marvin Feldmann
fa5aea7631 Suppress file name too long warning
Suppress Warning: "File name is longer than the maximum allowed path length on this platform (4096)"
2015-09-14 17:15:10 +02:00
William Knauss
4f144f2662 Addresses #62 2015-07-11 13:15:34 -04:00
William Knauss
ba4c30add1 Addresses #51 2015-07-11 13:09:20 -04:00
a8b443d48c Merge pull request #57 from repat/patch-2
double array at save()
2015-05-05 11:33:53 +01:00
repat
9c6e0d64cf double array at save()
sic, see code example on line 68 https://github.com/parsecsv/parsecsv-for-php/blob/master/parsecsv.lib.php#L68
2015-05-05 10:42:12 +02:00
83ec2fbce7 Merge pull request #56 from repat/patch-1
typo
2015-05-04 20:52:36 +01:00
repat
e750fcfb07 typo 2015-05-04 18:57:32 +02:00
William Knauss
b7d1848363 Merge pull request #54 from williamknauss/53-flock-issue
Fixing flock issue
2015-03-25 22:23:31 -04:00
William Knauss
8bb51f8bab Fixing flock issue
Why not make life easier just use file put contents
2015-03-25 22:19:54 -04:00
William Knauss
22fcff2d24 Merge pull request #45 from helpse/patch-1
Added iconv() to output method
2014-12-03 12:41:03 -05:00
Sergio Melendez
5e8a5df988 Added iconv() to output method 2014-10-07 08:46:14 -05:00
813ef3849e Tweak indentation in Makefile to improved readability 2014-06-19 14:35:02 +01:00
d795ad0e05 Merge pull request #37 from commonquail/tabify-makefile
GNU Make requires tab-indentation
2014-06-19 14:33:01 +01:00
Mikkel Kjeldsen
ac4c4699cb GNU Make requires tab-indentation
GNU Make does not play nicely with leading spaces after rules. It
requires that the first line starts with a tab. Although it isn't
strictly necessary to change subsequent lines as well, mixing tabs and
spaces is a nightmare.
2014-06-19 14:36:50 +02:00
e0728a3941 Merge pull request #33 from williamknauss/code-cleanup2
Code cleanup2
2014-06-06 09:35:40 +01:00
William Knauss
2f3732e350 _wfile 2014-06-05 20:53:19 -04:00
William Knauss
01e71adf36 _rfile 2014-06-05 20:52:43 -04:00
William Knauss
0c4a804db1 _check_count 2014-06-05 20:52:23 -04:00
William Knauss
4366201dc0 _check_data 2014-06-05 20:51:26 -04:00
William Knauss
0422d5d9fe _enclose_value 2014-06-05 20:50:48 -04:00
William Knauss
6f4d150e6f _validate_offset 2014-06-05 20:50:08 -04:00
William Knauss
494087ab1d _validate_row_condition 2014-06-05 20:49:49 -04:00
William Knauss
ce19deec4e _validate_row_conditions 2014-06-05 20:48:11 -04:00
William Knauss
33825514d9 load_data 2014-06-05 20:46:29 -04:00
William Knauss
8af4d1e513 unparse 2014-06-05 20:45:28 -04:00
William Knauss
4d07760933 parse_string 2014-06-05 20:44:14 -04:00
William Knauss
710f22eeb9 parse_file 2014-06-05 20:40:00 -04:00
William Knauss
604872faad auto 2014-06-05 20:39:21 -04:00
William Knauss
8e19ecf94f encoding 2014-06-05 20:37:02 -04:00
William Knauss
31417caafd output 2014-06-05 20:36:32 -04:00
William Knauss
17e060ea33 save 2014-06-05 20:35:40 -04:00
William Knauss
936b6f4a50 parse 2014-06-05 20:34:08 -04:00
William Knauss
65061046bd __construct 2014-06-05 20:32:55 -04:00
William Knauss
4393781abc Merge pull request #8 from parsecsv/master
U2D
2014-06-05 20:29:02 -04:00
William Knauss
8bbd474e66 Merge pull request #32 from williamknauss/proper-access
Proper access
2014-06-05 20:22:09 -04:00
William Knauss
734b35abc5 made _validate_row_conditions protected 2014-06-05 20:18:17 -04:00
William Knauss
5cb602be2d made _validate_row_condition protected 2014-06-05 20:17:58 -04:00
William Knauss
b8920f99cb made _validate_offset protected 2014-06-05 20:17:29 -04:00
William Knauss
b8248af92e made _enclose_value protected 2014-06-05 20:17:08 -04:00
William Knauss
d1f25ee3df made _check_data protected 2014-06-05 20:16:45 -04:00
William Knauss
0d5ae35a34 made _check_count protected 2014-06-05 20:15:20 -04:00
William Knauss
e1c8cae852 made _rfile protected 2014-06-05 20:14:50 -04:00
William Knauss
844a1520f3 made _wfile proctected 2014-06-05 20:14:16 -04:00
William Knauss
81746a561f Merge pull request #31 from williamknauss/issue-27
fix for issue #27
2014-06-05 17:10:17 -04:00
William Knauss
1524618293 Fix for #27 2014-06-05 17:03:26 -04:00
William Knauss
e98cef4846 Merge pull request #7 from parsecsv/master
U2D
2014-06-05 16:55:43 -04:00
William Knauss
4ed88da7a2 Merge pull request #30 from williamknauss/start-testing
Start testing
2014-06-05 16:55:17 -04:00
William Knauss
18a6479aec EOF updates 2014-06-05 16:42:52 -04:00
William Knauss
1c4bcaffa6 bootstrap update 2014-06-05 16:37:32 -04:00
William Knauss
7527267c68 travis updates 2014-06-05 16:35:00 -04:00
William Knauss
b074f83644 travis updates 2014-06-05 15:56:08 -04:00
William Knauss
7b83653ee2 added travis.yml 2014-06-05 15:49:46 -04:00
William Knauss
0ed23e7b84 Makefile 2014-06-05 15:32:25 -04:00
William Knauss
4a76ed9ca9 EOF and report cleanup 2014-06-05 12:08:17 -04:00
William Knauss
68eab2de59 construct 2014-06-05 12:04:39 -04:00
William Knauss
32b50efe82 Merge branch 'master' of https://github.com/williamknauss/php-parsecsv into start-testing 2014-06-05 12:02:11 -04:00
William Knauss
372c43fba4 Merge pull request #6 from parsecsv/master
U2D
2014-06-05 12:00:02 -04:00
William Knauss
7d63a8c894 Merge pull request #29 from williamknauss/keep_file_data_construct_param
Keep file data construct param
2014-06-05 11:59:33 -04:00
William Knauss
7187bbd68f construct param 2014-06-05 11:56:50 -04:00
William Knauss
ee784f3180 Merge branch 'master' of https://github.com/williamknauss/php-parsecsv into start-testing 2014-06-05 11:44:10 -04:00
William Knauss
633666060b Merge pull request #5 from parsecsv/master
U2D
2014-06-05 11:43:33 -04:00
William Knauss
8a5f15bdd8 Merge pull request #26 from parsecsv/fix-end-of-data-issue
Fix last line parsing issue
2014-06-05 11:40:23 -04:00
William Knauss
a6f8c708f9 1 2014-06-05 01:51:46 -04:00
cff692d976 Fix issue when CSV data does not end with a newline
If CSV data didn't end with "\n", "\r", or "\r\n" the last line of the
CSV would be ignored, as the parser wouldn't trigger end of row logic
for the last row.

This change forces the parser to process the end of the CSV data as it's
own character (false), and deals with end of data just like it treats
end of row.
2014-06-05 01:56:14 +01:00
William Knauss
c3c13258f3 Merge pull request #4 from parsecsv/master
U2D
2014-06-04 14:38:48 -04:00
9cf0ba9f97 Merge pull request #23 from williamknauss/readme-update
Readme update
2014-06-04 18:56:01 +01:00
William Knauss
18eb8a8f11 Updated readme with installation instructions 2014-06-04 13:52:13 -04:00
William Knauss
44a5507e10 Updated Composer 2014-06-04 13:48:14 -04:00
William Knauss
3ffcd731ee Merge pull request #3 from parsecsv/master
UPD
2014-06-04 03:44:53 -04:00
William Knauss
3545dbeb00 Merge pull request #20 from Norcoen/master
Force enclosing of all columns with optional switch
2014-06-03 14:09:46 -04:00
Norcoen
0235c24b36 Pass delimiter from unparse function to _enclose_value function, revert
changes from previous approach
2014-06-03 15:52:36 +02:00
Norcoen
33b1a0d196 Fix local/global delimiter bug between output() and _enclose_value() by
setting global delimiter to local if not null
2014-06-03 15:02:49 +02:00
Norcoen
f3c70ad17c Fix local/global delimiter bug between output() and _enclose_value() by
setting global delimiter to local if not null
2014-06-03 15:01:04 +02:00
Norcoen
98a146bd38 Force enclosing of all columns with optional switch 2014-06-03 14:45:07 +02:00
William Knauss
0486a4bf3e Merge pull request #18 from parsecsv/williamknauss-new-issue-14
williamknauss new issue 14
2014-06-02 20:37:04 -04:00
William Knauss
90042a553c ugh 2014-06-02 20:35:20 -04:00
William Knauss
73d7acb493 fix conflicts 2014-06-02 20:34:08 -04:00
William Knauss
2ed5801b33 Merge branch 'williamknauss-new-issue-14' 2014-06-02 20:30:38 -04:00
William Knauss
7b6692d7fd @norcoen caching request 2014-06-02 20:13:31 -04:00
William Knauss
01d25e0fdd Tabs to spaces 2014-06-02 20:09:20 -04:00
William Knauss
c64a4bffd7 Merge pull request #12 from williamknauss/tab_to_spaces
Fix #11
2014-05-17 12:51:24 -04:00
William Knauss
2d7f18ebc9 converted tabs to spaces 2014-05-17 12:47:45 -04:00
William Knauss
ee5b34e1c1 Merge branch 'master' of https://github.com/parsecsv/parsecsv-for-php 2014-05-17 12:43:00 -04:00
William Knauss
44929708ca Merge pull request #10 from parsecsv/fix-author-name-spelling
Fix typo in author name
2014-05-17 12:41:36 -04:00
c55ab2ec2c Fix typo in author's last name 2014-05-17 10:50:01 +01:00
William Knauss
6784c614ea Merge pull request #2 from parsecsv/master
Fork Update
2014-05-16 19:49:55 -04:00
William Knauss
5a70a7bffa Merge pull request #9 from williamknauss/composer-support
Composer support
2014-05-16 19:37:46 -04:00
William Knauss
c1a6946815 added gitignore 2014-05-16 19:33:15 -04:00
William Knauss
dbf415bd92 Added Composer.json 2014-05-16 19:30:59 -04:00
William Knauss
c915579955 Merge pull request #8 from williamknauss/readme_update-1
Readme update
2014-05-16 17:36:59 -04:00
William Knauss
55aaa1eb17 Grammer Fix 2014-05-16 17:36:14 -04:00
William Knauss
ab069e5d2d Updated readme 2014-05-16 17:35:08 -04:00
William Knauss
7e7aeba761 Merge pull request #6 from williamknauss/issue-5
Issue 5
2014-05-14 10:29:48 -04:00
William Knauss
a3e3582222 Patch for #5 2014-05-14 10:26:32 -04:00
William Knauss
fff3e73f08 Merge pull request #1 from parsecsv/master
U2D
2014-05-14 10:20:18 -04:00
f59af53183 Add contributors section to readme 2014-05-14 14:50:10 +01:00
629b0c9fd5 Indent header comment start/end strings 2014-05-14 10:18:02 +01:00
698a570a11 Add license header 2014-05-14 10:12:45 +01:00
2aca09e05d Add URL to PHP class which inspired parseCSV's creation 2014-05-14 09:26:21 +01:00
7a9fc101f8 Update copyright year in readme and license file 2014-05-14 09:24:27 +01:00
a1564a9a99 Correct project URL, and update copyright 2014-05-14 09:19:42 +01:00
4b280885f4 Merge pull request #1 from williamknauss/master
Basic Cleanup
2014-05-14 09:14:26 +01:00
William Knauss
88ad81f061 removed end of php line
its not really needed
2014-05-13 21:26:06 -04:00
William Knauss
7e46cc193a line feed should only be \r 2014-05-13 21:23:53 -04:00
William Knauss
a274874084 documenation changes 2014-05-13 21:23:23 -04:00
William Knauss
dea1b453eb _validate_row_conditions readability 2014-05-13 21:21:58 -04:00
William Knauss
9a8bd77eb8 forgot access flag 2014-05-13 21:21:04 -04:00
William Knauss
89a2817765 _validate_row_condition readability 2014-05-13 21:19:44 -04:00
William Knauss
75d7d51a9c _validate_offset readability 2014-05-13 21:05:53 -04:00
William Knauss
9b6dbd9849 _enclose_value readability 2014-05-13 21:05:11 -04:00
William Knauss
61d1c27eac _check_data readability 2014-05-13 21:04:25 -04:00
William Knauss
ecbb0736f1 more changes 2014-05-13 18:56:26 -04:00
William Knauss
2ab7625bb5 _rfile readability 2014-05-13 18:24:31 -04:00
William Knauss
0f39cfa75a _wfile readability 2014-05-13 18:23:27 -04:00
William Knauss
0457fbfba2 removed back comments 2014-05-13 18:22:18 -04:00
William Knauss
af5d7cf70d load_data readability 2014-05-09 21:57:17 -04:00
William Knauss
531cc66a5e unparse readability 2014-05-09 21:55:54 -04:00
William Knauss
178699580e unparse readability 2014-05-09 21:55:36 -04:00
William Knauss
8c300568bb parse_string readability 2014-05-09 21:54:09 -04:00
William Knauss
28967dea20 extra space 2014-05-09 21:46:11 -04:00
William Knauss
46b42776e4 Properties documentation 2014-05-09 21:45:03 -04:00
William Knauss
8ba88c582d removed documentation whitespace 2014-05-09 21:31:22 -04:00
William Knauss
ba1d462044 updated properties to "public"
removed "var" and set to "public"
2014-05-09 21:30:47 -04:00
William Knauss
0323d5108b parse_file documentation 2014-02-06 18:31:34 -05:00
William Knauss
2988278f0b parse_file readability 2014-02-06 18:30:43 -05:00
William Knauss
9301b016c8 auto documentation 2014-02-06 18:30:11 -05:00
William Knauss
75038f9d2f auto readability 2014-02-06 18:27:54 -05:00
William Knauss
b72385395e condition spacing 2014-02-06 08:17:00 -05:00
William Knauss
eb3c9faa4a construct docblock spacing 2014-02-05 19:16:51 -05:00
William Knauss
2f142e7313 public encoding 2014-02-05 19:16:35 -05:00
William Knauss
05dbcaf652 encoding update 2014-02-05 19:14:00 -05:00
William Knauss
4639fa1701 Output documentation 2014-02-05 19:12:16 -05:00
William Knauss
8bb8e2d7cf output readability 2014-02-05 19:09:57 -05:00
William Knauss
c7e1f825a0 save documentation 2014-02-05 18:41:21 -05:00
William Knauss
0638049fb2 save readability 2014-02-05 18:38:55 -05:00
William Knauss
585a0d472e parse documentation 2014-02-05 18:37:23 -05:00
William Knauss
d6a070ce08 Change __constructor docblock stype 2014-02-05 18:33:44 -05:00
William Knauss
4454196b4c parse readability 2014-02-05 18:31:27 -05:00
William Knauss
6a6754ca04 __construct documentation 2014-02-05 18:29:01 -05:00
William Knauss
8dd2e52073 __construct readability 2014-02-05 18:25:13 -05:00
William Knauss
e16d818d07 cleaned up construct 2014-02-05 18:24:41 -05:00
William Knauss
9e6fdbb42a Updated project link 2014-02-05 18:22:20 -05:00
85ca7af160 Update License.txt file 2014-02-05 21:18:07 +00:00
1b91591d32 Add readme 2014-02-05 21:16:50 +00:00
zynode
dfe298f4d0 Fixed a typo in the header comment regarding example code.
git-svn-id: http://parsecsv-for-php.googlecode.com/svn/trunk@44 339761fc-0c37-0410-822d-8b8cac1f6a97
2008-11-17 15:48:46 +00:00
32 changed files with 2348 additions and 843 deletions

15
.editorconfig Normal file
View File

@@ -0,0 +1,15 @@
# @see http://editorconfig.org/
# This is the top-most .editorconfig file; do not search in parent directories.
root = true
# All files.
[*]
indent_style = space
indent_size = 4
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
[composer.json]
indent_size = 4

6
.gitignore vendored Normal file
View File

@@ -0,0 +1,6 @@
*.bak
/.idea
/phive.xml
/tools
composer.lock
vendor/

18
.travis.yml Normal file
View File

@@ -0,0 +1,18 @@
language: php
php:
- 7.2
- 7.1
- 7.0
- 5.6
- 5.5
- 5.4
script:
- phpunit --configuration tests/phpunit.xml
notifications:
email:
- will.knauss@gmail.com
on_success: never
on_failure: always

View File

@@ -1,3 +1,23 @@
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
@@ -10,7 +30,7 @@ Date: 1-July-2008
- 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 mulitple
minimum. Specifically handy when using multiple
instances of parseCSV to process large files.
-----------------------------------
@@ -159,7 +179,7 @@ Date: 2-Jan-2007
- Added auto() function to automatically detect
delimiter character.
Useful for user upload incase delimiter is
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
@@ -170,7 +190,7 @@ Date: 2-Jan-2007
almost no matter what the delimiter is.
- Generally updated some of the core workings
to increase performance, and offer better
to increase performance, and offer better
support for large (1MB and up) files.
- Added code examples to header comment.

View File

@@ -1,4 +1,6 @@
Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
(The MIT license)
Copyright (c) 2014 Jim Myhrberg.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
@@ -7,13 +9,13 @@ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.

15
Makefile Normal file
View File

@@ -0,0 +1,15 @@
COMPOSER_BIN_DIR := vendor/bin
PHPUNIT_ARGS = -c tests/phpunit.xml
test: phpunit-dep
${COMPOSER_BIN_DIR}/phpunit ${PHPUNIT_ARGS}
phpunit-dep:
test -f ${COMPOSER_BIN_DIR}/phpunit || ( \
echo "phpunit is required to run tests." \
"Please run: composer install" >&2 && \
exit 1 \
)
.SILENT:
.PHONY: test phpunit-dep

1244
ParseCsvForPhp.php Normal file

File diff suppressed because it is too large Load Diff

147
README.md Normal file
View File

@@ -0,0 +1,147 @@
# ParseCsvForPhp
This 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.
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
* Supports enclosed values, enclosed commas, double quotes and new lines.
* Automatic delimiter character detection.
* Sort data by specific fields/columns.
* Easy data manipulation.
* Basic SQL-like _conditions_, _offset_ and _limit_ options for filtering
data.
* 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.
It certainly works with PHP 7.2 and all versions in between.
## Example Usage
**General**
```php
$csv = new ParseCsvForPhp('data.csv');
print_r($csv->data);
```
**Tab delimited, and encoding conversion**
```php
$csv = new ParseCsvForPhp();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
print_r($csv->data);
```
**Auto-detect delimiter character**
```php
$csv = new ParseCsvForPhp();
$csv->auto('data.csv');
print_r($csv->data);
```
**Modify data in a CSV file**
```php
$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();
```
**Replace field names or set ones if missing**
```php
$csv = new ParseCsvForPhp();
$csv->fields = ['id', 'name', 'category']
$csv->parse('data.csv');
```
**Add row/entry to end of CSV file**
_Only recommended when you know the exact structure of the file._
```php
$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**
```php
$csv = new ParseCsvForPhp();
$csv->output('movies.csv', $array, array('field 1', 'field 2'), ',');
```
For more complex examples, see the ``tests`` and `examples` directories.
## Credits
* ParseCsvForPhp is based on the concept of [Ming Hong Ng][ming]'s [CsvFileParser][]
class.
[ming]: http://minghong.blogspot.com/
[CsvFileParser]: http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
## Contributors
Please find a complete list on the project's [contributors][] page.
[contributors]: https://github.com/parsecsv/parsecsv-for-php/graphs/contributors
## License
(The MIT license)
Copyright (c) 2014 Jim Myhrberg.
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.

23
composer.json Normal file
View File

@@ -0,0 +1,23 @@
{
"name": "parsecsv/php-parsecsv",
"description": "CSV data parser for PHP",
"license": "MIT",
"authors": [
{
"name": "Jim Myhrberg",
"email": "contact@jimeh.me"
},
{
"name": "William Knauss",
"email": "will.knauss@gmail.com"
}
],
"autoload": {
"classmap": [
"."
]
},
"require-dev": {
"phpunit/phpunit": "4.1.*"
}
}

View File

@@ -2,12 +2,12 @@
<?php
# include parseCSV class.
require_once('../parsecsv.lib.php');
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new parseCSV();
# create new object.
$csv = new ParseCsvForPhp();
# Parse '_books.csv' using automatic delimiter detection...
@@ -28,21 +28,29 @@ $csv->auto('_books.csv');
?>
</pre>
<style type="text/css" media="screen">
table { background-color: #BBB; }
th { background-color: #EEE; }
td { background-color: #FFF; }
table {
background-color: #BBB;
}
th {
background-color: #EEE;
}
td {
background-color: #FFF;
}
</style>
<table border="0" cellspacing="1" cellpadding="3">
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>

View File

@@ -2,12 +2,12 @@
<?php
# include parseCSV class.
require_once('../parsecsv.lib.php');
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new parseCSV();
# create new object.
$csv = new ParseCsvForPhp();
# Example conditions:
@@ -28,21 +28,29 @@ $csv->auto('_books.csv');
?>
</pre>
<style type="text/css" media="screen">
table { background-color: #BBB; }
th { background-color: #EEE; }
td { background-color: #FFF; }
table {
background-color: #BBB;
}
th {
background-color: #EEE;
}
td {
background-color: #FFF;
}
</style>
<table border="0" cellspacing="1" cellpadding="3">
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>

View File

@@ -1,12 +1,12 @@
<?php
# include parseCSV class.
require_once('../parsecsv.lib.php');
# include ParseCsvForPhp class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new parseCSV();
# create new object.
$csv = new ParseCsvForPhp();
# Parse '_books.csv' using automatic delimiter detection...
@@ -31,4 +31,4 @@ $csv->output('books.csv');
# or is set to null, output will only return the generated CSV
# output data, and will not output to the browser itself.
?>
?>

View File

@@ -2,12 +2,12 @@
<?php
# include parseCSV class.
require_once('../parsecsv.lib.php');
# include class.
require_once('../ParseCsvForPhp.php');
# create new parseCSV object.
$csv = new parseCSV();
# create new object.
$csv = new ParseCsvForPhp();
# if sorting is enabled, the whole CSV file
@@ -41,21 +41,29 @@ $csv->auto('_books.csv');
?>
</pre>
<style type="text/css" media="screen">
table { background-color: #BBB; }
th { background-color: #EEE; }
td { background-color: #FFF; }
table {
background-color: #BBB;
}
th {
background-color: #EEE;
}
td {
background-color: #FFF;
}
</style>
<table border="0" cellspacing="1" cellpadding="3">
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>
<tr>
<?php foreach ($csv->titles as $value): ?>
<th><?php echo $value; ?></th>
<?php endforeach; ?>
</tr>
<?php foreach ($csv->data as $key => $row): ?>
<tr>
<?php foreach ($row as $value): ?>
<td><?php echo $value; ?></td>
<?php endforeach; ?>
</tr>
<?php endforeach; ?>
</table>

View File

@@ -1,771 +0,0 @@
<?php
class parseCSV {
/*
Class: parseCSV v0.4.3 beta
http://code.google.com/p/parsecsv-for-php/
Fully conforms to the specifications lined out on wikipedia:
- http://en.wikipedia.org/wiki/Comma-separated_values
Based on the concept of Ming Hong Ng's CsvFileParser class:
- http://minghong.blogspot.com/2006/07/csv-parser-for-php.html
Copyright (c) 2007 Jim Myhrberg (jim@zydev.info).
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
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.
Code Examples
----------------
# general usage
$csv = new parseCSV('data.csv');
print_r($csv->data);
----------------
# tab delimited, and encoding conversion
$csv = new parseCSV();
$csv->encoding('UTF-16', 'UTF-8');
$csv->delimiter = "\t";
$csv->parse('data.tsv');
print_r($csv->data);
----------------
# auto-detect delimiter character
$csv = new parseCSV();
$csv->auto('data.csv');
print_r($csv->data);
----------------
# modify data in a csv file
$csv = new parseCSV();
$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 extact sctructure of the file
$csv = new parseCSV();
$csv->save('data.csv', 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 parseCSV();
$csv->output (true, 'movies.csv', $array);
----------------
*/
/**
* Configuration
* - set these options with $object->var_name = 'value';
*/
# use first line/entry as field names
var $heading = true;
# override field names
var $fields = array();
# sort entries by this field
var $sort_by = null;
var $sort_reverse = false;
# sort behavior passed to ksort/krsort functions
# regular = SORT_REGULAR
# numeric = SORT_NUMERIC
# string = SORT_STRING
var $sort_type = null;
# delimiter (comma) and enclosure (double quote)
var $delimiter = ',';
var $enclosure = '"';
# basic SQL-like conditions for row matching
var $conditions = null;
# number of rows to ignore from beginning of data
var $offset = null;
# limits the number of returned rows to specified amount
var $limit = null;
# number of rows to analyze when attempting to auto-detect delimiter
var $auto_depth = 15;
# characters to ignore when attempting to auto-detect delimiter
var $auto_non_chars = "a-zA-Z0-9\n\r";
# preferred delimiter characters, only used when all filtering method
# returns multiple possible delimiters (happens very rarely)
var $auto_preferred = ",;\t.:|";
# character encoding options
var $convert_encoding = false;
var $input_encoding = 'ISO-8859-1';
var $output_encoding = 'ISO-8859-1';
# used by unparse(), save(), and output() functions
var $linefeed = "\r\n";
# only used by output() function
var $output_delimiter = ',';
var $output_filename = 'data.csv';
# keep raw file data in memory after successful parsing (useful for debugging)
var $keep_file_data = false;
/**
* Internal variables
*/
# current file
var $file;
# loaded file contents
var $file_data;
# error while parsing input data
# 0 = No errors found. Everything should be fine :)
# 1 = Hopefully correctable syntax error was found.
# 2 = Enclosure character (double quote by default)
# was found in non-enclosed field. This means
# the file is either corrupt, or does not
# standard CSV formatting. Please validate
# the parsed data yourself.
var $error = 0;
# detailed error info
var $error_info = array();
# array of field values in data parsed
var $titles = array();
# two dimentional array of CSV data
var $data = array();
/**
* Constructor
* @param input CSV file or string
* @return nothing
*/
function parseCSV ($input = null, $offset = null, $limit = null, $conditions = null) {
if ( $offset !== null ) $this->offset = $offset;
if ( $limit !== null ) $this->limit = $limit;
if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( !empty($input) ) $this->parse($input);
}
// ==============================================
// ----- [ Main Functions ] ---------------------
// ==============================================
/**
* Parse CSV file or string
* @param input CSV file or string
* @return nothing
*/
function parse ($input = null, $offset = null, $limit = null, $conditions = null) {
if ( $input === null ) $input = $this->file;
if ( !empty($input) ) {
if ( $offset !== null ) $this->offset = $offset;
if ( $limit !== null ) $this->limit = $limit;
if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( 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;
}
return true;
}
/**
* Save changes, or new file and/or data
* @param file file to save to
* @param data 2D array with data
* @param append append current data to end of target CSV if exists
* @param fields field names
* @return true or false
*/
function save ($file = null, $data = array(), $append = false, $fields = array()) {
if ( empty($file) ) $file = &$this->file;
$mode = ( $append ) ? 'at' : 'wt' ;
$is_php = ( preg_match('/\.php$/i', $file) ) ? true : false ;
return $this->_wfile($file, $this->unparse($data, $fields, $append, $is_php), $mode);
}
/**
* Generate CSV based string for output
* @param filename if specified, headers and data will be output directly to browser as a downloable file
* @param data 2D array with data
* @param fields field names
* @param delimiter delimiter used to separate data
* @return CSV data using delimiter of choice, or default
*/
function output ($filename = null, $data = array(), $fields = array(), $delimiter = null) {
if ( empty($filename) ) $filename = $this->output_filename;
if ( $delimiter === null ) $delimiter = $this->output_delimiter;
$data = $this->unparse($data, $fields, null, null, $delimiter);
if ( $filename !== null ) {
header('Content-type: application/csv');
header('Content-Disposition: attachment; filename="'.$filename.'"');
echo $data;
}
return $data;
}
/**
* Convert character encoding
* @param input input character encoding, uses default if left blank
* @param output output character encoding, uses default if left blank
* @return nothing
*/
function encoding ($input = null, $output = null) {
$this->convert_encoding = true;
if ( $input !== null ) $this->input_encoding = $input;
if ( $output !== null ) $this->output_encoding = $output;
}
/**
* Auto-Detect Delimiter: Find delimiter by analyzing a specific number of
* rows to determine most probable delimiter character
* @param file local CSV file
* @param parse true/false parse file directly
* @param search_depth number of rows to analyze
* @param preferred preferred delimiter characters
* @param enclosure enclosure character, default is double quote (").
* @return delimiter character
*/
function auto ($file = null, $parse = true, $search_depth = null, $preferred = null, $enclosure = null) {
if ( $file === null ) $file = $this->file;
if ( empty($search_depth) ) $search_depth = $this->auto_depth;
if ( $enclosure === null ) $enclosure = $this->enclosure;
if ( $preferred === null ) $preferred = $this->auto_preferred;
if ( empty($this->file_data) ) {
if ( $this->_check_data($file) ) {
$data = &$this->file_data;
} else return false;
} else {
$data = &$this->file_data;
}
$chars = array();
$strlen = strlen($data);
$enclosed = false;
$n = 1;
$to_end = true;
// walk specific depth finding posssible delimiter characters
for ( $i=0; $i < $strlen; $i++ ) {
$ch = $data{$i};
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
// open and closing quotes
if ( $ch == $enclosure ) {
if ( !$enclosed || $nch != $enclosure ) {
$enclosed = ( $enclosed ) ? false : true ;
} elseif ( $enclosed ) {
$i++;
}
// end of row
} elseif ( ($ch == "\n" && $pch != "\r" || $ch == "\r") && !$enclosed ) {
if ( $n >= $search_depth ) {
$strlen = 0;
$to_end = false;
} else {
$n++;
}
// count character
} elseif (!$enclosed) {
if ( !preg_match('/['.preg_quote($this->auto_non_chars, '/').']/i', $ch) ) {
if ( !isset($chars[$ch][$n]) ) {
$chars[$ch][$n] = 1;
} else {
$chars[$ch][$n]++;
}
}
}
}
// filtering
$depth = ( $to_end ) ? $n-1 : $n ;
$filtered = array();
foreach( $chars as $char => $value ) {
if ( $match = $this->_check_count($char, $value, $depth, $preferred) ) {
$filtered[$match] = $char;
}
}
// capture most probable delimiter
ksort($filtered);
$this->delimiter = reset($filtered);
// parse data
if ( $parse ) $this->data = $this->parse_string();
return $this->delimiter;
}
// ==============================================
// ----- [ Core Functions ] ---------------------
// ==============================================
/**
* Read file to string and call parse_string()
* @param file local CSV file
* @return 2D array with CSV data, or false on failure
*/
function parse_file ($file = null) {
if ( $file === null ) $file = $this->file;
if ( empty($this->file_data) ) $this->load_data($file);
return ( !empty($this->file_data) ) ? $this->parse_string() : false ;
}
/**
* Parse CSV strings to arrays
* @param data CSV string
* @return 2D array with CSV data, or false on failure
*/
function parse_string ($data = null) {
if ( empty($data) ) {
if ( $this->_check_data() ) {
$data = &$this->file_data;
} else return false;
}
$white_spaces = str_replace($this->delimiter, '', " \t\x0B\0");
$rows = array();
$row = array();
$row_count = 0;
$current = '';
$head = ( !empty($this->fields) ) ? $this->fields : array() ;
$col = 0;
$enclosed = false;
$was_enclosed = false;
$strlen = strlen($data);
// walk through each character
for ( $i=0; $i < $strlen; $i++ ) {
$ch = $data{$i};
$nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
$pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
// open/close quotes, and inline quotes
if ( $ch == $this->enclosure ) {
if ( !$enclosed ) {
if ( ltrim($current, $white_spaces) == '' ) {
$enclosed = true;
$was_enclosed = true;
} else {
$this->error = 2;
$error_row = count($rows) + 1;
$error_col = $col + 1;
if ( !isset($this->error_info[$error_row.'-'.$error_col]) ) {
$this->error_info[$error_row.'-'.$error_col] = array(
'type' => 2,
'info' => 'Syntax error found on row '.$error_row.'. Non-enclosed fields can not contain double-quotes.',
'row' => $error_row,
'field' => $error_col,
'field_name' => (!empty($head[$col])) ? $head[$col] : null,
);
}
$current .= $ch;
}
} elseif ($nch == $this->enclosure) {
$current .= $ch;
$i++;
} elseif ( $nch != $this->delimiter && $nch != "\r" && $nch != "\n" ) {
for ( $x=($i+1); isset($data{$x}) && ltrim($data{$x}, $white_spaces) == ''; $x++ ) {}
if ( $data{$x} == $this->delimiter ) {
$enclosed = false;
$i = $x;
} else {
if ( $this->error < 1 ) {
$this->error = 1;
}
$error_row = count($rows) + 1;
$error_col = $col + 1;
if ( !isset($this->error_info[$error_row.'-'.$error_col]) ) {
$this->error_info[$error_row.'-'.$error_col] = array(
'type' => 1,
'info' =>
'Syntax error found on row '.(count($rows) + 1).'. '.
'A single double-quote was found within an enclosed string. '.
'Enclosed double-quotes must be escaped with a second double-quote.',
'row' => count($rows) + 1,
'field' => $col + 1,
'field_name' => (!empty($head[$col])) ? $head[$col] : null,
);
}
$current .= $ch;
$enclosed = false;
}
} else {
$enclosed = false;
}
// end of field/row
} elseif ( ($ch == $this->delimiter || $ch == "\n" || $ch == "\r") && !$enclosed ) {
$key = ( !empty($head[$col]) ) ? $head[$col] : $col ;
$row[$key] = ( $was_enclosed ) ? $current : trim($current) ;
$current = '';
$was_enclosed = false;
$col++;
// end of row
if ( $ch == "\n" || $ch == "\r" ) {
if ( $this->_validate_offset($row_count) && $this->_validate_row_conditions($row, $this->conditions) ) {
if ( $this->heading && empty($head) ) {
$head = $row;
} elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
if ( isset($rows[$row[$this->sort_by]]) ) {
$rows[$row[$this->sort_by].'_0'] = &$rows[$row[$this->sort_by]];
unset($rows[$row[$this->sort_by]]);
for ( $sn=1; isset($rows[$row[$this->sort_by].'_'.$sn]); $sn++ ) {}
$rows[$row[$this->sort_by].'_'.$sn] = $row;
} else $rows[$row[$this->sort_by]] = $row;
} else $rows[] = $row;
}
}
$row = array();
$col = 0;
$row_count++;
if ( $this->sort_by === null && $this->limit !== null && count($rows) == $this->limit ) {
$i = $strlen;
}
if ( $ch == "\r" && $nch == "\n" ) $i++;
}
// append character to current field
} else {
$current .= $ch;
}
}
$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;
}
( $this->sort_reverse ) ? krsort($rows, $sort_type) : ksort($rows, $sort_type) ;
if ( $this->offset !== null || $this->limit !== null ) {
$rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset) , $this->limit, true);
}
}
if ( !$this->keep_file_data ) {
$this->file_data = null;
}
return $rows;
}
/**
* Create CSV data from array
* @param data 2D array with data
* @param fields field names
* @param append if true, field names will not be output
* @param is_php if a php die() call should be put on the first
* line of the file, this is later ignored when read.
* @param delimiter field delimiter to use
* @return CSV data (text string)
*/
function unparse ( $data = array(), $fields = array(), $append = false , $is_php = false, $delimiter = null) {
if ( !is_array($data) || empty($data) ) $data = &$this->data;
if ( !is_array($fields) || empty($fields) ) $fields = &$this->titles;
if ( $delimiter === null ) $delimiter = $this->delimiter;
$string = ( $is_php ) ? "<?php header('Status: 403'); die(' '); ?>".$this->linefeed : '' ;
$entry = array();
// create heading
if ( $this->heading && !$append && !empty($fields) ) {
foreach( $fields as $key => $value ) {
$entry[] = $this->_enclose_value($value);
}
$string .= implode($delimiter, $entry).$this->linefeed;
$entry = array();
}
// create data
foreach( $data as $key => $row ) {
foreach( $row as $field => $value ) {
$entry[] = $this->_enclose_value($value);
}
$string .= implode($delimiter, $entry).$this->linefeed;
$entry = array();
}
return $string;
}
/**
* Load local file or string
* @param input local CSV file
* @return true or false
*/
function load_data ($input = null) {
$data = null;
$file = null;
if ( $input === null ) {
$file = $this->file;
} elseif ( file_exists($input) ) {
$file = $input;
} else {
$data = $input;
}
if ( !empty($data) || $data = $this->_rfile($file) ) {
if ( $this->file != $file ) $this->file = $file;
if ( preg_match('/\.php$/i', $file) && preg_match('/<\?.*?\?>(.*)/ims', $data, $strip) ) {
$data = ltrim($strip[1]);
}
if ( $this->convert_encoding ) $data = iconv($this->input_encoding, $this->output_encoding, $data);
if ( substr($data, -1) != "\n" ) $data .= "\n";
$this->file_data = &$data;
return true;
}
return false;
}
// ==============================================
// ----- [ Internal Functions ] -----------------
// ==============================================
/**
* Validate a row against specified conditions
* @param row array with values from a row
* @param conditions specified conditions that the row must match
* @return true of false
*/
function _validate_row_conditions ($row = array(), $conditions = null) {
if ( !empty($row) ) {
if ( !empty($conditions) ) {
$conditions = (strpos($conditions, ' OR ') !== false) ? explode(' OR ', $conditions) : array($conditions) ;
$or = '';
foreach( $conditions as $key => $value ) {
if ( strpos($value, ' AND ') !== false ) {
$value = explode(' AND ', $value);
$and = '';
foreach( $value as $k => $v ) {
$and .= $this->_validate_row_condition($row, $v);
}
$or .= (strpos($and, '0') !== false) ? '0' : '1' ;
} else {
$or .= $this->_validate_row_condition($row, $value);
}
}
return (strpos($or, '1') !== false) ? true : false ;
}
return true;
}
return false;
}
/**
* Validate a row against a single condition
* @param row array with values from a row
* @param condition specified condition that the row must match
* @return true of false
*/
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',
'contains',
'does not contain',
);
$operators_regex = array();
foreach( $operators as $value ) {
$operators_regex[] = preg_quote($value, '/');
}
$operators_regex = implode('|', $operators_regex);
if ( preg_match('/^(.+) ('.$operators_regex.') (.+)$/i', trim($condition), $capture) ) {
$field = $capture[1];
$op = $capture[2];
$value = $capture[3];
if ( preg_match('/^([\'\"]{1})(.*)([\'\"]{1})$/i', $value, $capture) ) {
if ( $capture[1] == $capture[3] ) {
$value = $capture[2];
$value = str_replace("\\n", "\n", $value);
$value = str_replace("\\r", "\r", $value);
$value = str_replace("\\t", "\t", $value);
$value = stripslashes($value);
}
}
if ( array_key_exists($field, $row) ) {
if ( ($op == '=' || $op == 'equals' || $op == 'is') && $row[$field] == $value ) {
return '1';
} elseif ( ($op == '!=' || $op == 'is not') && $row[$field] != $value ) {
return '1';
} elseif ( ($op == '<' || $op == 'is less than' ) && $row[$field] < $value ) {
return '1';
} elseif ( ($op == '>' || $op == 'is greater than') && $row[$field] > $value ) {
return '1';
} elseif ( ($op == '<=' || $op == 'is less than or equals' ) && $row[$field] <= $value ) {
return '1';
} elseif ( ($op == '>=' || $op == 'is greater than or equals') && $row[$field] >= $value ) {
return '1';
} elseif ( $op == 'contains' && preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
return '1';
} elseif ( $op == 'does not contain' && !preg_match('/'.preg_quote($value, '/').'/i', $row[$field]) ) {
return '1';
} else {
return '0';
}
}
}
return '1';
}
/**
* Validates if the row is within the offset or not if sorting is disabled
* @param current_row the current row number being processed
* @return true of false
*/
function _validate_offset ($current_row) {
if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
return true;
}
/**
* Enclose values if needed
* - only used by unparse()
* @param value string to process
* @return Processed value
*/
function _enclose_value ($value = null) {
if ( $value !== null && $value != '' ) {
$delimiter = preg_quote($this->delimiter, '/');
$enclosure = preg_quote($this->enclosure, '/');
if ( preg_match("/".$delimiter."|".$enclosure."|\n|\r/i", $value) || ($value{0} == ' ' || substr($value, -1) == ' ') ) {
$value = str_replace($this->enclosure, $this->enclosure.$this->enclosure, $value);
$value = $this->enclosure.$value.$this->enclosure;
}
}
return $value;
}
/**
* Check file data
* @param file local filename
* @return true or false
*/
function _check_data ($file = null) {
if ( empty($this->file_data) ) {
if ( $file === null ) $file = $this->file;
return $this->load_data($file);
}
return true;
}
/**
* Check if passed info might be delimiter
* - only used by find_delimiter()
* @return special string used for delimiter selection, or false
*/
function _check_count ($char, $array, $depth, $preferred) {
if ( $depth == count($array) ) {
$first = null;
$equal = null;
$almost = false;
foreach( $array as $key => $value ) {
if ( $first == null ) {
$first = $value;
} elseif ( $value == $first && $equal !== false) {
$equal = true;
} elseif ( $value == $first+1 && $equal !== false ) {
$equal = true;
$almost = true;
} else {
$equal = false;
}
}
if ( $equal ) {
$match = ( $almost ) ? 2 : 1 ;
$pref = strpos($preferred, $char);
$pref = ( $pref !== false ) ? str_pad($pref, 3, '0', STR_PAD_LEFT) : '999' ;
return $pref.$match.'.'.(99999 - str_pad($first, 5, '0', STR_PAD_LEFT));
} else return false;
}
}
/**
* Read local file
* @param file local filename
* @return Data from file, or false on failure
*/
function _rfile ($file = null) {
if ( is_readable($file) ) {
if ( !($fh = fopen($file, 'r')) ) return false;
$data = fread($fh, filesize($file));
fclose($fh);
return $data;
}
return false;
}
/**
* Write to local file
* @param file local filename
* @param string data to write to file
* @param mode fopen() mode
* @param lock flock() mode
* @return true or false
*/
function _wfile ($file, $string = '', $mode = 'wb', $lock = 2) {
if ( $fp = fopen($file, $mode) ) {
flock($fp, $lock);
$re = fwrite($fp, $string);
$re2 = fclose($fp);
if ( $re != false && $re2 != false ) return true;
}
return false;
}
}
?>

13
tests/Bootstrap.php Normal file
View File

@@ -0,0 +1,13 @@
<?php
$dir = realpath(__DIR__);
defined('BASE') OR define('BASE', dirname($dir) . '/');
require_once BASE . 'ParseCsvForPhp.php';
if (!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,11 @@
<?php
namespace PHPUnit\Framework;
// Only needed to keep unit test code compatible with older PHPUnit versions
/** @noinspection PhpUndefinedClassInspection */
/** @noinspection AutoloadingIssuesInspection */
class TestCase extends \PHPUnit_Framework_TestCase {
}

Binary file not shown.
1 idSite idVisit visitIp visitorId type (actionDetails 0) url (actionDetails 0) pageTitle (actionDetails 0) pageIdAction (actionDetails 0) idpageview (actionDetails 0) serverTimePretty (actionDetails 0) pageId (actionDetails 0) timeSpent (actionDetails 0) timeSpentPretty (actionDetails 0) interactionPosition (actionDetails 0) icon (actionDetails 0) timestamp (actionDetails 0) type (actionDetails 1) url (actionDetails 1) pageTitle (actionDetails 1) pageIdAction (actionDetails 1) idpageview (actionDetails 1) serverTimePretty (actionDetails 1) pageId (actionDetails 1) timeSpent (actionDetails 1) timeSpentPretty (actionDetails 1) generationTimeMilliseconds (actionDetails 1) generationTime (actionDetails 1) interactionPosition (actionDetails 1) icon (actionDetails 1) timestamp (actionDetails 1) type (actionDetails 2) url (actionDetails 2) pageTitle (actionDetails 2) pageIdAction (actionDetails 2) idpageview (actionDetails 2) serverTimePretty (actionDetails 2) pageId (actionDetails 2) timeSpent (actionDetails 2) timeSpentPretty (actionDetails 2) generationTimeMilliseconds (actionDetails 2) generationTime (actionDetails 2) interactionPosition (actionDetails 2) icon (actionDetails 2) timestamp (actionDetails 2) type (actionDetails 3) url (actionDetails 3) pageTitle (actionDetails 3) pageIdAction (actionDetails 3) idpageview (actionDetails 3) serverTimePretty (actionDetails 3) pageId (actionDetails 3) timeSpent (actionDetails 3) timeSpentPretty (actionDetails 3) generationTimeMilliseconds (actionDetails 3) generationTime (actionDetails 3) interactionPosition (actionDetails 3) icon (actionDetails 3) timestamp (actionDetails 3) type (actionDetails 4) url (actionDetails 4) pageTitle (actionDetails 4) pageIdAction (actionDetails 4) idpageview (actionDetails 4) serverTimePretty (actionDetails 4) pageId (actionDetails 4) timeSpent (actionDetails 4) timeSpentPretty (actionDetails 4) generationTimeMilliseconds (actionDetails 4) generationTime (actionDetails 4) interactionPosition (actionDetails 4) icon (actionDetails 4) timestamp (actionDetails 4) type (actionDetails 5) url (actionDetails 5) pageTitle (actionDetails 5) pageIdAction (actionDetails 5) idpageview (actionDetails 5) serverTimePretty (actionDetails 5) pageId (actionDetails 5) timeSpent (actionDetails 5) timeSpentPretty (actionDetails 5) generationTimeMilliseconds (actionDetails 5) generationTime (actionDetails 5) interactionPosition (actionDetails 5) icon (actionDetails 5) timestamp (actionDetails 5) type (actionDetails 6) url (actionDetails 6) pageTitle (actionDetails 6) pageIdAction (actionDetails 6) idpageview (actionDetails 6) serverTimePretty (actionDetails 6) pageId (actionDetails 6) timeSpent (actionDetails 6) timeSpentPretty (actionDetails 6) generationTimeMilliseconds (actionDetails 6) generationTime (actionDetails 6) interactionPosition (actionDetails 6) icon (actionDetails 6) timestamp (actionDetails 6) type (actionDetails 7) url (actionDetails 7) pageTitle (actionDetails 7) pageIdAction (actionDetails 7) idpageview (actionDetails 7) serverTimePretty (actionDetails 7) pageId (actionDetails 7) timeSpent (actionDetails 7) timeSpentPretty (actionDetails 7) generationTimeMilliseconds (actionDetails 7) generationTime (actionDetails 7) interactionPosition (actionDetails 7) icon (actionDetails 7) timestamp (actionDetails 7) type (actionDetails 8) url (actionDetails 8) pageTitle (actionDetails 8) pageIdAction (actionDetails 8) idpageview (actionDetails 8) serverTimePretty (actionDetails 8) pageId (actionDetails 8) timeSpent (actionDetails 8) timeSpentPretty (actionDetails 8) generationTimeMilliseconds (actionDetails 8) generationTime (actionDetails 8) interactionPosition (actionDetails 8) icon (actionDetails 8) timestamp (actionDetails 8) type (actionDetails 9) url (actionDetails 9) pageTitle (actionDetails 9) pageIdAction (actionDetails 9) idpageview (actionDetails 9) serverTimePretty (actionDetails 9) pageId (actionDetails 9) timeSpent (actionDetails 9) timeSpentPretty (actionDetails 9) generationTimeMilliseconds (actionDetails 9) generationTime (actionDetails 9) interactionPosition (actionDetails 9) icon (actionDetails 9) timestamp (actionDetails 9) type (actionDetails 10) url (actionDetails 10) pageTitle (actionDetails 10) pageIdAction (actionDetails 10) idpageview (actionDetails 10) serverTimePretty (actionDetails 10) pageId (actionDetails 10) timeSpent (actionDetails 10) timeSpentPretty (actionDetails 10) generationTimeMilliseconds (actionDetails 10) generationTime (actionDetails 10) interactionPosition (actionDetails 10) icon (actionDetails 10) timestamp (actionDetails 10) type (actionDetails 11) url (actionDetails 11) pageTitle (actionDetails 11) pageIdAction (actionDetails 11) idpageview (actionDetails 11) serverTimePretty (actionDetails 11) pageId (actionDetails 11) timeSpent (actionDetails 11) timeSpentPretty (actionDetails 11) generationTimeMilliseconds (actionDetails 11) generationTime (actionDetails 11) interactionPosition (actionDetails 11) icon (actionDetails 11) timestamp (actionDetails 11) type (actionDetails 12) url (actionDetails 12) pageTitle (actionDetails 12) pageIdAction (actionDetails 12) idpageview (actionDetails 12) serverTimePretty (actionDetails 12) pageId (actionDetails 12) timeSpent (actionDetails 12) timeSpentPretty (actionDetails 12) generationTimeMilliseconds (actionDetails 12) generationTime (actionDetails 12) interactionPosition (actionDetails 12) icon (actionDetails 12) timestamp (actionDetails 12) type (actionDetails 13) url (actionDetails 13) pageTitle (actionDetails 13) pageIdAction (actionDetails 13) idpageview (actionDetails 13) serverTimePretty (actionDetails 13) pageId (actionDetails 13) timeSpent (actionDetails 13) timeSpentPretty (actionDetails 13) generationTimeMilliseconds (actionDetails 13) generationTime (actionDetails 13) interactionPosition (actionDetails 13) icon (actionDetails 13) timestamp (actionDetails 13) type (actionDetails 14) url (actionDetails 14) pageTitle (actionDetails 14) pageIdAction (actionDetails 14) idpageview (actionDetails 14) serverTimePretty (actionDetails 14) pageId (actionDetails 14) timeSpent (actionDetails 14) timeSpentPretty (actionDetails 14) generationTimeMilliseconds (actionDetails 14) generationTime (actionDetails 14) interactionPosition (actionDetails 14) icon (actionDetails 14) timestamp (actionDetails 14) type (actionDetails 15) url (actionDetails 15) pageTitle (actionDetails 15) pageIdAction (actionDetails 15) idpageview (actionDetails 15) serverTimePretty (actionDetails 15) pageId (actionDetails 15) timeSpent (actionDetails 15) timeSpentPretty (actionDetails 15) generationTimeMilliseconds (actionDetails 15) generationTime (actionDetails 15) interactionPosition (actionDetails 15) icon (actionDetails 15) timestamp (actionDetails 15) type (actionDetails 16) url (actionDetails 16) pageTitle (actionDetails 16) pageIdAction (actionDetails 16) idpageview (actionDetails 16) serverTimePretty (actionDetails 16) pageId (actionDetails 16) timeSpent (actionDetails 16) timeSpentPretty (actionDetails 16) generationTimeMilliseconds (actionDetails 16) generationTime (actionDetails 16) interactionPosition (actionDetails 16) icon (actionDetails 16) timestamp (actionDetails 16) type (actionDetails 17) url (actionDetails 17) pageTitle (actionDetails 17) pageIdAction (actionDetails 17) idpageview (actionDetails 17) serverTimePretty (actionDetails 17) pageId (actionDetails 17) timeSpent (actionDetails 17) timeSpentPretty (actionDetails 17) generationTimeMilliseconds (actionDetails 17) generationTime (actionDetails 17) interactionPosition (actionDetails 17) icon (actionDetails 17) timestamp (actionDetails 17) type (actionDetails 18) url (actionDetails 18) pageTitle (actionDetails 18) pageIdAction (actionDetails 18) idpageview (actionDetails 18) serverTimePretty (actionDetails 18) pageId (actionDetails 18) timeSpent (actionDetails 18) timeSpentPretty (actionDetails 18) generationTimeMilliseconds (actionDetails 18) generationTime (actionDetails 18) interactionPosition (actionDetails 18) icon (actionDetails 18) timestamp (actionDetails 18) type (actionDetails 19) url (actionDetails 19) pageTitle (actionDetails 19) pageIdAction (actionDetails 19) idpageview (actionDetails 19) serverTimePretty (actionDetails 19) pageId (actionDetails 19) timeSpent (actionDetails 19) timeSpentPretty (actionDetails 19) generationTimeMilliseconds (actionDetails 19) generationTime (actionDetails 19) interactionPosition (actionDetails 19) icon (actionDetails 19) timestamp (actionDetails 19) type (actionDetails 20) url (actionDetails 20) pageTitle (actionDetails 20) pageIdAction (actionDetails 20) idpageview (actionDetails 20) serverTimePretty (actionDetails 20) pageId (actionDetails 20) timeSpent (actionDetails 20) timeSpentPretty (actionDetails 20) generationTimeMilliseconds (actionDetails 20) generationTime (actionDetails 20) interactionPosition (actionDetails 20) icon (actionDetails 20) timestamp (actionDetails 20) type (actionDetails 21) url (actionDetails 21) pageTitle (actionDetails 21) pageIdAction (actionDetails 21) idpageview (actionDetails 21) serverTimePretty (actionDetails 21) pageId (actionDetails 21) timeSpent (actionDetails 21) timeSpentPretty (actionDetails 21) generationTimeMilliseconds (actionDetails 21) generationTime (actionDetails 21) interactionPosition (actionDetails 21) icon (actionDetails 21) timestamp (actionDetails 21) type (actionDetails 22) url (actionDetails 22) pageTitle (actionDetails 22) pageIdAction (actionDetails 22) idpageview (actionDetails 22) serverTimePretty (actionDetails 22) pageId (actionDetails 22) timeSpent (actionDetails 22) timeSpentPretty (actionDetails 22) generationTimeMilliseconds (actionDetails 22) generationTime (actionDetails 22) interactionPosition (actionDetails 22) icon (actionDetails 22) timestamp (actionDetails 22) type (actionDetails 23) url (actionDetails 23) pageTitle (actionDetails 23) pageIdAction (actionDetails 23) idpageview (actionDetails 23) serverTimePretty (actionDetails 23) pageId (actionDetails 23) timeSpent (actionDetails 23) timeSpentPretty (actionDetails 23) generationTimeMilliseconds (actionDetails 23) generationTime (actionDetails 23) interactionPosition (actionDetails 23) icon (actionDetails 23) timestamp (actionDetails 23) type (actionDetails 24) url (actionDetails 24) pageTitle (actionDetails 24) pageIdAction (actionDetails 24) idpageview (actionDetails 24) serverTimePretty (actionDetails 24) pageId (actionDetails 24) timeSpent (actionDetails 24) timeSpentPretty (actionDetails 24) generationTimeMilliseconds (actionDetails 24) generationTime (actionDetails 24) interactionPosition (actionDetails 24) icon (actionDetails 24) timestamp (actionDetails 24) type (actionDetails 25) url (actionDetails 25) pageTitle (actionDetails 25) pageIdAction (actionDetails 25) idpageview (actionDetails 25) serverTimePretty (actionDetails 25) pageId (actionDetails 25) timeSpent (actionDetails 25) timeSpentPretty (actionDetails 25) generationTimeMilliseconds (actionDetails 25) generationTime (actionDetails 25) interactionPosition (actionDetails 25) icon (actionDetails 25) timestamp (actionDetails 25) type (actionDetails 26) url (actionDetails 26) pageTitle (actionDetails 26) pageIdAction (actionDetails 26) idpageview (actionDetails 26) serverTimePretty (actionDetails 26) pageId (actionDetails 26) timeSpent (actionDetails 26) timeSpentPretty (actionDetails 26) generationTimeMilliseconds (actionDetails 26) generationTime (actionDetails 26) interactionPosition (actionDetails 26) icon (actionDetails 26) timestamp (actionDetails 26) type (actionDetails 27) url (actionDetails 27) pageTitle (actionDetails 27) pageIdAction (actionDetails 27) idpageview (actionDetails 27) serverTimePretty (actionDetails 27) pageId (actionDetails 27) timeSpent (actionDetails 27) timeSpentPretty (actionDetails 27) generationTimeMilliseconds (actionDetails 27) generationTime (actionDetails 27) interactionPosition (actionDetails 27) icon (actionDetails 27) timestamp (actionDetails 27) type (actionDetails 28) url (actionDetails 28) pageTitle (actionDetails 28) pageIdAction (actionDetails 28) idpageview (actionDetails 28) serverTimePretty (actionDetails 28) pageId (actionDetails 28) timeSpent (actionDetails 28) timeSpentPretty (actionDetails 28) generationTimeMilliseconds (actionDetails 28) generationTime (actionDetails 28) interactionPosition (actionDetails 28) icon (actionDetails 28) timestamp (actionDetails 28) type (actionDetails 29) url (actionDetails 29) pageTitle (actionDetails 29) pageIdAction (actionDetails 29) idpageview (actionDetails 29) serverTimePretty (actionDetails 29) pageId (actionDetails 29) timeSpent (actionDetails 29) timeSpentPretty (actionDetails 29) generationTimeMilliseconds (actionDetails 29) generationTime (actionDetails 29) interactionPosition (actionDetails 29) icon (actionDetails 29) timestamp (actionDetails 29) type (actionDetails 30) url (actionDetails 30) pageTitle (actionDetails 30) pageIdAction (actionDetails 30) idpageview (actionDetails 30) serverTimePretty (actionDetails 30) pageId (actionDetails 30) timeSpent (actionDetails 30) timeSpentPretty (actionDetails 30) generationTimeMilliseconds (actionDetails 30) generationTime (actionDetails 30) interactionPosition (actionDetails 30) icon (actionDetails 30) timestamp (actionDetails 30) type (actionDetails 31) url (actionDetails 31) pageTitle (actionDetails 31) pageIdAction (actionDetails 31) idpageview (actionDetails 31) serverTimePretty (actionDetails 31) pageId (actionDetails 31) timeSpent (actionDetails 31) timeSpentPretty (actionDetails 31) generationTimeMilliseconds (actionDetails 31) generationTime (actionDetails 31) interactionPosition (actionDetails 31) icon (actionDetails 31) timestamp (actionDetails 31) type (actionDetails 32) url (actionDetails 32) pageTitle (actionDetails 32) pageIdAction (actionDetails 32) idpageview (actionDetails 32) serverTimePretty (actionDetails 32) pageId (actionDetails 32) timeSpent (actionDetails 32) timeSpentPretty (actionDetails 32) generationTimeMilliseconds (actionDetails 32) generationTime (actionDetails 32) interactionPosition (actionDetails 32) icon (actionDetails 32) timestamp (actionDetails 32) type (actionDetails 33) url (actionDetails 33) pageTitle (actionDetails 33) pageIdAction (actionDetails 33) idpageview (actionDetails 33) serverTimePretty (actionDetails 33) pageId (actionDetails 33) timeSpent (actionDetails 33) timeSpentPretty (actionDetails 33) generationTimeMilliseconds (actionDetails 33) generationTime (actionDetails 33) interactionPosition (actionDetails 33) icon (actionDetails 33) timestamp (actionDetails 33) type (actionDetails 34) url (actionDetails 34) pageTitle (actionDetails 34) pageIdAction (actionDetails 34) idpageview (actionDetails 34) serverTimePretty (actionDetails 34) pageId (actionDetails 34) timeSpent (actionDetails 34) timeSpentPretty (actionDetails 34) generationTimeMilliseconds (actionDetails 34) generationTime (actionDetails 34) interactionPosition (actionDetails 34) icon (actionDetails 34) timestamp (actionDetails 34) type (actionDetails 35) url (actionDetails 35) pageTitle (actionDetails 35) pageIdAction (actionDetails 35) idpageview (actionDetails 35) serverTimePretty (actionDetails 35) pageId (actionDetails 35) timeSpent (actionDetails 35) timeSpentPretty (actionDetails 35) generationTimeMilliseconds (actionDetails 35) generationTime (actionDetails 35) interactionPosition (actionDetails 35) icon (actionDetails 35) timestamp (actionDetails 35) type (actionDetails 36) url (actionDetails 36) pageTitle (actionDetails 36) pageIdAction (actionDetails 36) idpageview (actionDetails 36) serverTimePretty (actionDetails 36) pageId (actionDetails 36) timeSpent (actionDetails 36) timeSpentPretty (actionDetails 36) generationTimeMilliseconds (actionDetails 36) generationTime (actionDetails 36) interactionPosition (actionDetails 36) icon (actionDetails 36) timestamp (actionDetails 36) type (actionDetails 37) url (actionDetails 37) pageTitle (actionDetails 37) pageIdAction (actionDetails 37) idpageview (actionDetails 37) serverTimePretty (actionDetails 37) pageId (actionDetails 37) timeSpent (actionDetails 37) timeSpentPretty (actionDetails 37) interactionPosition (actionDetails 37) icon (actionDetails 37) timestamp (actionDetails 37) type (actionDetails 38) url (actionDetails 38) pageTitle (actionDetails 38) pageIdAction (actionDetails 38) idpageview (actionDetails 38) serverTimePretty (actionDetails 38) pageId (actionDetails 38) timeSpent (actionDetails 38) timeSpentPretty (actionDetails 38) interactionPosition (actionDetails 38) icon (actionDetails 38) timestamp (actionDetails 38) type (actionDetails 39) url (actionDetails 39) pageTitle (actionDetails 39) pageIdAction (actionDetails 39) idpageview (actionDetails 39) serverTimePretty (actionDetails 39) pageId (actionDetails 39) timeSpent (actionDetails 39) timeSpentPretty (actionDetails 39) generationTimeMilliseconds (actionDetails 39) generationTime (actionDetails 39) interactionPosition (actionDetails 39) icon (actionDetails 39) timestamp (actionDetails 39) type (actionDetails 40) url (actionDetails 40) pageTitle (actionDetails 40) pageIdAction (actionDetails 40) idpageview (actionDetails 40) serverTimePretty (actionDetails 40) pageId (actionDetails 40) generationTimeMilliseconds (actionDetails 40) generationTime (actionDetails 40) interactionPosition (actionDetails 40) icon (actionDetails 40) timestamp (actionDetails 40) goalConversions siteCurrency siteCurrencySymbol serverDate visitServerHour lastActionTimestamp lastActionDateTime serverTimestamp firstActionTimestamp serverTimePretty serverDatePretty serverDatePrettyFirstAction serverTimePrettyFirstAction userId visitorType visitorTypeIcon visitConverted visitConvertedIcon visitCount visitEcommerceStatus visitEcommerceStatusIcon daysSinceFirstVisit daysSinceLastEcommerceOrder visitDuration visitDurationPretty searches actions interactions referrerType referrerTypeName referrerName referrerKeyword referrerKeywordPosition referrerUrl referrerSearchEngineUrl referrerSearchEngineIcon languageCode language deviceType deviceTypeIcon deviceBrand deviceModel operatingSystem operatingSystemName operatingSystemIcon operatingSystemCode operatingSystemVersion browserFamily browserFamilyDescription browser browserName browserIcon browserCode browserVersion events continent continentCode country countryCode countryFlag region regionCode city location latitude longitude visitLocalTime visitLocalHour daysSinceLastVisit resolution plugins pluginsIcons provider providerName providerUrl customVariableName1 customVariableValue1 customVariableName2 customVariableValue2 customVariableName3 customVariableValue3 customVariableName4 customVariableValue4 customVariableName5 customVariableValue5 pageUrl__1 pageTitle__1 pageUrl__2 pageTitle__2 pageUrl__3 pageTitle__3 pageUrl__4 pageTitle__4 pageUrl__5 pageTitle__5 pageUrl__6 pageTitle__6 pageUrl__7 pageTitle__7 pageUrl__8 pageTitle__8 pageUrl__9 pageTitle__9 pageUrl__10 pageTitle__10 pageUrl__11 pageTitle__11 pageUrl__12 pageTitle__12 pageUrl__13 pageUrl__14 pageTitle__14 pageUrl__15 pageTitle__15 pageUrl__16 pageTitle__16 pageUrl__17 pageTitle__17 pageUrl__18 pageTitle__18 pageUrl__19 pageTitle__19 pageUrl__20 pageTitle__20 pageUrl__21 pageTitle__21 pageUrl__22 pageTitle__22 pageUrl__23 pageTitle__23 pageUrl__24 pageUrl__25 pageTitle__25 pageUrl__26 pageTitle__26 pageUrl__27 pageTitle__27 pageUrl__28 pageTitle__28 pageUrl__29 pageTitle__29 pageUrl__30 pageTitle__30 pageUrl__31 pageTitle__31 pageUrl__32 pageTitle__32 pageUrl__33 pageTitle__33 pageUrl__34 pageTitle__34 pageUrl__35 pageTitle__35 pageUrl__36 pageTitle__36 pageUrl__37 pageTitle__37 pageUrl__38 pageTitle__38 pageUrl__39 pageTitle__39 pageUrl__40 pageTitle__40 pageUrl__41 pageTitle__41 entryPageTitle entryPageUrl exitPageTitle exitPageUrl generationTimeMilliseconds (actionDetails 0) generationTime (actionDetails 0) timeSpentRef (actionDetails 9) custom_float (actionDetails 9)
2 13 129930 213. 6c38cb8dca6e1f5d action http://_asktermmesswert/Button1 Ok 9551 04.1.2017 17:42:12 1181863 20 20 s 1 1483551732 action http://application/_Main/mnDatenbankSpeichern Save changes in the database 9646 04.1.2017 17:42:32 1181864 15 15 s 1092 1,09 s 2 1483551752 action http://application/_Main/bbRingversuchwechseln Ring test 9386 04.1.2017 17:42:47 1181865 58 58 s 6966 6,97 s 3 1483551767 action http://application/_Main/mnPML_ToTest Sample-measurand-laboratory allocation 9915 04.1.2017 17:43:45 1181866 14 14 s 851 0,85 s 4 1483551825 action http://application/_Main/_ErstellePMLabKombination/btnAddAll Include allcombinations 9864 04.1.2017 17:43:59 1181867 22 22 s 204 0,2 s 5 1483551839 action http://application/_Main/mnHomogeneityImportMesswerte Import test results 9574 04.1.2017 17:44:21 1181868 9 9 s 189 0,19 s 6 1483551861 action http://application/_Main/mnCalcMean Ring test parameters 9289 04.1.2017 17:44:30 1181869 3 3 s 598 0,6 s 7 1483551870 action http://application/_Main/_CalcMeanSTD_MDI/btnReportMeanSTD Assigned values/s.d. 9659 04.1.2017 17:44:33 1181870 15 15 s 10369 10,37 s 8 1483551873 action http://application/_Main/_CalcMeanSTD_MDI/btnCalculateMean Computation 9290 04.1.2017 17:44:48 1181871 55 55 s 22762 22,76 s 9 1483551888 action http://application/_Main/_CalcMeanSTD_MDI/mnReportMitLaborcode with Lab code 9411 04.1.2017 17:45:43 1181872 80 1 Minuten 20s 6345 6,35 s 10 1483551943 action http://application/_Main/bbHistogram_NormalPlot Histogram normal plot 9361 04.1.2017 17:47:03 1181873 31 31 s 5985 5,99 s 11 1483552023 action http://application/_Main/bbVariance_ToleranceLimits Tolerance limits rel. standard deviations 9873 04.1.2017 17:47:34 1181874 12 12 s 567 0,57 s 12 1483552054 action http://application/_Main/_Youdenplot_MDI/PageControl1 9363 04.1.2017 17:47:46 1181875 0 0 s 4 0,004 s 13 1483552066 action http://application/_Main/bbYoudenplot Youden plot 9364 04.1.2017 17:47:46 1181876 30 30 s 497 0,5 s 14 1483552066 action http://application/_Main/bbOverAllSamples Laboratory mean values 9293 04.1.2017 17:48:16 1181877 33 33 s 458 0,46 s 15 1483552096 action http://application/_Main/bbLoadSelect Load selection 12749 04.1.2017 17:48:49 1181878 7 7 s 62 0,06 s 16 1483552129 action http://application/_Main/bbPML_ToTest Sample-measurand-laboratory allocation 9321 04.1.2017 17:48:56 1181879 5 5 s 1192 1,19 s 17 1483552136 action http://application/_Main/bbLCode Laboratories 9350 04.1.2017 17:49:01 1181880 4 4 s 635 0,64 s 18 1483552141 action http://application/_Main/_LaborCodierung/btnReset Delete all laboratory codes 10435 04.1.2017 17:49:05 1181881 14 14 s 4333 4,33 s 19 1483552145 action http://application/_Main/mnNewDatabase New database 9441 04.1.2017 17:49:19 1181882 17 17 s 6939 6,94 s 20 1483552159 action http://application/_Main/mnHomogeneityBerechnung Calculation (ISO 13528:2015 and Harmonized Protocol) 9579 04.1.2017 17:49:36 1181883 14 14 s 612 0,61 s 21 1483552176 action http://application/_Main/_CalcHomogeneity_MDI/mniReportChart Graphics and text for current combination 9643 04.1.2017 17:49:50 1181884 0 0 s 4912 4,91 s 22 1483552190 action http://application/_Main/bbYoudenplot Youden plot 9364 04.1.2017 17:50:05 1181886 16 16 s 855 0,86 s 24 1483552205 action http://application/_Main/_Youdenplot_MDI/PageControl1 9363 04.1.2017 17:50:06 1181885 0 0 s 5 0,005 s 23 1483552206 action http://application/_Main/bbEinzeldarstellung Summary results 9268 04.1.2017 17:50:10 1181888 6 6 s 2941 2,94 s 26 1483552210 action http://application/_Main/_GraphicMeanSTD_MDI/mnuYAutoscaleAll Automatic scaling for all chart contents 9301 04.1.2017 17:50:11 1181887 34 34 s 1 0,001 s 25 1483552211 action http://application/_Main/_GraphicMeanSTD_MDI/btnOutlier Outliers 9503 04.1.2017 17:50:44 1181889 2 2 s 76 0,08 s 27 1483552244 action http://application/_Main/_GraphicMeanSTD_MDI/btnConfBandOptions ... 9777 04.1.2017 17:50:46 1181890 1 1 s 1482 1,48 s 28 1483552246 action http://application/_Main/_GraphicMeanSTD_MDI/mnConfLinien Lines 10077 04.1.2017 17:50:47 1181891 18 18 s 1529 1,53 s 29 1483552247 action http://application/_Main/bbPM_ToTest Sample-measurand allocation 9319 04.1.2017 17:51:05 1181892 2 2 s 100 0,1 s 30 1483552265 action http://application/_Main/bbPML_ToTest Sample-measurand-laboratory allocation 9321 04.1.2017 17:51:07 1181893 3 3 s 1178 1,18 s 31 1483552267 action http://application/_Main/bbLabToTest Laboratory allocation 9317 04.1.2017 17:51:10 1181894 34 34 s 109 0,11 s 32 1483552270 action http://application/_Main/bbYoudenplot Youden plot 9364 04.1.2017 17:51:44 1181895 1 1 s 47 0,05 s 33 1483552304 action http://application/_Main/bbScoreGraphic Survey of Z-Scores 9269 04.1.2017 17:51:45 1181896 32 32 s 310 0,31 s 34 1483552305 action http://application/_Main/_GraphicZScores_MDI/btnLCode Lab code 9487 04.1.2017 17:52:17 1181897 8 8 s 234 0,23 s 35 1483552337 action http://application/_Main/_GraphicZScores_MDI/btnClose Close 9488 04.1.2017 17:52:25 1181898 2 2 s 130 0,13 s 36 1483552345 action http://application/_Main/_Youdenplot_MDI/btnClose Close 9799 04.1.2017 17:52:27 1181899 1 1 s 86 0,09 s 37 1483552347 action http://application/_Main/_LabStructure/btnClose Close 9866 04.1.2017 17:52:28 1181900 1 1 s 38 1483552348 action http://application/_Main/_ErstellePMLabKombination/btnClose Close 9946 04.1.2017 17:52:29 1181901 1 1 s 39 1483552349 action http://application/_Main/_ErstellePMKombination/btnClose Close 9831 04.1.2017 17:52:30 1181902 1 1 s 1 0,001 s 40 1483552350 action http://application/_Main/btnClose Close 9245 04.1.2017 17:52:31 1181903 29 0,03 s 41 1483552351 0 EUR 2017-01-04 16 1483548751 2017-01-04 16:52:31 1483548751 1483548132 17:52:31 Mittwoch, 4. Januar 2017 Mittwoch, 4. Januar 2017 17:42:12 new 0 1 none 0 0 620 10 Minuten 20s 0 41 41 direct Direkte Zugriffe en Englisch unbekannt plugins/Morpheus/icons/dist/devices/unknown.png unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/os/UNK.png UNK UNK unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/browsers/UNK.png UNK 0 Südamerika ams Brasilien br plugins/Morpheus/icons/dist/flags/br.png Sao Paulo 27 São Paulo São Paulo, Sao Paulo, Brasilien -23.473000 -46.666000 16:42:12 16 0 1920x1080 wcs.net.br Wcs http://www.wcs.net.br/ From _1710 Serial _1710 Version 21. App PROLab Plus Demo OsLanguage Portuguese http://_asktermmesswert/Button1 Ok http://application/_Main/mnDatenbankSpeichern Save changes in the database http://application/_Main/bbRingversuchwechseln Ring test http://application/_Main/mnPML_ToTest Sample-measurand-laboratory allocation http://application/_Main/_ErstellePMLabKombination/btnAddAll Include allcombinations http://application/_Main/mnHomogeneityImportMesswerte Import test results http://application/_Main/mnCalcMean Ring test parameters http://application/_Main/_CalcMeanSTD_MDI/btnReportMeanSTD Assigned values/s.d. http://application/_Main/_CalcMeanSTD_MDI/btnCalculateMean Computation http://application/_Main/_CalcMeanSTD_MDI/mnReportMitLaborcode with Lab code http://application/_Main/bbHistogram_NormalPlot Histogram normal plot http://application/_Main/bbVariance_ToleranceLimits Tolerance limits rel. standard deviations http://application/_Main/_Youdenplot_MDI/PageControl1 http://application/_Main/bbYoudenplot Youden plot http://application/_Main/bbOverAllSamples Laboratory mean values http://application/_Main/bbLoadSelect Load selection http://application/_Main/bbPML_ToTest Sample-measurand-laboratory allocation http://application/_Main/bbLCode Laboratories http://application/_Main/_LaborCodierung/btnReset Delete all laboratory codes http://application/_Main/mnNewDatabase New database http://application/_Main/mnHomogeneityBerechnung Calculation (ISO 13528:2015 and Harmonized Protocol) http://application/_Main/_CalcHomogeneity_MDI/mniReportChart Graphics and text for current combination http://application/_Main/bbYoudenplot Youden plot http://application/_Main/_Youdenplot_MDI/PageControl1 http://application/_Main/bbEinzeldarstellung Summary results http://application/_Main/_GraphicMeanSTD_MDI/mnuYAutoscaleAll Automatic scaling for all chart contents http://application/_Main/_GraphicMeanSTD_MDI/btnOutlier Outliers http://application/_Main/_GraphicMeanSTD_MDI/btnConfBandOptions ... http://application/_Main/_GraphicMeanSTD_MDI/mnConfLinien Lines http://application/_Main/bbPM_ToTest Sample-measurand allocation http://application/_Main/bbPML_ToTest Sample-measurand-laboratory allocation http://application/_Main/bbLabToTest Laboratory allocation http://application/_Main/bbYoudenplot Youden plot http://application/_Main/bbScoreGraphic Survey of Z-Scores http://application/_Main/_GraphicZScores_MDI/btnLCode Lab code http://application/_Main/_GraphicZScores_MDI/btnClose Close http://application/_Main/_Youdenplot_MDI/btnClose Close http://application/_Main/_LabStructure/btnClose Close http://application/_Main/_ErstellePMLabKombination/btnClose Close http://application/_Main/_ErstellePMKombination/btnClose Close http://application/_Main/btnClose Close Ok http://_asktermmesswert/Button1 Close http://application/_Main/btnClose
3 13 129999 154. 69dafac11ed871fb action http://application/_Main/Grundtabellen1 Basic tables 9295 04.1.2017 16:08:19 1182416 35 35 s 1 1483546099 action http://application/_Main/mnHomogeneityImportMesswerte Import test results 9574 04.1.2017 16:08:54 1182417 12 12 s 1107 1,11 s 2 1483546134 action http://application/_Main/_ImportGroups_FP/btnLoad Open 9576 04.1.2017 16:09:06 1182418 30 30 s 10551 10,55 s 3 1483546146 action http://application/_Main/_ImportGroups_FP/btnFiletransfer Transfer data 9578 04.1.2017 16:09:36 1182419 44 44 s 32089 32,09 s 4 1483546176 action http://application/_Main/mnHomogeneityBerechnung Calculation (ISO 13528:2015 and Harmonized Protocol) 9579 04.1.2017 16:10:20 1182420 889 0,89 s 5 1483546220 0 EUR 2017-01-04 15 1483542620 2017-01-04 15:10:20 1483542620 1483542499 16:10:20 Mittwoch, 4. Januar 2017 Mittwoch, 4. Januar 2017 16:08:19 new 0 1 none 0 0 122 2 Minuten 2s 0 5 5 direct Direkte Zugriffe en Englisch unbekannt plugins/Morpheus/icons/dist/devices/unknown.png unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/os/UNK.png UNK UNK unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/browsers/UNK.png UNK 0 Afrika afr Südafrika za plugins/Morpheus/icons/dist/flags/za.png Gauteng 06 Johannesburg Johannesburg, Gauteng, Südafrika -26.205000 28.050000 15:08:19 15 0 1366x768 telkomadsl.co.za Telkomadsl http://www.telkomadsl.co.za/ From _1710 Serial _1710 Version 30..0 App PROLab Plus OsLanguage English http://application/_Main/Grundtabellen1 Basic tables http://application/_Main/mnHomogeneityImportMesswerte Import test results http://application/_Main/_ImportGroups_FP/btnLoad Open http://application/_Main/_ImportGroups_FP/btnFiletransfer Transfer data http://application/_Main/mnHomogeneityBerechnung Calculation (ISO 13528:2015 and Harmonized Protocol) Basic tables http://application/_Main/Grundtabellen1 Calculation (ISO 13528:2015 and Harmonized Protocol) http://application/_Main/mnHomogeneityBerechnung 4945 4,95 s
4 13 129898 85..0 79a87d1a340cd850 action http://application/_Main/bbLabToTest Laboratory allocation 9317 04.1.2017 15:28:18 1181575 21 21 s 1 1483543698 action http://application/_Main/_LabStructure/btnDelete Exclude selectedlaboratories 9835 04.1.2017 15:28:39 1181576 13 13 s 3481 3,48 s 2 1483543719 action http://application/_Main/_LabStructure/btnAdd Include selectedlaboratories 9913 04.1.2017 15:28:52 1181577 214 3 Minuten 34s 24 0,02 s 3 1483543732 action http://application/_Main/_LabStructure/btnClose Close 9866 04.1.2017 15:32:26 1181578 4 4 s 1 0,001 s 4 1483543946 action http://application/_Main/Grundtabellen1 Basic tables 9295 04.1.2017 15:32:30 1181579 8 8 s 4355 4,36 s 5 1483543950 action http://application/_Main/_EditBasicTables/btnClose Close 9267 04.1.2017 15:32:38 1181580 2 2 s 9 0,009 s 6 1483543958 action http://application/_Main/Grundtabellen1 Basic tables 9295 04.1.2017 15:32:40 1181581 334 5 Minuten 34s 4211 4,21 s 7 1483543960 action http://application/_Main/_EditBasicTables/btnClose Close 9267 04.1.2017 15:38:14 1181582 0 0 s 10 0,01 s 8 1483544294 action http://application/_Main/mnCalcZScores_Results Computation of scores and tolerance limits 9260 04.1.2017 15:38:14 1181583 0 0 s 34018 34,02 s 9 1483544294 4 Save as Excel file 04.1.2017 15:38:14 1181584 10 1483544294 action http://application/_Main/_CalcZScores_Results_MDI/JvSpeedButton5 Close form 9772 04.1.2017 15:38:14 1181585 5 0,005 s 11 1483544294 0 EUR 2017-01-04 14 1483540694 2017-01-04 14:38:14 1483540694 1483540098 15:38:14 Mittwoch, 4. Januar 2017 Mittwoch, 4. Januar 2017 15:28:18 new 0 1 none 0 0 597 9 Minuten 57s 0 11 11 direct Direkte Zugriffe en Englisch unbekannt plugins/Morpheus/icons/dist/devices/unknown.png unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/os/UNK.png UNK UNK unbekannt unbekannt unbekannt plugins/Morpheus/icons/dist/browsers/UNK.png UNK 0 Europa eur Dänemark dk plugins/Morpheus/icons/dist/flags/dk.png Dänemark 56.000000 10.000000 14:28:18 14 0 1680x1050 Ip unbekannt From _1710 Serial _1710 Version 17..0 App PROLab Plus OsLanguage Danish http://application/_Main/bbLabToTest Laboratory allocation http://application/_Main/_LabStructure/btnDelete Exclude selectedlaboratories http://application/_Main/_LabStructure/btnAdd Include selectedlaboratories http://application/_Main/_LabStructure/btnClose Close http://application/_Main/Grundtabellen1 Basic tables http://application/_Main/_EditBasicTables/btnClose Close http://application/_Main/Grundtabellen1 Basic tables http://application/_Main/_EditBasicTables/btnClose Close http://application/_Main/mnCalcZScores_Results Computation of scores and tolerance limits Save as Excel file http://application/_Main/_CalcZScores_Results_MDI/JvSpeedButton5 Close form Laboratory allocation http://application/_Main/bbLabToTest Close form http://application/_Main/_CalcZScores_Results_MDI/JvSpeedButton5 2641 2,64 s 0 18873

Binary file not shown.
1 sep=;
2 title;isbn;publishedAt
3 Красивая кулинария;5454-5587-3210;21.05.2011
4 The Wine Connoisseurs;2547-8548-2541;12.12.2011
5 Weißwein;1313-4545-8875;23.02.2012

View File

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

View File

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

View File

@@ -0,0 +1,3 @@
"column1","column2"
"value1","value2"
"value3","value4"
1 column1 column2
2 value1 value2
3 value3 value4

View File

@@ -0,0 +1,3 @@
'column1','column2'
'value1','value2'
'value3','value4'
1 'column1' 'column2'
2 'value1' 'value2'
3 'value3' 'value4'

View File

@@ -0,0 +1,5 @@
SMS
0444
5555
6606
7777
1 SMS
2 0444
3 5555
4 6606
5 7777

View File

@@ -0,0 +1,45 @@
<?php
class ConstructTest extends PHPUnit\Framework\TestCase {
/**
* @access protected
* @var ParseCsvForPhp object
*/
protected $csv = null;
public function test_offset_param() {
$offset = 10;
$this->csv = new ParseCsvForPhp(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->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->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->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->assertTrue(is_string($this->csv->file_data));
$this->assertEquals($csv, $this->csv->file_data);
}
}

169
tests/methods/ParseTest.php Normal file
View File

@@ -0,0 +1,169 @@
<?php
class ParseTest extends PHPUnit\Framework\TestCase {
/**
* @access protected
* @var ParseCsvForPhp
*/
protected $csv;
/**
* Setup
* Setup our test environment objects
*
* @access public
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
}
public function test_parse() {
// 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');
}
private function parse_repetitive_string($content) {
$this->csv->delimiter = ';';
$this->csv->heading = false;
$success = $this->csv->parse(str_repeat($content . ';', 500));
$this->assertEquals(true, $success);
$row = array_pop($this->csv->data);
$expected_data = array_fill(0, 500, $content);
$expected_data [] = '';
$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');
}
public function testSingleColumnWithZeros() {
$this->csv->delimiter = null;
$this->csv->parse("URL\nhttp://www.amazon.com/ROX-Ice-Ball-Maker-Original/dp/B00MX59NMQ/ref=sr_1_1?ie=UTF8&qid=1435604374&sr=8-1&keywords=rox,+ice+molds");
$row = array_pop($this->csv->data);
$expected_data = ['URL' => 'http://www.amazon.com/ROX-Ice-Ball-Maker-Original/dp/B00MX59NMQ/ref=sr_1_1?ie=UTF8&qid=1435604374&sr=8-1&keywords=rox,+ice+molds'];
$this->assertEquals($expected_data, $row);
}
public function testAllNumericalCsv() {
$this->csv->heading = false;
$sInput = "86545235689\r\n34365587654\r\n13469874576";
$this->assertEquals(false, $this->csv->auto($sInput));
$this->assertEquals(null, $this->csv->delimiter);
$expected_data = explode("\r\n", $sInput);
$actual_data = array_map('reset', $this->csv->data);
$this->assertEquals($expected_data, $actual_data);
}
public function testMissingEndingLineBreak() {
$this->csv->heading = false;
$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_column = array_map('reset', $actual_data);
$this->assertEquals($expected_data, $actual_column);
$this->assertEquals([
'a',
'b',
"c\r\nd",
], 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() {
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
$expected = [
['SMS' => '0444'],
['SMS' => '5555'],
['SMS' => '6606'],
['SMS' => '7777'],
];
$this->assertEquals($expected, $this->csv->data);
}
public function test_Piwik_data() {
if (!function_exists('array_column')) {
// function only available in PHP >= 5.5
return;
}
$this->csv->use_mb_convert_encoding = true;
$this->csv->output_encoding = 'UTF-8';
$this->csv->auto(__DIR__ . '/../example_files/Piwik_API_download.csv');
$aAction27 = array_column($this->csv->data, 'url (actionDetails 27)');
$this->assertEquals([
'http://application/_Main/_GraphicMeanSTD_MDI/btnConfBandOptions',
'',
'',
], $aAction27);
$aCity = array_column($this->csv->data, 'city');
$this->assertEquals([
'São Paulo',
'Johannesburg',
'',
], $aCity);
}
protected function _get_magazines_data() {
return [
[
'title' => 'Красивая кулинария',
'isbn' => '5454-5587-3210',
'publishedAt' => '21.05.2011',
],
[
'title' => 'The Wine Connoisseurs',
'isbn' => '2547-8548-2541',
'publishedAt' => '12.12.2011',
],
[
'title' => 'Weißwein',
'isbn' => '1313-4545-8875',
'publishedAt' => '23.02.2012',
],
];
}
public function autoQuotesDataProvider() {
return array(
array('auto-double-enclosure.csv', '"'),
array('auto-single-enclosure.csv', "'"),
);
}
/**
* @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);
$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);
}
}

View File

@@ -0,0 +1,65 @@
<?php
class SaveTest extends PHPUnit\Framework\TestCase {
/** @var ParseCsvForPhp */
private $csv;
private $temp_filename;
/**
* Setup our test environment objects; will be called before each test.
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
$this->csv->auto(__DIR__ . '/../example_files/single_column.csv');
// Remove last 2 lines to simplify comparison
unset($this->csv->data[2], $this->csv->data[3]);
$temp_dir = str_replace("\\", '/', sys_get_temp_dir());
if (substr($temp_dir, -1) != '/') {
// From the PHP.net documentation:
// This function does not always add trailing slash. This behaviour
// is inconsistent across systems.
$temp_dir .= '/';
}
$this->temp_filename = $temp_dir . 'parsecsv_test_file.csv';
}
public function testSaveWithDefaultSettings() {
$expected = "SMS\r0444\r5555\r";
$this->saveAndCompare($expected);
}
public function testSaveWithDosLineEnding() {
$this->csv->linefeed = "\r\n";
$expected = "SMS\r\n0444\r\n5555\r\n";
$this->saveAndCompare($expected);
}
public function testSaveWithUnixLineEnding() {
$this->csv->linefeed = "\n";
$expected = "SMS\n0444\n5555\n";
$this->saveAndCompare($expected);
}
public function testSaveWithoutHeader() {
$this->csv->linefeed = "\n";
$this->csv->heading = false;
$expected = "0444\n5555\n";
$this->saveAndCompare($expected);
}
public function testAllQuotes() {
$this->csv->enclose_all = true;
$expected = "\"SMS\"\r\"0444\"\r\"5555\"\r";
$this->saveAndCompare($expected);
}
private function saveAndCompare($expected) {
$this->csv->save($this->temp_filename);
$content = file_get_contents($this->temp_filename);
$this->assertEquals($expected, $content);
}
}

18
tests/phpunit.xml Normal file
View File

@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<phpunit
bootstrap="Bootstrap.php"
colors="false"
convertNoticesToExceptions="true"
convertWarningsToExceptions="true"
stopOnError="true"
stopOnFailure="true"
stopOnIncomplete="true"
stopOnSkipped="false">
<testsuites>
<testsuite name="ParseCsvForPhp Test Suite">
<directory suffix="est.php">properties/</directory>
<directory suffix="est.php">methods/</directory>
</testsuite>
</testsuites>
</phpunit>

View File

@@ -0,0 +1,28 @@
<?php
class BaseClass extends PHPUnit\Framework\TestCase {
/**
* @access protected
* @var ParseCsvForPhp object
*/
protected $csv;
/**
* Setup
* Setup our test environment objects
*
* @access public
*/
public function setUp() {
$this->csv = new ParseCsvForPhp();
}
protected function _compareWithExpected($expected) {
$this->csv->auto(__DIR__ . '/../../examples/_books.csv');
$actual = array_map(function ($row) {
return $row['title'];
}, $this->csv->data);
$this->assertEquals($expected, $actual);
}
}

View File

@@ -0,0 +1,47 @@
<?php
class ConditionsTest extends BaseClass {
public function testNotDanBrown() {
$this->csv->conditions = 'author does not contain dan brown';
$this->_compareWithExpected([
'The Killing Kind',
'The Third Secret',
'The Last Templar',
'The Traveller',
'Crisis Four',
'Prey',
'The Broker (Paperback)',
'Without Blood (Paperback)',
'State of Fear (Paperback)',
'The Rule of Four (Paperback)',
]);
}
public function testRating() {
$this->csv->conditions = 'rating < 3';
$this->_compareWithExpected([
'The Killing Kind',
'The Third Secret',
]);
$this->csv->conditions = 'rating >= 5';
$this->_compareWithExpected([
'The Traveller',
'Prey',
'State of Fear (Paperback)',
'Digital Fortress : A Thriller (Mass Market Paperback)',
'Angels & Demons (Mass Market Paperback)',
]);
}
public function testTitleContainsSecretOrCode() {
$this->csv->conditions = 'title contains code OR title contains SECRET';
$this->_compareWithExpected([
'The Third Secret',
'The Da Vinci Code (Hardcover)',
]);
}
}

View File

@@ -0,0 +1,58 @@
<?php
class SortByTest extends BaseClass {
public function testSortByRating() {
$this->csv->sort_by = 'rating';
$this->csv->conditions = 'title does not contain Blood';
$this->_compareWithExpected([
// Rating 0
'The Killing Kind',
'The Third Secret',
// Rating 3
'The Last Templar',
'The Broker (Paperback)',
// Rating 4
'Deception Point (Paperback)',
'The Rule of Four (Paperback)',
'The Da Vinci Code (Hardcover)',
// Rating 5
'State of Fear (Paperback)',
'Prey',
'Digital Fortress : A Thriller (Mass Market Paperback)',
'Angels & Demons (Mass Market Paperback)',
]);
}
public function testReverseSortByRating() {
$this->csv->sort_by = 'rating';
$this->csv->conditions =
'title does not contain Prey AND ' .
'title does not contain Fortress AND ' .
'title does not contain Blood AND ' .
'title does not contain Fear';
$this->csv->sort_reverse = true;
$this->_compareWithExpected([
// Rating 5
'Angels & Demons (Mass Market Paperback)',
'The Traveller',
// Rating 4
'The Da Vinci Code (Hardcover)',
'The Rule of Four (Paperback)',
'Deception Point (Paperback)',
// Rating 3
'The Broker (Paperback)',
'The Last Templar',
// Rating 0
'The Third Secret',
'The Killing Kind',
]);
}
}

View File

@@ -0,0 +1,149 @@
<?php
class default_values_properties_Test extends PHPUnit\Framework\TestCase {
/**
* @access protected
* @var ParseCsvForPhp object
*/
protected $csv = null;
/**
* Setup
* Setup our test environment objects
*
* @access public
*/
public function setUp() {
//setup parse CSV
$this->csv = new ParseCsvForPhp();
}
public function test_heading_default() {
$this->assertTrue(is_bool($this->csv->heading));
$this->assertTrue($this->csv->heading);
}
public function test_fields_default() {
$this->assertTrue(is_array($this->csv->fields));
$this->assertCount(0, $this->csv->fields);
}
public function test_sort_by_default() {
$this->assertNull($this->csv->sort_by);
}
public function test_sort_reverse_default() {
$this->assertTrue(is_bool($this->csv->sort_reverse));
$this->assertFalse($this->csv->sort_reverse);
}
public function test_sort_type_default() {
$this->assertNull($this->csv->sort_type);
}
public function test_delimiter_default() {
$this->assertTrue(is_string($this->csv->delimiter));
$this->assertEquals(',', $this->csv->delimiter);
}
public function test_enclosure_default() {
$this->assertTrue(is_string($this->csv->enclosure));
$this->assertEquals('"', $this->csv->enclosure);
}
public function test_enclose_all_default() {
$this->assertTrue(is_bool($this->csv->enclose_all));
$this->assertFalse($this->csv->enclose_all);
}
public function test_conditions_default() {
$this->assertNull($this->csv->conditions);
}
public function test_offset_default() {
$this->assertNull($this->csv->offset);
}
public function test_limit_default() {
$this->assertNull($this->csv->limit);
}
public function test_auto_depth_default() {
$this->assertTrue(is_numeric($this->csv->auto_depth));
$this->assertEquals(15, $this->csv->auto_depth);
}
public function test_auto_non_chars_default() {
$this->assertTrue(is_string($this->csv->auto_non_chars));
$this->assertEquals("a-zA-Z0-9\n\r", $this->csv->auto_non_chars);
}
public function test_auto_preferred_default() {
$this->assertTrue(is_string($this->csv->auto_preferred));
$this->assertEquals(",;\t.:|", $this->csv->auto_preferred);
}
public function test_convert_encoding_default() {
$this->assertTrue(is_bool($this->csv->convert_encoding));
$this->assertFalse($this->csv->convert_encoding);
}
public function test_input_encoding_default() {
$this->assertTrue(is_string($this->csv->input_encoding));
$this->assertEquals('ISO-8859-1', $this->csv->input_encoding);
}
public function test_output_encoding_default() {
$this->assertTrue(is_string($this->csv->output_encoding));
$this->assertEquals('ISO-8859-1', $this->csv->output_encoding);
}
public function test_linefeed_default() {
$this->assertTrue(is_string($this->csv->linefeed));
$this->assertEquals("\r", $this->csv->linefeed);
}
public function test_output_delimiter_default() {
$this->assertTrue(is_string($this->csv->output_delimiter));
$this->assertEquals(',', $this->csv->output_delimiter);
}
public function test_output_filename_default() {
$this->assertTrue(is_string($this->csv->output_filename));
$this->assertEquals('data.csv', $this->csv->output_filename);
}
public function test_keep_file_data_default() {
$this->assertTrue(is_bool($this->csv->keep_file_data));
$this->assertFalse($this->csv->keep_file_data);
}
public function test_file_default() {
$this->assertNull($this->csv->file);
}
public function test_file_data_default() {
$this->assertNull($this->csv->file_data);
}
public function test_error_default() {
$this->assertTrue(is_numeric($this->csv->error));
$this->assertEquals(0, $this->csv->error);
}
public function test_error_info_default() {
$this->assertTrue(is_array($this->csv->error_info));
$this->assertCount(0, $this->csv->error_info);
}
public function test_titles_default() {
$this->assertTrue(is_array($this->csv->titles));
$this->assertCount(0, $this->csv->titles);
}
public function test_data_default() {
$this->assertTrue(is_array($this->csv->data));
$this->assertCount(0, $this->csv->data);
}
}

View File

@@ -0,0 +1,138 @@
<?php
class worthless_properties_Test extends PHPUnit\Framework\TestCase {
/**
* @access protected
* @var ParseCsvForPhp
*/
protected $csv = null;
/**
* Reflection Object
* The reflection class object
*
* @access protected
* @var ReflectionClass
*/
protected $reflection = null;
/**
* Reflection Properties
* The reflected class properties
*
* @access protected
* @var ReflectionProperty[]
*/
protected $properties = null;
/**
* Setup
* Setup our test environment objects
*
* @access public
*/
public function setUp() {
//setup parse CSV
$this->csv = new ParseCsvForPhp();
//setup the reflection class
$this->reflection = new ReflectionClass($this->csv);
//setup the reflected class properties
$this->properties = $this->reflection->getProperties();
}
/**
* Tear down
* Tear down our test environment objects
*
* @access public
*/
public function tearDown() {
$this->csv = null;
$this->reflection = null;
$this->properties = null;
}
/**
* test_propertiesCount
* Counts the number of properties to make sure we didn't add or
* subtract any without thinking
*
* @access public
*/
public function test_propertiesCount() {
$this->assertCount(28, $this->properties);
}
/**
* test_property_names
* We have an expected set of properties that should exists
* Make sure our expected number of properties matches the real
* count of properties and also check to make sure our expected
* properties exists within the class
*
* @access public
*/
public function test_property_names() {
//set our expected properties name(s)
$expected_names = array(
'heading',
'fields',
'sort_by',
'sort_reverse',
'sort_type',
'delimiter',
'enclosure',
'enclose_all',
'conditions',
'offset',
'limit',
'auto_depth',
'auto_non_chars',
'auto_preferred',
'convert_encoding',
'input_encoding',
'output_encoding',
'use_mb_convert_encoding',
'linefeed',
'output_delimiter',
'output_filename',
'keep_file_data',
'file',
'file_data',
'error',
'error_info',
'titles',
'data',
);
// Find our real properties
$real_properties = array_map(function (ReflectionProperty $property) {
return $property->getName();
}, $this->properties);
// Lets make sure our expected matches the number of real properties
$this->assertEquals($expected_names, $real_properties);
}
/**
* test_count_public_properties
* We at this point only have public properties so
* lets verify all properties are public
*
* @access public
*/
public function test_count_public_properties() {
$counter = 0;
for ($a = count($this->properties) - 1; $a >= 0; $a--) {
if ($this->properties[$a]->isPublic() === true) {
$counter++;
}
}
$this->assertCount($counter, $this->properties);
}
}