      1: <?php
      2:
      3: /*
      4:  * This file is part of the CRUDlex package.
      5:  *
      6:  * (c) Philip Lehmann-Böhm <philip@philiplb.de>
      7:  *
      8:  * For the full copyright and license information, please view the LICENSE
      9:  * file that was distributed with this source code.
     10:  */
     11:
     12: namespace CRUDlex;
     13:
     14: class CRUDEntityDefinition {
     15:
     16:     /**
     17:      * The table where the data is stored.
     18:      */
     19:     protected $table;
     20:
     21:     /**
     22:      * Holds all fields in the same structure as in the CRUD YAML file.
     23:      */
     24:     protected $fields;
     25:
     26:     /**
     27:      * The label for the entity.
     28:      */
     29:     protected $label;
     30:
     31:     /**
     32:      * An array with the children referencing the entity. All entries are
     33:      * arrays with three referencing elements: table, fieldName, entity
     34:      */
     35:     protected $children;
     36:
     37:     /**
     38:      * Labels for the fields "id", "created_at" and "updated_at".
     39:      */
     40:     protected $standardFieldLabels;
     41:
     42:     /**
     43:      * An array containing the fields which should appear in the list view
     44:      * of the entity.
     45:      */
     46:     protected $listFields;
     47:
     48:     /**
     49:      * The fields used to display the children on the details page of an entity.
     50:      * The keys are the entity names as in the CRUD YAML and the values are the
     51:      * field names.
     52:      */
     53:     protected $childrenLabelFields;
     54:
     55:     /**
     56:      * Gets the field names exluding the given ones.
     57:      *
     58:      * @param array $exclude
     59:      * the field names to exclude
     60:      *
     61:      * @return array
     62:      * all field names excluding the given ones
     63:      */
     64:     protected function getFilteredFieldNames(array $exclude) {
     65:         $fieldNames = $this->getFieldNames();
     66:         $result = array();
     67:         foreach ($fieldNames as $fieldName) {
     68:             if (!in_array($fieldName, $exclude)) {
     69:                 $result[] = $fieldName;
     70:             }
     71:         }
     72:         return $result;
     73:     }
     74:
     75:     /**
     76:      * Gets the value of a field key.
     77:      *
     78:      * @param string $name
     79:      * the name of the field
     80:      * @param string $key
     81:      * the value of the key
     82:      *
     83:      * @return mixed
     84:      * the value of the field key or null if not existing
     85:      */
     86:     protected function getFieldValue($name, $key) {
     87:         if (key_exists($name, $this->fields) && key_exists($key, $this->fields[$name])) {
     88:             return $this->fields[$name][$key];
     89:         }
     90:         return null;
     91:     }
     92:
     93:     /**
     94:      * Sets the value of a field key. If the field or the key in the field
     95:      * don't exist, they get created.
     96:      *
     97:      * @param string $name
     98:      * the name of the field
     99:      * @param string $key
    100:      * the value of the key
    101:      * @param mixed $value
    102:      * the new value
    103:      */
    104:     protected function setFieldValue($name, $key, $value) {
    105:         if (!key_exists($name, $this->fields)) {
    106:             $this->fields[$name] = array();
    107:         }
    108:         $this->fields[$name][$key] = $value;
    109:     }
    110:
    111:     /**
    112:      * Gets the value of a reference field.
    113:      *
    114:      * @param string $fieldName
    115:      * the field name of the reference
    116:      * @param string $key
    117:      * the key of the reference value
    118:      *
    119:      * @return string
    120:      * the value of the reference field
    121:      */
    122:     protected function getReferenceValue($fieldName, $key) {
    123:         if ($this->getType($fieldName) != 'reference') {
    124:             return null;
    125:         }
    126:         return $this->fields[$fieldName]['reference'][$key];
    127:     }
    128:
    129:     /**
    130:      * Constructor.
    131:      *
    132:      * @param string $table
    133:      * the table of the entity
    134:      * @param array $fields
    135:      * the fieldstructure just like the CRUD YAML
    136:      * @param string $label
    137:      * the label of the entity
    138:      * @param array $listFields
    139:      * an array containing the fields which should appear in the list view of
    140:      * the entity
    141:      * @param array $standardFieldLabels
    142:      * labels for the fields "id", "created_at" and "updated_at"
    143:      * @param array $childrenLabelFields
    144:      * the fields used to display the children on the details page of an entity;
    145:      * The keys are the entity names as in the CRUD YAML and the values are the
    146:      * field names
    147:      */
    148:     public function __construct($table, $fields, $label, $listFields, $standardFieldLabels, $childrenLabelFields) {
    149:         $this->table = $table;
    150:         $this->fields = $fields;
    151:         $this->children = array();
    152:         $this->listFields = $listFields;
    153:         $this->label = $label;
    154:         $this->standardFieldLabels = $standardFieldLabels;
    155:         $this->childrenLabelFields = $childrenLabelFields;
    156:     }
    157:
    158:     /**
    159:      * Gets all field names, including the implicit ones like "id" or
    160:      * "created_at".
    161:      *
    162:      * @return array
    163:      * the field names
    164:      */
    165:     public function getFieldNames() {
    166:         $fieldNames = $this->getReadOnlyFields();
    167:         foreach ($this->fields as $field => $value) {
    168:             $fieldNames[] = $field;
    169:         }
    170:         return $fieldNames;
    171:     }
    172:
    173:     /**
    174:      * Gets the field names to be used in the listview. If they were not specified in
    175:      * the constructor, all public field names are returned.
    176:      *
    177:      * @return array
    178:      * the field names to be used in the listview
    179:      */
    180:     public function getListFieldNames() {
    181:         if ($this->listFields) {
    182:             return $this->listFields;
    183:         }
    184:         return $this->getPublicFieldNames();
    185:     }
    186:
    187:     /**
    188:      * Gets the fields used to display the children on the details page of an
    189:      * entity. The keys are the entity names as in the CRUD YAML and the values
    190:      * are the field names.
    191:      *
    192:      * @return array
    193:      * the fields used to display the children on the details page
    194:      */
    195:     public function getChildrenLabelFields() {
    196:         return $this->childrenLabelFields;
    197:     }
    198:
    199:     /**
    200:      * Gets the public field names. The internal fields "version" and
    201:      * "deleted_at" are filtered.
    202:      *
    203:      * @return array
    204:      * the public field names
    205:      */
    206:     public function getPublicFieldNames() {
    207:         $exclude = array('version', 'deleted_at');
    208:         $result = $this->getFilteredFieldNames($exclude);
    209:         return $result;
    210:     }
    211:
    212:     /**
    213:      * Gets the field names which are editable. Not editable are fields like the
    214:      * id or the created_at.
    215:      *
    216:      * @return array
    217:      * the editable field names
    218:      */
    219:     public function getEditableFieldNames() {
    220:         $result = $this->getFilteredFieldNames($this->getReadOnlyFields());
    221:         return $result;
    222:     }
    223:
    224:     /**
    225:      * Gets the read only field names like the id or the created_at.
    226:      *
    227:      * @return array
    228:      * the read only field names
    229:      */
    230:     public function getReadOnlyFields() {
    231:         return array('id', 'created_at', 'updated_at', 'version', 'deleted_at');
    232:     }
    233:
    234:     /**
    235:      * Gets the type of a field.
    236:      *
    237:      * @param string $fieldName
    238:      * the field name
    239:      *
    240:      * @return string
    241:      * the type or null on invalid field name
    242:      */
    243:     public function getType($fieldName) {
    244:         return $this->getFieldValue($fieldName, 'type');
    245:     }
    246:
    247:     /**
    248:      * Sets the type of a field.
    249:      *
    250:      * @param string $fieldName
    251:      * the field name
    252:      * @param string $value
    253:      * the new field type
    254:      */
    255:     public function setType($fieldName, $value) {
    256:         return $this->setFieldValue($fieldName, 'type', $value);
    257:     }
    258:
    259:     /**
    260:      * Gets whether a field is required.
    261:      *
    262:      * @param string $fieldName
    263:      * the field name
    264:      *
    265:      * @return bool
    266:      * true if so
    267:      */
    268:     public function isRequired($fieldName) {
    269:         $result = $this->getFieldValue($fieldName, 'required');
    270:         if ($result === null) {
    271:             $result = false;
    272:         }
    273:         return $result;
    274:     }
    275:
    276:
    277:     /**
    278:      * Sets whether a field is required.
    279:      *
    280:      * @param string $fieldName
    281:      * the field name
    282:      * @param bool $fieldName
    283:      * the new required state
    284:      */
    285:     public function setRequired($fieldName, $value) {
    286:         return $this->setFieldValue($fieldName, 'required', $value);
    287:     }
    288:
    289:
    290:     /**
    291:      * Gets whether a field is unique.
    292:      *
    293:      * @param string $fieldName
    294:      * the field name
    295:      *
    296:      * @return bool
    297:      * true if so
    298:      */
    299:     public function isUnique($fieldName) {
    300:         $result = $this->getFieldValue($fieldName, 'unique');
    301:         if ($result === null) {
    302:             $result = false;
    303:         }
    304:         return $result;
    305:     }
    306:
    307:     /**
    308:      * Gets the table field of a reference.
    309:      *
    310:      * @param string $fieldName
    311:      * the field name of the reference
    312:      *
    313:      * @return string
    314:      * the table field of a reference or null on invalid field name
    315:      */
    316:     public function getReferenceTable($fieldName) {
    317:         return $this->getReferenceValue($fieldName, 'table');
    318:     }
    319:
    320:     /**
    321:      * Gets the name field of a reference.
    322:      *
    323:      * @param string $fieldName
    324:      * the field name of the reference
    325:      *
    326:      * @return string
    327:      * the name field of a reference or null on invalid field name
    328:      */
    329:     public function getReferenceNameField($fieldName) {
    330:         return $this->getReferenceValue($fieldName, 'nameField');
    331:     }
    332:
    333:
    334:     /**
    335:      * Gets the entity field of a reference.
    336:      *
    337:      * @param string $fieldName
    338:      * the field name of the reference
    339:      *
    340:      * @return string
    341:      * the entity field of a reference or null on invalid field name
    342:      */
    343:     public function getReferenceEntity($fieldName) {
    344:         return $this->getReferenceValue($fieldName, 'entity');
    345:     }
    346:
    347:     /**
    348:      * Gets the file path of a field.
    349:      *
    350:      * @param string $fieldName
    351:      * the field name
    352:      *
    353:      * @return string
    354:      * the file path of a field or null on invalid field name
    355:      */
    356:     public function getFilePath($fieldName) {
    357:         return $this->getFieldValue($fieldName, 'filepath');
    358:     }
    359:
    360:     /**
    361:      * Gets the value of a fixed field.
    362:      *
    363:      * @param string $fieldName
    364:      * the field name
    365:      *
    366:      * @return string
    367:      * the value of a fixed field or null on invalid field name
    368:      */
    369:     public function getFixedValue($fieldName) {
    370:         return $this->getFieldValue($fieldName, 'fixedvalue');
    371:     }
    372:
    373:     /**
    374:      * Sets the value of a fixed field.
    375:      *
    376:      * @param string $fieldName
    377:      * the field name
    378:      * @param string $value
    379:      * the new value for the fixed field
    380:      */
    381:     public function setFixedValue($fieldName, $value) {
    382:         return $this->setFieldValue($fieldName, 'fixedvalue', $value);
    383:     }
    384:
    385:     /**
    386:      * Gets the items of a set field.
    387:      *
    388:      * @param string $fieldName
    389:      * the field name
    390:      *
    391:      * @return array
    392:      * the items of the set field or null on invalid field name
    393:      */
    394:     public function getSetItems($fieldName) {
    395:         return $this->getFieldValue($fieldName, 'setitems');
    396:     }
    397:
    398:     /**
    399:      * Gets the step size of a float field.
    400:      *
    401:      * @param string $fieldName
    402:      * the field name
    403:      *
    404:      * @return array
    405:      * the step size of a float field or null on invalid field name
    406:      */
    407:     public function getFloatStep($fieldName) {
    408:         return $this->getFieldValue($fieldName, 'floatStep');
    409:     }
    410:
    411:     /**
    412:      * Gets the label of a field.
    413:      *
    414:      * @param string $fieldName
    415:      * the field name
    416:      *
    417:      * @return string
    418:      * the label of the field or the field name if no label is set in the CRUD
    419:      * YAML
    420:      */
    421:     public function getFieldLabel($fieldName) {
    422:         $result = $this->getFieldValue($fieldName, 'label');
    423:         if ($result === null && key_exists($fieldName, $this->standardFieldLabels)) {
    424:             $result = $this->standardFieldLabels[$fieldName];
    425:         }
    426:         if ($result === null) {
    427:             $result = $fieldName;
    428:         }
    429:         return $result;
    430:     }
    431:
    432:     /**
    433:      * Gets the table where the data is stored.
    434:      *
    435:      * @return @string
    436:      * the table where the data is stored
    437:      */
    438:     public function getTable() {
    439:         return $this->table;
    440:     }
    441:
    442:     /**
    443:      * Gets the label for the entity.
    444:      *
    445:      * @return @string
    446:      * the label for the entity
    447:      */
    448:     public function getLabel() {
    449:         return $this->label;
    450:     }
    451:
    452:     /**
    453:      * Adds a child to this definition in case the other
    454:      * definition has a reference to this one.
    455:      *
    456:      * @param string $table
    457:      * the table of the referencing definition
    458:      * @param string $fieldName
    459:      * the field name of the referencing definition
    460:      * @param string $entity
    461:      * the entity of the referencing definition
    462:      */
    463:     public function addChild($table, $fieldName, $entity) {
    464:         $this->children[] = array($table, $fieldName, $entity);
    465:     }
    466:
    467:     /**
    468:      * Gets the referencing children to this definition.
    469:      *
    470:      * @return array
    471:      * an array with the children referencing the entity. All entries are arrays
    472:      * with three referencing elements: table, fieldName, entity
    473:      */
    474:     public function getChildren() {
    475:         return $this->children;
    476:     }
    477: }
    478: