|
| 1 | +<?php |
| 2 | + |
| 3 | +namespace PHPFUI\ORM; |
| 4 | + |
| 5 | +/** |
| 6 | + * A MorphMany class to mimic Eloquent MorphMany. |
| 7 | + * |
| 8 | + * Requirements: |
| 9 | + * |
| 10 | + * The morphing records needs two fields: an integer related key and a string field type long enough to hold the table name of the relationship. They should both be prefixed with the morph field prefix passed into the class. The related key field should follow the same id naming conventions as the rest of the database. |
| 11 | + * |
| 12 | + * In the **Record** class definition, you need to define a virtual field with the name of the MorphMany relationship. The key of the virtual field is the member name and the value is an array. |
| 13 | + * |
| 14 | + * The values in the array should be **\PHPFUI\ORM\MorphMany::class**, followed by the morphing table class name, then morph field prefix. Sort field and sort order are optional fields. |
| 15 | + * |
| 16 | + * Example: |
| 17 | + * ```php |
| 18 | + * protected static array $virtualFields = [ |
| 19 | + * 'images' => [\PHPFUI\ORM\MorphToMany::class, \Tests\App\Table\Image::class, 'imageable', ], |
| 20 | + * ]; |
| 21 | + * ``` |
| 22 | + */ |
| 23 | +class MorphMany extends \PHPFUI\ORM\VirtualField |
| 24 | + { |
| 25 | + /** |
| 26 | + * @param array<string> $parameters morphing table class name, morph field prefix, optional sort column, optional sort order. |
| 27 | + */ |
| 28 | + public function getValue(array $parameters) : \PHPFUI\ORM\RecordCursor |
| 29 | + { |
| 30 | + $morphTableClass = \array_shift($parameters); |
| 31 | + $morphTable = new $morphTableClass(); |
| 32 | + $morphFieldPrefix = \array_shift($parameters); |
| 33 | + $condition = new \PHPFUI\ORM\Condition($morphFieldPrefix . '_type', $this->currentRecord->getTableName()); |
| 34 | + $primaryKey = $this->currentRecord->getPrimaryKeys()[0]; |
| 35 | + $condition->and($morphFieldPrefix . \PHPFUI\ORM::$idSuffix, $this->currentRecord->{$primaryKey}); |
| 36 | + $morphTable->setWhere($condition); |
| 37 | + |
| 38 | + $orderBy = \array_shift($parameters); |
| 39 | + $sort = \array_shift($parameters) ?? 'asc'; |
| 40 | + |
| 41 | + if ($orderBy) |
| 42 | + { |
| 43 | + $morphTable->addOrderBy($orderBy, $sort); |
| 44 | + } |
| 45 | + |
| 46 | + return $morphTable->getRecordCursor(); |
| 47 | + } |
| 48 | + |
| 49 | + /** |
| 50 | + * @param mixed $value to add as morph relation for the current record |
| 51 | + * @param array<string> $parameters morphing table class name, morph field prefix, optional sort column, optional sort order |
| 52 | + */ |
| 53 | + public function setValue(mixed $value, array $parameters) : void |
| 54 | + { |
| 55 | + $morphTableClass = \array_shift($parameters); |
| 56 | + $morphTable = new $morphTableClass(); |
| 57 | + $morphFieldPrefix = \array_shift($parameters); |
| 58 | + $primaryKey = $this->currentRecord->getPrimaryKeys()[0]; |
| 59 | + |
| 60 | + $morphTypeField = $morphFieldPrefix . '_type'; |
| 61 | + $morphIdField = $morphFieldPrefix . \PHPFUI\ORM::$idSuffix; |
| 62 | + |
| 63 | + $value->{$morphTypeField} = $this->currentRecord->getTableName(); |
| 64 | + $primaryKeyValue = $this->currentRecord->{$primaryKey}; |
| 65 | + |
| 66 | + if (! $primaryKeyValue) |
| 67 | + { |
| 68 | + $this->currentRecord->insert(); |
| 69 | + $primaryKeyValue = $this->currentRecord->{$primaryKey}; |
| 70 | + } |
| 71 | + $value->{$morphIdField} = $primaryKeyValue; |
| 72 | + |
| 73 | + $value->insert(); |
| 74 | + } |
| 75 | + } |
0 commit comments