Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like SchemaProvider 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 SchemaProvider, and based on these observations, apply Extract Interface, too.
| 1 | <?php namespace Neomerx\JsonApi\Schema; |
||
| 31 | abstract class SchemaProvider implements SchemaProviderInterface |
||
| 32 | { |
||
| 33 | /** Links information */ |
||
| 34 | const LINKS = DocumentInterface::KEYWORD_LINKS; |
||
| 35 | |||
| 36 | /** Linked data key. */ |
||
| 37 | const DATA = DocumentInterface::KEYWORD_DATA; |
||
| 38 | |||
| 39 | /** Relationship meta */ |
||
| 40 | const META = DocumentInterface::KEYWORD_META; |
||
| 41 | |||
| 42 | /** If 'self' URL should be shown. */ |
||
| 43 | const SHOW_SELF = 'showSelf'; |
||
| 44 | |||
| 45 | /** If 'related' URL should be shown. */ |
||
| 46 | const SHOW_RELATED = 'related'; |
||
| 47 | |||
| 48 | /** If data should be shown in relationships. */ |
||
| 49 | const SHOW_DATA = 'showData'; |
||
| 50 | |||
| 51 | /** |
||
| 52 | * @var string |
||
| 53 | */ |
||
| 54 | protected $resourceType; |
||
| 55 | |||
| 56 | /** |
||
| 57 | * @var string Must end with '/' |
||
| 58 | */ |
||
| 59 | protected $selfSubUrl; |
||
| 60 | |||
| 61 | /** |
||
| 62 | * @var bool |
||
| 63 | */ |
||
| 64 | protected $isShowAttributesInIncluded = true; |
||
|
1 ignored issue
–
show
|
|||
| 65 | |||
| 66 | /** |
||
| 67 | * @var SchemaFactoryInterface |
||
| 68 | */ |
||
| 69 | private $factory; |
||
| 70 | |||
| 71 | /** |
||
| 72 | * @var ContainerInterface |
||
| 73 | */ |
||
| 74 | private $container; |
||
| 75 | |||
| 76 | /** |
||
| 77 | * @param SchemaFactoryInterface $factory |
||
| 78 | * @param ContainerInterface $container |
||
| 79 | */ |
||
| 80 | 62 | public function __construct(SchemaFactoryInterface $factory, ContainerInterface $container) |
|
| 81 | { |
||
| 82 | 62 | $isOk = (is_string($this->resourceType) === true && empty($this->resourceType) === false); |
|
| 83 | 62 | if ($isOk === false) { |
|
| 84 | 1 | throw new InvalidArgumentException(T::t('Resource type is not set for Schema \'%s\'.', [static::class])); |
|
| 85 | } |
||
| 86 | |||
| 87 | 61 | if ($this->selfSubUrl === null) { |
|
| 88 | 57 | $this->selfSubUrl = '/' . $this->resourceType . '/'; |
|
| 89 | 57 | } else { |
|
| 90 | $isOk = |
||
| 91 | 5 | is_string($this->selfSubUrl) === true && |
|
| 92 | 5 | empty($this->selfSubUrl) === false && |
|
| 93 | 5 | $this->selfSubUrl[0] === '/' && |
|
| 94 | 5 | $this->selfSubUrl[strlen($this->selfSubUrl) - 1] == '/'; |
|
| 95 | |||
| 96 | 5 | if ($isOk === false) { |
|
| 97 | 1 | $message = T::t('\'Self\' sub-url set incorrectly for Schema \'%s\'.', [static::class]); |
|
| 98 | 1 | throw new InvalidArgumentException($message); |
|
| 99 | } |
||
| 100 | } |
||
| 101 | |||
| 102 | 60 | $this->factory = $factory; |
|
| 103 | 60 | $this->container = $container; |
|
| 104 | 60 | } |
|
| 105 | |||
| 106 | /** |
||
| 107 | * @inheritdoc |
||
| 108 | */ |
||
| 109 | 57 | public function getResourceType() |
|
| 113 | |||
| 114 | /** |
||
| 115 | * @inheritdoc |
||
| 116 | */ |
||
| 117 | 49 | public function getSelfSubUrl($resource = null) |
|
| 121 | |||
| 122 | /** |
||
| 123 | * @inheritdoc |
||
| 124 | */ |
||
| 125 | 47 | public function getSelfSubLink($resource) |
|
| 129 | |||
| 130 | /** |
||
| 131 | * @inheritdoc |
||
| 132 | */ |
||
| 133 | 4 | public function getRelationshipSelfLink($resource, $name, $meta = null, $treatAsHref = false) |
|
| 139 | |||
| 140 | /** |
||
| 141 | * @inheritdoc |
||
| 142 | */ |
||
| 143 | 4 | public function getRelationshipRelatedLink($resource, $name, $meta = null, $treatAsHref = false) |
|
| 149 | |||
| 150 | /** |
||
| 151 | * @inheritdoc |
||
| 152 | */ |
||
| 153 | 53 | public function getPrimaryMeta($resource) |
|
| 157 | |||
| 158 | /** |
||
| 159 | * @inheritdoc |
||
| 160 | */ |
||
| 161 | 29 | public function getLinkageMeta($resource) |
|
| 165 | |||
| 166 | /** |
||
| 167 | * @inheritdoc |
||
| 168 | */ |
||
| 169 | 19 | public function getInclusionMeta($resource) |
|
| 173 | |||
| 174 | /** |
||
| 175 | * @inheritdoc |
||
| 176 | */ |
||
| 177 | 30 | public function getRelationshipsPrimaryMeta($resource) |
|
| 181 | |||
| 182 | /** |
||
| 183 | * @inheritdoc |
||
| 184 | */ |
||
| 185 | 16 | public function getRelationshipsInclusionMeta($resource) |
|
| 189 | |||
| 190 | /** |
||
| 191 | * @inheritdoc |
||
| 192 | */ |
||
| 193 | 19 | public function isShowAttributesInIncluded() |
|
| 197 | |||
| 198 | /** |
||
| 199 | * Get resource links. |
||
| 200 | * |
||
| 201 | * @param object $resource |
||
| 202 | * @param bool $isPrimary |
||
| 203 | * @param array $includeRelationships A list of relationships that will be included as full resources. |
||
| 204 | * |
||
| 205 | * @return array |
||
| 206 | */ |
||
| 207 | 8 | public function getRelationships($resource, $isPrimary, array $includeRelationships) |
|
| 213 | |||
| 214 | /** |
||
| 215 | * @inheritdoc |
||
| 216 | */ |
||
| 217 | 51 | public function createResourceObject($resource, $isOriginallyArrayed, $attributeKeysFilter = null) |
|
| 221 | |||
| 222 | /** |
||
| 223 | * @inheritdoc |
||
| 224 | */ |
||
| 225 | 51 | public function getRelationshipObjectIterator($resource, $isPrimary, array $includeRelationships) |
|
| 231 | |||
| 232 | /** |
||
| 233 | * @inheritdoc |
||
| 234 | */ |
||
| 235 | 26 | public function getIncludePaths() |
|
| 239 | |||
| 240 | /** |
||
| 241 | * @inheritdoc |
||
| 242 | */ |
||
| 243 | 47 | public function getResourceLinks($resource) |
|
| 251 | |||
| 252 | /** |
||
| 253 | * @inheritdoc |
||
| 254 | */ |
||
| 255 | 16 | public function getIncludedResourceLinks($resource) |
|
| 259 | |||
| 260 | /** |
||
| 261 | * @param object $resource |
||
| 262 | * @param string $name |
||
| 263 | * |
||
| 264 | * @return string |
||
| 265 | */ |
||
| 266 | 4 | protected function getRelationshipSelfUrl($resource, $name) |
|
| 272 | |||
| 273 | /** |
||
| 274 | * @param object $resource |
||
| 275 | * @param string $name |
||
| 276 | * |
||
| 277 | * @return string |
||
| 278 | */ |
||
| 279 | 4 | protected function getRelationshipRelatedUrl($resource, $name) |
|
| 285 | |||
| 286 | /** |
||
| 287 | * @param string $subHref |
||
| 288 | * @param null|mixed $meta |
||
| 289 | * @param bool $treatAsHref |
||
| 290 | * |
||
| 291 | * @return LinkInterface |
||
| 292 | */ |
||
| 293 | 49 | protected function createLink($subHref, $meta = null, $treatAsHref = false) |
|
| 297 | |||
| 298 | /** |
||
| 299 | * @param object $resource |
||
| 300 | * @param string $relationshipName |
||
| 301 | * @param array $description |
||
| 302 | * @param bool $isShowSelf |
||
| 303 | * @param bool $isShowRelated |
||
| 304 | * |
||
| 305 | * @return array <string,LinkInterface> |
||
| 306 | */ |
||
| 307 | 40 | protected function readLinks($resource, $relationshipName, array $description, $isShowSelf, $isShowRelated) |
|
| 319 | |||
| 320 | /** |
||
| 321 | * @param object $resource |
||
| 322 | * @param string $name |
||
| 323 | * @param array $desc |
||
| 324 | * |
||
| 325 | * @return RelationshipObjectInterface |
||
| 326 | */ |
||
| 327 | 40 | protected function createRelationshipObject($resource, $name, array $desc) |
|
| 338 | |||
| 339 | /** |
||
| 340 | * @param array $array |
||
| 341 | * @param string $key |
||
| 342 | * @param mixed $default |
||
| 343 | * |
||
| 344 | * @return mixed |
||
| 345 | */ |
||
| 346 | 40 | private function getValue(array $array, $key, $default = null) |
|
| 350 | } |
||
| 351 |
Very long variable names usually make code harder to read. It is therefore recommended not to make variable names too verbose.