Complex classes like Statement 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 Statement, and based on these observations, apply Extract Interface, too.
| 1 | <?php  | 
            ||
| 19 | final class Statement  | 
            ||
| 20 | { | 
            ||
| 21 | /**  | 
            ||
| 22 | * @var StatementId|null The unique identifier  | 
            ||
| 23 | */  | 
            ||
| 24 | private $id;  | 
            ||
| 25 | |||
| 26 | /**  | 
            ||
| 27 |      * @var Verb $verb The {@link Verb} | 
            ||
| 28 | */  | 
            ||
| 29 | private $verb;  | 
            ||
| 30 | |||
| 31 | /**  | 
            ||
| 32 |      * @var Actor The {@link Actor} | 
            ||
| 33 | */  | 
            ||
| 34 | private $actor;  | 
            ||
| 35 | |||
| 36 | /**  | 
            ||
| 37 |      * @var Object The {@link Object} | 
            ||
| 38 | */  | 
            ||
| 39 | private $object;  | 
            ||
| 40 | |||
| 41 | /**  | 
            ||
| 42 |      * @var Result The {@link Activity} {@link Result} | 
            ||
| 43 | */  | 
            ||
| 44 | private $result;  | 
            ||
| 45 | |||
| 46 | /**  | 
            ||
| 47 | * @var Actor The Authority that asserted the Statement true  | 
            ||
| 48 | */  | 
            ||
| 49 | private $authority;  | 
            ||
| 50 | |||
| 51 | /**  | 
            ||
| 52 | * @var \DateTime The timestamp of when the events described in this statement occurred  | 
            ||
| 53 | */  | 
            ||
| 54 | private $created;  | 
            ||
| 55 | |||
| 56 | /**  | 
            ||
| 57 | * @var \DateTime The timestamp of when this statement was recorded by the LRS  | 
            ||
| 58 | */  | 
            ||
| 59 | private $stored;  | 
            ||
| 60 | |||
| 61 | 4 | /**  | 
            |
| 62 | * @var Context|null A context giving the statement more meaning  | 
            ||
| 63 | 4 | */  | 
            |
| 64 | 4 | private $context;  | 
            |
| 65 | 4 | ||
| 66 | 4 | private $attachments;  | 
            |
| 67 | 4 | ||
| 68 | 4 | /**  | 
            |
| 69 | 4 | * @param StatementId|null $id  | 
            |
| 70 | 4 | * @param Actor $actor  | 
            |
| 71 | 4 | * @param Verb $verb  | 
            |
| 72 | * @param Object $object  | 
            ||
| 73 | * @param Result|null $result  | 
            ||
| 74 | * @param Actor|null $authority  | 
            ||
| 75 | * @param \DateTime|null $created  | 
            ||
| 76 | * @param \DateTime|null $stored  | 
            ||
| 77 | * @param Context|null $context  | 
            ||
| 78 | 2 | * @param Attachment[]|null $attachments  | 
            |
| 79 | */  | 
            ||
| 80 | 2 | public function __construct(StatementId $id = null, Actor $actor, Verb $verb, Object $object, Result $result = null, Actor $authority = null, \DateTime $created = null, \DateTime $stored = null, Context $context = null, array $attachments = null)  | 
            |
| 81 |     { | 
            ||
| 82 | $this->id = $id;  | 
            ||
| 83 | $this->actor = $actor;  | 
            ||
| 84 | $this->verb = $verb;  | 
            ||
| 85 | $this->object = $object;  | 
            ||
| 86 | $this->result = $result;  | 
            ||
| 87 | $this->authority = $authority;  | 
            ||
| 88 | 3 | $this->created = $created;  | 
            |
| 89 | $this->stored = $stored;  | 
            ||
| 90 | 3 | $this->context = $context;  | 
            |
| 91 | $this->attachments = null !== $attachments ? array_values($attachments) : null;  | 
            ||
| 92 | }  | 
            ||
| 93 | |||
| 94 | public function withId(StatementId $id = null)  | 
            ||
| 101 | |||
| 102 | public function withActor(Actor $actor)  | 
            ||
| 109 | |||
| 110 | 3 | public function withVerb(Verb $verb)  | 
            |
| 117 | |||
| 118 | public function withObject(Object $object)  | 
            ||
| 125 | |||
| 126 | public function withResult(Result $result = null)  | 
            ||
| 133 | |||
| 134 | /**  | 
            ||
| 135 | * Creates a new Statement based on the current one containing an Authority  | 
            ||
| 136 | * that asserts the Statement true.  | 
            ||
| 137 | *  | 
            ||
| 138 | * @param Actor $authority The Authority asserting the Statement true  | 
            ||
| 139 | *  | 
            ||
| 140 | * @return Statement The new Statement  | 
            ||
| 141 | */  | 
            ||
| 142 | public function withAuthority(Actor $authority = null)  | 
            ||
| 143 |     { | 
            ||
| 144 | $statement = clone $this;  | 
            ||
| 145 | $statement->authority = $authority;  | 
            ||
| 146 | |||
| 147 | return $statement;  | 
            ||
| 148 | }  | 
            ||
| 149 | |||
| 150 | public function withTimestamp(\DateTime $timestamp = null)  | 
            ||
| 157 | |||
| 158 | public function withStored(\DateTime $stored = null)  | 
            ||
| 165 | |||
| 166 | public function withContext(Context $context = null)  | 
            ||
| 173 | |||
| 174 | 2 | /**  | 
            |
| 175 | * @param Attachment[]|null $attachments  | 
            ||
| 176 | *  | 
            ||
| 177 | * @return self  | 
            ||
| 178 | */  | 
            ||
| 179 | public function withAttachments(array $attachments = null)  | 
            ||
| 180 |     { | 
            ||
| 181 | $statement = clone $this;  | 
            ||
| 182 | $statement->attachments = null !== $attachments ? array_values($attachments) : null;  | 
            ||
| 183 | |||
| 184 | 1 | return $statement;  | 
            |
| 185 | }  | 
            ||
| 186 | 1 | ||
| 187 | 1 | /**  | 
            |
| 188 | * Returns the Statement's unique identifier.  | 
            ||
| 189 | 1 | *  | 
            |
| 190 | 1 | * @return StatementId|null The identifier  | 
            |
| 191 | */  | 
            ||
| 192 | public function getId()  | 
            ||
| 196 | |||
| 197 | /**  | 
            ||
| 198 |      * Returns the Statement's {@link Verb}. | 
            ||
| 199 | *  | 
            ||
| 200 | * @return Verb The Verb  | 
            ||
| 201 | */  | 
            ||
| 202 | 2 | public function getVerb()  | 
            |
| 206 | |||
| 207 | /**  | 
            ||
| 208 |      * Returns the Statement's {@link Actor}. | 
            ||
| 209 | *  | 
            ||
| 210 | * @return Actor The Actor  | 
            ||
| 211 | */  | 
            ||
| 212 | public function getActor()  | 
            ||
| 216 | 2 | ||
| 217 | /**  | 
            ||
| 218 | 2 |      * Returns the Statement's {@link Object}. | 
            |
| 219 | *  | 
            ||
| 220 | * @return \Xabbuh\XApi\Model\Object The Object  | 
            ||
| 221 | */  | 
            ||
| 222 | 2 | public function getObject()  | 
            |
| 226 | 2 | ||
| 227 | /**  | 
            ||
| 228 |      * Returns the {@link Activity} {@link Result}. | 
            ||
| 229 | *  | 
            ||
| 230 | 2 | * @return Result The Result  | 
            |
| 231 | */  | 
            ||
| 232 | public function getResult()  | 
            ||
| 236 | |||
| 237 | /**  | 
            ||
| 238 | 2 | * Returns the Authority that asserted the Statement true.  | 
            |
| 239 | *  | 
            ||
| 240 | * @return Actor The Authority  | 
            ||
| 241 | */  | 
            ||
| 242 | 2 | public function getAuthority()  | 
            |
| 243 |     { | 
            ||
| 244 | return $this->authority;  | 
            ||
| 245 | }  | 
            ||
| 246 | 2 | ||
| 247 | 1 | /**  | 
            |
| 248 | * Returns the timestamp of when the events described in this statement  | 
            ||
| 249 | * occurred.  | 
            ||
| 250 | 1 | *  | 
            |
| 251 | * @return \DateTime The timestamp  | 
            ||
| 252 | */  | 
            ||
| 253 | public function getTimestamp()  | 
            ||
| 257 | |||
| 258 | /**  | 
            ||
| 259 | * Returns the timestamp of when the events described in this statement  | 
            ||
| 260 | * occurred.  | 
            ||
| 261 | *  | 
            ||
| 262 | * @return \DateTime The timestamp  | 
            ||
| 263 | */  | 
            ||
| 264 | public function getCreated()  | 
            ||
| 265 |     { | 
            ||
| 266 | return $this->created;  | 
            ||
| 267 | }  | 
            ||
| 268 | |||
| 269 | /**  | 
            ||
| 270 | * Returns the timestamp of when this statement was recorded by the LRS.  | 
            ||
| 271 | *  | 
            ||
| 272 | * @return \DateTime The timestamp  | 
            ||
| 273 | */  | 
            ||
| 274 | public function getStored()  | 
            ||
| 275 |     { | 
            ||
| 276 | return $this->stored;  | 
            ||
| 277 | }  | 
            ||
| 278 | |||
| 279 | /**  | 
            ||
| 280 | * Returns the context that gives the statement more meaning.  | 
            ||
| 281 | *  | 
            ||
| 282 | * @return Context|null  | 
            ||
| 283 | */  | 
            ||
| 284 | public function getContext()  | 
            ||
| 288 | |||
| 289 | public function getAttachments()  | 
            ||
| 293 | |||
| 294 | /**  | 
            ||
| 295 | * Tests whether or not this Statement is a void Statement (i.e. it voids  | 
            ||
| 296 | * another Statement).  | 
            ||
| 297 | *  | 
            ||
| 298 | * @return bool True if the Statement voids another Statement, false otherwise  | 
            ||
| 299 | */  | 
            ||
| 300 | public function isVoidStatement()  | 
            ||
| 304 | |||
| 305 | /**  | 
            ||
| 306 |      * Returns a {@link StatementReference} for the Statement. | 
            ||
| 307 | *  | 
            ||
| 308 | * @return StatementReference The reference  | 
            ||
| 309 | */  | 
            ||
| 310 | public function getStatementReference()  | 
            ||
| 316 | |||
| 317 | /**  | 
            ||
| 318 | * Returns a Statement that voids the current Statement.  | 
            ||
| 319 | *  | 
            ||
| 320 | * @param Actor $actor The Actor voiding this Statement  | 
            ||
| 321 | *  | 
            ||
| 322 | * @return Statement The voiding Statement  | 
            ||
| 323 | */  | 
            ||
| 324 | public function getVoidStatement(Actor $actor)  | 
            ||
| 333 | |||
| 334 | /**  | 
            ||
| 335 | * Checks if another statement is equal.  | 
            ||
| 336 | *  | 
            ||
| 337 | * Two statements are equal if and only if all of their properties are equal.  | 
            ||
| 338 | *  | 
            ||
| 339 | * @param Statement $statement The statement to compare with  | 
            ||
| 340 | *  | 
            ||
| 341 | * @return bool True if the statements are equal, false otherwise  | 
            ||
| 342 | */  | 
            ||
| 343 | public function equals(Statement $statement)  | 
            ||
| 419 | }  | 
            ||
| 420 | 
Unless you are absolutely sure that the expression can never be null because of other conditions, we strongly recommend to add an additional type check to your code: