/vendor/league/csv/src/AbstractCsv.php

https://bitbucket.org/ltdwebant/laboratorium · PHP · 273 lines · 109 code · 31 blank · 133 comment · 8 complexity · 9ed4b7c2a9ebf128faea583a6d7fda6b MD5 · raw file

  1. <?php
  2. /**
  3. * This file is part of the League.csv library
  4. *
  5. * @license http://opensource.org/licenses/MIT
  6. * @link https://github.com/thephpleague/csv/
  7. * @version 8.2.2
  8. * @package League.csv
  9. *
  10. * For the full copyright and license information, please view the LICENSE
  11. * file that was distributed with this source code.
  12. */
  13. namespace League\Csv;
  14. use InvalidArgumentException;
  15. use IteratorAggregate;
  16. use JsonSerializable;
  17. use League\Csv\Config\Controls;
  18. use League\Csv\Config\Output;
  19. use League\Csv\Modifier\QueryFilter;
  20. use League\Csv\Modifier\StreamFilter;
  21. use League\Csv\Modifier\StreamIterator;
  22. use SplFileInfo;
  23. use SplFileObject;
  24. use SplTempFileObject;
  25. /**
  26. * An abstract class to enable basic CSV manipulation
  27. *
  28. * @package League.csv
  29. * @since 4.0.0
  30. *
  31. */
  32. abstract class AbstractCsv implements JsonSerializable, IteratorAggregate
  33. {
  34. use Controls;
  35. use Output;
  36. use QueryFilter;
  37. use StreamFilter;
  38. /**
  39. * UTF-8 BOM sequence
  40. */
  41. const BOM_UTF8 = "\xEF\xBB\xBF";
  42. /**
  43. * UTF-16 BE BOM sequence
  44. */
  45. const BOM_UTF16_BE = "\xFE\xFF";
  46. /**
  47. * UTF-16 LE BOM sequence
  48. */
  49. const BOM_UTF16_LE = "\xFF\xFE";
  50. /**
  51. * UTF-32 BE BOM sequence
  52. */
  53. const BOM_UTF32_BE = "\x00\x00\xFE\xFF";
  54. /**
  55. * UTF-32 LE BOM sequence
  56. */
  57. const BOM_UTF32_LE = "\xFF\xFE\x00\x00";
  58. /**
  59. * The path
  60. *
  61. * can be a StreamIterator object, a SplFileObject object or the string path to a file
  62. *
  63. * @var StreamIterator|SplFileObject|string
  64. */
  65. protected $path;
  66. /**
  67. * The file open mode flag
  68. *
  69. * @var string
  70. */
  71. protected $open_mode;
  72. /**
  73. * Creates a new instance
  74. *
  75. * The path must be an SplFileInfo object
  76. * an object that implements the `__toString` method
  77. * a path to a file
  78. *
  79. * @param StreamIterator|SplFileObject|string $path The file path
  80. * @param string $open_mode The file open mode flag
  81. */
  82. protected function __construct($path, $open_mode = 'r+')
  83. {
  84. $this->open_mode = strtolower($open_mode);
  85. $this->path = $path;
  86. $this->initStreamFilter($this->path);
  87. }
  88. /**
  89. * The destructor
  90. */
  91. public function __destruct()
  92. {
  93. $this->path = null;
  94. }
  95. /**
  96. * Return a new {@link AbstractCsv} from a SplFileObject
  97. *
  98. * @param SplFileObject $file
  99. *
  100. * @return static
  101. */
  102. public static function createFromFileObject(SplFileObject $file)
  103. {
  104. $csv = new static($file);
  105. $controls = $file->getCsvControl();
  106. $csv->setDelimiter($controls[0]);
  107. $csv->setEnclosure($controls[1]);
  108. if (isset($controls[2])) {
  109. $csv->setEscape($controls[2]);
  110. }
  111. return $csv;
  112. }
  113. /**
  114. * Return a new {@link AbstractCsv} from a PHP resource stream or a StreamIterator
  115. *
  116. * @param resource $stream
  117. *
  118. * @return static
  119. */
  120. public static function createFromStream($stream)
  121. {
  122. return new static(new StreamIterator($stream));
  123. }
  124. /**
  125. * Return a new {@link AbstractCsv} from a string
  126. *
  127. * The string must be an object that implements the `__toString` method,
  128. * or a string
  129. *
  130. * @param string $str the string
  131. *
  132. * @return static
  133. */
  134. public static function createFromString($str)
  135. {
  136. $file = new SplTempFileObject();
  137. $file->fwrite(static::validateString($str));
  138. return new static($file);
  139. }
  140. /**
  141. * validate a string
  142. *
  143. * @param mixed $str the value to evaluate as a string
  144. *
  145. * @throws InvalidArgumentException if the submitted data can not be converted to string
  146. *
  147. * @return string
  148. */
  149. protected static function validateString($str)
  150. {
  151. if (is_string($str) || (is_object($str) && method_exists($str, '__toString'))) {
  152. return (string) $str;
  153. }
  154. throw new InvalidArgumentException('Expected data must be a string or stringable');
  155. }
  156. /**
  157. * Return a new {@link AbstractCsv} from a file path
  158. *
  159. * @param mixed $path file path
  160. * @param string $open_mode the file open mode flag
  161. *
  162. * @throws InvalidArgumentException If $path is a SplTempFileObject object
  163. *
  164. * @return static
  165. */
  166. public static function createFromPath($path, $open_mode = 'r+')
  167. {
  168. if ($path instanceof SplTempFileObject) {
  169. throw new InvalidArgumentException('an `SplTempFileObject` object does not contain a valid path');
  170. }
  171. if ($path instanceof SplFileInfo) {
  172. $path = $path->getPath().'/'.$path->getBasename();
  173. }
  174. return new static(static::validateString($path), $open_mode);
  175. }
  176. /**
  177. * Return a new {@link AbstractCsv} instance from another {@link AbstractCsv} object
  178. *
  179. * @param string $class the class to be instantiated
  180. * @param string $open_mode the file open mode flag
  181. *
  182. * @return static
  183. */
  184. protected function newInstance($class, $open_mode)
  185. {
  186. $csv = new $class($this->path, $open_mode);
  187. $csv->delimiter = $this->delimiter;
  188. $csv->enclosure = $this->enclosure;
  189. $csv->escape = $this->escape;
  190. $csv->input_encoding = $this->input_encoding;
  191. $csv->input_bom = $this->input_bom;
  192. $csv->output_bom = $this->output_bom;
  193. $csv->newline = $this->newline;
  194. return $csv;
  195. }
  196. /**
  197. * Return a new {@link Writer} instance from a {@link AbstractCsv} object
  198. *
  199. * @param string $open_mode the file open mode flag
  200. *
  201. * @return Writer
  202. */
  203. public function newWriter($open_mode = 'r+')
  204. {
  205. return $this->newInstance(Writer::class, $open_mode);
  206. }
  207. /**
  208. * Return a new {@link Reader} instance from a {@link AbstractCsv} object
  209. *
  210. * @param string $open_mode the file open mode flag
  211. *
  212. * @return Reader
  213. */
  214. public function newReader($open_mode = 'r+')
  215. {
  216. return $this->newInstance(Reader::class, $open_mode);
  217. }
  218. /**
  219. * Returns the inner CSV Document Iterator object
  220. *
  221. * @return StreamIterator|SplFileObject
  222. */
  223. public function getIterator()
  224. {
  225. $iterator = $this->setIterator();
  226. $iterator->setCsvControl($this->delimiter, $this->enclosure, $this->escape);
  227. $iterator->setFlags(SplFileObject::READ_CSV | SplFileObject::READ_AHEAD | SplFileObject::SKIP_EMPTY);
  228. return $iterator;
  229. }
  230. /**
  231. * Set the Inner Iterator
  232. *
  233. * @return StreamIterator|SplFileObject
  234. */
  235. protected function setIterator()
  236. {
  237. if ($this->path instanceof StreamIterator || $this->path instanceof SplFileObject) {
  238. return $this->path;
  239. }
  240. return new SplFileObject($this->getStreamFilterPath(), $this->open_mode);
  241. }
  242. }