Subversion-Projekte lars-tiefland.laravel_shop

Revision

Details | Letzte Änderung | Log anzeigen | RSS feed

Revision Autor Zeilennr. Zeile
148 lars 1
<?php
2
 
3
/**
4
 * Hoa
5
 *
6
 *
7
 * @license
8
 *
9
 * New BSD License
10
 *
11
 * Copyright © 2007-2017, Hoa community. All rights reserved.
12
 *
13
 * Redistribution and use in source and binary forms, with or without
14
 * modification, are permitted provided that the following conditions are met:
15
 *     * Redistributions of source code must retain the above copyright
16
 *       notice, this list of conditions and the following disclaimer.
17
 *     * Redistributions in binary form must reproduce the above copyright
18
 *       notice, this list of conditions and the following disclaimer in the
19
 *       documentation and/or other materials provided with the distribution.
20
 *     * Neither the name of the Hoa nor the names of its contributors may be
21
 *       used to endorse or promote products derived from this software without
22
 *       specific prior written permission.
23
 *
24
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
25
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
26
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
27
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDERS AND CONTRIBUTORS BE
28
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
29
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
30
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
31
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
32
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
33
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
34
 * POSSIBILITY OF SUCH DAMAGE.
35
 */
36
 
37
namespace Psy\Readline\Hoa;
38
 
39
/**
40
 * Class \Hoa\Console\Readline\Autocompleter\Path.
41
 *
42
 * Path autocompleter.
43
 */
44
class AutocompleterPath implements Autocompleter
45
{
46
    /**
47
     * Root is the current working directory.
48
     */
49
    const PWD = null;
50
 
51
    /**
52
     * Root.
53
     */
54
    protected $_root = null;
55
 
56
    /**
57
     * Iterator factory. Please, see the self::setIteratorFactory method.
58
     */
59
    protected $_iteratorFactory = null;
60
 
61
    /**
62
     * Constructor.
63
     */
64
    public function __construct(
65
        string $root = null,
66
        \Closure $iteratorFactory = null
67
    ) {
68
        if (null === $root) {
69
            $root = static::PWD;
70
        }
71
 
72
        if (null !== $root) {
73
            $this->setRoot($root);
74
        }
75
 
76
        if (null !== $iteratorFactory) {
77
            $this->setIteratorFactory($iteratorFactory);
78
        }
79
    }
80
 
81
    /**
82
     * Complete a word.
83
     * Returns null for no word, a full-word or an array of full-words.
84
     */
85
    public function complete(&$prefix)
86
    {
87
        $root = $this->getRoot();
88
 
89
        if (static::PWD === $root) {
90
            $root = \getcwd();
91
        }
92
 
93
        $path = $root.\DIRECTORY_SEPARATOR.$prefix;
94
 
95
        if (!\is_dir($path)) {
96
            $path = \dirname($path).\DIRECTORY_SEPARATOR;
97
            $prefix = \basename($prefix);
98
        } else {
99
            $prefix = null;
100
        }
101
 
102
        $iteratorFactory = $this->getIteratorFactory() ?:
103
                               static::getDefaultIteratorFactory();
104
 
105
        try {
106
            $iterator = $iteratorFactory($path);
107
            $out = [];
108
            $length = \mb_strlen($prefix);
109
 
110
            foreach ($iterator as $fileinfo) {
111
                $filename = $fileinfo->getFilename();
112
 
113
                if (null === $prefix ||
114
                    (\mb_substr($filename, 0, $length) === $prefix)) {
115
                    if ($fileinfo->isDir()) {
116
                        $out[] = $filename.'/';
117
                    } else {
118
                        $out[] = $filename;
119
                    }
120
                }
121
            }
122
        } catch (\Exception $e) {
123
            return null;
124
        }
125
 
126
        $count = \count($out);
127
 
128
        if (1 === $count) {
129
            return $out[0];
130
        }
131
 
132
        if (0 === $count) {
133
            return null;
134
        }
135
 
136
        return $out;
137
    }
138
 
139
    /**
140
     * Get definition of a word.
141
     */
142
    public function getWordDefinition(): string
143
    {
144
        return '/?[\w\d\\_\-\.]+(/[\w\d\\_\-\.]*)*';
145
    }
146
 
147
    /**
148
     * Set root.
149
     */
150
    public function setRoot(string $root)
151
    {
152
        $old = $this->_root;
153
        $this->_root = $root;
154
 
155
        return $old;
156
    }
157
 
158
    /**
159
     * Get root.
160
     */
161
    public function getRoot()
162
    {
163
        return $this->_root;
164
    }
165
 
166
    /**
167
     * Set iterator factory (a finder).
168
     */
169
    public function setIteratorFactory(\Closure $iteratorFactory)
170
    {
171
        $old = $this->_iteratorFactory;
172
        $this->_iteratorFactory = $iteratorFactory;
173
 
174
        return $old;
175
    }
176
 
177
    /**
178
     * Get iterator factory.
179
     */
180
    public function getIteratorFactory()
181
    {
182
        return $this->_iteratorFactory;
183
    }
184
 
185
    /**
186
     * Get default iterator factory (based on \DirectoryIterator).
187
     */
188
    public static function getDefaultIteratorFactory()
189
    {
190
        return function ($path) {
191
            return new \DirectoryIterator($path);
192
        };
193
    }
194
}