Complex classes like Kohana_Jam_Errors often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.
Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.
While breaking up the class, it is a good idea to analyze how other classes use Kohana_Jam_Errors, and based on these observations, apply Extract Interface, too.
| 1 | <?php defined('SYSPATH') OR die('No direct script access.'); |
||
| 11 | abstract class Kohana_Jam_Errors implements Countable, SeekableIterator, ArrayAccess { |
||
| 12 | |||
| 13 | 1 | public static function message($error_filename, $attribute, $error, $params) |
|
| 14 | { |
||
| 15 | 1 | if ($message = Kohana::message($error_filename, "{$attribute}.{$error}")) |
|
| 16 | 1 | { |
|
| 17 | |||
| 18 | } |
||
| 19 | 1 | elseif ($message = Kohana::message('validators', $error)) |
|
| 20 | { |
||
| 21 | |||
| 22 | 1 | } |
|
| 23 | else |
||
| 24 | { |
||
| 25 | return $error_filename.":{$attribute}.{$error}"; |
||
| 26 | } |
||
| 27 | |||
| 28 | 1 | return __($message, $params); |
|
| 29 | } |
||
| 30 | |||
| 31 | 1 | public static function attribute_label(Jam_Meta $meta, $attribute_name) |
|
| 32 | { |
||
| 33 | 1 | if ($attribute = $meta->attribute($attribute_name)) |
|
| 34 | 1 | { |
|
| 35 | 1 | $label = $attribute->label; |
|
| 36 | 1 | } |
|
| 37 | else |
||
| 38 | { |
||
| 39 | $label = Inflector::humanize($attribute_name); |
||
| 40 | } |
||
| 41 | |||
| 42 | 1 | return UTF8::ucfirst($label); |
|
| 43 | } |
||
| 44 | |||
| 45 | /** |
||
| 46 | * @var Jam_Meta The current meta object, based on the model we're returning |
||
| 47 | */ |
||
| 48 | protected $_meta = NULL; |
||
| 49 | |||
| 50 | /** |
||
| 51 | * @var Jam_Validated The current class we're placing results into |
||
| 52 | */ |
||
| 53 | protected $_model = NULL; |
||
| 54 | |||
| 55 | /** |
||
| 56 | * @var string |
||
| 57 | */ |
||
| 58 | protected $_error_filename = NULL; |
||
| 59 | |||
| 60 | private $_container = array(); |
||
| 61 | private $_current; |
||
| 62 | |||
| 63 | /** |
||
| 64 | * Tracks a database result |
||
| 65 | * |
||
| 66 | * @param mixed $result |
||
|
|
|||
| 67 | * @param mixed $model |
||
| 68 | */ |
||
| 69 | 194 | public function __construct(Jam_Validated $model, $error_filename) |
|
| 70 | { |
||
| 71 | 194 | $this->_model = $model; |
|
| 72 | 194 | $this->_meta = $model->meta(); |
|
| 73 | 194 | $this->_error_filename = $error_filename; |
|
| 74 | 194 | } |
|
| 75 | |||
| 76 | 182 | public function as_array() |
|
| 77 | { |
||
| 78 | 182 | return $this->_container; |
|
| 79 | } |
||
| 80 | |||
| 81 | 110 | public function add($attribute, $error, array $params = array()) |
|
| 82 | { |
||
| 83 | 110 | if ( ! isset($this->_container[$attribute])) |
|
| 84 | 110 | { |
|
| 85 | 110 | $this->_container[$attribute] = array(); |
|
| 86 | 110 | } |
|
| 87 | |||
| 88 | 110 | $this->_container[$attribute][$error] = $params; |
|
| 89 | |||
| 90 | 110 | return $this; |
|
| 91 | } |
||
| 92 | |||
| 93 | 3 | public function messages($attribute = NULL) |
|
| 94 | { |
||
| 95 | 3 | $messages = array(); |
|
| 96 | |||
| 97 | 3 | if ($attribute !== NULL) |
|
| 98 | 3 | { |
|
| 99 | 3 | foreach (array_filter(Arr::extract($this->_container, (array) $attribute)) as $attribute_name => $errors) |
|
| 100 | { |
||
| 101 | foreach ($errors as $error => $params) |
||
| 102 | { |
||
| 103 | $messages[] = Jam_Errors::message($this->_error_filename, $attribute_name, $error, Arr::merge($params, array( |
||
| 104 | ':model' => $this->_meta->model(), |
||
| 105 | ':attribute' => Jam_Errors::attribute_label($this->_meta, $attribute_name), |
||
| 106 | ))); |
||
| 107 | } |
||
| 108 | 3 | } |
|
| 109 | |||
| 110 | 3 | return $messages; |
|
| 111 | } |
||
| 112 | |||
| 113 | foreach ($this->_container as $attribute => $errors) |
||
| 114 | { |
||
| 115 | $messages[$attribute] = $this->messages($attribute); |
||
| 116 | } |
||
| 117 | |||
| 118 | return $messages; |
||
| 119 | } |
||
| 120 | |||
| 121 | 1 | public function messages_all() |
|
| 126 | |||
| 127 | 1 | private function _add_messages_all(Jam_Validated $model, array & $messages) |
|
| 161 | |||
| 162 | public function messages_dump() |
||
| 166 | |||
| 167 | private function _model_messages_dump(Jam_Model $model) |
||
| 200 | |||
| 201 | public function __toString() |
||
| 202 | { |
||
| 203 | return $this->render(); |
||
| 204 | } |
||
| 205 | |||
| 206 | public function render() |
||
| 207 | { |
||
| 208 | $all_messages = array(); |
||
| 209 | foreach ($this->messages() as $field => $messages) |
||
| 210 | { |
||
| 211 | $all_messages[] = join(', ', $messages); |
||
| 212 | } |
||
| 213 | |||
| 214 | return join(', ', $all_messages); |
||
| 215 | } |
||
| 216 | |||
| 217 | public function first() |
||
| 226 | |||
| 227 | public function seek($offset) |
||
| 228 | { |
||
| 229 | if ($this->offsetExists($offset)) |
||
| 230 | { |
||
| 231 | $this->_current = $offset; |
||
| 232 | |||
| 233 | return TRUE; |
||
| 234 | } |
||
| 240 | |||
| 241 | public function offsetSet($offset, $value) |
||
| 245 | |||
| 246 | public function offsetExists($offset) |
||
| 250 | |||
| 251 | public function offsetUnset($offset) |
||
| 259 | |||
| 260 | 1 | public function offsetGet($offset) |
|
| 264 | |||
| 265 | 1 | public function rewind() |
|
| 270 | |||
| 271 | 1 | public function current() |
|
| 275 | |||
| 276 | 1 | public function key() |
|
| 280 | |||
| 281 | 1 | public function next() |
|
| 287 | |||
| 288 | public function prev() |
||
| 294 | |||
| 295 | 1 | public function valid() |
|
| 299 | |||
| 300 | 11 | public function count() |
|
| 304 | } |
||
| 305 |
This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.
Consider the following example. The parameter
$italyis not defined by the methodfinale(...).The most likely cause is that the parameter was removed, but the annotation was not.