Overview

Namespaces

  • Charcoal
    • Loader
    • Model
      • Service
      • ServiceProvider
    • Source
      • Database
    • Validator

Classes

  • Charcoal\Loader\CollectionLoader
  • Charcoal\Loader\FileLoader
  • Charcoal\Model\AbstractMetadata
  • Charcoal\Model\AbstractModel
  • Charcoal\Model\Collection
  • Charcoal\Model\Model
  • Charcoal\Model\ModelMetadata
  • Charcoal\Model\ModelValidator
  • Charcoal\Model\Service\MetadataLoader
  • Charcoal\Model\Service\ModelBuilder
  • Charcoal\Model\Service\ModelLoader
  • Charcoal\Model\Service\ModelLoaderBuilder
  • Charcoal\Model\ServiceProvider\ModelServiceProvider
  • Charcoal\Source\AbstractSource
  • Charcoal\Source\Database\DatabaseFilter
  • Charcoal\Source\Database\DatabaseOrder
  • Charcoal\Source\Database\DatabasePagination
  • Charcoal\Source\DatabaseSource
  • Charcoal\Source\DatabaseSourceConfig
  • Charcoal\Source\Filter
  • Charcoal\Source\Order
  • Charcoal\Source\Pagination
  • Charcoal\Source\SourceConfig
  • Charcoal\Validator\AbstractValidator
  • Charcoal\Validator\ValidatorResult

Interfaces

  • Charcoal\Model\CollectionInterface
  • Charcoal\Model\DescribableInterface
  • Charcoal\Model\MetadataInterface
  • Charcoal\Model\ModelInterface
  • Charcoal\Source\DatabaseSourceInterface
  • Charcoal\Source\FilterInterface
  • Charcoal\Source\OrderInterface
  • Charcoal\Source\PaginationInterface
  • Charcoal\Source\SourceInterface
  • Charcoal\Source\StorableInterface
  • Charcoal\Validator\ValidatableInterface
  • Charcoal\Validator\ValidatorInterface

Traits

  • Charcoal\Model\DescribableTrait
  • Charcoal\Source\StorableTrait
  • Charcoal\Validator\ValidatableTrait
  • Overview
  • Namespace
  • Class
  1: <?php
  2: 
  3: namespace Charcoal\Model\Service;
  4: 
  5: use \Exception;
  6: 
  7: // Module `charcoal-factory` dependencies
  8: use \Charcoal\Factory\FactoryInterface;
  9: 
 10: // Local module (`charcoal-core`) dependencies
 11: use \Charcoal\Model\ModelMetadata;
 12: use \Charcoal\Model\Service\MetadataLoader;
 13: 
 14: /**
 15:  *
 16:  */
 17: final class ModelBuilder
 18: {
 19:     const DEFAULT_SOURCE_TYPE = 'database';
 20: 
 21:     /**
 22:      * @var FactoryInterface
 23:      */
 24:     private $factory;
 25: 
 26:     /**
 27:      * @var MetadataLoader
 28:      */
 29:     private $metadataLoader;
 30: 
 31:     /**
 32:      * @var FactoryInterface
 33:      */
 34:     private $sourceFactory;
 35: 
 36:     /**
 37:      * @param array $data Constructor dependencies.
 38:      */
 39:     public function __construct(array $data)
 40:     {
 41:         $this->setFactory($data['factory']);
 42:         $this->setMetadataLoader($data['metadata_loader']);
 43:         $this->setSourceFactory($data['source_factory']);
 44:     }
 45: 
 46:     /**
 47:      * Build a model, pre-initializing its metadata and its source.
 48:      *
 49:      * By default, the name of the "obj type" (the model class name) is used to determine the metadata ident to load.
 50:      * To load a custom metadata for the object, use the `$metadataIdent` argument.
 51:      *
 52:      * By default, the object's _default_ source (from its metadata) is used as source.
 53:      * To load a custom source for the object, use the `$sourceIdent` argument.
 54:      *
 55:      * @param string      $objType       The object type of the Model.
 56:      * @param string|null $metadataIdent Optional. The metadata ident of the object.
 57:      * @param string|null $sourceIdent   Optional. The custom source ident to load as source.
 58:      * @return ModelInterface
 59:      */
 60:     public function build($objType, $metadataIdent = null, $sourceIdent = null)
 61:     {
 62:         $metadata = $this->createMetadata($objType, $metadataIdent);
 63:         $source = $this->createSource($metadata, $sourceIdent);
 64:         $args = array_merge($this->factory->arguments(), [
 65:             'metadata'  => $metadata,
 66:             'source'    => $source
 67:         ]);
 68:         $model = $this->factory->create($objType, $args);
 69:         $model->source()->setModel($model);
 70:         return $model;
 71:     }
 72: 
 73:     /**
 74:      * The builder can be invoked (used as function).
 75:      *
 76:      * @param string      $objType       The object type of the Model.
 77:      * @param string|null $metadataIdent Optional. The metadata ident of the object.
 78:      * @param string|null $sourceIdent   Optional. The custom source ident to load as source.
 79:      * @return ModelInterface
 80:      */
 81:     public function __invoke($objType, $metadataIdent = null, $sourceIdent = null)
 82:     {
 83:         return $this->build($objType, $metadataIdent, $sourceIdent);
 84:     }
 85: 
 86: 
 87:     /**
 88:      * @param FactoryInterface $factory The factory to use to create models.
 89:      * @return ModelLoaderBuilder Chainable
 90:      */
 91:     private function setFactory(FactoryInterface $factory)
 92:     {
 93:         $this->factory = $factory;
 94:         return $this;
 95:     }
 96: 
 97:     /**
 98:      * @param MetadataLoader $loader The loader instance, used to load metadata.
 99:      * @return DescribableInterface Chainable
100:      */
101:     private function setMetadataLoader(MetadataLoader $loader)
102:     {
103:         $this->metadataLoader = $loader;
104:         return $this;
105:     }
106: 
107:     /**
108:      * @param FactoryInterface $factory The factory to use to create models.
109:      * @return ModelLoaderBuilder Chainable
110:      */
111:     private function setSourceFactory(FactoryInterface $factory)
112:     {
113:         $this->sourceFactory = $factory;
114:         return $this;
115:     }
116: 
117:     /**
118:      * @param string      $objType       The type of object to load.
119:      *     (A class name or object identifier).
120:      * @param string|null $metadataIdent Optional. The metadata identifier to load.
121:      *     If NULL, it will be implied from objType.
122:      * @return MetadataInterface
123:      */
124:     private function createMetadata($objType, $metadataIdent = null)
125:     {
126:         $metadataIdent = ($metadataIdent !== null) ? $metadataIdent : $objType;
127:         return $this->metadataLoader->load($metadataIdent, new ModelMetadata());
128:     }
129: 
130:     /**
131:      * @param ModelMetadata $metadata    The object metadata, where to find the object's
132:      *     source configuration.
133:      * @param string|null   $sourceIdent Optional. Custom source ident to load.
134:      *     If NULL, the default (from metadata) will be used.
135:      * @throws Exception If the source is not defined in the model's metadata.
136:      * @return SourceInterface
137:      */
138:     private function createSource(ModelMetadata $metadata, $sourceIdent = null)
139:     {
140:         if ($sourceIdent === null) {
141:             $sourceIdent = $metadata->defaultSource();
142:         }
143:         $sourceConfig = $metadata->source($sourceIdent);
144: 
145:         if (!$sourceConfig) {
146:             throw new Exception(
147:                 sprintf('Can not create %s source: "%s" is not defined in metadata.', get_class($this), $sourceIdent)
148:             );
149:         }
150: 
151:         $sourceType = isset($sourceConfig['type']) ? $sourceConfig['type'] : self::DEFAULT_SOURCE_TYPE;
152:         $source = $this->sourceFactory->create($sourceType);
153:         $source->setData($sourceConfig);
154: 
155:         return $source;
156:     }
157: }
158: 
API documentation generated by ApiGen