FileStorageAcl.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258
  1. <?php
  2. Lib::loadClass('Core_AclBase');
  3. Lib::loadClass('FileStorage');
  4. class Schema_FileStorageAcl extends Core_AclBase {
  5. public function __construct() {}
  6. public function getNamespace() { return 'default_objects/' . $this->getName(); }
  7. public function getSourceName() { return 'default_objects'; }
  8. public function init($force = false) {}
  9. public function isInitialized() { return true; }
  10. public function getName() { return 'File'; }
  11. public function getRootTableName() { return 'CRM_FILES'; }
  12. public function getFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
  13. public function getVisibleFieldListByIdZasob() { return $this->getRealFieldListByIdZasob(); }
  14. public function getVirtualFieldListByIdZasob() { return array(); }
  15. public function getRealFieldListByIdZasob() {
  16. $cols = array();// FileStorage::getFileById()
  17. $cols[1] = 'id';
  18. $cols[2] = 'name';
  19. $cols[3] = 'size';
  20. $cols[4] = 'mimeType';
  21. $cols[5] = 'version';
  22. $cols[6] = 'content';
  23. // $cols[] = 'relativePath';
  24. // $cols[] = 'absolutePath';
  25. // $cols[] = 'exists';
  26. return $cols;
  27. }
  28. public function getFields() {// @returns array - $this->_fields
  29. $fields[1] = ['name'=>'id', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  30. $fields[2] = ['name'=>'name', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  31. $fields[3] = ['name'=>'size', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  32. $fields[4] = ['name'=>'mimeType', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  33. $fields[5] = ['name'=>'version', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  34. $fields[6] = ['name'=>'content', 'perms'=>'R', 'opis'=>'', 'label'=>'', 'sort_prio'=>999];
  35. return $fields;
  36. }
  37. public function getFieldIdByName($fieldName) {
  38. $fields = $this->getRealFieldListByIdZasob();
  39. if (empty($fieldName)) return null;
  40. foreach ($fields as $idField => $vFieldName) {
  41. if ($vFieldName == $fieldName) return $idField;
  42. }
  43. return null;
  44. }
  45. public function isDecimalField($fieldName) { return false; }
  46. public function isGeomField($fieldName) { return false; }
  47. public function isDateField($fieldName) { return false; }
  48. public function isDateTimeField($fieldName) { return false; }
  49. public function isStringField($fieldName) {
  50. if ('name' == $fieldName) return true;
  51. if ('mimeType' == $fieldName) return true;
  52. return false;
  53. }
  54. public function isTextField($fieldName) { return false; }
  55. public function isBinaryField($fieldName) {
  56. if ('content' == $fieldName) return true;
  57. return false;
  58. }
  59. public function isEnumerationField($fieldName) { return false; }
  60. public function getFieldType($fieldName) {
  61. switch ($fieldName) {
  62. case 'id': return ['name'=>'id', 'type'=>'int']; break;
  63. case 'name': return ['name'=>'name', 'type'=>'string']; break;
  64. }
  65. return null;
  66. }
  67. public function isAllowed($idZasob, $taskPerm, $record = null) {
  68. if ('C' == $taskPerm && $idZasob > 1 && $idZasob < 7) return true;
  69. if ('R' == $taskPerm && $idZasob > 0 && $idZasob < 7) return true;
  70. return false;
  71. }
  72. public function hasFieldPerm($idZasob, $taskPerm) {
  73. if ('C' == $taskPerm && $idZasob > 1 && $idZasob < 7) return true;
  74. if ('R' == $taskPerm && $idZasob > 0 && $idZasob < 7) return true;
  75. return false;
  76. }
  77. // TODO: replace legacy functions: isAllowed, hasFieldPerm, getFieldIdByName
  78. public function canCreateField($fieldName) {
  79. $fields = $this->getRealFieldListByIdZasob();
  80. if (!in_array($fieldName, $fields)) return false;
  81. return true;
  82. }
  83. public function canReadField($fieldName) {
  84. $fields = $this->getRealFieldListByIdZasob();
  85. if (!in_array($fieldName, $fields)) return false;
  86. return true;
  87. }
  88. public function canReadObjectField($fieldName, $record) {
  89. return $this->canReadField($fieldName);
  90. }
  91. public function canWriteField($fieldName) {
  92. $fields = $this->getRealFieldListByIdZasob();
  93. if (!in_array($fieldName, $fields)) return false;
  94. return true;
  95. }
  96. public function canWriteObjectField($fieldName, $record) {
  97. return $this->canWriteField($fieldName);
  98. }
  99. public function getTotal($params = array()) {// TODO: use ParseOgcQuery
  100. $sqlLimit = V::get('limit', 10000, $params);
  101. $sqlOffset = V::get('limitstart', 0, $params);
  102. // TODO: parse params:
  103. // [sortBy] => ID D,test_date A
  104. // [cols] => Array( [0] => ID
  105. // [1] => test_date
  106. // [2] => A_STATUS )
  107. // [ogc:Filter] => "<ogc:Filter><ogc:PropertyIsEqualTo><ogc:PropertyName>id</ogc:PropertyName><ogc:Literal>35</ogc:Literal></ogc:Filter>"
  108. $sqlWhereAddOgcFilter = '';
  109. $ogcFilter = V::get('ogc:Filter', '', $params);
  110. if (!empty($ogcFilter)) {
  111. Lib::loadClass('ParseOgcFilter');
  112. $parser = new ParseOgcFilter();
  113. $parser->loadOgcFilter($ogcFilter);
  114. $queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
  115. $usedFields = $queryWhereBuilder->getUsedFields();
  116. foreach ($usedFields as $fieldName) {
  117. if (!$this->getFieldIdByName($fieldName)) throw new Exception("Not allowed PropertyName '{$fieldName}'");
  118. }
  119. $sqlWhereAddOgcFilter = $queryWhereBuilder->getQueryWhere('t');
  120. if (!empty($sqlWhereAddOgcFilter)) $sqlWhereAddOgcFilter = " and {$sqlWhereAddOgcFilter}";
  121. DBG::_('DBG_DS', '>1', "ogc:Filter parser", $parser, __CLASS__, __FUNCTION__, __LINE__);
  122. DBG::_('DBG_DS', '>1', "ogc:Filter queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
  123. DBG::_('DBG_DS', '>1', "ogc:Filter usedFields", $usedFields, __CLASS__, __FUNCTION__, __LINE__);
  124. DBG::_('DBG_DS', '>1', "ogc:Filter sqlWhereAddOgcFilter", $sqlWhereAddOgcFilter, __CLASS__, __FUNCTION__, __LINE__);
  125. }
  126. $sqlTblName = FileStorage::getTableName();
  127. $sqlUserLogin = User::getLogin();
  128. $sqlWhere = "1=1";
  129. // $sqlWhere .= " and t.`A_RECORD_CREATE_AUTHOR` = '{$sqlUserLogin}' ";// TODO: Acl to read file
  130. $sqlWhere .= $sqlWhereAddOgcFilter;
  131. if ($pk = V::get('primaryKey', 0, $params, 'int')) $sqlWhere .= " and t.`ID` = {$pk} ";
  132. return DB::getPDO()->fetchValue("
  133. select count(1) as total
  134. from `{$sqlTblName}` t
  135. where {$sqlWhere}
  136. ");
  137. }
  138. public function getItem($primaryKey, $params = []) {
  139. $items = $this->getItems(['primaryKey'=>$primaryKey]);
  140. return (!empty($items[$primaryKey])) ? $items[$primaryKey] : null;
  141. }
  142. public function getItems($params = array()) {// TODO: use ParseOgcQuery
  143. $sqlLimit = V::get('limit', 10000, $params);
  144. $sqlOffset = V::get('limitstart', 0, $params);
  145. // TODO: parse params:
  146. // [sortBy] => ID D,test_date A
  147. // [cols] => Array( [0] => ID
  148. // [1] => test_date
  149. // [2] => A_STATUS )
  150. // [ogc:Filter] => "<ogc:Filter><ogc:PropertyIsEqualTo><ogc:PropertyName>id</ogc:PropertyName><ogc:Literal>35</ogc:Literal></ogc:Filter>"
  151. $sqlWhereAddOgcFilter = '';
  152. $ogcFilter = V::get('ogc:Filter', '', $params);
  153. if (!empty($ogcFilter)) {
  154. Lib::loadClass('ParseOgcFilter');
  155. $parser = new ParseOgcFilter();
  156. $parser->loadOgcFilter($ogcFilter);
  157. $queryWhereBuilder = $parser->convertToSqlQueryWhereBuilder();
  158. $usedFields = $queryWhereBuilder->getUsedFields();
  159. foreach ($usedFields as $fieldName) {
  160. if (!$this->getFieldIdByName($fieldName)) throw new Exception("Not allowed PropertyName '{$fieldName}'");
  161. }
  162. $sqlWhereAddOgcFilter = $queryWhereBuilder->getQueryWhere('t');
  163. if (!empty($sqlWhereAddOgcFilter)) $sqlWhereAddOgcFilter = " and {$sqlWhereAddOgcFilter}";
  164. DBG::_('DBG_DS', '>1', "ogc:Filter parser", $parser, __CLASS__, __FUNCTION__, __LINE__);
  165. DBG::_('DBG_DS', '>1', "ogc:Filter queryWhereBuilder", $queryWhereBuilder, __CLASS__, __FUNCTION__, __LINE__);
  166. DBG::_('DBG_DS', '>1', "ogc:Filter usedFields", $usedFields, __CLASS__, __FUNCTION__, __LINE__);
  167. DBG::_('DBG_DS', '>1', "ogc:Filter sqlWhereAddOgcFilter", $sqlWhereAddOgcFilter, __CLASS__, __FUNCTION__, __LINE__);
  168. }
  169. $sqlTblName = FileStorage::getTableName();
  170. $sqlUserLogin = User::getLogin();
  171. $sqlWhere = "1=1";
  172. // $sqlWhere .= " and t.`A_RECORD_CREATE_AUTHOR` = '{$sqlUserLogin}' ";// TODO: Acl to read file
  173. $sqlWhere .= $sqlWhereAddOgcFilter;
  174. if ($pk = V::get('primaryKey', 0, $params, 'int')) $sqlWhere .= " and t.`ID` = {$pk} ";
  175. $rows = array_map(function($row) {
  176. $wfsItem = array();
  177. $wfsItem['id'] = $row['ID'];
  178. $wfsItem['name'] = V::get('FILE_LABEL', $row['ID'], $row);
  179. $wfsItem['size'] = $row['FILE_SIZE'];
  180. $wfsItem['mimeType'] = $row['FILE_MIME_TYPE'];
  181. $wfsItem['version'] = $row['FILE_VERSION'];
  182. {// fetch file content
  183. $objectFile = FileStorage::getFileById($row['ID']);// TODO: avoid sql in FileStorage::convertFromDBRow($row)
  184. $wfsItem['content'] = ($objectFile['exists']) ? base64_encode(file_get_contents($objectFile['absolutePath'])) : null;
  185. }
  186. return $wfsItem;
  187. }, DB::getPDO()->fetchAll("
  188. select t.ID
  189. , t.FILE_HASH
  190. , t.FILE_LABEL
  191. , t.FILE_TYPE
  192. , t.FILE_MIME_TYPE
  193. , t.FILE_MTIME
  194. , t.FILE_SIZE
  195. , t.FILE_VERSION
  196. , t.A_STATUS
  197. , t.A_RECORD_CREATE_DATE
  198. , t.A_RECORD_CREATE_AUTHOR
  199. , t.A_RECORD_UPDATE_DATE
  200. , t.A_RECORD_UPDATE_AUTHOR
  201. , t.A_ADM_COMPANY
  202. , t.A_CLASSIFIED
  203. , INET_NTOA(t.A_USER_IP) as IP
  204. from `{$sqlTblName}` t
  205. where {$sqlWhere}
  206. order by ID DESC
  207. limit {$sqlLimit} offset {$sqlOffset}
  208. "));
  209. $items = array();
  210. foreach ($rows as $row) {
  211. $items[$row['id']] = (object)$row;
  212. }
  213. return $items;
  214. }
  215. public function addItem($itemTodo) {
  216. if (is_object($itemTodo)) {
  217. $itemTodo = (array)$itemTodo;
  218. }
  219. if (!is_array($itemTodo)) throw new HttpException('Item is not array', 400);
  220. if (empty($itemTodo)) {
  221. DBG::_('DBG_DS', '>2', "Item patch is empty", null, __CLASS__, __FUNCTION__, __LINE__);
  222. return 0;// nothing to insert
  223. }
  224. if (empty($itemTodo['content'])) throw new Exception("Empty file content");
  225. $fileName = V::get('name', '', $itemTodo);
  226. $binaryContent = base64_decode($itemTodo['content']);
  227. return FileStorage::addFile($binaryContent, $fileName);
  228. }
  229. public function getGeomFieldType($fieldName) { return null; }
  230. public function getPrimaryKeyField() { return 'id'; }
  231. public function getAttributesFromZasoby() {
  232. $attributes = array();// fldName => [ 'id_zasob' => int, 'label' => str, 'description' => str ]
  233. // if ($acl->hasFieldPerm($idZasob, 'W')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_write", "true");
  234. // if ($acl->hasFieldPerm($idZasob, 'C')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_create", "true");
  235. // if (!$acl->hasFieldPerm($idZasob, 'R')) $elNode->setAttributeNS($rootWfsNsUri, "{$rootWfsNs}:allow_read", "false");
  236. return $attributes;
  237. }
  238. public function getXsdFieldType($fieldName) {
  239. switch ($fieldName) {
  240. case 'id': return 'xsd:integer';
  241. case 'name': return 'xsd:string';
  242. case 'size': return 'xsd:integer';
  243. case 'mimeType': return 'xsd:string';
  244. case 'version': return 'xsd:integer';
  245. case 'content': return 'xsd:base64Binary';
  246. default: throw new HttpException("Error field not exists '{$fieldName}'", 404);
  247. }
  248. }
  249. }