PageRenderTime 64ms CodeModel.GetById 21ms RepoModel.GetById 0ms app.codeStats 1ms

/lib/LIB_Document.inc

https://bitbucket.org/joaoborsoi/avalanche
PHP | 2492 lines | 2025 code | 346 blank | 121 comment | 378 complexity | 8ee92fa255a958374feddf7402e3a796 MD5 | raw file
  1. <?php
  2. require_once('UM_User.inc');
  3. require_once('LIB_Node.inc');
  4. require_once('AV_FaultTolerantFS.inc');
  5. define('HALF_SEARCH_LIMIT', 50000);
  6. //--Class: LIB_Document
  7. //--Desc: Library document class.
  8. class LIB_Document extends LIB_Node
  9. {
  10. //
  11. //--Private
  12. //
  13. protected $docMainTable; //--Desc: Document database main table
  14. protected $docTable; //--Desc: Document database table
  15. protected $docPath;
  16. protected $foderTables;
  17. //
  18. //--Public
  19. //
  20. //--Method: __constructor
  21. //--Desc: Constructor.
  22. function __construct(&$module)
  23. {
  24. parent::__construct($module);
  25. $this->docMainTable = new FORM_DynTable("LIB_Document", $this->module);
  26. $this->docTable = NULL;
  27. }
  28. function LoadFieldsDef($docId, $path)
  29. {
  30. if($docId != NULL)
  31. {
  32. $SQL = 'SELECT path FROM LIB_Folder,LIB_DocumentLink WHERE ';
  33. $SQL .= "docId = '$docId' AND ";
  34. $SQL .= 'LIB_DocumentLink.folderId=LIB_Folder.folderId ';
  35. $SQL .= 'LIMIT 1 LOCK IN SHARE MODE';
  36. $path = $this->dbDriver->GetOne($SQL);
  37. if($path == NULL)
  38. throw new AV_Exception(INVALID_FIELD, $this->lang,
  39. array('fieldName'=>'path'));
  40. $path = addslashes($path);
  41. $disableFileReq = true;
  42. }
  43. else
  44. $disableFileReq = false;
  45. $this->folderTables = $this->GetFolderTables($path);
  46. $fieldsDef=array_merge($this->docMainTable->LoadFieldsDef($disableFileReq),
  47. $this->nodeTable->LoadFieldsDef($disableFileReq));
  48. foreach($this->folderTables as $table)
  49. {
  50. require_once($table['dataModule'].'.inc');
  51. $this->docTable[$table['tableName']]=
  52. new $table['dataModule']($table['tableName'],$this->module);
  53. $fieldsDef =
  54. array_merge($fieldsDef,
  55. $this->docTable[$table['tableName']]->LoadFieldsDef($disableFileReq));
  56. }
  57. $fieldsDef[2080]['fieldName'] = 'keywords';
  58. $fieldsDef[2080]['required'] = false;
  59. $fieldsDef[2080]['allowNull'] = true;
  60. $fieldsDef[2080]['stripSlashes'] = false;
  61. ksort($fieldsDef);
  62. return $fieldsDef;
  63. }
  64. //--Method: Insert
  65. //--Desc: Inserts new document to the library
  66. function Insert($fields)
  67. {
  68. $folderData = parent::Insert($fields);
  69. // Retrieves docId to be returned
  70. $docId = $this->dbDriver->GetOne('SELECT LAST_INSERT_ID() FROM DUAL');
  71. if($docId === NULL)
  72. throw new AV_Exception(FAILED, $this->lang);
  73. $this->docMainTable->Insert($fields,array('docId'=>$docId));
  74. foreach($this->docTable as $table)
  75. $table->Insert($fields, array('docId'=>$docId));
  76. if($fields['keywords'] != NULL)
  77. $this->InsertKeywords($fields['keywords']);
  78. $this->CreateDocLink($folderData['folderId'],$docId,$fields['beforeDocId']);
  79. $fields['docId'] = $docId;
  80. $this->InsHistory($fields);
  81. $this->NotifyAdmin('adminInsDocLogTag',$fields);
  82. return $docId;
  83. }
  84. //--Method: Set
  85. //--Desc: Sets document data
  86. function Set($fields)
  87. {
  88. // sets node
  89. $fields['nodeId'] = $fields['docId'];
  90. parent::Set($fields);
  91. $this->docMainTable->Set($fields);
  92. $oldValues = array();
  93. foreach($this->docTable as $table)
  94. {
  95. $_oldValues = $table->Set($fields);
  96. if($this->module->pageBuilder->siteConfig->getVar('admin','history'))
  97. $oldValues = array_merge($oldValues,$_oldValues);
  98. }
  99. // delete keywords
  100. if($fields['keywords'] !== NULL)
  101. {
  102. $SQL = "DELETE FROM LIB_Keyword WHERE docId = '".$fields['docId']."'";
  103. $this->dbDriver->ExecSQL($SQL);
  104. if($fields['keywords'] != NULL)
  105. $this->InsertKeywords($fields['keywords'],$fields['docId']);
  106. }
  107. $this->InsHistory($fields,$oldValues);
  108. $this->NotifyAdmin('adminSetDocLogTag',$fields);
  109. }
  110. function Duplicate($path, $docId, $beforeDocId)
  111. {
  112. $folderData = parent::Duplicate($path,$docId);
  113. // Retrieves docId to be returned
  114. $targetId = $this->dbDriver->GetOne('SELECT LAST_INSERT_ID()');
  115. if($targetId === NULL)
  116. throw new AV_Exception(FAILED, $this->lang);
  117. $fields['docId'] = $targetId;
  118. $sourceKey['fieldName'] = 'docId';
  119. $sourceKey['fieldValue'] = $docId;
  120. $this->docMainTable->Duplicate($sourceKey,$fields);
  121. foreach($this->docTable as $table)
  122. $table->Duplicate($sourceKey,$fields);
  123. $this->DuplicateKeywords($docId,$targetId);
  124. $this->CreateDocLink($folderData['folderId'],$targetId,$beforeDocId);
  125. $fields['path'] = $path;
  126. $this->NotifyAdmin('adminDupDocLogTag',$fields);
  127. return $targetId;
  128. }
  129. function InsDocLink($path, $docId, $beforeDocId)
  130. {
  131. if($this->dbDriver->type=='oracle')
  132. {
  133. $LOCK = 'LOCK TABLE LIB_FolderTables,LIB_Folder,LIB_DocumentLink ';
  134. $LOCK .= 'IN SHARE MODE';
  135. $this->dbDriver->ExecSQL($LOCK);
  136. }
  137. // check if path is compatible with the docId table
  138. $SQL = 'SELECT DISTINCT id, tableName ';
  139. $SQL .= 'FROM LIB_FolderTables,LIB_Folder,LIB_DocumentLink WHERE ';
  140. $SQL .= "docId = '$docId' AND ";
  141. $SQL .= 'LIB_DocumentLink.folderId=LIB_Folder.folderId AND ';
  142. $SQL .= 'folderTables = id ';
  143. $SQL .= 'ORDER BY printOrder LIMIT 2,10 LOCK IN SHARE MODE';
  144. $docTables = $this->dbDriver->GetAll($SQL);
  145. if(count($docTables) == 0)
  146. throw new AV_Exception(NOT_FOUND, $this->lang);
  147. $folderTables = $this->GetFolderTables($path);
  148. if($docTables !== $folderTables)
  149. throw new AV_Exception(INVALID_PATH, $this->lang,
  150. array('fieldName','path'));
  151. // checks out for write permission
  152. $folderData = $this->GetFolderData($path,'share');
  153. $this->CheckNodePermission($folderData, true);
  154. $docData = $this->GetDocData($docId, 'share');
  155. // checks out for read permission
  156. $this->CheckNodePermission($docData, false);
  157. $this->CreateDocLink($folderData['folderId'], $docId, $beforeDocId);
  158. $fields = $this->GetDocFields($docId, $path);
  159. $fields['path'] = $path;
  160. $this->NotifyAdmin('adminCopyDocLogTag',$fields);
  161. }
  162. //--Method: DelDocLink
  163. //--Desc: Deletes document link in the library.
  164. function DelDocLink($path, $docId)
  165. {
  166. $folderData = $this->GetFolderData($path, 'share');
  167. // checks out for write permission
  168. $data = $this->CheckNodePermission($folderData, true);
  169. // checks restricted deletion flag
  170. $this->CheckRestrictedDeletion($folderData, $data['memberData'], $docId);
  171. // lock link (table row) that will be deleted
  172. $SQL = 'SELECT * FROM LIB_DocumentLink ';
  173. $SQL .= "WHERE docId = '$docId' ";
  174. $SQL .= "AND folderId='".$folderData['folderId']."' ";
  175. $SQL .= 'FOR UPDATE ';
  176. $row = $this->dbDriver->GetRow($SQL);
  177. if(count($row)==NULL)
  178. throw new AV_Exception(NOT_FOUND, $this->lang);
  179. $SQL = 'SELECT COUNT(*) as numLinks ';
  180. $SQL .= 'FROM LIB_DocumentLink dl ';
  181. $SQL .= "WHERE dl.docId = '$docId' ";
  182. $SQL .= 'LOCK IN SHARE MODE ';
  183. $numLinks = $this->dbDriver->GetOne($SQL);
  184. $returnFields = $this->GetReturnFields($path);
  185. if(count($returnFields)>0)
  186. {
  187. $tables = array();
  188. foreach($returnFields as $key=>$field)
  189. {
  190. if(!isset($tables[$field['tableName']]))
  191. {
  192. if($key>0)
  193. $FROM .= ',';
  194. $FROM .= $field['tableName']." t$key";
  195. if($key>0)
  196. $WHERE .= "AND ";
  197. if($field['tableName']=='LIB_Node')
  198. $WHERE .= "t$key.nodeId='$docId' ";
  199. else
  200. $WHERE .= "t$key.docId='$docId' ";
  201. $tables[$field['tableName']] = "t$key";
  202. }
  203. if($key>0)
  204. $SELECT .= ',';
  205. $SELECT .= $tables[$field['tableName']].'.'.$field['fieldName'];
  206. }
  207. $SQL = "SELECT $SELECT FROM $FROM WHERE $WHERE ";
  208. $row = $this->dbDriver->GetRow($SQL);
  209. if(count($row) === NULL)
  210. throw new AV_Exception(FAILED, $this->lang);
  211. }
  212. // if it's the last document link, deletes full node and file
  213. if($numLinks == 1)
  214. $this->Del(array('nodeId'=>$docId));
  215. else
  216. {
  217. // not the last link, deletes only the link
  218. $SQL = 'DELETE FROM LIB_DocumentLink ';
  219. $SQL .= 'WHERE ';
  220. $SQL .= "folderId = '".$folderData['folderId']."' AND ";
  221. $SQL .= "docId = '$docId' ";
  222. $this->dbDriver->ExecSQL($SQL);
  223. }
  224. $row['path'] = $path;
  225. $this->NotifyAdmin('adminDelDocLogTag',$row);
  226. }
  227. function &GetForm($keyFields, $path, $fieldName, $sourceId, & $templates,
  228. & $formObject, $defValues = array(),$dateFormat = NULL,
  229. $numberFormat = true, $short = false)
  230. {
  231. if($keyFields != NULL)
  232. $this->LoadFieldsDef($keyFields['docId']);
  233. else
  234. $this->LoadFieldsDef(NULL,$path);
  235. $formObject->attrs['folderTables'] = $this->folderTables[0]['id'];
  236. foreach($this->docTable as $table)
  237. $table->GetForm($keyFields,$fieldName,$sourceId,$templates,
  238. $formObject,$defValues,$dateFormat,$numberFormat,$short);
  239. $this->docMainTable->GetForm($keyFields,$fieldName,$sourceId,$templates,
  240. $formObject,$defValues,$dateFormat,
  241. $numberFormat,$short);
  242. if($keyFields != NULL)
  243. $keyFields['nodeId'] = $keyFields['docId'];
  244. else
  245. {
  246. $folderData = $this->GetFolderData($path, 'share');
  247. if(!isset($defValues['userRight']) && isset($folderData['defUserRight']))
  248. $defValues['userRight'] = $folderData['defUserRight'];
  249. if(!isset($defValues['groupRight']) && isset($folderData['defGroupRight']))
  250. $defValues['groupRight'] = $folderData['defGroupRight'];
  251. if(!isset($defValues['otherRight']) && isset($folderData['defOtherRight']))
  252. $defValues['otherRight'] = $folderData['defOtherRight'];
  253. }
  254. parent::GetForm($keyFields,$fieldName,$sourceId,$templates,
  255. $formObject,$defValues,$dateFormat,$numberFormat,$short);
  256. // keywords field
  257. if($fieldName==NULL || $fieldName=='keywords')
  258. {
  259. $SQL = "SELECT keyword FROM LIB_Keyword WHERE docId = '";
  260. $SQL .= $keyFields['docId']."'";
  261. $keywords = $this->dbDriver->GetCol($SQL);
  262. $keywordsField = new AV_ModObject('field', $this->module->pageBuilder);
  263. $keywordsField->attrs['fieldName'] = 'keywords';
  264. $keywordsField->attrs['value'] = implode(', ', $keywords);
  265. $keywordsField->attrs['type'] = 'text';
  266. $keywordsField->attrs['size'] = '255';
  267. $keywordsField->attrs['attributes'] = "size='50'";
  268. $keywordsField->attrs['label'] =
  269. $this->label->GetLabel('LIB_Document_keywords', $this->lang);
  270. $formObject->children[2080] = & $keywordsField;
  271. $formObject->attrs['keywords'] = $keywordsField->attrs['value'];
  272. }
  273. if($fieldName==NULL || $fieldName=='langTab')
  274. {
  275. // language tab
  276. $langList = $this->label->GetLangList();
  277. $langTab = new FORM_Object('field', $this->module->pageBuilder,
  278. $templates, 'langTabItem');
  279. $langTab->attrs['fieldName'] = 'langTab';
  280. $langTab->attrs['type'] = 'langTab';
  281. $langTab->attrs['adminLangTitle']=$this->label->GetLabel('adminLangTitle',
  282. $this->lang);
  283. // creates tab items
  284. foreach($langList as $key => $lang)
  285. {
  286. $field = new AV_ModObject('tab', $this->module->pageBuilder);
  287. $field->attrs['type'] = 'langTabItem';
  288. $field->attrs['lang'] = $lang['lang'];
  289. $field->attrs['label'] = mb_substr($lang['lang'],0,2);
  290. $langTab->children[] = $field;
  291. }
  292. $formObject->children[500] = & $langTab;
  293. }
  294. ksort($formObject->children);
  295. return $formObject;
  296. }
  297. function GetHistory($docId)
  298. {
  299. $SQL = '(SELECT dh.id, u.login, u.name, dh.histDate, dh.fieldName, ';
  300. $SQL .= 'dh.value, NULL as parentField ';
  301. $SQL .= 'FROM LIB_DocHistory dh, UM_User u ';
  302. $SQL .= "WHERE dh.docId='$docId' ";
  303. $SQL .= 'AND dh.userId = u.userId) ';
  304. $SQL .= 'UNION ';
  305. $SQL .= '(SELECT dh.id, u.login, u.name, dh.histDate, dh.fieldName, ';
  306. $SQL .= 'dh.value, dhor.fieldName as parentField ';
  307. $SQL .= 'FROM LIB_DocHistory dh, LIB_DocHistoryObjRef dhor, UM_User u ';
  308. $SQL .= "WHERE dh.docId=dhor.refId AND dhor.docId='$docId' ";
  309. $SQL .= 'AND dh.userId = u.userId) ';
  310. $SQL .= 'ORDER BY id ';
  311. $historyList = $this->dbDriver->GetAll($SQL);
  312. foreach($historyList as &$history)
  313. if($history['value']!=NULL)
  314. $history['value'] = json_decode($history['value'],true);
  315. return $historyList;
  316. }
  317. function DocList($params)
  318. {
  319. $path = $this->PreparePath($params['path']);
  320. // checks for returnFields
  321. $aux['recursiveSearch'] = false; // prevents recursive search
  322. $aux['path'][] = $path;
  323. $this->LoadReturnFields($aux);
  324. $folderTables = $this->GetFolderTables($path);
  325. foreach($folderTables as $key=>$folder)
  326. {
  327. $tableObj = new FORM_DynTable($folder['tableName'], $this->module);
  328. $fieldsDef = $tableObj->LoadFieldsDef();
  329. foreach($fieldsDef as $def)
  330. {
  331. if(in_array($def['fieldName'],$aux['returnFields']))
  332. {
  333. if($def['type']!='objectList' &&
  334. $def['type']!='fileList')
  335. $returnFields[] = "t$key.".$def['fieldName'];
  336. }
  337. }
  338. if(!in_array($folder['tableName'],$tables))
  339. {
  340. $tables[$folder['tableName']] = $folder['tableName'] . " t$key";
  341. $tablesWhere[] .= "t$key.docId ";
  342. }
  343. }
  344. $returnFields = implode(',', $returnFields);
  345. if(count($returnFields)==0)
  346. throw new AV_Exception(FAILED, $this->lang);
  347. $SQL .= 'SELECT doc.docId, docLink.folderId, folderTables, path,';
  348. $SQL .= "docLink.fixedOrder,$returnFields ";
  349. $SQL .= 'FROM LIB_DocumentLink docLink,LIB_Folder folder,';
  350. $SQL .= 'LIB_Node docNode, LIB_Document doc, LIB_Node folderNode,';
  351. $SQL .= implode(',',$tables);
  352. $SQL .= " WHERE path = '$path' ";
  353. $SQL .= 'AND docLink.folderId=folder.folderId ';
  354. $SQL .= 'AND docLink.docId=docNode.nodeId ';
  355. $SQL .= 'AND docLink.docId=doc.docId ';
  356. $SQL .= 'AND docLink.folderId=folderNode.nodeId ';
  357. $SQL .= 'AND docLink.docId='.implode(' AND docLink.docId=',$tablesWhere);
  358. // loads user member data and groups
  359. $sessionH = & $this->module->pageBuilder->sessionH;
  360. // checks if user is not logged and also public access right
  361. if(!$sessionH->isGuest())
  362. {
  363. $userMan = new UM_User($this->module);
  364. $params['memberData'] = $userMan->GetMemberData('share', false, false);
  365. $params['memberGroups'] = $userMan->GetMemberGroupsIds('share');
  366. }
  367. $SQL .= " AND ";
  368. if(isset($params['memberData']['userId']))
  369. {
  370. if(count($params['memberGroups'])==0)
  371. throw new AV_Exception(INVALID_FIELD, $this->lang,
  372. array('fieldName'=>'memberGroups'));
  373. $groups = implode(',',$params['memberGroups']);
  374. # check folder permission
  375. $SQL .= 'IF(folderNode.userId='.$params['memberData']['userId'].',';
  376. $SQL .= "INSTR(folderNode.userRight,'r'),";
  377. $SQL .= "IF(folderNode.groupId IN ($groups),";
  378. $SQL .= "INSTR(folderNode.groupRight,'r'),";
  379. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  380. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  381. $SQL .= "WHERE ngr.nodeId=folderNode.nodeId)<>0,1, ";
  382. $SQL .= "INSTR(folderNode.otherRight,'r'))))<>0 ";
  383. # check node permission
  384. $SQL .= ' AND ';
  385. $SQL .= 'IF(docNode.userId='.$params['memberData']['userId'].',';
  386. $SQL .= "INSTR(docNode.userRight,'r'),";
  387. $SQL .= "IF(docNode.groupId IN ($groups),";
  388. $SQL .= "INSTR(docNode.groupRight,'r'),";
  389. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  390. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  391. $SQL .= "WHERE ngr.nodeId=docNode.nodeId)<>0,1, ";
  392. $SQL .= "INSTR(docNode.otherRight,'r'))))<>0 ";
  393. }
  394. else
  395. {
  396. $SQL .= "INSTR(folderNode.otherRight,'r')<>0 ";
  397. $SQL .= "AND INSTR(docNode.otherRight,'r')<>0 ";
  398. }
  399. $SQL .= $this->GetExclusionFiltersSQL($params['exclusionFilters']);
  400. $SQL .= ' LIMIT ' . HALF_SEARCH_LIMIT;
  401. return $this->dbDriver->GetAll($SQL);
  402. }
  403. //--Method: Search
  404. //--Desc: Searches library documents
  405. function &Search(& $params)
  406. {
  407. if(!isset($params['tempTable']))
  408. $params['tempTable'] = true;
  409. // prepare filter
  410. $params['filter'] = $this->PrepareFilter($params['filter']);
  411. // search allows more then one path
  412. $params['path'] = explode(',',$params['path']);
  413. foreach($params['path'] as &$path)
  414. // prepare path
  415. $path = $this->PreparePath($path);
  416. // if should search keywords
  417. $key = array_search('keywords',$params['searchCriteria']);
  418. $params['searchKeywords'] = ($key !== false && $key !== NULL ||
  419. $params['searchCriteria'] == '*');
  420. if($params['searchKeywords'])
  421. {
  422. if($params['searchCriteria'] != '*')
  423. unset($params['searchCriteria'][$key]);
  424. // if no filter is specified, does not search keywords
  425. if($params['filter'] === NULL)
  426. $params['searchKeywords'] = false;
  427. }
  428. // checks for returnFields
  429. if($params['returnFields']==NULL)
  430. $this->LoadReturnFields($params);
  431. // saves default values for later use when deciding which search object
  432. // should be searched just bellow
  433. $exclusionFilters = $params['exclusionFilters'];
  434. $searchCriteria = $params['searchCriteria'];
  435. // load search fields and create result table with them
  436. $this->LoadSearchDefs($params);
  437. // loads user member data and groups
  438. $sessionH = & $this->module->pageBuilder->sessionH;
  439. // checks if user is not logged and also public access right
  440. if(!$sessionH->isGuest())
  441. {
  442. $userMan = new UM_User($this->module);
  443. $params['memberData'] = $userMan->GetMemberData('share', false, false);
  444. $params['memberGroups'] = $userMan->GetMemberGroupsIds('share');
  445. }
  446. try
  447. {
  448. foreach($params['searchObjs'] as $key=>$obj)
  449. {
  450. // search object if:
  451. // - returnFields has any field from the object tables and
  452. // - exclusionFilters are not given or all fields exists on the object
  453. // tables and
  454. // - searchCriteria are not given or any field exists on the object
  455. // tables
  456. if(count($obj['returnFields'])>0 &&
  457. ($exclusionFilters==NULL ||
  458. count($exclusionFilters)==count($obj['exclusionFilters'])) &&
  459. ($params['searchKeywords'] ||
  460. $searchCriteria==NULL ||
  461. count($obj['searchCriteria'])>0) &&
  462. ($params['orderBy'] == 'matches' ||
  463. $params['orderBy'] == 'fixedOrder' ||
  464. $obj['foundOrderBy']))
  465. {
  466. if(!$params['searchKeywords'] &&
  467. $searchCriteria==NULL ||
  468. count($obj['searchCriteria'])>0)
  469. $this->SearchObject($params,$obj);
  470. if($params['searchKeywords'])
  471. $this->SearchKeywords($params,$obj);
  472. }
  473. }
  474. $result = $this->GetSearchResult($params);
  475. if($params['tempTable'])
  476. $this->dbDriver->ExecSQL("DROP TABLE ".$params['tableName']);
  477. return $result;
  478. }
  479. catch(Exception $e)
  480. {
  481. if($params['tempTable'])
  482. $this->dbDriver->ExecSQL("DROP TABLE ".$params['tableName']);
  483. throw $e;
  484. }
  485. }
  486. //--Method: SetOrder
  487. function SetOrder($docId, $path, $offset)
  488. {
  489. $folderData = $this->GetFolderData($path, 'share');
  490. // checks out for write permission
  491. $data = $this->CheckNodePermission($folderData, true);
  492. $folderId = $folderData['folderId'];
  493. // locks selected document
  494. if($this->dbDriver->type=='oracle')
  495. {
  496. // for oracle, lock all folder files
  497. $SQL = 'SELECT fixedOrder FROM LIB_DocumentLink ';
  498. $SQL .= "WHERE folderId=$folderId FOR UPDATE";
  499. $this->dbDriver->ExecSQL($SQL);
  500. }
  501. $SQL = 'SELECT fixedOrder FROM LIB_DocumentLink ';
  502. $SQL .= "WHERE folderId=$folderId AND docId=$docId ";
  503. if($this->dbDriver->type!='oracle')
  504. $SQL .= "FOR UPDATE";
  505. $currPos = $this->dbDriver->GetOne($SQL);
  506. if($currPos == NULL)
  507. throw new AV_Exception(FAILED, $this->lang);
  508. // finds and locks next doc by position
  509. $SQL = 'SELECT docId, fixedOrder FROM LIB_DocumentLink ';
  510. $WHERE = "WHERE folderId=$folderId AND ";
  511. if($offset < 0)
  512. {
  513. $WHERE .= "fixedOrder<$currPos ";
  514. $WHERE .= "ORDER BY fixedOrder DESC ";
  515. }
  516. else
  517. {
  518. $WHERE .= "fixedOrder>$currPos ";
  519. $WHERE .= "ORDER BY fixedOrder ASC ";
  520. }
  521. $WHERE .= 'LIMIT '.abs($offset).' ';
  522. $SQL .= $WHERE;
  523. if($this->dbDriver->type!='oracle')
  524. $SQL .= "FOR UPDATE";
  525. $next = $this->dbDriver->GetAll($SQL);
  526. if(count($next) == 0)
  527. return;
  528. $SQL = "UPDATE LIB_DocumentLink SET ";
  529. if($offset < 0)
  530. $SQL .= "fixedOrder=fixedOrder+1 ";
  531. else
  532. $SQL .= "fixedOrder=fixedOrder-1 ";
  533. $SQL .= $WHERE;
  534. $this->dbDriver->ExecSQL($SQL);
  535. $SQL = "UPDATE LIB_DocumentLink SET fixedOrder='".end($next)['fixedOrder']."' WHERE ";
  536. $SQL .= "folderId=$folderId AND docId=$docId";
  537. $this->dbDriver->ExecSQL($SQL);
  538. $fields = $this->GetDocFields($docId, $path);
  539. $fields['path'] = $path;
  540. $this->NotifyAdmin('adminSetOrderLogTag',$fields);
  541. }
  542. function TakeDocOwnership($docId,$path)
  543. {
  544. $fields = $this->GetDocFields($docId, $path);
  545. if(count($fields)==NULL)
  546. throw new AV_Exception(NOT_FOUND,$this->lang);
  547. $login = $this->TakeOwnership($docId);
  548. $this->NotifyAdmin('adminTakeDocOwnershipLogTag',$fields);
  549. return $login;
  550. }
  551. function GetDocLinks($docId)
  552. {
  553. if($docId == NULL)
  554. throw new AV_Exception(INVALID_FIELD, $this->lang,
  555. array('fieldName','docId'));
  556. $SQL = 'SELECT f.folderId, path ';
  557. $SQL .= 'FROM LIB_DocumentLink l, LIB_Folder f ';
  558. $SQL .= "WHERE docId=$docId AND l.folderId=f.folderId ";
  559. return $this->dbDriver->GetAll($SQL);
  560. }
  561. function GetFileContent($fieldName,$docId,$size,$jpegQuality,
  562. $maxWidth=NULL,$maxHeight=NULL,$bgColor=NULL,
  563. $cropRatio=NULL)
  564. {
  565. $SQL = 'SELECT fld.tableName ';
  566. $SQL .= 'FROM LIB_DocumentLink dl,LIB_Folder f,LIB_FolderTables ft,';
  567. $SQL .= 'FORM_Field fld ';
  568. $SQL .= "WHERE docId='$docId' AND dl.folderId=f.folderId ";
  569. $SQL .= 'AND folderTables=id AND ft.tableName=fld.tableName ';
  570. $SQL .= "AND fieldName='$fieldName' LIMIT 1";
  571. $tableName = $this->dbDriver->GetOne($SQL);
  572. if($tableName == NULL)
  573. throw new AV_Exception(INVALID_FIELD, $this->lang,
  574. Array('fieldName'=>'fieldName',
  575. 'addMsg'=>' (fieldName)'));
  576. if($size != NULL || $maxHeight != NULL && $maxWidth != NULL ||
  577. $bgColor != NULL)
  578. $docData = & $this->GetThumb($tableName,$fieldName,$docId,$size,
  579. $jpegQuality,$maxWidth,$maxHeight,
  580. $bgColor,$cropRatio);
  581. else
  582. {
  583. $SQL = 'SELECT nodeId,userId,groupId,userRight,groupRight,otherRight,';
  584. $SQL .= 'UNIX_TIMESTAMP(creationDate) as creationDate,';
  585. $SQL .= 'UNIX_TIMESTAMP(lastChanged) as lastChanged,';
  586. $SQL .= "lastChangedUserId,${fieldName},${fieldName}FileName,";
  587. $SQL .= "${fieldName}Type ";
  588. $SQL .= "FROM LIB_Node node,$tableName doc ";
  589. $SQL .= "WHERE nodeId=$docId AND nodeId=docId ";
  590. $docData = & $this->dbDriver->GetRow($SQL);
  591. if(count($docData) == 0)
  592. throw new AV_Exception(NOT_FOUND, $this->lang);
  593. if($this->module->pageBuilder->siteConfig->getVar('admin','blobToFS'))
  594. {
  595. $libPath = $this->module->pageBuilder->siteConfig->getVar("dirs",
  596. "library");
  597. $docData[$fieldName] = ft_file_get_contents($libPath . $docData[$fieldName]);
  598. if($docData[$fieldName] === false)
  599. throw new AV_Exception(FAILED, $this->lang,
  600. array('addMsg'=>' (unable to read file)',
  601. 'filePath'=>$libPath . $docData[$fieldName]));
  602. }
  603. }
  604. // checks out for read permission
  605. $this->CheckNodePermission($docData, false);
  606. return $docData;
  607. }
  608. function CheckDocPermission($docId,$write)
  609. {
  610. $docData = $this->GetDocData($docId, 'share');
  611. $this->CheckNodePermission($docData, $write);
  612. }
  613. function DelBlobFS()
  614. {
  615. $libPath = $this->module->pageBuilder->siteConfig->getVar("dirs",
  616. "library");
  617. $SQL = "SELECT id FROM LIB_BlobFS WHERE deleted='1' FOR UPDATE ";
  618. $unlinkList = $this->dbDriver->GetCol($SQL);
  619. foreach($unlinkList as $id)
  620. ft_unlink($libPath . $id);
  621. $SQL = "DELETE FROM LIB_BlobFS WHERE deleted='1' ";
  622. $this->dbDriver->ExecSQL($SQL);
  623. }
  624. protected function InsHistory($values,$oldValues=NULL)
  625. {
  626. if(!$this->module->pageBuilder->siteConfig->getVar('admin','history'))
  627. return;
  628. $userMan = new UM_User($this->module);
  629. $memberData = $userMan->GetMemberData('share', false, false);
  630. foreach($this->docTable as $tableName=>& $table)
  631. {
  632. $fieldsDef = $table->LoadFieldsDef();
  633. foreach($fieldsDef as & $field)
  634. {
  635. $value = NULL;
  636. switch($field['type'])
  637. {
  638. case 'text': case 'integer': case "date": case "datetime": case "cpf":
  639. case "cnpj": case "cep": case 'float': case 'currency': case 'percent':
  640. case "select": case "radio": case "selectMult": case 'legalEntityRef':
  641. case 'naturalPersonRef': case 'leOrNpEntityRef': case 'folder':
  642. case 'formula': case 'boolean': case "selectMultiple":
  643. if(strpos($field['accessMode'],'w') !== false &&
  644. $values[$field['fieldName']]!== NULL &&
  645. ($oldValues==NULL ||
  646. $values[$field['fieldName']]!=$oldValues[$field['fieldName']]))
  647. $value = "'".addslashes(json_encode($values[$field['fieldName']]))."'";
  648. break;
  649. case 'objectList':
  650. if($values[$field['fieldName']]!== NULL && $oldValues != NULL && count($oldValues[$field['fieldName']])>0)
  651. {
  652. if(count($oldValues[$field['fieldName']])>50)
  653. $oldValues[$field['fieldName']] = array_slice($oldValues[$field['fieldName']],0,50);
  654. $value = "'".addslashes(json_encode($oldValues[$field['fieldName']]))."'";
  655. }
  656. break;
  657. case 'fileList':
  658. if($values[$field['fieldName']]!== NULL && $oldValues != NULL)
  659. {
  660. $diff = false;
  661. if(count($values[$field['fieldName']])!=
  662. count($oldValues[$field['fieldName']]))
  663. $diff = true;
  664. else
  665. {
  666. foreach($values[$field['fieldName']] as $key=>$val)
  667. {
  668. if($val['docId']!=$oldValues[$field['fieldName']][$key])
  669. {
  670. $diff = true;
  671. break;
  672. }
  673. }
  674. }
  675. }
  676. if($diff)
  677. $value = 'NULL';
  678. break;
  679. case 'schedule': case 'file': case 'textArea': case "langLabel":
  680. case "langTextArea": case "langHtmlArea": case 'htmlArea':
  681. case 'usageTerms':
  682. default:
  683. break;
  684. }
  685. if($value!=NULL)
  686. {
  687. $SQL = 'INSERT INTO LIB_DocHistory ';
  688. $SQL .= '(docId,userId,histDate,tableName,fieldName,value) VALUES ';
  689. $SQL .= "('".$values['docId']."','".$memberData['userId']."',NOW(),";
  690. $SQL .= "'$tableName','".$field['fieldName']."',".$value.")";
  691. $this->dbDriver->ExecSQL($SQL);
  692. }
  693. }
  694. }
  695. }
  696. protected function GetFolderTables($path)
  697. {
  698. $path = $this->PreparePath($path);
  699. // loads path rights
  700. $SQL = 'SELECT ft.id, ft.tableName, ftp.dataModule ';
  701. $SQL .= 'FROM LIB_Folder f, LIB_FolderTables ft, LIB_FolderType ftp WHERE ';
  702. $SQL .= "path = '$path' AND ";
  703. $SQL .= 'folderTables = ft.id AND ';
  704. $SQL .= 'ft.id=ftp.id ';
  705. $SQL .= 'ORDER BY printOrder LIMIT 12 LOCK IN SHARE MODE ';
  706. $folderTables = $this->dbDriver->GetAll($SQL);
  707. if(count($folderTables) == 0)
  708. throw new AV_Exception(INVALID_PATH, $this->lang,
  709. array('addMsg'=>" ($path)"));
  710. array_splice($folderTables,0,2);
  711. return $folderTables;
  712. }
  713. //--Method: GetSearchResult
  714. //--Desc: Returns results from SearchKeywords and SearchAll methods
  715. //--Desc: checking permissions.
  716. protected function GetSearchResult(& $params)
  717. {
  718. if(!$params['tempTable'])
  719. $params['query'] = '(('.implode(') UNION (',$params['query']).'))';
  720. if($params['totalResults'])
  721. {
  722. if($params['tempTable'])
  723. {
  724. $SQL = 'SELECT COUNT(DISTINCT docId) FROM '. $params['tableName'];
  725. $params['totalResults'] = $this->dbDriver->GetOne($SQL);
  726. }
  727. else
  728. {
  729. $SQL = 'SELECT COUNT(DISTINCT docId) FROM '.$params['query']. ' res';
  730. $params['totalResults'] = $this->dbDriver->GetOne($SQL);
  731. }
  732. }
  733. $SQL = 'SELECT res.docId,path,folderTables,fixedOrder,';
  734. $SQL .= implode(',', $params['returnFieldsFound']);
  735. if($this->dbDriver->type=='oracle')
  736. // ORACLE
  737. $SQL .= ', maxMatches, sumMatches';
  738. else
  739. {
  740. // MYSQL
  741. $SQL .= ', MAX(matches) as maxMatches';
  742. $SQL .= ', SUM(matches) as sumMatches';
  743. }
  744. $SQL .= ' FROM ';
  745. if($this->dbDriver->type=='oracle')
  746. {
  747. // ORACLE
  748. $SQL .= '(SELECT r.*,';
  749. $SQL .= 'ROW_NUMBER() OVER (PARTITION BY docId ORDER BY docId) as rank ';
  750. $SQL .= 'FROM ';
  751. if($params['tempTable'])
  752. $SQL .= $params['tableName'];
  753. else
  754. $SQL .= $params['query'];
  755. $SQL .= ' r) res,';
  756. $SQL .= '(SELECT docId,MAX(matches) as maxMatches,';
  757. $SQL .= 'SUM(matches) as sumMatches ';
  758. $SQL .= 'FROM ';
  759. if($params['tempTable'])
  760. $SQL .= $params['tableName'];
  761. else
  762. $SQL .= $params['query'];
  763. $SQL .= ' GROUP BY docId ';
  764. $SQL .= ') groupRes ';
  765. $SQL .= 'WHERE res.docId=groupRes.docId AND res.rank=1';
  766. }
  767. else
  768. {
  769. // MYSQL
  770. if($params['tempTable'])
  771. $SQL .= $params['tableName'];
  772. else
  773. $SQL .= $params['query'];
  774. $SQL .= ' res ';
  775. $SQL .= 'GROUP BY docId';
  776. }
  777. $SQL .= " ORDER BY ";
  778. if($params['orderBy'] == 'matches')
  779. {
  780. $SQL .= ' maxMatches ' . ($params['order'] ? 'DESC' : 'ASC');
  781. $SQL .= ', sumMatches ' . ($params['order'] ? 'DESC' : 'ASC');
  782. }
  783. else
  784. {
  785. $SQL .= ' '.$params['orderBy'];
  786. $SQL .= ($params['order'] ? ' ASC' : ' DESC');
  787. }
  788. $SQL .= ', res.docId ';
  789. if($params['limit'] != NULL)
  790. {
  791. $SQL .= ' LIMIT ';
  792. if(isset($params['offset']))
  793. $SQL .= $params['offset'] . ',';
  794. $SQL .= $params['limit'];
  795. }
  796. $results = $this->dbDriver->GetAll($SQL);
  797. // for oracle table, clob fields must be loaded before dropping temporary table
  798. if($this->dbDriver->type=='oracle')
  799. {
  800. foreach($results as & $row)
  801. {
  802. foreach($params['clobFields'] as $clobField)
  803. $x = $row[$clobField];
  804. }
  805. }
  806. // format date fields and retrieves object list fields
  807. if(count($params['dateFields'])>0 ||
  808. count($params['floatFields'])>0 ||
  809. count($params['objectListFields'])>0 ||
  810. count($params['fileListFields'])>0 ||
  811. count($params['selectMultFields'])>0)
  812. {
  813. $locale = localeconv();
  814. foreach($results as & $res)
  815. {
  816. if($params['dateFormat']!=NULL)
  817. {
  818. foreach($params['dateFields'] as $dateField)
  819. {
  820. $res[$dateField.'_timestamp'] = strtotime($res[$dateField]);
  821. if($res[$dateField]!=NULL)
  822. $res[$dateField]=strftime($params['dateFormat'],
  823. (int)$res[$dateField.'_timestamp']);
  824. }
  825. }
  826. if($params['numberFormat'])
  827. {
  828. foreach($params['floatFields'] as &$floatField)
  829. {
  830. $res[$floatField.'Value']=$res[$floatField];
  831. $res[$floatField]=number_format($res[$floatField],
  832. $locale['frac_digits'],
  833. $locale['mon_decimal_point'],
  834. $locale['mon_thousands_sep']);
  835. }
  836. }
  837. foreach($params['objectListFields'] as &$objectListField)
  838. {
  839. $SQL = 'SELECT path, parentIdField FROM FORM_ObjectListField ol, LIB_Folder f ';
  840. $SQL .= "WHERE tableName='".$objectListField['tableName']."' ";
  841. $SQL .= "AND fieldName='".$objectListField['fieldName']."' ";
  842. $SQL .= 'AND ol.folderId=f.folderId ';
  843. $objectList = $this->dbDriver->GetRow($SQL);
  844. if(count($objectList)==0)
  845. throw new AV_Exception(FAILED, $this->lang);
  846. $subsearch = array();
  847. $subsearch['path'] = $objectList['path'];
  848. $exlusionFilter['fieldName'] = $objectList['parentIdField'];
  849. $exlusionFilter['value'] = $res['docId'];
  850. $exlusionFilter['operator'] = '=';
  851. $subsearch['exclusionFilters'][$objectList['parentIdField']][]= $exlusionFilter;
  852. $subsearch['orderBy'] = 'matches';
  853. $subsearch['dateFormat'] = $params['dateFormat'];
  854. $subsearch['tempTable'] = $params['tempTable'];
  855. $res[$objectListField['fieldName']] = $this->Search($subsearch);
  856. }
  857. foreach($params['fileListFields'] as &$fileListField)
  858. {
  859. $SQL = 'SELECT fd.docId,fd.contentFileName,fd.contentSize,';
  860. $SQL .= 'l_title.value as title,fd.authors,l_descr.value as descr,';
  861. $SQL .= 'fd.contentType ';
  862. $SQL .= 'FROM LIB_ContentFile ci, LIB_FileDocument fd, ';
  863. $SQL .= 'LANG_Label l_title, LANG_Text l_descr ';
  864. $SQL .= "WHERE ci.tableName='".$fileListField['tableName']."' ";
  865. $SQL .= "AND ci.fieldName='".$fileListField['fieldName']."' ";
  866. $SQL .= "AND ci.nodeId='".$res['docId']."' ";
  867. $SQL .= 'AND ci.fileId=fd.docId ';
  868. $SQL .= 'AND fd.title = l_title.labelId ';
  869. $SQL .= 'AND fd.descr = l_descr.labelId ';
  870. $SQL .= "AND l_title.lang='".$this->lang."' ";
  871. $SQL .= 'AND l_title.lang=l_descr.lang ';
  872. $res[$fileListField['fieldName']] = $this->dbDriver->GetAll($SQL);
  873. }
  874. foreach($params['selectMultFields'] as &$selectMultField)
  875. {
  876. $selectFieldInfo = $selectMultField['selectFieldInfo'];
  877. $SQL = 'SELECT ';
  878. $SQL .= 'o.'.$selectFieldInfo['optionTableKey'].',';
  879. $SQL .= 'o.'.$selectFieldInfo['optionTableValue'].' ';
  880. $SQL .= 'FROM ';
  881. $SQL .= $selectFieldInfo['optionTable'] . ' o,';
  882. $SQL .= $selectFieldInfo['selectedTable'] . ' s ';
  883. $SQL .= 'WHERE ';
  884. $SQL .= 'o.'.$selectFieldInfo['optionTableKey'].'=';
  885. $SQL .= 's.'.$selectFieldInfo['optionTableKey'].' ';
  886. $SQL .= "AND s.docId='".$res['docId']."' ";
  887. $res[$selectMultField['fieldName']] = $this->dbDriver->GetAll($SQL);
  888. }
  889. }
  890. }
  891. return $results;
  892. }
  893. //--Method: GetDocData
  894. //--Desc: Returns document attributes
  895. private function GetDocData($docId, $lockMode, & $status)
  896. {
  897. // loads path rights
  898. $SQL = 'SELECT * ';
  899. $SQL .= 'FROM LIB_Node node, LIB_Document doc ';
  900. $SQL .= 'WHERE ';
  901. $SQL .= "nodeId = $docId AND ";
  902. $SQL .= 'nodeId = docId ';
  903. switch($lockMode)
  904. {
  905. case 'share':
  906. $SQL .= ' LOCK IN SHARE MODE';
  907. break;
  908. case 'update':
  909. $SQL .= ' FOR UPDATE';
  910. break;
  911. }
  912. $doc = $this->dbDriver->GetRow($SQL);
  913. if(count($doc) == 0)
  914. throw new AV_Exception(NOT_FOUND, $this->lang);
  915. return $doc;
  916. }
  917. private function LoadReturnFields(& $params)
  918. {
  919. $SQL = 'SELECT DISTINCT fieldName FROM LIB_Folder, LIB_DocReturnFields ';
  920. $SQL .= 'WHERE (';
  921. foreach($params['path'] as $key=>&$path)
  922. {
  923. if($key>0)
  924. $SQL .= ' OR ';
  925. if($params['recursiveSearch'])
  926. $SQL .= "path LIKE '".$path."%' ";
  927. else
  928. $SQL .= "path = '".$path."' ";
  929. }
  930. $SQL .= ') AND folderTables=id ';
  931. $params['returnFields'] = $this->dbDriver->GetCol($SQL);
  932. }
  933. private function GetReturnFields($path)
  934. {
  935. $SQL = 'SELECT rf.tableName,rf.fieldName ';
  936. $SQL .= 'FROM LIB_Folder f, LIB_DocReturnFields rf, FORM_Field field ';
  937. $SQL .= "WHERE f.path = '$path' AND f.folderTables=rf.id ";
  938. $SQL .= 'AND rf.tableName=field.tableName AND rf.fieldName=field.fieldName ';
  939. $SQL .= "AND field.type NOT IN ('objectList','fileList','selectMultiple') ";
  940. $SQL .= 'ORDER BY printOrder ';
  941. return $this->dbDriver->GetAll($SQL);
  942. }
  943. private function GetDocFields($docId,$path)
  944. {
  945. $returnFields = $this->GetReturnFields($path);
  946. $SELECT = NULL;
  947. $FROM = NULL;
  948. $WHERE = NULL;
  949. foreach($returnFields as $key=>$field)
  950. {
  951. if($SELECT == NULL)
  952. $SELECT = "SELECT ";
  953. else
  954. $SELECT .= ',';
  955. $SELECT .= "t$key.".$field['fieldName'];
  956. if($FROM == NULL)
  957. $FROM = ' FROM ';
  958. else
  959. $FROM .= ',';
  960. $FROM .= $field['tableName']." t$key";
  961. if($WHERE == NULL)
  962. $WHERE = ' WHERE ';
  963. else
  964. $WHERE .= ' AND ';
  965. if($field['tableName']=='LIB_Node')
  966. $WHERE .= "t$key.nodeId='$docId'";
  967. else
  968. $WHERE .= "t$key.docId='$docId'";
  969. }
  970. $SQL = "$SELECT $FROM $WHERE";
  971. return $this->dbDriver->GetRow($SQL);
  972. }
  973. protected function LoadSearchDefs(& $params)
  974. {
  975. // each folder represents a search object, which has multiple tables
  976. // searches search object and the tables associated to each one
  977. // (folderTables)
  978. $SQL = 'SELECT DISTINCT (ft.id), ft.tableName, ft.printOrder ';
  979. $SQL .= 'FROM LIB_Folder f, LIB_FolderTables ft WHERE (';
  980. foreach($params['path'] as $key=>&$path)
  981. {
  982. if($key>0)
  983. $SQL .= ' OR ';
  984. if($params['recursiveSearch'])
  985. $SQL .= "path LIKE '".$path."%' ";
  986. else
  987. $SQL .= "path = '".$path."' ";
  988. }
  989. $SQL .= ') AND f.folderTables=ft.id ';
  990. $SQL .= 'ORDER BY ft.id, ft.printOrder ';
  991. $folderTables = $this->dbDriver->GetAll($SQL);
  992. if(count($folderTables)==0)
  993. throw new AV_Exception(INVALID_PATH, $this->lang);
  994. // creates temporary table for storing results
  995. if($params['tempTable'])
  996. {
  997. $params['tableName'] = uniqid('LIB_SearchResult_',false);
  998. $SQL = 'CREATE TEMPORARY TABLE ' . $params['tableName'];
  999. $SQL .= '(docId INTEGER UNSIGNED NOT NULL';
  1000. $SQL .= ',folderId INTEGER UNSIGNED NOT NULL';
  1001. $SQL .= ',folderTables INTEGER UNSIGNED NOT NULL';
  1002. $SQL .= ',path VARCHAR(255) NOT NULL';
  1003. $SQL .= ',matches INTEGER UNSIGNED NOT NULL';
  1004. $SQL .= ',fixedOrder INTEGER UNSIGNED NOT NULL';
  1005. }
  1006. $params['foundOrderBy'] = false;
  1007. $params['searchTables'] = array();
  1008. $params['searchFields'] = array();
  1009. // loads LIB_Node fields
  1010. $fieldsDef = $this->nodeTable->LoadFieldsDef();
  1011. $params['searchTables']['LIB_Node'] = array();
  1012. $params['searchTables']['LIB_Node']['tableRef'] = 'docNode';
  1013. foreach($fieldsDef as $def)
  1014. $this->GetSearchField('LIB_Node',$this->nodeTable,$def,$params);
  1015. // load LIB_Document fields
  1016. $fieldsDef = $this->docMainTable->LoadFieldsDef();
  1017. $params['searchTables']['LIB_Document'] = array();
  1018. $params['searchTables']['LIB_Document']['tableRef'] = 'doc';
  1019. foreach($fieldsDef as $def)
  1020. $this->GetSearchField('LIB_Document',$this->docMainTable,$def,$params);
  1021. $searchCriteria = $params['searchCriteria'];
  1022. $exclusionFilters = $params['exclusionFilters'];
  1023. $returnFields = $params['returnFields'];
  1024. $searchCriteriaCtrl = $searchCriteria;
  1025. $exclusionFiltersCtrl = $exclusionFilters;
  1026. $returnFieldsCtrl = $returnFields;
  1027. // load folderTables fields
  1028. $tableNum = 0;
  1029. $id = NULL;
  1030. foreach($folderTables as $folder)
  1031. {
  1032. $tableName = $folder['tableName'];
  1033. if($id != NULL && $id != $folder['id'])
  1034. {
  1035. if($params['searchCriteria'] != '*')
  1036. $searchCriteriaCtrl = array_intersect($searchCriteriaCtrl,
  1037. $params['searchCriteria']);
  1038. $exclusionFiltersCtrl = array_intersect_assoc($exclusionFiltersCtrl,
  1039. $params['exclusionFilters']);
  1040. $returnFieldsCtrl = array_intersect($returnFieldsCtrl,
  1041. $params['returnFields']);
  1042. $params['searchCriteria'] = $searchCriteria;
  1043. $params['exclusionFilters'] = $exclusionFilters;
  1044. $params['returnFields'] = $returnFields;
  1045. }
  1046. $id = $folder['id'];
  1047. // load table fields if not done yet
  1048. if(!isset($params['searchTables'][$tableName]))
  1049. {
  1050. $tableObj = new FORM_DynTable($tableName, $this->module);
  1051. $fieldsDef = $tableObj->LoadFieldsDef();
  1052. $params['searchTables'][$tableName] = array();
  1053. $params['searchTables'][$tableName]['tableRef'] = 't'.$tableNum++;
  1054. foreach($fieldsDef as $def)
  1055. $this->GetSearchField($tableName,$tableObj,$def,$params);
  1056. }
  1057. $params['searchObjs'][$id]['returnFields'] =
  1058. array_merge((array)$params['searchObjs'][$id]['returnFields'],
  1059. (array)$params['searchTables'][$tableName]['returnFields']);
  1060. $params['searchObjs'][$id]['returnFieldsRefs'] =
  1061. array_merge((array)$params['searchObjs'][$id]['returnFieldsRefs'],
  1062. (array)$params['searchTables'][$tableName]['returnFieldsRefs']);
  1063. $params['searchObjs'][$id]['exclusionFilters'] =
  1064. array_merge((array)$params['searchObjs'][$id]['exclusionFilters'],
  1065. (array)$params['searchTables'][$tableName]['exclusionFilters']);
  1066. $params['searchObjs'][$id]['searchCriteria'] =
  1067. array_merge((array)$params['searchObjs'][$id]['searchCriteria'],
  1068. (array)$params['searchTables'][$tableName]['searchCriteria']);
  1069. $tableRef = $tableName . ' ';
  1070. $tableRef .= $params['searchTables'][$tableName]['tableRef'];
  1071. $params['searchObjs'][$id]['tables'][] = $tableRef;
  1072. $params['searchObjs'][$id]['tables'] =
  1073. array_merge($params['searchObjs'][$id]['tables'],
  1074. (array)$params['searchTables'][$tableName]['tables']);
  1075. $tablesWhere = 'docLink.docId=';
  1076. $tablesWhere .= $params['searchTables'][$tableName]['keyField'];
  1077. $params['searchObjs'][$id]['tablesWhere'][] = $tablesWhere;
  1078. $params['searchObjs'][$id]['tablesWhere'] =
  1079. array_merge($params['searchObjs'][$id]['tablesWhere'],
  1080. (array)$params['searchTables'][$tableName]['tablesWhere']);
  1081. if($params['searchTables'][$tableName]['foundOrderBy'])
  1082. {
  1083. $params['searchObjs'][$id]['foundOrderBy'] = true;
  1084. $params['searchObjs'][$id]['orderByRef'] = $params['orderByRef'];
  1085. }
  1086. }
  1087. if($params['searchCriteria'] != '*')
  1088. $searchCriteriaCtrl = array_intersect($searchCriteriaCtrl,
  1089. $params['searchCriteria']);
  1090. $exclusionFiltersCtrl = array_intersect_assoc($exclusionFiltersCtrl,
  1091. $params['exclusionFilters']);
  1092. $returnFieldsCtrl = array_intersect($returnFieldsCtrl,
  1093. $params['returnFields']);
  1094. if($params['tempTable'])
  1095. {
  1096. if(count($params['searchFields']>0))
  1097. $SQL .= ','.implode(',',$params['searchFields']);
  1098. $SQL .= ')';
  1099. }
  1100. // consist order by
  1101. if(!$params['foundOrderBy'])
  1102. {
  1103. switch($params['orderBy'])
  1104. {
  1105. case 'matches':
  1106. break;
  1107. case 'fixedOrder':
  1108. $params['orderByRef'] = 'docLink.fixedOrder';
  1109. break;
  1110. default:
  1111. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1112. array('fieldName'=>'orderBy',
  1113. 'orderBy'=>$params['orderBy']));
  1114. }
  1115. }
  1116. if(count($returnFieldsCtrl) > 0)
  1117. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1118. array('fieldName'=>'returnFields',
  1119. 'returnFields'=>$returnFieldsCtrl,
  1120. 'returnFieldsFound'=>$params['returnFieldsFound']));
  1121. if($params['searchCriteria'] != '*' &&
  1122. count($searchCriteriaCtrl) > 0)
  1123. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1124. array('fieldName'=>'searchCriteria',
  1125. 'value'=>$params['searchCriteria']));
  1126. if(count($exclusionFiltersCtrl) > 0)
  1127. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1128. array('fieldName'=>'exclusionFilters',
  1129. 'value'=>$params['exclusionFilters']));
  1130. if($params['tempTable'])
  1131. $this->dbDriver->ExecSQL($SQL);
  1132. }
  1133. private function GetSearchField($tableName,$tableObj,$def,&$params)
  1134. {
  1135. $tableRef = $params['searchTables'][$tableName]['tableRef'];
  1136. $fieldRef = $tableRef . '.' . $def['fieldName'];
  1137. if($def['keyField'] == '1')
  1138. $params['searchTables'][$tableName]['keyField'] = $fieldRef;
  1139. if(//strpos($def['accessMode'],'r') === false ||
  1140. ($def['type'] != 'dummy' &&
  1141. $def['type'] != 'hidden' &&
  1142. $def['type'] != 'text' &&
  1143. $def['type'] != 'textArea' &&
  1144. $def['type'] != 'htmlArea' &&
  1145. $def['type'] != 'langLabel' &&
  1146. $def['type'] != 'langTextArea' &&
  1147. $def['type'] != 'langHtmlArea' &&
  1148. $def['type'] != 'select' &&
  1149. $def['type'] != 'selectMult' &&
  1150. $def['type'] != 'selectMultiple' &&
  1151. $def['type'] != 'radio' &&
  1152. $def['type'] != 'readOnlySelect' &&
  1153. $def['type'] != 'date' &&
  1154. $def['type'] != 'datetime' &&
  1155. $def['type'] != 'boolean' &&
  1156. $def['type'] != 'accessRight' &&
  1157. $def['type'] != 'integer' &&
  1158. $def['type'] != 'float' &&
  1159. $def['type'] != 'currency' &&
  1160. $def['type'] != 'percent' &&
  1161. $def['type'] != 'fileList' &&
  1162. $def['type'] != 'cnpj' &&
  1163. $def['type'] != 'cpf' &&
  1164. $def['type'] != 'cep' &&
  1165. $def['type'] != 'objectList' ))
  1166. return;
  1167. if($params['orderBy'] == $def['fieldName'])
  1168. {
  1169. $params['orderByRef'] = $tableRef . '.' .$def['fieldName'];
  1170. $params['foundOrderBy'] = true;
  1171. $params['searchTables'][$tableName]['foundOrderBy'] = true;
  1172. }
  1173. $optFieldRef = NULL;
  1174. // sets searchCriteria
  1175. $key = array_search($def['fieldName'],$params['searchCriteria']);
  1176. if($key !== false && $key !== NULL || $params['searchCriteria']=='*')
  1177. {
  1178. switch($def['type'])
  1179. {
  1180. default:
  1181. $params['searchTables'][$tableName]['searchCriteria'][] = $fieldRef;
  1182. break;
  1183. case 'select':
  1184. case 'readOnlySelect':
  1185. case 'radio':
  1186. $this->GetSelectField($tableName, $tableObj, $def, $tableRef,
  1187. $fieldRef, $params, $optFieldRef);
  1188. $params['searchTables'][$tableName]['searchCriteria'][] = $optFieldRef;
  1189. break;
  1190. case 'langLabel':
  1191. case 'langTextArea':
  1192. case 'langHtmlArea':
  1193. $this->GetLangField($tableName, $def, $fieldRef, $params,$optFieldRef,
  1194. $def['type']!='langLabel');
  1195. $params['searchTables'][$tableName]['searchCriteria'][] = $optFieldRef;
  1196. break;
  1197. case 'fileList':
  1198. case 'objectList':
  1199. break;
  1200. }
  1201. if($params['searchCriteria']!='*')
  1202. unset($params['searchCriteria'][$key]);
  1203. }
  1204. // sets exclusionFilters
  1205. if(isset($params['exclusionFilters'][$def['fieldName']]))
  1206. {
  1207. switch($def['type'])
  1208. {
  1209. default:
  1210. $params['searchTables'][$tableName]['exclusionFilters'][$fieldRef]=
  1211. $params['exclusionFilters'][$def['fieldName']];
  1212. break;
  1213. case 'langLabel':
  1214. if($optFieldRef == NULL)
  1215. $this->GetLangField($tableName,$def,$fieldRef,$params,$optFieldRef,
  1216. $def['type']!='langLabel');
  1217. $params['searchTables'][$tableName]['exclusionFilters'][$optFieldRef]=
  1218. $params['exclusionFilters'][$def['fieldName']];
  1219. break;
  1220. }
  1221. unset($params['exclusionFilters'][$def['fieldName']]);
  1222. }
  1223. // sets returnFields
  1224. // result table needs only fields on returnFields or orderBy
  1225. $key = array_search($def['fieldName'],$params['returnFields']);
  1226. if($key !== false && $key !== NULL ||
  1227. $params['orderBy'] == $def['fieldName'])
  1228. {
  1229. switch($def['type'])
  1230. {
  1231. case 'integer':
  1232. case 'text':
  1233. case 'hidden':
  1234. case 'dummy':
  1235. if(!isset($params['searchFields'][$def['fieldName']]))
  1236. if($def['consistType']=='integer')
  1237. $params['searchFields'][$def['fieldName']] =
  1238. $def['fieldName'].' INTEGER UNSIGNED';
  1239. else
  1240. $params['searchFields'][$def['fieldName']] =
  1241. $def['fieldName'].' VARCHAR('.$def['size'].')';
  1242. $params['searchTables'][$tableName]['returnFields'][] =
  1243. $def['fieldName'];
  1244. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1245. break;
  1246. case 'htmlArea': case 'textArea':
  1247. if(!isset($params['searchFields'][$def['fieldName']]))
  1248. $params['searchFields'][$def['fieldName']] =
  1249. $def['fieldName'].' TEXT';
  1250. if($this->dbDriver->type=='oracle')
  1251. $params['clobFields'][] = $def['fieldName'];
  1252. $params['searchTables'][$tableName]['returnFields'][] = $def['fieldName'];
  1253. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1254. break;
  1255. case 'select':
  1256. case 'readOnlySelect':
  1257. case 'radio':
  1258. if(!isset($params['searchFields'][$def['fieldName']]))
  1259. $params['searchFields'][$def['fieldName']] =
  1260. $def['fieldName'].' '.$this->GetDBFieldType($tableName,$def['fieldName']);
  1261. if(!isset($params['searchFields'][$def['fieldName'].'Text']))
  1262. $params['searchFields'][$def['fieldName'].'Text'] =
  1263. $def['fieldName'].'Text VARCHAR(255)';
  1264. $params['searchTables'][$tableName]['returnFields'][] =
  1265. $def['fieldName'];
  1266. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1267. if($optFieldRef == NULL)
  1268. $this->GetSelectField($tableName, $tableObj, $def, $tableRef,
  1269. $fieldRef, $params, $optFieldRef);
  1270. $returnField = $optFieldRef . ' as ' . $def['fieldName'].'Text';
  1271. $params['searchTables'][$tableName]['returnFields'][] =
  1272. $def['fieldName'].'Text';
  1273. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName'].'Text'] =
  1274. $returnField;
  1275. break;
  1276. case 'selectMult':
  1277. case 'selectMultiple':
  1278. break;
  1279. case 'date':
  1280. if(!isset($params['searchFields'][$def['fieldName']]))
  1281. $params['searchFields'][$def['fieldName']] =
  1282. $def['fieldName']." DATE";
  1283. $params['searchTables'][$tableName]['returnFields'][] =
  1284. $def['fieldName'];
  1285. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1286. break;
  1287. case 'datetime':
  1288. if(!isset($params['searchFields'][$def['fieldName']]))
  1289. $params['searchFields'][$def['fieldName']] =
  1290. $def['fieldName']." DATETIME";
  1291. $params['searchTables'][$tableName]['returnFields'][] =
  1292. $def['fieldName'];
  1293. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1294. break;
  1295. case 'langLabel':
  1296. case 'langTextArea':
  1297. case 'langHtmlArea':
  1298. if(!isset($params['searchFields'][$def['fieldName']]))
  1299. if($def['type'] == 'langLabel')
  1300. $params['searchFields'][$def['fieldName']] =
  1301. $def['fieldName'].' VARCHAR(255)';
  1302. else
  1303. $params['searchFields'][$def['fieldName']] =
  1304. $def['fieldName'].' TEXT';
  1305. if($optFieldRef == NULL)
  1306. $this->GetLangField($tableName, $def, $fieldRef, $params,
  1307. $optFieldRef, $def['type']!='langLabel');
  1308. $returnField = $optFieldRef .' as ' . $def['fieldName'];
  1309. $params['searchTables'][$tableName]['returnFields'][] =
  1310. $def['fieldName'];
  1311. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] =
  1312. $returnField;
  1313. break;
  1314. case 'boolean':
  1315. if(!isset($params['searchFields'][$def['fieldName']]))
  1316. $params['searchFields'][$def['fieldName']] =
  1317. $def['fieldName'].' CHAR(1)';
  1318. $params['searchTables'][$tableName]['returnFields'][] =
  1319. $def['fieldName'];
  1320. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1321. break;
  1322. case 'accessRight':
  1323. if(!isset($params['searchFields'][$def['fieldName']]))
  1324. $params['searchFields'][$def['fieldName']] =
  1325. $def['fieldName'].' CHAR(2)';
  1326. $params['searchTables'][$tableName]['returnFields'][] =
  1327. $def['fieldName'];
  1328. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1329. break;
  1330. case 'currency':
  1331. case 'float':
  1332. case 'percent':
  1333. if(!isset($params['searchFields'][$def['fieldName']]))
  1334. $params['searchFields'][$def['fieldName']] =
  1335. $def['fieldName'].' DOUBLE';
  1336. $params['searchTables'][$tableName]['returnFields'][] =
  1337. $def['fieldName'];
  1338. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1339. break;
  1340. case 'fileList':
  1341. if($params['detailedFileList'])
  1342. break;
  1343. if(!isset($params['searchFields'][$def['fieldName']]))
  1344. $params['searchFields'][$def['fieldName']] =
  1345. $def['fieldName'].' VARCHAR(255)';
  1346. $params['searchTables'][$tableName]['returnFields'][] =
  1347. $def['fieldName'];
  1348. $fieldRef = "(SELECT GROUP_CONCAT(fileId ORDER BY idx) ";
  1349. $fieldRef .= 'FROM LIB_ContentFile ci ';
  1350. $fieldRef .= "WHERE tableName='$tableName' ";
  1351. $fieldRef .= "AND fieldName='".$def['fieldName']."' ";
  1352. $fieldRef .= 'AND ci.nodeId=doc.docId GROUP BY tableName, fieldName, nodeId) as ';
  1353. $fieldRef .= $def['fieldName'];
  1354. $params['searchTables'][$tableName]['returnFieldsRefs'][$def['fieldName']] = $fieldRef;
  1355. break;
  1356. case 'objectList':
  1357. break;
  1358. default:
  1359. $field = ($params['orderBy'] == $def['fieldName'])?
  1360. 'orderBy':'returnFields';
  1361. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1362. array('fieldName'=>$field,
  1363. 'addMsg'=>" ($field)",
  1364. 'field'=>$def));
  1365. }
  1366. if(($key !== false && $key !== NULL ||
  1367. $params['orderBy'] == $def['fieldName']) &&
  1368. !in_array($def['fieldName'],$params['dateFields']) &&
  1369. !in_array($def['fieldName'],$params['returnFieldsFound']))
  1370. {
  1371. if($def['type'] == 'date' || $def['type'] == 'datetime')
  1372. {
  1373. $params['returnFieldsFound'][$def['fieldName']] = $def['fieldName'];
  1374. $params['dateFields'][] = $def['fieldName'];
  1375. $params['resultGroupByFields'][] = $def['fieldName'];
  1376. }
  1377. elseif($def['type'] == 'objectList')
  1378. {
  1379. $objectListField = array();
  1380. $objectListField['fieldName'] = $def['fieldName'];
  1381. $objectListField['tableName'] = $tableName;
  1382. $params['objectListFields'][] = $objectListField;
  1383. }
  1384. elseif($def['type']=='fileList' && $params['detailedFileList'])
  1385. {
  1386. $fileListFields = array();
  1387. $fileListFields['fieldName'] = $def['fieldName'];
  1388. $fileListFields['tableName'] = $tableName;
  1389. $params['fileListFields'][] = $fileListFields;
  1390. }
  1391. elseif($def['type']=='selectMult' || $def['type']=='selectMultiple')
  1392. {
  1393. $selectMultField = array();
  1394. $selectMultField['fieldName'] = $def['fieldName'];
  1395. $selectMultField['tableName'] = $tableName;
  1396. $selectMultField['selectFieldInfo'] = $tableObj->GetSelectFieldInfo($def['fieldName']);
  1397. $params['selectMultFields'][] = $selectMultField;
  1398. }
  1399. else
  1400. {
  1401. if($def['type'] == 'select' || $def['type'] == 'readOnlySelect' ||
  1402. $def['type'] == 'radio')
  1403. {
  1404. $params['returnFieldsFound'][$def['fieldName'].'Text'] = $def['fieldName'].'Text';
  1405. $params['resultGroupByFields'][] = $def['fieldName'].'Text';
  1406. }
  1407. elseif($def['type'] == 'float' || $def['type'] == 'percent' || $def['type'] == 'currency')
  1408. $params['floatFields'][] = $def['fieldName'];
  1409. $params['returnFieldsFound'][$def['fieldName']] = $def['fieldName'];
  1410. $params['resultGroupByFields'][] = $def['fieldName'];
  1411. }
  1412. $params['returnFieldsLabels'][] = $def['labelId'];
  1413. if($key !== false && $key !== NULL)
  1414. unset($params['returnFields'][$key]);
  1415. }
  1416. }
  1417. }
  1418. private function GetDBFieldType($tableName,$fieldName)
  1419. {
  1420. $field = $this->dbDriver->GetRow("DESC $tableName $fieldName");
  1421. return $field['Type'];
  1422. }
  1423. private function GetLangField($tableName, $def, $fieldRef, &$params,
  1424. &$optFieldRef,$textLabel = false)
  1425. {
  1426. $langTableRef = $def['fieldName']."_label";
  1427. $langTable = ($textLabel ? 'LANG_Text ':'LANG_Label '). $langTableRef;
  1428. $params['searchTables'][$tableName]['tables'][] = $langTable;
  1429. $tablesWhere = "$fieldRef=$langTableRef.labelId";
  1430. $params['searchTables'][$tableName]['tablesWhere'][] = $tablesWhere;
  1431. $tablesWhere = "$langTableRef.lang='".$this->lang."'";
  1432. $params['searchTables'][$tableName]['tablesWhere'][] = $tablesWhere;
  1433. $optFieldRef = "$langTableRef.value";
  1434. }
  1435. private function GetSelectField($tableName, &$tableObj, $def, $tableRef,
  1436. $fieldRef, &$params, &$optFieldRef)
  1437. {
  1438. // get select field info
  1439. $selectFieldInfo = $tableObj->GetSelectFieldInfo($def['fieldName']);
  1440. // sub-select to return optFieldRef for select text value
  1441. $optFieldRef = '(SELECT ';
  1442. if($selectFieldInfo['optionTableValue'] == NULL)
  1443. $optFieldRef .= 'label.value';
  1444. else
  1445. $optFieldRef .= 'opt.'.$selectFieldInfo['optionTableValue'];
  1446. $optFieldRef .= ' FROM '.$selectFieldInfo['optionTable'] . ' opt';
  1447. if($selectFieldInfo['optionTableValue'] == NULL)
  1448. $optFieldRef .= ', LANG_Label label';
  1449. $optFieldRef .= " WHERE $fieldRef=opt.";
  1450. $optFieldRef .= $selectFieldInfo['optionTableKey'];
  1451. if($selectFieldInfo['optionTableValue'] == NULL)
  1452. $optFieldRef .= " AND opt.name=label.labelId";
  1453. $optFieldRef .= ')';
  1454. return $optFieldRef;
  1455. }
  1456. //--Method: SearchTable
  1457. //--Desc: Search table
  1458. private function SearchObject(& $params, $obj)
  1459. {
  1460. $tables = ','.implode(',',$obj['tables']);
  1461. $tablesWhere = ' AND '.implode(' AND ',$obj['tablesWhere']);
  1462. $WHERE = NULL;
  1463. $MATCH = NULL;
  1464. // torna busca case insensitive para oracle
  1465. $preLike = '';
  1466. $posLike = '';
  1467. if($this->dbDriver->type=='oracle')
  1468. {
  1469. $preLike = 'LOWER(';
  1470. $posLike = ')';
  1471. }
  1472. foreach($params['filter'] as $key => $fulltext)
  1473. {
  1474. foreach($obj['searchCriteria'] as $criteria)
  1475. {
  1476. $criteria = $preLike.$criteria.$posLike;
  1477. if($WHERE !== NULL)
  1478. $WHERE .= ' OR ';
  1479. $WHERE .= "$criteria LIKE '".$fulltext."%' OR ";
  1480. $WHERE .= "$criteria LIKE '%".$fulltext."' OR ";
  1481. $WHERE .= "$criteria LIKE '%".$fulltext."%' OR ";
  1482. $WHERE .= "$criteria LIKE '".$fulltext."' ";
  1483. if($MATCH !== NULL)
  1484. $MATCH .= ' + ';
  1485. $MATCH .= "IF($criteria LIKE '".$fulltext." %' OR ";
  1486. $MATCH .= "$criteria LIKE '% ".$fulltext."' OR ";
  1487. $MATCH .= "$criteria LIKE '% ".$fulltext." %' OR ";
  1488. $MATCH .= "$criteria LIKE '".$fulltext."',1,0)";
  1489. $MATCH .= "+IF($criteria LIKE '".$fulltext."%' OR ";
  1490. $MATCH .= "$criteria LIKE '%".$fulltext."' OR ";
  1491. $MATCH .= "$criteria LIKE '%".$fulltext."%',1,0)";
  1492. $MATCH .= "+IF($criteria LIKE '".$fulltext."',1,0)";
  1493. }
  1494. }
  1495. if($MATCH !== NULL)
  1496. $MATCH = "($MATCH) as matches";
  1497. $PATH = '(';
  1498. foreach($params['path'] as $key=>&$path)
  1499. {
  1500. if($key>0)
  1501. $PATH .= ' OR ';
  1502. if($params['recursiveSearch'])
  1503. $PATH .= "path LIKE '".$path."%' ";
  1504. else
  1505. $PATH .= "path = '".$path."' ";
  1506. }
  1507. $PATH .= ')';
  1508. $returnFields = "";
  1509. $returnFieldsRefs = "";
  1510. if($params['tempTable'])
  1511. {
  1512. $returnFields = implode(',', $obj['returnFields']);
  1513. $returnFieldsRefs = implode(',',$obj['returnFieldsRefs']);
  1514. $SQL = 'INSERT INTO '.$params['tableName'];
  1515. $SQL .= '(docId,folderId,folderTables,';
  1516. $SQL .= "path,matches,fixedOrder,$returnFields) ";
  1517. }
  1518. else
  1519. {
  1520. foreach($params['returnFieldsFound'] as $fieldName=>$fieldsRef)
  1521. {
  1522. if($returnFieldsRefs!="")
  1523. $returnFieldsRefs .= ',';
  1524. if(isset($obj['returnFieldsRefs'][$fieldName]))
  1525. $returnFieldsRefs .= $obj['returnFieldsRefs'][$fieldName];
  1526. else
  1527. $returnFieldsRefs .= 'NULL as '.$fieldName;
  1528. }
  1529. }
  1530. $SQL .= 'SELECT doc.docId,docLink.folderId,folderTables,path,';
  1531. if($MATCH != NULL)
  1532. $SQL .= $MATCH;
  1533. else
  1534. $SQL .= '0 as matches';
  1535. $SQL .= ",docLink.fixedOrder,$returnFieldsRefs";
  1536. $SQL .= ' FROM ';
  1537. if($this->dbDriver->type=='oracle')
  1538. {
  1539. $SQL .= '(SELECT * FROM ';
  1540. $SQL .= '(SELECT dl.docId,dl.folderId,dl.fixedOrder,path,folderTables,';
  1541. $SQL .= 'ROW_NUMBER() OVER (PARTITION BY docId ORDER BY docId) as rn ';
  1542. $SQL .= 'FROM LIB_DocumentLink dl, LIB_Folder f ';
  1543. $SQL .= 'WHERE dl.folderId = f.folderId ';
  1544. $SQL .= 'AND '.$PATH;
  1545. $SQL .= ') WHERE rn=1 ';
  1546. $SQL .= ') docLink,';
  1547. }
  1548. else
  1549. $SQL .= 'LIB_DocumentLink docLink,LIB_Folder p_folder,';
  1550. $SQL .= 'LIB_Node folderNode'.$tables;
  1551. $SQL .= ' WHERE folderNode.nodeId = docLink.folderId ';
  1552. if($this->dbDriver->type!='oracle')
  1553. $SQL .= 'AND '.$PATH.' AND p_folder.folderId = docLink.folderId ';
  1554. $SQL .= $tablesWhere;
  1555. $SQL .= " AND ";
  1556. if(isset($params['memberData']['userId']))
  1557. {
  1558. if(count($params['memberGroups'])==0)
  1559. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1560. array('fieldName'=>'memberGroups'));
  1561. $groups = implode(',',$params['memberGroups']);
  1562. # check folder permission
  1563. $SQL .= 'IF(folderNode.userId='.$params['memberData']['userId'].',';
  1564. $SQL .= "INSTR(folderNode.userRight,'r'),";
  1565. $SQL .= "IF(folderNode.groupId IN ($groups),";
  1566. $SQL .= "INSTR(folderNode.groupRight,'r'),";
  1567. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  1568. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  1569. $SQL .= "WHERE ngr.nodeId=folderNode.nodeId)<>0,1, ";
  1570. $SQL .= "INSTR(folderNode.otherRight,'r'))))<>0 ";
  1571. # check node permission
  1572. $SQL .= ' AND ';
  1573. $SQL .= 'IF(docNode.userId='.$params['memberData']['userId'].',';
  1574. $SQL .= "INSTR(docNode.userRight,'r'),";
  1575. $SQL .= "IF(docNode.groupId IN ($groups),";
  1576. $SQL .= "INSTR(docNode.groupRight,'r'),";
  1577. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  1578. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  1579. $SQL .= "WHERE ngr.nodeId=docNode.nodeId)<>0,1, ";
  1580. $SQL .= "INSTR(docNode.otherRight,'r'))))<>0 ";
  1581. }
  1582. else
  1583. {
  1584. $SQL .= "INSTR(folderNode.otherRight,'r')<>0 ";
  1585. $SQL .= "AND INSTR(docNode.otherRight,'r')<>0 ";
  1586. }
  1587. if($WHERE !== NULL)
  1588. $SQL .= "AND ($WHERE) ";
  1589. $SQL .= $this->GetExclusionFiltersSQL($obj['exclusionFilters']);
  1590. if($this->dbDriver->type!='oracle')
  1591. $SQL .= 'GROUP BY doc.docId ';
  1592. $SQL .= 'ORDER BY ' . (isset($obj['orderByRef'])?$obj['orderByRef']:$params['orderBy']);
  1593. if($params['orderBy'] == 'matches')
  1594. $SQL .= ($params['order'] ? ' DESC' : ' ASC');
  1595. else
  1596. $SQL .= ($params['order'] ? ' ASC' : ' DESC');
  1597. if($params['tempTable'])
  1598. {
  1599. $SQL .= ',docId LIMIT ' . HALF_SEARCH_LIMIT;
  1600. $this->dbDriver->ExecSQL($SQL);
  1601. }
  1602. else
  1603. $params['query'][] = $SQL;
  1604. }
  1605. //--Method: SearchKeywords
  1606. //--Desc: Search keywords
  1607. protected function SearchKeywords(& $params, $obj)
  1608. {
  1609. $tables = ','.implode(',',$obj['tables']);
  1610. $tablesWhere = ' AND '.implode(' AND ',$obj['tablesWhere']);
  1611. $PATH = '(';
  1612. foreach($params['path'] as $key=>&$path)
  1613. {
  1614. if($key>0)
  1615. $PATH .= ' OR ';
  1616. if($params['recursiveSearch'])
  1617. $PATH .= "path LIKE '".$path."%' ";
  1618. else
  1619. $PATH .= "path = '".$path."' ";
  1620. }
  1621. $PATH .= ')';
  1622. $WHERE = NULL;
  1623. foreach($params['filter'] as $key => $keyword)
  1624. {
  1625. if($WHERE !== NULL)
  1626. $WHERE .= ' OR ';
  1627. $WHERE .= "keyword = '$keyword' ";
  1628. }
  1629. if($params['tempTable'])
  1630. {
  1631. $returnFields = implode(',',$obj['returnFields']);
  1632. $returnFieldsRefs = implode(',',$obj['returnFieldsRefs']);
  1633. $SQL = 'INSERT INTO '.$params['tableName'];
  1634. $SQL .= '(docId,folderId,folderTables,';
  1635. $SQL .= "path,matches,fixedOrder,$returnFields) ";
  1636. }
  1637. else
  1638. {
  1639. foreach($params['returnFieldsFound'] as $fieldName=>$fieldsRef)
  1640. {
  1641. if($returnFieldsRefs!="")
  1642. $returnFieldsRefs .= ',';
  1643. if(isset($obj['returnFieldsRefs'][$fieldName]))
  1644. $returnFieldsRefs .= $obj['returnFieldsRefs'][$fieldName];
  1645. else
  1646. $returnFieldsRefs .= 'NULL as '.$fieldName;
  1647. }
  1648. }
  1649. $SQL .= 'SELECT docLink.docId,docLink.folderId,folderTables,path,';
  1650. if($this->dbDriver->type=='oracle')
  1651. $SQL .= 'matches, ';
  1652. else
  1653. {
  1654. $SQL .= 'COUNT(DISTINCT m.docId, m.keyword)*3 ';
  1655. $SQL .= 'as matches, ';
  1656. }
  1657. $SQL .= "docLink.fixedOrder,$returnFieldsRefs ";
  1658. $SQL .= 'FROM ';
  1659. if($this->dbDriver->type=='oracle')
  1660. {
  1661. $SQL .= '(SELECT * FROM ';
  1662. $SQL .= '(SELECT dl.docId,dl.folderId,dl.fixedOrder,path,folderTables,';
  1663. $SQL .= 'ROW_NUMBER() OVER (PARTITION BY docId ORDER BY docId) as rn ';
  1664. $SQL .= 'FROM LIB_DocumentLink dl, LIB_Folder f ';
  1665. $SQL .= 'WHERE dl.folderId = f.folderId ';
  1666. $SQL .= 'AND '.$PATH;
  1667. $SQL .= ') WHERE rn=1 ';
  1668. $SQL .= ') docLink,';
  1669. $SQL .= '(SELECT COUNT(*)*3 as matches, docId FROM ';
  1670. $SQL .= '(SELECT DISTINCT docId,keyword FROM LIB_Keyword k ';
  1671. $SQL .= 'WHERE '.$WHERE;
  1672. $SQL .= ')dk GROUP BY docId) m, ';
  1673. }
  1674. else
  1675. $SQL .= 'LIB_DocumentLink docLink,LIB_Folder folder,LIB_Keyword m,';
  1676. $SQL .= 'LIB_Node folderNode ' . $tables;
  1677. $SQL .= ' WHERE folderNode.nodeId = docLink.folderId ';
  1678. $SQL .= 'AND docLink.docId = m.docId ';
  1679. if($this->dbDriver->type!='oracle')
  1680. {
  1681. $SQL .= 'AND '.$PATH.' AND folder.folderId = docLink.folderId ';
  1682. }
  1683. $SQL .= $tablesWhere;
  1684. $SQL .= " AND ";
  1685. if(isset($params['memberData']['userId']))
  1686. {
  1687. if(count($params['memberGroups'])==0)
  1688. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1689. array('fieldName'=>'memberGroups'));
  1690. $groups = implode(',',$params['memberGroups']);
  1691. # check folder permission
  1692. $SQL .= 'IF(folderNode.userId='.$params['memberData']['userId'].',';
  1693. $SQL .= "INSTR(folderNode.userRight,'r'),";
  1694. $SQL .= "IF(folderNode.groupId IN ($groups),";
  1695. $SQL .= "INSTR(folderNode.groupRight,'r'),";
  1696. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  1697. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  1698. $SQL .= "WHERE ngr.nodeId=folderNode.nodeId)<>0,1, ";
  1699. $SQL .= "INSTR(folderNode.otherRight,'r'))))<>0 ";
  1700. # check node permission
  1701. $SQL .= ' AND ';
  1702. $SQL .= 'IF(docNode.userId='.$params['memberData']['userId'].',';
  1703. $SQL .= "INSTR(docNode.userRight,'r'),";
  1704. $SQL .= "IF(docNode.groupId IN ($groups),";
  1705. $SQL .= "INSTR(docNode.groupRight,'r'),";
  1706. $SQL .= "IF((SELECT SUM(IF(ngr.groupId IN ($groups),";
  1707. $SQL .= "INSTR(ngr.groupRight,'r'),0)) FROM LIB_NodeGroupRights ngr ";
  1708. $SQL .= "WHERE ngr.nodeId=docNode.nodeId)<>0,1, ";
  1709. $SQL .= "INSTR(docNode.otherRight,'r'))))<>0 ";
  1710. }
  1711. else
  1712. {
  1713. $SQL .= "INSTR(folderNode.otherRight,'r')<>0 ";
  1714. $SQL .= "AND INSTR(docNode.otherRight,'r')<>0 ";
  1715. }
  1716. if($this->dbDriver->type!='oracle' && $WHERE !== NULL)
  1717. $SQL .= "AND ($WHERE) ";
  1718. $SQL .= $this->GetExclusionFiltersSQL($obj['exclusionFilters']);
  1719. if($this->dbDriver->type!='oracle')
  1720. $SQL .= 'GROUP BY doc.docId ';
  1721. $SQL .= 'ORDER BY ' . (isset($obj['orderByRef'])?$obj['orderByRef']:$params['orderBy']);
  1722. if($params['orderBy'] == 'matches')
  1723. $SQL .= ($params['order'] ? ' DESC' : ' ASC');
  1724. else
  1725. $SQL .= ($params['order'] ? ' ASC' : ' DESC');
  1726. if($params['tempTable'])
  1727. {
  1728. $SQL .= ',docId LIMIT ' . HALF_SEARCH_LIMIT;
  1729. $this->dbDriver->ExecSQL($SQL);
  1730. }
  1731. else
  1732. $params['query'][] = $SQL;
  1733. }
  1734. //--Method: PrepareFilters
  1735. //--Desc: Separetes filter in an array and replaces * to %
  1736. private function PrepareFilter($filter)
  1737. {
  1738. if($filter === NULL || $filter === '')
  1739. return NULL;
  1740. // to lower case
  1741. $filter = mb_strtolower($filter);
  1742. // isolates full written filter, without quotes and double spaces
  1743. $fullFilter = str_replace("\"", '', $filter);
  1744. $fullFilter = addslashes($fullFilter);
  1745. while(mb_strpos($fullFilter, ' ') !== false)
  1746. $fullFilter = str_replace(' ', ' ', $fullFilter);
  1747. // separates phrases
  1748. $filter = explode("\"", $filter);
  1749. foreach($filter as $pos => $chunk)
  1750. {
  1751. $chunk = addslashes($chunk);
  1752. if(($pos % 2 == 1) && ($pos<(count($filter)-1)))
  1753. {
  1754. // phrase
  1755. if($chunk != "")
  1756. $ret[] = $chunk;
  1757. }
  1758. else
  1759. {
  1760. // single words
  1761. // eliminate double spaces
  1762. while(mb_strpos($chunk, ' ') !== false)
  1763. $chunk = str_replace(' ', ' ', $chunk);
  1764. $chunk = trim($chunk);
  1765. if($chunk != "")
  1766. // prepare filters
  1767. $ret = array_merge((array)$ret, (array)explode(' ', $chunk));
  1768. }
  1769. }
  1770. $ret[] = $fullFilter;
  1771. return $ret;
  1772. }
  1773. protected function GetExclusionFiltersSQL($exclusionFilters)
  1774. {
  1775. if(count($exclusionFilters)<=0)
  1776. return NULL;
  1777. foreach($exclusionFilters as $fieldName => $field)
  1778. {
  1779. $SQL .= 'AND (';
  1780. foreach($field as $key=>$exFilter)
  1781. {
  1782. if($key > 0)
  1783. $SQL .= ' OR ';
  1784. if($exFilter['value']===NULL)
  1785. {
  1786. switch($exFilter['operator'])
  1787. {
  1788. case '=':
  1789. $SQL .= "$fieldName IS NULL";
  1790. break;
  1791. case '<>':
  1792. $SQL .= "$fieldName IS NOT NULL";
  1793. break;
  1794. default:
  1795. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1796. array('fieldName'=>'exclusionFilters'));
  1797. }
  1798. }
  1799. else
  1800. {
  1801. switch($exFilter['operator'])
  1802. {
  1803. case '=': case '<>': case '>': case '>=': case '<': case '<=': case 'LIKE':
  1804. break;
  1805. default:
  1806. throw new AV_Exception(INVALID_FIELD, $this->lang,
  1807. array('fieldName'=>'exclusionFilters',
  1808. 'exclusionFilter'=>$exFilter));
  1809. }
  1810. $SQL .= "$fieldName ".$exFilter['operator'];
  1811. $SQL .= " '".$exFilter['value']."'";
  1812. }
  1813. }
  1814. $SQL .= ') ';
  1815. }
  1816. return $SQL;
  1817. }
  1818. //--Method: CreateDocLink
  1819. //--Desc: Performs SQL to create document link not considering table locks.
  1820. private function CreateDocLink($folderId, $docId, $beforeDocId = NULL)
  1821. {
  1822. if($this->dbDriver->type=='oracle')
  1823. {
  1824. $fixedOrder = 'LIB_DocumentLinkFixedOrder.NEXTVAL';
  1825. }
  1826. else
  1827. {
  1828. if($beforeDocId == NULL)
  1829. {
  1830. //get fixedOrder
  1831. $SQL = 'SELECT MAX(fixedOrder) as fixedOrder FROM LIB_DocumentLink';
  1832. $SQL .= " WHERE folderId = $folderId FOR UPDATE";
  1833. $fixedOrder = $this->dbDriver->GetOne($SQL);
  1834. $fixedOrder = $fixedOrder + 1;
  1835. }
  1836. else
  1837. {
  1838. $SQL = 'SELECT fixedOrder FROM LIB_DocumentLink ';
  1839. $SQL .= "WHERE folderId='$folderId' ";
  1840. $SQL .= 'AND fixedOrder >= (SELECT fixedOrder FROM LIB_DocumentLink ';
  1841. $SQL .= "WHERE folderId='$folderId' AND docId='$beforeDocId') ";
  1842. $SQL .= 'ORDER BY fixedOrder ASC ';
  1843. $SQL .= 'FOR UPDATE ';
  1844. $fixedOrderAfter = $this->dbDriver->GetCol($SQL);
  1845. if(count($fixedOrderAfter)==0)
  1846. throw new AV_Exception(NOT_FOUND, $this->lang,
  1847. array('fieldName'=>'beforeDocId'));
  1848. $fixedOrder = $fixedOrderAfter[0];
  1849. $SQL = "UPDATE LIB_DocumentLink SET fixedOrder=fixedOrder+1 ";
  1850. $SQL .= "WHERE folderId='$folderId' ";
  1851. $SQL .= "AND fixedOrder >= '$fixedOrder' ";
  1852. $this->dbDriver->ExecSQL($SQL);
  1853. }
  1854. }
  1855. // inserts document link
  1856. $SQL = 'INSERT INTO LIB_DocumentLink ';
  1857. $SQL .= '(folderId, docId,fixedOrder) VALUES ';
  1858. $SQL .= "($folderId, $docId, $fixedOrder)";
  1859. $this->dbDriver->ExecSQL($SQL);
  1860. }
  1861. private function &GetThumb($tableName,$fieldName,$docId,$size,$jpegQuality,
  1862. $maxWidth=NULL,$maxHeight=NULL,$bgColor=NULL,
  1863. $cropRatio=NULL)
  1864. {
  1865. if($size!=NULL)
  1866. {
  1867. if($maxHeight==NULL)
  1868. $maxHeight=$size;
  1869. if($maxWidth==NULL)
  1870. $maxWidth=$size;
  1871. }
  1872. if ($bgColor != NULL)
  1873. {
  1874. $bgColor = preg_replace('/[^0-9a-fA-F]/', '', (string)$bgColor);
  1875. if($bgColor[0] == '#')
  1876. $bgColor = substr($bgColor, 1);
  1877. }
  1878. $blobToFS = $this->module->pageBuilder->siteConfig->getVar('admin',
  1879. 'blobToFS');
  1880. $libPath = $this->module->pageBuilder->siteConfig->getVar("dirs",
  1881. "library");
  1882. // first, try cache
  1883. $SQL = 'SELECT nodeId,userId,groupId,userRight,groupRight,otherRight,';
  1884. $SQL .= 'UNIX_TIMESTAMP(creationDate) as creationDate,';
  1885. $SQL .= 'UNIX_TIMESTAMP(node.lastChanged) as lastChanged,';
  1886. $SQL .= "lastChangedUserId,${fieldName}FileName,${fieldName}Type,";
  1887. $SQL .= "img.thumb as ${fieldName} ";
  1888. $SQL .= "FROM LIB_Node node,$tableName doc,LIB_ImageThumbCache img ";
  1889. $SQL .= "WHERE nodeId=$docId AND nodeId=doc.docId ";
  1890. $SQL .= "AND tableName='$tableName' AND fieldName='$fieldName' ";
  1891. $SQL .= "AND doc.docId=img.docId AND jpegQuality=$jpegQuality ";
  1892. if($maxWidth != NULL && $maxHeight != NULL)
  1893. $SQL .= "AND maxWidth=$maxWidth AND maxHeight=$maxHeight ";
  1894. if($bgColor)
  1895. $SQL .= "AND bgColor='$bgColor' ";
  1896. if($cropRatio)
  1897. $SQL .= "AND cropRatio='$cropRatio' ";
  1898. $SQL .= 'AND node.lastChanged=img.lastChanged ';
  1899. $docData = $this->dbDriver->GetRow($SQL);
  1900. if(count($docData) > 0)
  1901. {
  1902. if($blobToFS)
  1903. {
  1904. $docData[$fieldName] = ft_file_get_contents($libPath . $docData[$fieldName]);
  1905. if($docData[$fieldName] === false)
  1906. throw new AV_Exception(FAILED, $this->lang,
  1907. array('addMsg'=>' (unable to read file)',
  1908. 'filePath'=>$libPath . $docData[$fieldName]));
  1909. }
  1910. return $docData;
  1911. }
  1912. // reads file content
  1913. $SQL = 'SELECT nodeId,userId,groupId,userRight,groupRight,otherRight,';
  1914. $SQL .= 'UNIX_TIMESTAMP(creationDate) as creationDate,';
  1915. $SQL .= 'UNIX_TIMESTAMP(lastChanged) as lastChanged,';
  1916. $SQL .= "lastChangedUserId,${fieldName},${fieldName}FileName,";
  1917. $SQL .= "${fieldName}Type ";
  1918. $SQL .= "FROM LIB_Node node,$tableName ";
  1919. $SQL .= "WHERE nodeId=$docId AND nodeId=docId ";
  1920. $SQL .= "AND ${fieldName}Type LIKE 'image/%' ";
  1921. $SQL .= 'LOCK IN SHARE MODE ';
  1922. $docData = $this->dbDriver->GetRow($SQL);
  1923. if(count($docData) == 0)
  1924. throw new AV_Exception(NOT_FOUND, $this->lang);
  1925. $blobToFS = $this->module->pageBuilder->siteConfig->getVar('admin','blobToFS');
  1926. $libPath = $this->module->pageBuilder->siteConfig->getVar("dirs",
  1927. "library");
  1928. if($blobToFS)
  1929. {
  1930. $docData[$fieldName] = ft_file_get_contents($libPath . $docData[$fieldName]);
  1931. if($docData[$fieldName] === false)
  1932. throw new AV_Exception(FAILED, $this->lang,
  1933. array('addMsg'=>' (unable to read file)',
  1934. 'filePath'=>$libPath . $docData[$fieldName]));
  1935. }
  1936. // erases old files
  1937. $SQL = 'DELETE FROM LIB_ImageThumbCache ';
  1938. $SQL .= "WHERE tableName='$tableName' AND fieldName='$fieldName' ";
  1939. $SQL .= "AND docId=$docId AND jpegQuality=$jpegQuality ";
  1940. if($maxWidth != NULL && $maxHeight != NULL)
  1941. $SQL .= "AND maxWidth=$maxWidth AND maxHeight=$maxHeight ";
  1942. if($bgColor)
  1943. $SQL .= "AND bgColor='$bgColor' ";
  1944. if($cropRatio)
  1945. $SQL .= "AND cropRatio='$cropRatio' ";
  1946. $this->dbDriver->ExecSQL($SQL);
  1947. $srcImg = imagecreatefromstring($docData[$fieldName]);
  1948. if($srcImg===FALSE)
  1949. {
  1950. $adminInvalidImage = $this->label->GetLabel('adminInvalidImageTag',
  1951. $this->lang);
  1952. throw new AV_Exception(FAILED, $this->lang,
  1953. Array('addMsg'=>" ($adminInvalidImage)"));
  1954. }
  1955. $srcX = ImageSX($srcImg);
  1956. $srcY = ImageSY($srcImg);
  1957. // Ratio cropping
  1958. $offsetX = 0;
  1959. $offsetY = 0;
  1960. if($cropRatio)
  1961. {
  1962. $cropRatioArr = explode(':', (string)$cropRatio);
  1963. if(count($cropRatioArr) == 2)
  1964. {
  1965. $ratioComputed = $srcX / $srcY;
  1966. $cropRatioComputed = (float) $cropRatioArr[0] / (float) $cropRatioArr[1];
  1967. if ($ratioComputed < $cropRatioComputed)
  1968. { // Image is too tall so we will crop the top and bottom
  1969. $origHeight = $srcY;
  1970. $srcY = $srcX / $cropRatioComputed;
  1971. $offsetY = ($origHeight - $srcY) / 2;
  1972. }
  1973. else if ($ratioComputed > $cropRatioComputed)
  1974. { // Image is too wide so we will crop off the left and right sides
  1975. $origWidth = $srcX;
  1976. $srcX = $srcY * $cropRatioComputed;
  1977. $offsetX = ($origWidth - $srcX) / 2;
  1978. }
  1979. }
  1980. }
  1981. if($maxWidth==NULL && $maxHeight==NULL ||
  1982. $srcX < $maxWidth && $srcY < $maxHeight)
  1983. {
  1984. $dstX = $srcX;
  1985. $dstY = $srcY;
  1986. }
  1987. else
  1988. {
  1989. $dstY = $maxHeight;
  1990. $dstX = $srcX/($srcY/$maxHeight);
  1991. if ($dstX > $maxWidth)
  1992. {
  1993. $dstX = $maxWidth;
  1994. $dstY = $srcY/($srcX/$maxWidth);
  1995. }
  1996. }
  1997. //
  1998. $dstImg = ImageCreateTrueColor($dstX,$dstY);
  1999. switch($docData["${fieldName}Type"])
  2000. {
  2001. case 'image/gif':
  2002. case 'image/x-png':
  2003. case 'image/png':
  2004. if (!$bgColor)
  2005. {
  2006. // If this is a GIF or a PNG, we need to set up transparency
  2007. imagealphablending($dstImg, false);
  2008. imagesavealpha($dstImg, true);
  2009. }
  2010. else
  2011. {
  2012. // Fill the background with the specified color for matting purposes
  2013. $background = false;
  2014. if(strlen($bgColor) == 6)
  2015. $background = imagecolorallocate($dstImg,
  2016. hexdec($bgColor[0].$bgColor[1]),
  2017. hexdec($bgColor[2].$bgColor[3]),
  2018. hexdec($bgColor[4].$bgColor[5]));
  2019. else if (strlen($bgColor) == 3)
  2020. $background = imagecolorallocate($dstImg,
  2021. hexdec($bgColor[0].$bgColor[0]),
  2022. hexdec($bgColor[1].$bgColor[1]),
  2023. hexdec($bgColor[2].$bgColor[2]));
  2024. if ($background)
  2025. imagefill($dstImg, 0, 0, $background);
  2026. }
  2027. }
  2028. ImageCopyResampled($dstImg,$srcImg,0,0,$offsetX,$offsetY,$dstX,$dstY,$srcX,$srcY);
  2029. ob_start();
  2030. switch($docData["${fieldName}Type"])
  2031. {
  2032. case 'image/jpeg':
  2033. case 'image/pjpeg':
  2034. ImageJpeg($dstImg, NULL, $jpegQuality);
  2035. break;
  2036. case 'image/gif':
  2037. ImageGif($dstImg);
  2038. break;
  2039. case 'image/x-png':
  2040. case 'image/png':
  2041. ImagePng($dstImg);
  2042. break;
  2043. }
  2044. $docData[$fieldName] = ob_get_contents();
  2045. ob_end_clean();
  2046. ImageDestroy($srcImg);
  2047. ImageDestroy($dstImg);
  2048. $SQL = 'INSERT INTO LIB_ImageThumbCache ';
  2049. $SQL .= '(tableName,fieldName,docId,jpegQuality';
  2050. if($maxWidth != NULL && $maxHeight != NULL)
  2051. $SQL .= ',maxWidth,maxHeight';
  2052. if($bgColor)
  2053. $SQL .= ',bgColor';
  2054. if($cropRatio)
  2055. $SQL .= ',cropRatio';
  2056. $SQL .= ",lastChanged,thumb) VALUES ";
  2057. $SQL .= "('$tableName','$fieldName','$docId','$jpegQuality'";
  2058. if($maxWidth != NULL && $maxHeight != NULL)
  2059. $SQL .= ",'$maxWidth','$maxHeight'";
  2060. if($bgColor)
  2061. $SQL .= ",'$bgColor'";
  2062. if($cropRatio)
  2063. $SQL .= ",'$cropRatio'";
  2064. $SQL .= ",FROM_UNIXTIME(".$docData['lastChanged']."),";
  2065. if(!$blobToFS)
  2066. {
  2067. switch($this->dbDriver->type)
  2068. {
  2069. case 'mysql':
  2070. $SQL .= "'".addslashes($docData[$fieldName])."'";
  2071. break;
  2072. case 'oracle':
  2073. $SQL .= 'EMPTY_BLOB()';
  2074. }
  2075. $SQL .= ") ";
  2076. if($this->dbDriver->type=='oracle')
  2077. {
  2078. $this->dbDriver->BindBlob('thumb',$docData[$fieldName]);
  2079. $SQL .= 'RETURNING thumb INTO :thumb';
  2080. }
  2081. }
  2082. else
  2083. {
  2084. $this->dbDriver->ExecSQL('INSERT INTO LIB_BlobFS VALUES ()');
  2085. $blobId = $this->dbDriver->GetOne('SELECT LAST_INSERT_ID() FROM DUAL');
  2086. if(!ft_file_put_contents($libPath . $blobId,$docData[$fieldName]))
  2087. throw new AV_Exception(FAILED, $this->lang,
  2088. array('addMsg'=>' (unable to save image cache)'));
  2089. $SQL .= "'$blobId')";
  2090. }
  2091. $i = 0;
  2092. do
  2093. {
  2094. $status = SUCCESS;
  2095. try
  2096. {
  2097. $this->dbDriver->ExecSQL($SQL);
  2098. }
  2099. catch(Exception $e)
  2100. {
  2101. $status = FAILED;
  2102. $i++;
  2103. }
  2104. } while($status != SUCCESS && $i < 10);
  2105. if($status != SUCCESS)
  2106. $this->module->PrintLog('Unable to save image cache');
  2107. return $docData;
  2108. }
  2109. private function InsertKeywords($keywords, $docId = NULL)
  2110. {
  2111. // eliminate spaces before and after commas
  2112. while(mb_strpos($keywords, ', ') !== false)
  2113. $keywords = str_replace(', ', ',', $keywords);
  2114. while(mb_strpos($keywords, ' ,') !== false)
  2115. $keywords = str_replace(' ,', ',', $keywords);
  2116. // correct keywords containing commas at the start and end positions
  2117. if(mb_substr($keywords,0,1) == ',')
  2118. $keywords = mb_substr($keywords, 1);
  2119. if(mb_substr($keywords,- 1) == ',')
  2120. $keywords = mb_substr($keywords, 0, mb_strlen($keywords - 1));
  2121. $keywords = explode(',', mb_strtolower($keywords));
  2122. // insert keywords
  2123. $SQL = 'INSERT INTO LIB_Keyword (keyword, docId) VALUES ';
  2124. foreach($keywords as $num => $word)
  2125. {
  2126. if($num != 0)
  2127. $SQL .= ', ';
  2128. if($docId == NULL)
  2129. $SQL .= "('$word', LAST_INSERT_ID())";
  2130. else
  2131. $SQL .= "('$word', '$docId')";
  2132. }
  2133. $this->dbDriver->ExecSQL($SQL);
  2134. }
  2135. private function DuplicateKeywords($sourceId, $targetId)
  2136. {
  2137. // insert keywords
  2138. $SQL = 'INSERT INTO LIB_Keyword (keyword, docId) ';
  2139. $SQL .= "SELECT keyword, '$targetId' FROM LIB_Keyword ";
  2140. $SQL .= "WHERE docId='$sourceId'";
  2141. $this->dbDriver->ExecSQL($SQL);
  2142. }
  2143. }
  2144. ?>