      1: <?php
      2: /**
      3:  * Copyright 2012-2014 Rackspace US, Inc.
      4:  *
      5:  * Licensed under the Apache License, Version 2.0 (the "License");
      6:  * you may not use this file except in compliance with the License.
      7:  * You may obtain a copy of the License at
      8:  *
      9:  * http://www.apache.org/licenses/LICENSE-2.0
     10:  *
     11:  * Unless required by applicable law or agreed to in writing, software
     12:  * distributed under the License is distributed on an "AS IS" BASIS,
     13:  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
     14:  * See the License for the specific language governing permissions and
     15:  * limitations under the License.
     16:  */
     17:
     18: namespace OpenCloud\Image\Resource\Schema;
     19:
     20: use OpenCloud\Image\Enum\Schema as SchemaEnum;
     21: use OpenCloud\Image\Resource\JsonPatch\Encoder;
     22:
     23: /**
     24:  * Class that represents an individual property in a JSON schema
     25:  *
     26:  * @package OpenCloud\Images\Resource\Schema
     27:  */
     28: class Property extends AbstractSchemaItem
     29: {
     30:     const DELIMETER = '#';
     31:
     32:     /** @var string Name of property */
     33:     protected $name;
     34:
     35:     /** @var string Description of property */
     36:     protected $description;
     37:
     38:     /** @var string Type of property (e.g. string, array) */
     39:     protected $type;
     40:
     41:     /** @var array Enumerated types that values must adhere to */
     42:     protected $enum;
     43:
     44:     /** @var string Regex pattern that values must adhere to */
     45:     protected $pattern;
     46:
     47:     /** @var array Array items that this property may possess */
     48:     protected $items;
     49:
     50:     /** @var mixed This property's value */
     51:     protected $value;
     52:
     53:     /**
     54:      * @param array $data
     55:      * @return Property
     56:      */
     57:     public static function factory(array $data = array())
     58:     {
     59:         $property = new self();
     60:
     61:         $property->setName(self::stockProperty($data, SchemaEnum::NAME));
     62:         $property->setDescription(self::stockProperty($data, SchemaEnum::DESCRIPTION));
     63:         $property->setType(self::stockProperty($data, SchemaEnum::TYPE));
     64:         $property->setEnum(self::stockProperty($data, SchemaEnum::ENUM));
     65:         $property->setPattern(self::stockProperty($data, SchemaEnum::PATTERN));
     66:
     67:         if (isset($data[SchemaEnum::ITEMS])) {
     68:             // handle sub-schemas
     69:             $property->setItems($data[SchemaEnum::ITEMS]);
     70:         }
     71:
     72:         return $property;
     73:     }
     74:
     75:     /**
     76:      * @param $name
     77:      */
     78:     public function setName($name)
     79:     {
     80:         $this->name = $name;
     81:     }
     82:
     83:     /**
     84:      * @return string
     85:      */
     86:     public function getName()
     87:     {
     88:         return $this->name;
     89:     }
     90:
     91:     /**
     92:      * @param $description
     93:      */
     94:     public function setDescription($description)
     95:     {
     96:         $this->description = $description;
     97:     }
     98:
     99:     /**
    100:      * @return string
    101:      */
    102:     public function getDescription()
    103:     {
    104:         return $this->description;
    105:     }
    106:
    107:     /**
    108:      * @param $type
    109:      */
    110:     public function setType($type)
    111:     {
    112:         $this->type = $type;
    113:     }
    114:
    115:     /**
    116:      * @return string
    117:      */
    118:     public function getType()
    119:     {
    120:         return $this->type;
    121:     }
    122:
    123:     /**
    124:      * @param $enum
    125:      */
    126:     public function setEnum($enum)
    127:     {
    128:         $this->enum = $enum;
    129:     }
    130:
    131:     /**
    132:      * @return array
    133:      */
    134:     public function getEnum()
    135:     {
    136:         return $this->enum;
    137:     }
    138:
    139:     /**
    140:      * @param $pattern
    141:      */
    142:     public function setPattern($pattern)
    143:     {
    144:         $this->pattern = $pattern;
    145:     }
    146:
    147:     /**
    148:      * @return string
    149:      */
    150:     public function getPattern()
    151:     {
    152:         return $this->pattern;
    153:     }
    154:
    155:     /**
    156:      * @param $value
    157:      */
    158:     public function setValue($value)
    159:     {
    160:         $this->value = $value;
    161:     }
    162:
    163:     /**
    164:      * @return mixed
    165:      */
    166:     public function getValue()
    167:     {
    168:         return $this->value;
    169:     }
    170:
    171:     /**
    172:      * @param $data
    173:      */
    174:     public function setItems($data)
    175:     {
    176:         $this->items = Schema::factory($data);
    177:     }
    178:
    179:     /**
    180:      * @return array
    181:      */
    182:     public function getItems()
    183:     {
    184:         return $this->items;
    185:     }
    186:
    187:     /**
    188:      * Prepare the given pattern for Regex functions
    189:      *
    190:      * @param $pattern
    191:      * @return string
    192:      */
    193:     protected function preparePattern($pattern)
    194:     {
    195:         return self::DELIMETER . (string) $pattern . self::DELIMETER;
    196:     }
    197:
    198:     /**
    199:      * Validate the current value and ensure that it adheres to correct formatting, etc.
    200:      *
    201:      * @return bool
    202:      */
    203:     public function validate()
    204:     {
    205:         // deal with enumerated types
    206:         if (!empty($this->enum)) {
    207:             return in_array($this->value, $this->enum);
    208:         }
    209:
    210:         // handle patterns
    211:         if ($this->pattern) {
    212:             return (bool) preg_match($this->preparePattern($this->pattern), $this->value);
    213:         }
    214:
    215:         // handle type
    216:         if ($this->type) {
    217:             return $this->type === gettype($this->value);
    218:         }
    219:
    220:         return true;
    221:     }
    222:
    223:     /**
    224:      * Get the JSON pointer for this property
    225:      *
    226:      * @return string
    227:      */
    228:     public function getPath()
    229:     {
    230:         return sprintf("/%s", Encoder::transform($this->name));
    231:     }
    232: }
    233: