Completed
Branch releases/v0.2 (d913c4)
by Luke
02:17
created

File::__construct()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 10
CRAP Score 2

Importance

Changes 7
Bugs 0 Features 0
Metric Value
c 7
b 0
f 0
dl 0
loc 17
ccs 10
cts 10
cp 1
rs 9.4285
cc 2
eloc 8
nc 2
nop 4
crap 2
1
<?php
2
/**
3
 * CSVelte: Slender, elegant CSV for PHP.
4
 *
5
 * Inspired by Python's CSV module and Frictionless Data and the W3C's CSV
6
 * standardization efforts, CSVelte was written in an effort to take all the
7
 * suck out of working with CSV.
8
 *
9
 * @version   v0.2
10
 * @copyright Copyright (c) 2016 Luke Visinoni <[email protected]>
11
 * @author    Luke Visinoni <[email protected]>
12
 * @license   https://github.com/deni-zen/csvelte/blob/master/LICENSE The MIT License (MIT)
13
 */
14
namespace CSVelte\IO;
15
16
use CSVelte\Traits\IsReadable;
17
use CSVelte\Traits\IsWritable;
18
use CSVelte\Traits\IsSeekable;
19
20
use \SplFileObject;
21
use CSVelte\Contract\Readable;
22
use CSVelte\Contract\Writable;
23
use CSVelte\Contract\Seekable;
24
25
use CSVelte\Exception\NotYetImplementedException;
26
27
/**
28
 * CSVelte File.
29
 *
30
 * Represents a file for reading/writing. Implements both readable and writable
31
 * interfaces so that it can be passed to either ``CSVelte\Reader`` or
32
 * ``CSVelte\Writer``.
33
 *
34
 * @package    CSVelte
35
 * @subpackage CSVelte\IO
36
 * @copyright  (c) 2016, Luke Visinoni <[email protected]>
37
 * @author     Luke Visinoni <[email protected]>
38
 * @since      v0.2
39
 */
40
class File extends SplFileObject implements Readable, Writable, Seekable
41
{
42
    use IsReadable, IsWritable, IsSeekable;
43
44
    protected $seekable = null;
45
46
    /**
47
     * File Constructor
48
     *
49
     * Exactly the same as native SplFileObject constructor except that first it
50
     * resolves the filename if $use_include_path == true, to avoid weird
51
     * behavior with isReadable and isWritable.
52
     *
53
     * @param string  $filename         The filename to open
54
     * @param string  $open_mode        The fopen mode
55
     * @param boolean $use_include_path Should fopen search the include path
56
     * @param array   $context          An array of context options
57
     */
58 9
    public function __construct($filename, $open_mode = 'r', $use_include_path = false, $context = null)
59
    {
60
        /**
61
         * @note This fixes a possible bug? that causes SplFileObject to return
62
         *     false for isReadable() and isWritable() when $use_include_path
63
         *     is true, even if file exists and is both.
64
         */
65 9
        if ($use_include_path) {
66 1
            $filename = stream_resolve_include_path($filename);
67 1
        }
68 9
        parent::__construct(
69 9
            $filename,
70 9
            $open_mode,
71 9
            $use_include_path,
72
            $context
73 9
        );
74 9
    }
75
76
    /**
77
     * Get the file name.
78
     *
79
     * Return the entire file path and name of this file.
80
     *
81
     * @return string The file path and name
82
     */
83 2
    public function getName()
84
    {
85 2
        return $this->getPath();
86
    }
87
88
    /**
89
     * Read in the specified amount of characters from the file.
90
     *
91
     * Read $length characters from the file and return the resulting string.
92
     *
93
     * @param integer $length Amount of characters to read from file
94
     * @return string The specified amount of characters read from file
95
     */
96 4
    public function read($length)
97
    {
98 4
        $this->assertIsReadable();
99 4
        return $this->fread($length);
100
    }
101
102
    /**
103
     * Read the entire contents of file
104
     *
105
     * @param void
106
     * @return string The entire file contents
107
     * @access public
108
     */
109 1
    public function getContents()
110
    {
111 1
        return $this->read($this->getSize());
112
    }
113
114
    /**
115
     * Write data to the output
116
     *
117
     * @param string The data to write
118
     * @return int The number of bytes written
119
     * @access public
120
     */
121 4
    public function write($data)
122
    {
123 4
        $this->assertIsWritable();
124 4
        return $this->fwrite($data);
125
    }
126
127
    /**
128
     * Accessor for seekability.
129
     *
130
     * Returns true if possible to seek to a certain position within this file.
131
     *
132
     * @return boolean True if stream is seekable
133
     */
134 2
    public function isSeekable()
135
    {
136 2
        if (is_null($this->seekable)) {
137
            /**
138
             * @note This is the only way I could determine whether the file is
139
             *     seekable or not.
140
             */
141 2
            $pos = $this->ftell();
142 2
            $this->seekable = (0 === @$this->fseek($pos, SEEK_SET));
143 2
        }
144 2
        return $this->seekable;
145
    }
146
147
    /**
148
     * Seek to a position within an input
149
     *
150
     * @param integer Offset to seek to
151
     * @param integer Position from whence the offset should be applied
152
     * @return boolean True if seek was successful
153
     * @access public
154
     */
155 3
    public function seek($pos, $whence = SEEK_SET)
156
    {
157 3
        $this->assertIsSeekable();
158 2
        return $this->fseek($pos, $whence) === 0;
159
    }
160
}
161