Completed
Push — master ( cfa61c...ad11a2 )
by Ben
02:02
created

AbstractFormatterProvider::hasFormat()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 11
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 2
Metric Value
c 2
b 0
f 2
dl 0
loc 11
rs 9.4285
cc 2
eloc 6
nc 2
nop 1
1
<?php
2
3
namespace Benrowe\Formatter;
4
5
use ReflectionClass;
6
use ReflectionMethod;
7
use InvalidArgumentException;
8
9
/**
10
 * AbstractFormatterProvider
11
 *
12
 * Base level functionality for any FormatterProvider that wants to implement
13
 * the standard formatting convention of `public function asFormatType($value)`
14
 *
15
 * @package Benrowe\Formatter
16
 */
17
abstract class AbstractFormatterProvider implements FormatterProvider
18
{
19
    protected $defaultFormatter;
20
    /**
21
     * method prefix
22
     */
23
    const METHOD_PATTERN_MATCH = '/^as([A-Z]\w+)$/';
24
25
    public $nullValue = '<span>Not Set</span>';
26
27
    /**
28
     * Provide a list of formatters this that are available from this provider
29
     *
30
     * @return array
31
     */
32
    public function formats()
33
    {
34
        // get a list of all public non-static methods that start with
35
        // METHOD_PREFIX
36
        $reflect = new ReflectionClass($this);
37
        $formats = [];
38
        foreach ($reflect->getMethods(ReflectionMethod::IS_PUBLIC) as $method) {
39
            $name = $this->getFormatterName($method);
40
            if ($name) {
41
                $formats[] = $name;
42
            }
43
        }
44
45
        return $formats;
46
    }
47
48
    /**
49
     * Get the name of the formatter method
50
     *
51
     * @param ReflectionMethod $method
52
     * @return string
53
     */
54
    private function getFormatterName(ReflectionMethod $method)
55
    {
56
        preg_match(self::METHOD_PATTERN_MATCH, $method->getName(), $match);
57
        $isFormatter = !$method->isStatic() && $match;
0 ignored issues
show
Bug Best Practice introduced by
The expression $match of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
58
59
        return $isFormatter ? strtolower($match[1]) : '';
60
    }
61
62
    /**
63
     * Combine the value & params
64
     * @param  mixed $value  the value (first argument of the format method)
65
     * @param  string|array $format the name of the formatter, or an array of
66
     *                              the formatter and its addtional params
67
     * @return array of two elements, format and the params for the formatter
68
     *                  method
69
     * @throws InvalidArgumentException if the format is incorrect
70
     */
71
    protected function extractFormatAndParams($value, $format)
72
    {
73
        $params = [$value];
74
75
        if (is_array($format)) {
76
            if (!isset($format[0])) {
77
                throw new InvalidArgumentException(
78
                    'The $format must contain at least one element'
79
                );
80
            }
81
            $params = $format;
82
            $format = array_shift($params);
83
            array_unshift($params, $value);
84
        }
85
86
        return [$format, $params];
87
    }
88
89
    /**
90
     * Format the supplied value, based on the desired format + configuration
91
     *
92
     * @param  mixed $value The value to format
93
     * @param  string|array|null $format either the formatter name, or the formatter
94
     *                              config as an array. If it's an array, the
95
     *                              first item must be the same of the formatter
96
     * @return mixed
97
     * @throws InvalidArgumentException if the format is incorrect
98
     */
99
    public function format($value, $format = null)
100
    {
101
        $format = $format ?: $this->defaultFormatter;
102
103
        list($format, $params) = $this->extractFormatAndParams($value, $format);
104
105
        if (!$this->hasFormat($format)) {
106
            throw new InvalidArgumentException(
107
                'Unknown format: "' . $format . '"'
108
            );
109
        }
110
111
        // is the formatter in a custom defined
112
113
        $func = [$this, 'as'.$format];
114
115
        return call_user_func_array($func, $params);
116
    }
117
118
    /**
119
     * Check if the requested format exists in this provider
120
     *
121
     * @param  string  $format The formatter name you want to check for
122
     * @return boolean
123
     */
124
    public function hasFormat($format)
125
    {
126
        if (!preg_match("/^[A-Za-z]+$/", $format)) {
127
            throw new InvalidArgumentException(
128
                'Format "' . $format . '" is not provided in correct format'
129
            );
130
        }
131
        $formats = $this->formats();
132
133
        return in_array($format, $formats);
134
    }
135
}
136