Completed
Push — master ( b74cd0...088e4f )
by Dennis
11:47
created

Faker::guessProviderName()   C

Complexity

Conditions 32
Paths 32

Size

Total Lines 62
Code Lines 54

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 62
rs 5.8833
cc 32
eloc 54
nc 32
nop 1

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Dennis\Seeder\Provider;
3
4
/***************************************************************
5
 *
6
 *  Copyright notice
7
 *
8
 *  (c) 2016 Dennis Römmich <[email protected]>
9
 *
10
 *  All rights reserved
11
 *
12
 *  This script is part of the TYPO3 project. The TYPO3 project is
13
 *  free software; you can redistribute it and/or modify
14
 *  it under the terms of the GNU General Public License as published by
15
 *  the Free Software Foundation; either version 3 of the License, or
16
 *  (at your option) any later version.
17
 *
18
 *  The GNU General Public License can be found at
19
 *  http://www.gnu.org/copyleft/gpl.html.
20
 *
21
 *  This script is distributed in the hope that it will be useful,
22
 *  but WITHOUT ANY WARRANTY; without even the implied warranty of
23
 *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
24
 *  GNU General Public License for more details.
25
 *
26
 *  This copyright notice MUST APPEAR in all copies of the script!
27
 ***************************************************************/
28
use TYPO3\CMS\Core\Utility\GeneralUtility;
29
30
/**
31
 * Class Faker
32
 *
33
 * @method string getName()
34
 * @method string getFirstName()
35
 * @method string getFirstNameMale()
36
 * @method string getFirstNameFemale()
37
 * @method string getLastName()
38
 * @method string getTitle()
39
 * @method string getTitleMale()
40
 * @method string getTitleFemale()
41
 * @method string getCitySuffix()
42
 * @method string getStreetSuffix()
43
 * @method string getBuildingNumber()
44
 * @method string getCity()
45
 * @method string getStreetName()
46
 * @method string getStreetAddress()
47
 * @method string getPostcode()
48
 * @method string getAddress()
49
 * @method string getCountry()
50
 * @method string getLatitude()
51
 * @method string getLongitude()
52
 * @method string getEan13()
53
 * @method string getEan8()
54
 * @method string getIsbn13()
55
 * @method string getIsbn10()
56
 * @method string getPhoneNumber()
57
 * @method string getCompany()
58
 * @method string getCompanySuffix()
59
 * @method string getJobTitle()
60
 * @method string getCreditCardType()
61
 * @method string getCreditCardNumber()
62
 * @method string getCreditCardExpirationDate()
63
 * @method string getCreditCardExpirationDateString()
64
 * @method string getCreditCardDetails()
65
 * @method string getBankAccountNumber()
66
 * @method string getIban()
67
 * @method string getSwiftBicNumber()
68
 * @method string getVat()
69
 * @method string getWord()
70
 * @method string getWords()
71
 * @method string getSentence()
72
 * @method string getParagraph()
73
 * @method string getText()
74
 * @method string getRealText()
75
 * @method string getEmail()
76
 * @method string getSafeEmail()
77
 * @method string getFreeEmail()
78
 * @method string getCompanyEmail()
79
 * @method string getFreeEmailDomain()
80
 * @method string getSafeEmailDomain()
81
 * @method string getUserName()
82
 * @method string getPassword()
83
 * @method string getDomainName()
84
 * @method string getDomainWord()
85
 * @method string getTld()
86
 * @method string getUrl()
87
 * @method string getSlug()
88
 * @method string getIpv4()
89
 * @method string getIpv6()
90
 * @method string getLocalIpv4()
91
 * @method string getMacAddress()
92
 * @method string getUnixTime()
93
 * @method string getDateTime()
94
 * @method string getDateTimeAD()
95
 * @method string getIso8601()
96
 * @method string getDateTimeThisCentury()
97
 * @method string getDateTimeThisDecade()
98
 * @method string getDateTimeThisYear()
99
 * @method string getDateTimeThisMonth()
100
 * @method string getAmPm()
101
 * @method string getDayOfMonth()
102
 * @method string getDayOfWeek()
103
 * @method string getMonth()
104
 * @method string getMonthName()
105
 * @method string getYear()
106
 * @method string getCentury()
107
 * @method string getTimezone()
108
 * @method string getDate()
109
 * @method string getTime()
110
 * @method string getMd5()
111
 * @method string getSha1()
112
 * @method string getSha256()
113
 * @method string getLocale()
114
 * @method string getCountryCode()
115
 * @method string getCountryISOAlpha3()
116
 * @method string getLanguageCode()
117
 * @method string getCurrencyCode()
118
 * @method string getBoolean()
119
 * @method string getRandomDigit()
120
 * @method string getRandomDigitNotNull()
121
 * @method string getRandomLetter()
122
 * @method string getRandomAscii()
123
 * @method string getRandomNumber()
124
 * @method string getRandomFloat()
125
 * @method string getMacProcessor()
126
 * @method string getLinuxProcessor()
127
 * @method string getUserAgent()
128
 * @method string getChrome()
129
 * @method string getFirefox()
130
 * @method string getSafari()
131
 * @method string getOpera()
132
 * @method string getInternetExplorer()
133
 * @method string getWindowsPlatformToken()
134
 * @method string getMacPlatformToken()
135
 * @method string getLinuxPlatformToken()
136
 * @method string getUuid()
137
 * @method string getMimeType()
138
 * @method string getFileExtension()
139
 * @method string getImageUrl()
140
 * @method string getHexColor()
141
 * @method string getSafeHexColor()
142
 * @method string getRgbColor()
143
 * @method string getRgbCssColor()
144
 * @method string getSafeColorName()
145
 * @method string getColorName()
146
 *
147
 * @package Dennis\Seeder\Provider\Faker
148
 */
149
class Faker implements \Dennis\Seeder\Faker
150
{
151
    /** @var \Faker\Generator $generator */
152
    protected $generator = null;
153
154
    /** @var \Faker\Guesser\Name $guesser */
155
    protected $guesser = null;
156
157
    /**
158
     * Fields we don't take care of
159
     *
160
     * @var array $skippedProvider
161
     */
162
    public static $skippedProvider = [
163
        'l10n_parent',
164
        'l10n_diffsource',
165
        'cruser_id',
166
        'TSconfig',
167
        'tx_extbase_type',
168
        'felogin_redirectPid',
169
        't3ver_label',
170
        'starttime',
171
        'endtime',
172
    ];
173
174
    /**
175
     * Faker constructor.
176
     */
177
    public function __construct(\Faker\Generator $generator)
178
    {
179
        $this->generator = $generator;
180
    }
181
182
    /**
183
     * Returns random dummy data by property
184
     *
185
     * @param string $property
186
     * @return mixed
187
     * @throws NotFoundException
188
     */
189
    public function get($property)
190
    {
191
        if (!$provider = $this->guessProviderName($property)) {
192
            $provider = $property;
193
        }
194
195
        if (!$this->hasProvider($provider)) {
196
            throw new \Dennis\Seeder\Provider\NotFoundException(
197
                'No provider found for ' . $provider
198
            );
199
        }
200
201
        return $this->generate($provider);
202
    }
203
204
    /**
205
     * @return array
206
     */
207
    public function getSupportedProviders()
208
    {
209
        return $this->generator->getProviders();
210
    }
211
212
    /**
213
     * @param string $providerName
214
     * @return mixed
215
     */
216
    private function generate($providerName)
217
    {
218
        return $this->generator->$providerName;
219
    }
220
221
    /**
222
     * @param string $name
223
     * @return bool
224
     */
225
    private function hasProvider($name)
226
    {
227
        if (empty($name)) {
228
            return false;
229
        }
230
        if ($this->hasCustomProvider($name)) {
231
            return true;
232
        }
233
        try {
234
            if ($this->generator->getFormatter($name)) {
235
                return true;
236
            }
237
        } catch (\InvalidArgumentException $exception) {
238
            return false;
239
        }
240
        return false;
241
    }
242
243
    /**
244
     * @param string $className
245
     * @return mixed
246
     * @throws \Exception
247
     */
248
    private function callCustomProvider($className)
249
    {
250
        /** @var \Dennis\Seeder\Provider $providerClass */
251
        $providerClass = GeneralUtility::makeInstance($className, $this);
252
        if (!$providerClass instanceof \Dennis\Seeder\Provider) {
253
            throw new \Exception(get_class($providerClass) . ' must implement ' . \Dennis\Seeder\Provider::class);
254
        }
255
        return $providerClass->generate();
256
    }
257
258
    /**
259
     * @param string $name
260
     * @return bool
261
     */
262
    private function hasCustomProvider($name)
0 ignored issues
show
Coding Style introduced by
hasCustomProvider uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
263
    {
264
        return (isset($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['seeder']['provider'][$name]) && class_exists(
265
                $GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['seeder']['provider'][$name]
266
            ));
267
    }
268
269
    /**
270
     * @param string $name
271
     * @return string
0 ignored issues
show
Documentation introduced by
Should the return type not be string|null?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
272
     * @throws NotFoundException
273
     * @throws \Exception
274
     */
275
    public function guessProviderName($name)
276
    {
277
        if (empty($name)) {
278
            throw new \Dennis\Seeder\Provider\NotFoundException();
279
        }
280
        if (preg_match('/^is[_A-Z]/', $name)) {
281
            return 'boolean';
282
        }
283
        if (preg_match('/(_a|A)t$/', $name)) {
284
            return 'unixtime';
285
        }
286
        $name = GeneralUtility::strtolower($name);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $name. This often makes code more readable.
Loading history...
Deprecated Code introduced by
The method TYPO3\CMS\Core\Utility\G...alUtility::strtolower() has been deprecated with message: since TYPO3 CMS v8, this method will be removed in TYPO3 CMS v9, use mb_strtolower() instead

This method has been deprecated. The supplier of the class has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the method will be removed from the class and what other method or class to use instead.

Loading history...
287
        $name = str_replace('_', '', $name);
0 ignored issues
show
Coding Style introduced by
Consider using a different name than the parameter $name. This often makes code more readable.
Loading history...
288
        if ($this->hasProvider($name)) {
289
            return $name;
290
        }
291
        switch ($name) {
292
            case 'mail':
293
            case 'emailaddress':
294
                return 'email';
295
            case 'phone':
296
            case 'telephone':
297
            case 'fax':
298
            case 'telnumber':
299
                return 'phonenumber';
300
            case 'town':
301
                return 'city';
302
            case 'zipcode':
303
            case 'zip':
304
                return 'postcode';
305
            case 'currency':
306
                return 'currencycode';
307
            case 'website':
308
                return 'url';
309
            case 'companyname':
310
            case 'employer':
311
                return 'company';
312
            case 'body':
313
            case 'bodytext':
314
            case 'summary':
315
            case 'teaser':
316
            case 'article':
317
            case 'description':
318
                return 'text';
319
            case 'middlename':
320
                return 'name';
321
            case 'uri':
322
            case 'www':
323
                return 'url';
324
            case 'image':
325
                return 'imageurl';
326
            case 'lastlogin':
327
            case 'crdate':
328
            case 'tstamp':
329
                return 'unixtime';
330
            case 'disable':
331
                return 'boolean';
332
            // Default provider is text:
333
            default:
334
                return null;
335
        }
336
    }
337
338
    /**
339
     * @param $name
340
     * @param $value
341
     * @return mixed
342
     * @throws NotFoundException
343
     * @throws \Exception
344
     */
345
    public function __call($name, $value)
0 ignored issues
show
Coding Style introduced by
__call uses the super-global variable $GLOBALS which is generally not recommended.

Instead of super-globals, we recommend to explicitly inject the dependencies of your class. This makes your code less dependent on global state and it becomes generally more testable:

// Bad
class Router
{
    public function generate($path)
    {
        return $_SERVER['HOST'].$path;
    }
}

// Better
class Router
{
    private $host;

    public function __construct($host)
    {
        $this->host = $host;
    }

    public function generate($path)
    {
        return $this->host.$path;
    }
}

class Controller
{
    public function myAction(Request $request)
    {
        // Instead of
        $page = isset($_GET['page']) ? intval($_GET['page']) : 1;

        // Better (assuming you use the Symfony2 request)
        $page = $request->query->get('page', 1);
    }
}
Loading history...
346
    {
347
        $propertyArray = explode('get', $name);
348
        $property = strtolower($propertyArray[1]);
349
        if ($this->hasCustomProvider($property)) {
350
            return $this->callCustomProvider($GLOBALS['TYPO3_CONF_VARS']['EXTCONF']['seeder']['provider'][$property]);
351
        }
352
353
        return $this->get($property);
354
    }
355
}
356