AclSimpleSchemaBase.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268
  1. <?php
  2. Lib::loadClass('Api_WfsNs');
  3. Lib::loadClass('Api_WfsException');
  4. Lib::loadClass('User');
  5. Lib::loadClass('Core_AclHelper');
  6. Lib::loadClass('Core_AclBase');
  7. // TODO: need PermProfile - array of perm profile list or just 'R,W,X,C,S', etc.
  8. class Core_AclSimpleSchemaBase extends Core_AclBase {
  9. /** simpleSchema - php structure:
  10. $simpleSchema = [
  11. 'root' => [
  12. '@namespace' => 'default_db/ZALICZKA/Zaliczka',
  13. '@primaryKey' => 'ID',
  14. 'ID' => 'xsd:integer', // short syntax - define only simpleType
  15. 'KWOTA' => [ // long syntax - define type with another params like restrictions
  16. '@type' => 'xsd:decimal'
  17. ],
  18. 'worker' => 'ref:Worker' // short syntax - define only type = ref
  19. 'pozycja' => [ // long syntax - define ref with maxOccurs, TODO: use more xsd attributes
  20. '@ref' => 'ZaliczkaPozycja',
  21. '@maxOccurs' => 'unbounded'
  22. ]
  23. ],
  24. 'Worker' => [
  25. '@namespace' => 'default_objects/AccessOwner',
  26. ...
  27. ],
  28. 'ZaliczkaPozycja' => [
  29. '@namespace' => 'default_db/ZALICZKA_POZYCJA/ZaliczkaPozycja',
  30. ...
  31. ]
  32. ]
  33. */
  34. public $_simpleSchema = array();
  35. public $_xsdTypes = null;// set by parseXsdTypes()
  36. public $_name = '';
  37. public $_namespace = '';
  38. public $_primaryKey = '';
  39. public $_rootTableName = '';
  40. public $_sourceNamespace = '';
  41. public $_xmlnsMap = [];
  42. public function __construct($simpleSchema = null) {
  43. if ($simpleSchema) $this->_simpleSchema = $simpleSchema;
  44. if (!$this->_simpleSchema) throw new Exception("Missing simpleSchema");
  45. if (empty($this->_simpleSchema['root'])) throw new Exception("Wrong simpleSchema syntax");
  46. if (empty($this->_simpleSchema['root']['@namespace'])) throw new Exception("Missing @namespace in simpleSchema");
  47. $this->_namespace = $this->_simpleSchema['root']['@namespace'];
  48. $ns = explode('/', $this->_namespace);
  49. $this->_name = end($ns);
  50. if (empty($this->_rootTableName)) {
  51. if (count($ns) < 3) throw new Exception("Wrong @namespace syntax in simpleSchema ns({$this->_simpleSchema['root']['@namespace']})");
  52. $this->_rootTableName = $ns[1];
  53. }
  54. {
  55. $this->_sourceNamespace = explode('/', $this->_namespace);
  56. array_pop($this->_sourceNamespace);// remove name
  57. $this->_sourceNamespace = implode('__x3A__', $this->_sourceNamespace);
  58. }
  59. if (empty($this->_simpleSchema['root']['@primaryKey'])) $this->_simpleSchema['root']['@primaryKey'] = 'ID';// TODO: throw new Exception("Missing @primaryKey in simpleSchema");
  60. $this->_primaryKey = $this->_simpleSchema['root']['@primaryKey'];// TODO: check if field exists
  61. {// validate and fix _simpleSchema:
  62. // - convert field scalar to [ '@type' => ... ]
  63. // - check required @namespace attribute
  64. foreach ($this->_simpleSchema as $keySchema => $schema) {
  65. foreach ($schema as $fieldName => $params) {
  66. if ('@' == substr($fieldName, 0, 1)) continue;// skip params
  67. if (is_scalar($params)) {
  68. $this->_simpleSchema[ $keySchema ][ $fieldName ] = [ '@type' => $params ];
  69. } else if (!is_array($params)) {
  70. throw new Exception("Parse error - simpleSchema field type");
  71. }
  72. }
  73. if (empty($schema['@namespace'])) throw new Exception("Missing @namespace in schema for '{$keySchema}'");
  74. $ns = explode('/', $schema['@namespace']);
  75. $name = end($ns);
  76. if (count($ns) < 2) throw new Exception("Wrong @namespace syntax in schema for '{$keySchema}'");
  77. }
  78. }
  79. // $this->parseXsdTypes();// parse xsdTypes
  80. $this->_xsdTypes = array();
  81. {
  82. $generatedIdZasob = 10000;// fake zasob id
  83. foreach ($this->_simpleSchema['root'] as $key => $value) {
  84. if ('@' == substr($key, 0, 1)) continue;// skip attributes
  85. if (is_array($value)) {
  86. $fieldName = $key;
  87. $field = [ 'name' => $fieldName, 'perms' => '', 'idZasob' => $generatedIdZasob ];
  88. if (!empty($value['@label'])) $field['label'] = $value['@label'];
  89. if (!empty($value['@type'])) $field['xsdType'] = "{$value['@type']}";
  90. else if (!empty($value['@ref'])) {
  91. $field['xsdType'] = (false !== strpos($value['@ref'], '/'))
  92. ? "ref_uri:{$value['@ref']}"
  93. : "ref:{$value['@ref']}";
  94. }
  95. else throw new Exception("StorageAcl - field type not defined '{$key}'");
  96. if (!empty($value['@maxOccurs'])) $field['maxOccurs'] = $value['@maxOccurs'];
  97. $this->_xsdTypes[$fieldName] = $field;
  98. } else if (is_scalar($value)) {// short syntax: $fieldName => $xsdType
  99. $fieldName = $key;
  100. $field = [ 'name' => $fieldName, 'perms' => '', 'idZasob' => $generatedIdZasob ];
  101. $field['xsdType'] = $value;
  102. $this->_xsdTypes[$fieldName] = $field;
  103. } else {
  104. throw new Exception("StorageAcl - TODO: Unimplemented value type in simpleSchema: " . json_encode($value));
  105. }
  106. $generatedIdZasob++;
  107. }
  108. }
  109. // TODO: fix 'ref:*' types - use Core_AclHelper::parseNamespaceUrl($namespace)
  110. }
  111. public function __toString() {
  112. $out = "xsd @prefix(default_db__x3A__{$this->_rootTableName})" . "\n";
  113. $aliasRefUri = array();
  114. foreach ($this->_simpleSchema as $objectName => $schema) {
  115. if ('root' == $objectName) $objectName = $this->_name;
  116. $out .= "\t" . "{$objectName}";
  117. $out .= " @namespace({$schema['@namespace']})";
  118. $out .= "\n";
  119. foreach ($schema as $fieldName => $field) {
  120. if ('@' == substr($fieldName, 0, 1)) continue;// skip tags
  121. $out .= "\t\t" . "{$fieldName}";
  122. if (!empty($field['@type'])) {
  123. $out .= " @type({$field['@type']})";
  124. if (!empty($field['@alias'])) $out .= " @alias({$field['@alias']})";
  125. } else if (!empty($field['@ref'])) {
  126. $out .= " @ref({$field['@ref']})";
  127. if (false !== strpos($field['@ref'], '/')) $aliasRefUri[ $fieldName ] = $field['@ref'];
  128. } else {
  129. $out .= " @BUG('missing @type or @ref')";
  130. }
  131. // TODO: maxOccurs, nillable, etc.
  132. $out .= "\n";
  133. }
  134. foreach ($aliasRefUri as $fieldName => $nsUri) {
  135. $out .= "\t" . "{$objectName} @ref({$nsUri})" . "\n";
  136. // TODO: maxOccurs, nillable, etc.
  137. }
  138. }
  139. return $out;
  140. }
  141. public function hasSimpleSchema() { return true; }
  142. public function getSimpleSchema() { return $this->_simpleSchema; }
  143. public function getSimpleSchemaTree() {
  144. $tree = array();
  145. foreach ($this->_simpleSchema['root'] as $fieldName => $field) {
  146. $tree[ $fieldName ] = $field;
  147. if (is_array($field) && !empty($field['@ref'])) {
  148. $tree[ $fieldName ] = $this->_getSimpleSchemaTreeRec($field['@ref']);
  149. }
  150. }
  151. return $tree;
  152. }
  153. public function _getSimpleSchemaTreeRec($ref) {
  154. // echo "<p>DBG: F._getSimpleSchemaTreeRec({$ref})</p>";
  155. $tree = array();
  156. if (!empty($this->_simpleSchema[ $ref ])) {
  157. $tree = array();
  158. foreach ($this->_simpleSchema[ $ref ] as $fieldName => $field) {
  159. // echo "<p>DBG: F._getSimpleSchemaTreeRec({$ref}) 1/'{$fieldName}'</p>";
  160. $tree[ $fieldName ] = $field;
  161. if (is_array($field) && !empty($field['@ref'])) {
  162. $tree[ $fieldName ] = $this->_getSimpleSchemaTreeRec($field['@ref']);
  163. }
  164. }
  165. } else {
  166. $acl = Core_AclHelper::getAclByNamespace($ref);
  167. $tree[ '@namespace' ] = $acl->getNamespace();
  168. foreach ($acl->getXsdTypes() as $fieldName => $field) {
  169. // echo "<p>DBG: F._getSimpleSchemaTreeRec({$ref}) 2/'{$fieldName}'</p>";
  170. $tree[ $fieldName ] = $field;
  171. if (is_array($field) && !empty($field['@ref'])) {
  172. $tree[ $fieldName ] = $this->_getSimpleSchemaTreeRec($field['@ref']);
  173. }
  174. }
  175. }
  176. // echo'<pre>F._getSimpleSchemaTreeRec('.$ref.') tree';print_r($tree);echo'</pre>';
  177. return $tree;
  178. }
  179. public function getName() { return $this->_name; }
  180. public function getRootTableName() { return $this->_rootTableName; }
  181. public function getXsdTypes() { return $this->_xsdTypes; }
  182. public function getNamespace() { return $this->_namespace; }
  183. public function getSourceName() { return $this->_sourceNamespace; }
  184. public function init($force = false) {}
  185. public function isInitialized() { return true; }
  186. public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
  187. public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
  188. public function getVirtualFieldListByIdZasob() { return array(); }
  189. public function getRealFieldListByIdZasob($force = false) {
  190. $cols = array();
  191. foreach ($this->getFields() as $idField => $field) {
  192. $cols[$idField] = $field['name'];
  193. }
  194. return $cols;
  195. }
  196. public function getFields() {// @returns array - $this->_fields
  197. $fieldsById = array();
  198. foreach ($this->getXsdTypes() as $fieldName => $field) {
  199. $field['name'] = $fieldName;
  200. $field['label'] = V::get('label', $fieldName, $field);
  201. if ('p5:www_link' == $field['xsdType']) $field['simpleType'] = 'p5:www_link';
  202. $fieldsById[ $field['idZasob'] ] = $field;
  203. }
  204. return $fieldsById;
  205. }
  206. public function getFieldType($fieldName) {
  207. foreach ($this->getFields() as $field) {
  208. if ($fieldName == $field['name']) return $field;
  209. }
  210. return null;
  211. }
  212. // TODO: replace legacy functions: isAllowed, hasFieldPerm, getFieldIdByName
  213. public function canCreateField($fieldName) { return false; }// TODO: perms from Procesy
  214. public function canReadField($fieldName) { return true; }// TODO: perms from Procesy
  215. public function canReadObjectField($fieldName, $record) { return true; }// TODO: perms from Procesy
  216. public function canWriteField($fieldName) { return false; }// TODO: perms from Procesy
  217. public function canWriteObjectField($fieldName, $record) { return false; }// TODO: perms from Procesy
  218. public function getTotal($params = array()) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }// TODO: use ParseOgcQuery
  219. public function getItem($primaryKey) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }
  220. public function getItems($params = array()) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }// TODO: use ParseOgcQuery
  221. public function fetchItemRef(&$items) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }
  222. public function addItem($itemTodo) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }
  223. public function updateItem($itemPatch) { throw new Exception("Unimplemented - TODO: F." . __FUNCTION__); }
  224. public function getGeomFieldType($fieldName) { return null; }
  225. public function getPrimaryKeyField() { return $this->_primaryKey; }
  226. public function getID() { return 0; }
  227. public function getAttributesFromZasoby() { return array(); }
  228. public function isEnumerationField($fieldName) { return false; }
  229. public function getEnumerations($fieldName) { return null; }
  230. public function getXsdFieldType($fieldName) {
  231. $xsdTypes = $this->getXsdTypes();
  232. if (empty($xsdTypes[$fieldName])) throw new Exception("Field '{$fieldName}' not exists");
  233. return $xsdTypes[$fieldName]['xsdType'];
  234. }
  235. public function isGeomField($fieldName) {
  236. if ('File' == $fieldName) return false;
  237. if ('AccessGroupRead' == $fieldName) return false;
  238. if ('AccessGroupWrite' == $fieldName) return false;
  239. if ('AccessOwner' == $fieldName) return false;
  240. // if ('NestedObjectTest' == $fieldName) return false;
  241. // return $this->parentAcl->isGeomField($fieldName);
  242. }
  243. }