1<?php
2/*
3 * Copyright 2011 Google 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/**
19 * This class defines attributes, valid values, and usage which is generated from
20 * a given json schema. http://tools.ietf.org/html/draft-zyp-json-schema-03#section-5
21 *
22 * @author Chirag Shah <chirags@google.com>
23 *
24 */
25class Google_Model {
26  public function __construct( /* polymorphic */ ) {
27    if (func_num_args() ==  1 && is_array(func_get_arg(0))) {
28      // Initialize the model with the array's contents.
29      $array = func_get_arg(0);
30      $this->mapTypes($array);
31    }
32  }
33
34  /**
35   * Initialize this object's properties from an array.
36   *
37   * @param array $array Used to seed this object's properties.
38   * @return void
39   */
40  protected function mapTypes($array) {
41    foreach ($array as $key => $val) {
42      $this->$key = $val;
43
44      $keyTypeName = "__$key" . 'Type';
45      $keyDataType = "__$key" . 'DataType';
46      if ($this->useObjects() && property_exists($this, $keyTypeName)) {
47        if ($this->isAssociativeArray($val)) {
48          if (isset($this->$keyDataType) && 'map' == $this->$keyDataType) {
49            foreach($val as $arrayKey => $arrayItem) {
50              $val[$arrayKey] = $this->createObjectFromName($keyTypeName, $arrayItem);
51            }
52            $this->$key = $val;
53          } else {
54            $this->$key = $this->createObjectFromName($keyTypeName, $val);
55          }
56        } else if (is_array($val)) {
57          $arrayObject = array();
58          foreach ($val as $arrayIndex => $arrayItem) {
59            $arrayObject[$arrayIndex] = $this->createObjectFromName($keyTypeName, $arrayItem);
60          }
61          $this->$key = $arrayObject;
62        }
63      }
64    }
65  }
66
67  /**
68   * Returns true only if the array is associative.
69   * @param array $array
70   * @return bool True if the array is associative.
71   */
72  protected function isAssociativeArray($array) {
73    if (!is_array($array)) {
74      return false;
75    }
76    $keys = array_keys($array);
77    foreach($keys as $key) {
78      if (is_string($key)) {
79        return true;
80      }
81    }
82    return false;
83  }
84
85  /**
86   * Given a variable name, discover its type.
87   *
88   * @param $name
89   * @param $item
90   * @return object The object from the item.
91   */
92  private function createObjectFromName($name, $item) {
93    $type = $this->$name;
94    return new $type($item);
95  }
96
97  protected function useObjects() {
98    global $apiConfig;
99    return (isset($apiConfig['use_objects']) && $apiConfig['use_objects']);
100  }
101
102  /**
103   * Verify if $obj is an array.
104   * @throws Google_Exception Thrown if $obj isn't an array.
105   * @param array $obj Items that should be validated.
106   * @param string $type Array items should be of this type.
107   * @param string $method Method expecting an array as an argument.
108   */
109  public function assertIsArray($obj, $type, $method) {
110    if ($obj && !is_array($obj)) {
111      throw new Google_Exception("Incorrect parameter type passed to $method(), expected an"
112          . " array containing items of type $type.");
113    }
114  }
115}
116