Complex classes like Requests_Cookie 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 Requests_Cookie, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 15 | * Cookie storage object |
||
| 16 | * |
||
| 17 | * @package Rmccue\Requests |
||
| 18 | * @subpackage Cookies |
||
| 19 | */ |
||
| 20 | class Cookie { |
||
| 21 | /** |
||
| 22 | * Cookie name. |
||
| 23 | * |
||
| 24 | * @var string |
||
| 25 | */ |
||
| 26 | public $name; |
||
| 27 | |||
| 28 | /** |
||
| 29 | * Cookie value. |
||
| 30 | * |
||
| 31 | * @var string |
||
| 32 | */ |
||
| 33 | public $value; |
||
| 34 | |||
| 35 | /** |
||
| 36 | * Cookie attributes |
||
| 37 | * |
||
| 38 | * Valid keys are (currently) path, domain, expires, max-age, secure and |
||
| 39 | * httponly. |
||
| 40 | * |
||
| 41 | * @var Rmccue\Requests\Utility\CaseInsensitiveDictionary|array Array-like object |
||
| 42 | */ |
||
| 43 | public $attributes = array(); |
||
| 44 | |||
| 45 | /** |
||
| 46 | * Cookie flags |
||
| 47 | * |
||
| 48 | * Valid keys are (currently) creation, last-access, persistent and |
||
| 49 | * host-only. |
||
| 50 | * |
||
| 51 | * @var array |
||
| 52 | */ |
||
| 53 | public $flags = array(); |
||
| 54 | |||
| 55 | /** |
||
| 56 | * Reference time for relative calculations |
||
| 57 | * |
||
| 58 | * This is used in place of `time()` when calculating Max-Age expiration and |
||
| 59 | * checking time validity. |
||
| 60 | * |
||
| 61 | * @var int |
||
| 62 | */ |
||
| 63 | public $reference_time = 0; |
||
| 64 | |||
| 65 | /** |
||
| 66 | * Create a new cookie object |
||
| 67 | * |
||
| 68 | * @param string $name |
||
| 69 | * @param string $value |
||
| 70 | * @param array|\Rmccue\Requests\Utility\CaseInsensitiveDictionary $attributes Associative array of attribute data |
||
| 71 | */ |
||
| 72 | public function __construct($name, $value, $attributes = array(), $flags = array(), $reference_time = null) { |
||
| 91 | |||
| 92 | /** |
||
| 93 | * Check if a cookie is expired. |
||
| 94 | * |
||
| 95 | * Checks the age against $this->reference_time to determine if the cookie |
||
| 96 | * is expired. |
||
| 97 | * |
||
| 98 | * @return boolean True if expired, false if time is valid. |
||
| 99 | */ |
||
| 100 | public function is_expired() { |
||
| 117 | |||
| 118 | /** |
||
| 119 | * Check if a cookie is valid for a given URI |
||
| 120 | * |
||
| 121 | * @param \Rmccue\Requests\IRI $uri URI to check |
||
| 122 | * @return boolean Whether the cookie is valid for the given URI |
||
| 123 | */ |
||
| 124 | public function uri_matches(IRI $uri) { |
||
| 135 | |||
| 136 | /** |
||
| 137 | * Check if a cookie is valid for a given domain |
||
| 138 | * |
||
| 139 | * @param string $string Domain to check |
||
| 140 | * @return boolean Whether the cookie is valid for the given domain |
||
| 141 | */ |
||
| 142 | public function domain_matches($string) { |
||
| 182 | |||
| 183 | /** |
||
| 184 | * Check if a cookie is valid for a given path |
||
| 185 | * |
||
| 186 | * From the path-match check in RFC 6265 section 5.1.4 |
||
| 187 | * |
||
| 188 | * @param string $request_path Path to check |
||
| 189 | * @return boolean Whether the cookie is valid for the given path |
||
| 190 | */ |
||
| 191 | public function path_matches($request_path) { |
||
| 227 | |||
| 228 | /** |
||
| 229 | * Normalize cookie and attributes |
||
| 230 | * |
||
| 231 | * @return boolean Whether the cookie was successfully normalized |
||
| 232 | */ |
||
| 233 | public function normalize() { |
||
| 249 | |||
| 250 | /** |
||
| 251 | * Parse an individual cookie attribute |
||
| 252 | * |
||
| 253 | * Handles parsing individual attributes from the cookie values. |
||
| 254 | * |
||
| 255 | * @param string $name Attribute name |
||
| 256 | * @param string|boolean $value Attribute value (string value, or true if empty/flag) |
||
| 257 | * @return mixed Value if available, or null if the attribute value is invalid (and should be skipped) |
||
| 258 | */ |
||
| 259 | protected function normalize_attribute($name, $value) { |
||
| 307 | |||
| 308 | /** |
||
| 309 | * Format a cookie for a Cookie header |
||
| 310 | * |
||
| 311 | * This is used when sending cookies to a server. |
||
| 312 | * |
||
| 313 | * @return string Cookie formatted for Cookie header |
||
| 314 | */ |
||
| 315 | public function format_for_header() { |
||
| 318 | |||
| 319 | /** |
||
| 320 | * Format a cookie for a Cookie header |
||
| 321 | * |
||
| 322 | * @codeCoverageIgnore |
||
| 323 | * @deprecated Use {@see Rmccue\Requests\Cookie::format_for_header} |
||
| 324 | * @return string |
||
| 325 | */ |
||
| 326 | public function formatForHeader() { |
||
| 329 | |||
| 330 | /** |
||
| 331 | * Format a cookie for a Set-Cookie header |
||
| 332 | * |
||
| 333 | * This is used when sending cookies to clients. This isn't really |
||
| 334 | * applicable to client-side usage, but might be handy for debugging. |
||
| 335 | * |
||
| 336 | * @return string Cookie formatted for Set-Cookie header |
||
| 337 | */ |
||
| 338 | public function format_for_set_cookie() { |
||
| 356 | |||
| 357 | /** |
||
| 358 | * Format a cookie for a Set-Cookie header |
||
| 359 | * |
||
| 360 | * @codeCoverageIgnore |
||
| 361 | * @deprecated Use {@see Rmccue\Requests\Cookie::format_for_set_cookie} |
||
| 362 | * @return string |
||
| 363 | */ |
||
| 364 | public function formatForSetCookie() { |
||
| 367 | |||
| 368 | /** |
||
| 369 | * Get the cookie value |
||
| 370 | * |
||
| 371 | * Attributes and other data can be accessed via methods. |
||
| 372 | */ |
||
| 373 | public function __toString() { |
||
| 376 | |||
| 377 | /** |
||
| 378 | * Parse a cookie string into a cookie object |
||
| 379 | * |
||
| 380 | * Based on Mozilla's parsing code in Firefox and related projects, which |
||
| 381 | * is an intentional deviation from RFC 2109 and RFC 2616. RFC 6265 |
||
| 382 | * specifies some of this handling, but not in a thorough manner. |
||
| 383 | * |
||
| 384 | * @param string Cookie header value (from a Set-Cookie header) |
||
| 385 | * @return Rmccue\Requests\Cookie Parsed cookie object |
||
| 386 | */ |
||
| 387 | public static function parse($string, $name = '', $reference_time = null) { |
||
| 430 | |||
| 431 | /** |
||
| 432 | * Parse all Set-Cookie headers from request headers |
||
| 433 | * |
||
| 434 | * @param Rmccue\Requests\Response\Headers $headers Headers to parse from |
||
| 435 | * @param Rmccue\Requests\IRI|null $origin URI for comparing cookie origins |
||
| 436 | * @param int|null $time Reference time for expiration calculation |
||
| 437 | * @return array |
||
| 438 | */ |
||
| 439 | public static function parse_from_headers(Headers $headers, IRI $origin = null, $time = null) { |
||
| 494 | |||
| 495 | /** |
||
| 496 | * Parse all Set-Cookie headers from request headers |
||
| 497 | * |
||
| 498 | * @codeCoverageIgnore |
||
| 499 | * @deprecated Use {@see Rmccue\Requests\Cookie::parse_from_headers} |
||
| 500 | * @return string |
||
| 501 | */ |
||
| 506 |
Our type inference engine has found a suspicous assignment of a value to a property. This check raises an issue when a value that can be of a mixed type is assigned to a property that is type hinted more strictly.
For example, imagine you have a variable
$accountIdthat can either hold an Id object or false (if there is no account id yet). Your code now assigns that value to theidproperty of an instance of theAccountclass. This class holds a proper account, so the id value must no longer be false.Either this assignment is in error or a type check should be added for that assignment.