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

/class.xmoddocmgt.inc

https://github.com/jcplat/console-seolan
PHP | 2972 lines | 2560 code | 164 blank | 248 comment | 522 complexity | 32ede034b84a718cb9f08adbc4693c1a MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /// Classe de base d'un document integre dans la base documentaire (xmoddocmgt)
  3. class XDocumentDT {
  4. public $title;
  5. public $comment;
  6. public $countdocs=0;
  7. public $countdirs=0;
  8. public $node=false;
  9. public $tpl;
  10. public $fields;
  11. public $insearchengine=true;
  12. protected $symbol='';
  13. static $rep_rep=array();
  14. static function &objectFactory($oid, &$docmgt, $ors=NULL, $ar=NULL) {
  15. if(isset($docmgt->doccache[$oid])) return $docmgt->doccache[$oid];
  16. $doc=array();
  17. if(empty($ors)) {
  18. $rs=selectQuery('SELECT * FROM '.$docmgt->id.',_TYPES WHERE '.$docmgt->id.'.KOID="'.$oid.'" AND '.
  19. '_TYPES.KOID=DTYPE');
  20. $ors=$rs->fetch();
  21. if(empty($ors)) return $doc;
  22. else $rs->closeCursor();
  23. }
  24. $docclass=strtolower($ors['docclas'].'DT');
  25. if(!empty($ors['docclas'])) {
  26. include_once('class.'.$docclass.'.inc');
  27. if(!class_exists($docclass)) {
  28. if($ors['node']==1) $docclass='XDirectoryDT';
  29. else $docclass='XDocumentDT';
  30. }
  31. } else {
  32. if($ors['node']==1) $docclass='XDirectoryDT';
  33. else $docclass='XDocumentDT';
  34. }
  35. $docmgt->doccache[$oid]=new $docclass($oid, $ors, $docmgt, $ar);
  36. // Si l'objet n'a pas été correctement initialisé, on le déclare vide
  37. if (empty($docmgt->doccache[$oid]->fields)) $docmgt->doccache[$oid] = '';
  38. return $docmgt->doccache[$oid];
  39. }
  40. static function &repositoryFactory($typeraw=NULL, $typedisp=NULL) {
  41. if(!empty($typeraw)) {
  42. $module=$typeraw['modidd'];
  43. $tab=$typeraw['dtab'];
  44. } else {
  45. $module=$typedisp['omodidd']->raw;
  46. $tab=$typedisp['odtab']->raw;
  47. }
  48. if(!empty($tab)) {
  49. if(empty(self::$rep_rep[$tab])) {
  50. self::$rep_rep[$tab]=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$tab);
  51. }
  52. $mod=&self::$rep_rep[$tab];
  53. } else {
  54. if(empty(self::$rep_rep[$module])) {
  55. self::$rep_rep[$module]=XModule::objectFactory($module);
  56. }
  57. $mod=&self::$rep_rep[$module];
  58. }
  59. return $mod;
  60. }
  61. function __construct($oid, &$ors, &$docmgt, $ar=NULL) {
  62. $mod=&XDocumentDT::repositoryFactory($ors);
  63. if(is_object($mod)) {
  64. $dar=array('oid'=>$oid,'_lastupdate'=>false,'_options'=>array('local'=>1,'error'=>'return'),'fmoid'=>$docmgt->_moid,'tplentry'=>TZR_RETURN_DATA);
  65. if ($ar) $dar=array_merge($dar,$ar);
  66. $result=&$mod->XMCdisplay($dar,false);
  67. // S'il y a eu une erreur lors de la tentative de récupération des données de l'objet (dans ce cas $result contient le message d'erreur)
  68. if (!is_array($result)) return $result;
  69. $this->fields=&$result;
  70. $this->oid=$oid;
  71. $this->repository=&$mod;
  72. $this->module=&$docmgt;
  73. $this->tpl=&$docmgt->getTypes($ors['DTYPE']);
  74. $lines = explode("\n", stripslashes($this->tpl['oopts']->toText()));
  75. $this->tploptions=array();
  76. foreach($lines as &$line) {
  77. @list($var,$val)=explode('=',$line);
  78. if(!empty($var) && !empty($val)) {
  79. $var=trim($var);$val=trim($val);
  80. $this->tploptions[$var]=$val;
  81. }
  82. }
  83. $this->options=unserialize(stripslashes($ors['DPARAM']));
  84. $this->icon=&$this->tpl['oicon'];
  85. if(isset($this->tpl['osmallic']) && $this->tpl['osmallic']->raw!=''){
  86. $this->smallicon=&$this->tpl['osmallic']->html;
  87. $this->smalliconurl=&$this->tpl['osmallic']->url;
  88. }else{
  89. $this->smallicon=XLabels::getSysLabel('xmoddocmgt','defaultsdoc');
  90. $this->smalliconurl=TZR_SHARE_URL.'ico/'.XLabels::getSysLabel('xmoddocmgt','defaultsdoc_ico');
  91. }
  92. $this->title = $this->getTitle();
  93. $this->docs=$this->getFiles();
  94. $this->short=$this->title;
  95. $this->symbol = $ors['symbol'];
  96. $this->node=false;
  97. }
  98. }
  99. function saveOptions() {
  100. $dparam=addslashes(serialize($this->options));
  101. preparedUpdateQuery('UPDATE '.$this->module->id." SET DPARAM=? WHERE KOID=?",array($dparam,$this->oid));
  102. }
  103. function setOption($option, &$value) {
  104. $this->options[$option]=$value;
  105. }
  106. function &getOption($option) {
  107. if($this->options[$option]) return $this->options[$option];
  108. else return $this->tploptions[$option];
  109. }
  110. function getDocumentsDetails($oids=NULL) {
  111. }
  112. function getDirectoriesDetails($level=1) {
  113. }
  114. function getParents($level=1) {
  115. $this->parents=array();
  116. $this->parentsoid=array();
  117. if($this->oid==$this->module->rootOid()) return;
  118. $set=$this->module->father($this->oid);
  119. foreach($set as &$ors) {
  120. $oiddst=$ors['KOIDDST'];
  121. if(!empty($oiddst) && !in_array($oiddst,$this->parentsoid)) {
  122. if($this->module->secure1($oiddst,'index',$ors['node'])) {
  123. $d1=&XDocumentDT::objectFactory($oiddst,$this->module,$ors);
  124. if($level>1) $d1->getParents($level-1);
  125. $this->parents[]=&$d1;
  126. $this->parentsoid[]=$oiddst;
  127. }
  128. }
  129. }
  130. }
  131. // recherche de tous les chemins possibles qui sont stockés dans $this->paths
  132. //
  133. function getAllPaths() {
  134. $this->paths=array();
  135. $this->_getAllPaths1($this->paths, array($this->oid));
  136. foreach($this->paths as $i=>&$path) {
  137. $path=array_reverse($path);
  138. foreach($path as $j=>&$oidi) {
  139. $path[$j]=&XDocumentDT::objectFactory($oidi, $this->module);
  140. if($path[$j]->node!=1) unset($path[$j]);
  141. }
  142. }
  143. }
  144. private function _getAllPaths1(&$global, $currentpath) {
  145. if(empty($this->parents)) {
  146. if(!empty($currentpath)) {
  147. $global[]=$currentpath;
  148. }
  149. } else {
  150. foreach($this->parents as $i => &$p) {
  151. if(!in_array($p->oid, $currentpath)) {
  152. $copy=$currentpath;
  153. $copy[]=$this->parents[$i]->oid;
  154. $p->_getAllPaths1($global, $copy);
  155. }
  156. }
  157. }
  158. }
  159. function getContent($final=true,$update=true) {
  160. $oids=$this->module->subObjects4($this->oid, 1, false);
  161. if(!empty($this->oid)) {
  162. $this->docsoids = array_values($oids['2']);
  163. $this->countdocs = count($this->docsoids);
  164. }
  165. $this->dirsoids = array_values($oids['1']);
  166. $this->countdirs = count($this->dirsoids);
  167. }
  168. function getTitle() {
  169. return strip_tags($this->fields['link']);
  170. }
  171. /// rend le texte associe au document
  172. function getDescription() {
  173. return (!empty($this->fields['oremark'])?$this->fields['oremark']->html:'');
  174. }
  175. /// Retourne au format html la liste des fichiers du document
  176. function getFiles() {
  177. $this->countfiles=0;
  178. $txt='';
  179. foreach($this->fields['fields_object'] as $i=>&$v) {
  180. if(!empty($v->html)){
  181. if($v->fielddef instanceof XFileDef) {
  182. $txt.='<div class="tzr-xdirdef-dir"><div>'.$v->html.'</div></div> ';
  183. $this->countfiles++;
  184. }elseif($v->fielddef instanceof XFolderDef) {
  185. $txt.=$v->html.' ';
  186. if(isset($v->catalog)) $this->countfiles+=count($v->catalog);
  187. }
  188. }
  189. }
  190. return $txt;
  191. }
  192. /// rend liste des fichiers d'un document
  193. function getFilesDetails() {
  194. return getFilesDetails($this->fields);
  195. }
  196. /// liste les actions possible sur un document
  197. function &getActions() {
  198. static $m1=array('ro','rw','unlock');
  199. static $m2=array('ro');
  200. static $m3=array('ro','rw');
  201. static $m4=array();
  202. static $m5=array('ro','rw','lock');
  203. if($this->module->secure1($this->oid, 'edit',($this->node?"1":"2"))) {
  204. if(!empty($GLOBALS['XLOCK'])) {
  205. if(!empty($this->fields['_lock'])) {
  206. if(!empty($this->fields['_lock_editable'])) {
  207. $this->actions=&$m1;
  208. } else {
  209. $this->actions=&$m2;
  210. }
  211. } else $this->actions=&$m5;
  212. } elseif($this->tpl['omodid']->raw!=$this->module->_moid) {
  213. // si c'est un document partage et qu'on n'est pas dans son module d'origine
  214. $this->actions=&$m2;
  215. } else {
  216. $this->actions=&$m3;
  217. }
  218. } elseif($this->module->secure1($this->oid, 'display',($this->node?"1":"2"))) {
  219. $this->actions=&$m2;
  220. } else {
  221. $this->actions=&$m4;
  222. }
  223. }
  224. function del() {
  225. $mod = &XDocumentDT::repositoryFactory(NULL,$this->tpl);
  226. $mod->XMCdel(array('oid'=>$this->oid,'tplentry'=>TZR_RETURN_DATA));
  227. }
  228. function journal() {
  229. $mod = &XDocumentDT::repositoryFactory(NULL,$this->tpl);
  230. if(method_exists($mod,'journal')) {
  231. return $mod->journal(array('oid'=>$this->oid,'tplentry'=>TZR_RETURN_DATA));
  232. } else return NULL;
  233. }
  234. /// Ajout d'un document au moteur de recherche
  235. function addToSearchEngine(&$searchEngine) {
  236. $fields = $this->getSearchEngineData();
  237. $searchEngine->addItem($this->oid,$fields,$this->module->_moid,NULL);
  238. XLogs::notice(get_class($this),get_class($this).'::addToSearchEngine lucene');
  239. }
  240. function &getSearchEngineData(){
  241. $fields = array('notice'=>'', 'contents'=>'', 'title'=>'');
  242. $fields['contents']=getFilesContent($this->fields);
  243. $fields['title'] = $this->title;
  244. $fields['notice'] = $this->getSearchEngineNotice();
  245. return $fields;
  246. }
  247. function &getSearchEngineNotice(){
  248. $notice = '';
  249. // les champs !publiés et non fichiers dans la notice
  250. foreach($this->fields['fields_object'] as $i=>&$v) {
  251. $field = $v->fielddef;
  252. if ($field->indexable
  253. && (!$field->get_published()
  254. && !($field instanceof XFileDef)
  255. && !($field instanceof XFolderDef))){
  256. $notice .= ' '.$v->toText();
  257. }
  258. }
  259. // ajout des noms des champs fichiers
  260. $indexables = $this->getIndexablesFields();
  261. $files = getFilesDetails($this->fields);
  262. foreach($files as $afile){
  263. if (in_array($afile['field'], $indexables)){
  264. $notice .= ' '.$afile['title'];
  265. if ($afile['name'] != $afile['title'])
  266. $notice .= ' '.$afile['name'];
  267. }
  268. }
  269. return $notice;
  270. }
  271. /// rend la liste des champs indexables
  272. function getIndexablesFields(){
  273. $list = array();
  274. foreach($this->fields['fields_object'] as $i=>&$v) {
  275. if ($v->fielddef->indexable)
  276. $list[] = $v->fielddef->field;
  277. }
  278. return $list;
  279. }
  280. }
  281. /// Classe de base d'un document container (repertoire/dossier) integre dans la base documentaire (xmoddocmgt)
  282. class XDirectoryDT extends XDocumentDT {
  283. function __construct($oid, &$ors, &$docmgt, $ar=NULL) {
  284. parent::__construct($oid, $ors, $docmgt, $ar);
  285. $this->node=true;
  286. $this->comment=$this->getDescription();
  287. if(empty($this->icon->html)) {
  288. $this->icon->url=XLabels::getSysLabel('xmoddocmgt','directorybig','url');
  289. }
  290. if(isset($this->tpl['osmallic']->raw) && $this->tpl['osmallic']->raw!=''){
  291. $this->smallicon=&$this->tpl['osmallic']->html;
  292. $this->smalliconurl=&$this->tpl['osmallic']->url;
  293. }else{
  294. $this->smallicon=XLabels::getSysLabel('xmoddocmgt','defaultsdir');
  295. $this->smalliconurl=TZR_SHARE_URL.'ico/'.XLabels::getSysLabel('xmoddocmgt','defaultsdir_ico');
  296. }
  297. }
  298. /// la gestion des types possibles peut etre modifiee avec allowedChildType
  299. function getNewTypes($docs=false, $dirs=false) {
  300. if ($docs || $dirs){
  301. $phrase = '';
  302. $exp = $this->tpl['ocrules']->raw;
  303. $l = preg_split('/$/m', $exp);
  304. $convs = array(); /* tableau des associations antre symboles et lettres simples */
  305. $exps = array(); /* tableau des expressions a verifier */
  306. foreach($l as $foo=>$c){
  307. $c = trim($c);
  308. if (empty($c)) continue;
  309. /* si la chaine commence par un : c'est une affectation */
  310. $f = strpos($c, ':');
  311. if ($f !== false && $f == 0) {
  312. $c1 = substr($c, 1);
  313. list($symbol, $letter) = explode('=', $c1);
  314. $convs[$symbol] = $letter;
  315. } else {
  316. $exps[] = $c;
  317. }
  318. }
  319. $childsTypes = array(); /* tableau des types de descendants */
  320. foreach($this->documents as $oiddoc=>&$cdoc){
  321. $s = $cdoc->tpl['osymbol']->raw;
  322. if (isset($convs[$s])) $s = $convs[$s];
  323. $childsTypes[] = $s;
  324. }
  325. foreach($this->directories as $oiddoc=>&$cdoc){
  326. $s = $cdoc->tpl['osymbol']->raw;
  327. if (isset($convs[$s])) $s = $convs[$s];
  328. $childsTypes[] = $s;
  329. }
  330. }
  331. $exp = '';
  332. foreach($exps as $foo=>$e){
  333. if($exp != '') $exp .= '|'.$e;
  334. else $exp.=$e;
  335. }
  336. if(empty($exp)) $exp=".*";
  337. if($docs) {
  338. $typesname=array();
  339. $dtypes=$this->module->getTypes();
  340. foreach($dtypes as $i=>&$tpl) {
  341. $childsTypes2 = $childsTypes;
  342. $s = $tpl['osymbol']->raw;
  343. if (isset($convs[$s])) $s = $convs[$s];
  344. else $s='x';
  345. $childsTypes2[] = $s;
  346. sort($childsTypes2);
  347. $phrase2 = implode($childsTypes2, '');
  348. if($tpl['onode']->raw==2 && preg_match('/^('.$exp.')$/', $phrase2) && $this->allowedChildType($tpl, $childs) && $tpl['_rwsecure']) {
  349. $this->newdocs[$i]=&$tpl;
  350. $typesname[$i]=$tpl['otitle']->raw;
  351. }
  352. }
  353. array_multisort($typesname,$this->newdocs);
  354. }
  355. if($dirs) {
  356. $typesname=array();
  357. $oidtoprotect=$this->module->protectedOids();
  358. $dtypes=&$this->module->getTypes();
  359. foreach($dtypes as $i=>&$tpl) {
  360. if(!in_array($tpl['oid'], $oidtoprotect)) {
  361. $childsTypes2 = $childsTypes;
  362. $s = $tpl['osymbol']->raw;
  363. if (isset($convs[$s])) $s = $convs[$s];
  364. else $s='x';
  365. $childsTypes2[] = $s;
  366. sort($childsTypes2);
  367. $phrase2 = implode($childsTypes2, '');
  368. if($tpl['onode']->raw==1 && preg_match('/^('.$exp.')$/i', $phrase2) && $this->allowedChildType($tpl, $childs) && $tpl['_rwsecure']) {
  369. $this->newdirs[$i]=&$tpl;
  370. $typesname[$i]=$tpl['otitle']->raw;
  371. }
  372. }
  373. }
  374. array_multisort($typesname,$this->newdirs);
  375. }
  376. }
  377. /// types possibles pour un dossier des modeles
  378. function getNewTypesM($docs=false, $dirs=false) {
  379. $dtypes=&$this->module->getTypes();
  380. if($docs) {
  381. foreach($dtypes as $i=>&$tpl) {
  382. if($tpl['onode']->raw==2 && $tpl['_rwsecure']) {
  383. $this->newdocs[$i]=&$tpl;
  384. }
  385. }
  386. }
  387. if($dirs) {
  388. foreach($dtypes as $i=>&$tpl) {
  389. if($tpl['onode']->raw==1 && $tpl['_rwsecure']) {
  390. $this->newdirs[$i]=&$tpl;
  391. }
  392. }
  393. }
  394. }
  395. /// controle sur les regles du type : ne doit pas pouvoir etre surchargee
  396. private function _allowedChildType($csymbol, $phrase){
  397. return true;
  398. }
  399. protected function allowedChildType($csymbol) {
  400. return true;
  401. }
  402. function getDocumentsDetails() {
  403. if(!empty($this->documents)) return;
  404. if(empty($this->docsoids)) return;
  405. $order=$this->getOption('fileorder');
  406. list($order,$direction)=explode(' ',$order);
  407. // recherche des documents qui sont dans ce repertoire
  408. foreach($this->docsoids as $oid) {
  409. if(empty($set)) $set="'".$oid."'";
  410. else $set.=",'".$oid."'";
  411. }
  412. $rs=selectQuery('SELECT * FROM '.$this->module->idx.','.$this->module->id.',_TYPES where KOIDSRC in ('.$set.') '.
  413. ' and KOIDSRC='.$this->module->id.'.KOID and node=2 and '.$this->module->id.'.DTYPE=_TYPES.KOID/*2*/');
  414. if($rs) {
  415. $this->documents=array();
  416. $documents=array();
  417. $tmporder=array(); /* tableau temporaire construit pour le tri */
  418. $tmporder2=array(); /* tableau temporaire construit pour le tri */
  419. while($ors=$rs->fetch()) {
  420. if(!empty($ors['KOIDSRC'])) {
  421. // voir si document sur xdatasource et pas module -> false toujours ?
  422. $seenhere=in_array($ors['KOIDSRC'], $this->docsoids);
  423. if(!$seenhere) continue;
  424. $doc1 = &XDocumentDT::objectFactory($ors['KOIDSRC'], $this->module, $ors);
  425. // Si l'objet n'est pas accessible (dépublié par exemple)
  426. if (!is_object($doc1)) continue;
  427. $doc1->getActions();
  428. $documents[$ors['KOIDSRC']]=$doc1;
  429. $this->documents[$ors['KOIDSRC']]=NULL;
  430. if(isset($documents[$ors['KOIDSRC']]->fields['o'.$order])) {
  431. $tmporder[$ors['KOIDSRC']]=$documents[$ors['KOIDSRC']]->fields['o'.$order]->raw;
  432. } elseif($order=='doctype') {
  433. $tmporder[$ors['KOIDSRC']]=$documents[$ors['KOIDSRC']]->tpl['osymbol']->raw;
  434. } else {
  435. $tmporder[$ors['KOIDSRC']]=$documents[$ors['KOIDSRC']]->title;
  436. }
  437. $tmporder2[$ors['KOIDSRC']]=$documents[$ors['KOIDSRC']]->title;
  438. }
  439. }
  440. }
  441. if($direction=='DESC') array_multisort($tmporder, SORT_DESC, $tmporder2, $this->documents);
  442. else array_multisort($tmporder, SORT_ASC, $tmporder2, $this->documents);
  443. foreach($this->documents as $key=>&$val)
  444. $val=$documents[$key];
  445. }
  446. function getDirectoriesDetails($level=1) {
  447. if(!empty($this->directories)) return;
  448. if(empty($this->dirsoids)) return;
  449. $order=$this->getOption('directoryorder');
  450. list($order,$direction)=explode(' ',$order);
  451. // recherche des documents qui sont dans ce repertoire
  452. foreach($this->dirsoids as $oid) {
  453. if(empty($set)) $set="'".$oid."'";
  454. else $set.=",'".$oid."'";
  455. }
  456. $rs=selectQuery('SELECT * FROM '.$this->module->idx.','.$this->module->id.',_TYPES where KOIDSRC in ('.$set.') '.
  457. ' and KOIDSRC='.$this->module->id.'.KOID and '.$this->module->id.'.DTYPE=_TYPES.KOID/*1*/');
  458. if($rs) {
  459. $this->directories=array(); /* tableau des documents tries */
  460. $directories=array(); /* tableau des documents non tries */
  461. $tmporder=array(); /* tableau temporaire construit pour le tri */
  462. $tmporder2=array(); /* tableau temporaire construit pour le tri */
  463. while($ors=$rs->fetch()) {
  464. if(!empty($ors['KOIDSRC'])) {
  465. if(!$this->module->secure1($ors['KOIDSRC'], 'index',$ors['node'])) continue;
  466. $doc1 = &XDocumentDT::objectFactory($ors['KOIDSRC'], $this->module, $ors);
  467. $doc1->parents[]=&$this;
  468. $doc1->parentsoids[]=$this->oid;
  469. $this->directories[$ors['KOIDSRC']]=NULL;
  470. $directories[$ors['KOIDSRC']]=$doc1;
  471. $directories[$ors['KOIDSRC']]->getContent();
  472. if($level>0) {
  473. $directories[$ors['KOIDSRC']]->getDirectoriesDetails($level-1);
  474. }
  475. if(isset($directories[$ors['KOIDSRC']]->fields['o'.$order])) {
  476. $tmporder[$ors['KOIDSRC']]=$directories[$ors['KOIDSRC']]->fields['o'.$order]->raw;
  477. } elseif($order=='doctype') {
  478. $tmporder[$ors['KOIDSRC']]=$directories[$ors['KOIDSRC']]->tpl['osymbol']->raw;
  479. } else {
  480. $tmporder[$ors['KOIDSRC']]=$directories[$ors['KOIDSRC']]->title;
  481. }
  482. $tmporder2[$ors['KOIDSRC']]=$directories[$ors['KOIDSRC']]->title;
  483. }
  484. }
  485. if($direction=='DESC') array_multisort($tmporder, SORT_DESC, $tmporder2, $this->directories);
  486. else array_multisort($tmporder, SORT_ASC, $tmporder2, $this->directories);
  487. foreach($this->directories as $key=>&$val)
  488. $val=$directories[$key];
  489. }
  490. $rs->closeCursor();
  491. }
  492. // notice du repertoire pour moteur de recherche
  493. // le reste = document (si fichiers ils sont pris)
  494. function getSearchEngineNotice(){
  495. $notice = parent::getSearchEngineNotice();
  496. if (isset($this->fields['oremark']) && is_object($this->fields['oremark']) && (!$this->fields['oremark']->fielddef->indexable)){
  497. $notice = $this->fields['oremark']->text.' '.$notice;
  498. }
  499. return $notice;
  500. }
  501. // ajout d'un descendant
  502. //
  503. function addChild($oid) {
  504. $q="SELECT COUNT(*) FROM {$this->module->idx} WHERE KOIDSRC='$oid' AND KOIDDST='{$this->oid}'";
  505. $rs=selectQuery($q);
  506. $ors=$rs->fetch();
  507. if($ors['COUNT(*)']<=0) {
  508. $q='INSERT INTO '.$this->module->idx.' SET KOIDSRC="'.$oid.'", KOIDDST="'.$this->oid.'"';
  509. updateQuery($q);
  510. }
  511. }
  512. }
  513. /// Module de gestion d'une base documentaire
  514. class XModDocMgt extends XModule {
  515. public $prefix='DM';
  516. // suffixe de l'oid du dosssier qui contient les modeles
  517. var $patternSuffix = 'TEMPLATES';
  518. // table (xset) de description par defaut des dossiers
  519. public $defaultFolderTable = 'REP1';
  520. var $doccache=array();
  521. var $documentssec=true;
  522. public $trackchanges=true;
  523. public $trackaccess=false;
  524. public $searchtemplate='xmoddocmgt/searchResult.html';
  525. var $_s=array();
  526. function __construct($ar=NULL) {
  527. parent::__construct($ar);
  528. $this->idx = $this->prefix.'IDX';
  529. $this->id = $this->prefix.'ID';
  530. $this->lang = XShell::getLangData();
  531. $this->_f=array();
  532. $this->opts=XOpts::getOpt(XUser::get_current_user_uid(), $this->_moid, 'opts');
  533. XLabels::loadLabels('xmoddocmgt');
  534. }
  535. /// Liste des tables utilisées par le module
  536. public function usedTables(){
  537. $ret=$this->usedMainTables();
  538. $ret[]=$this->idx;
  539. $ret[]=$this->id;
  540. return $ret;
  541. }
  542. public function usedMainTables() {
  543. $rs=&selectQuery('select modidd,dtab from _TYPES where modid="'.$this->_moid.'"');
  544. $ret=array();
  545. while($ors=$rs->fetch()){
  546. if(!empty($ors['dtab'])) $ret[]=$ors['dtab'];
  547. else{
  548. $mod=XModule::objectFactory($ors['modidd']);
  549. if(is_object($mod)){
  550. $t=$mod->usedTables();
  551. if($t) $ret=array_merge($ret,$t);
  552. }
  553. }
  554. }
  555. return $ret;
  556. }
  557. /// rend la liste des types de doc ou le type de doc d'oid $oid
  558. public function &getTypes($oid=NULL) {
  559. $foooid=NULL;
  560. if(empty($this->doctypes) || empty($this->doctypes[$oid])) {
  561. // recherche des types de document
  562. $mods=array_keys(XModule::modulesUsingTable('_TYPES',false,false,false));
  563. $moid=$mods[0];
  564. $mod=XModule::objectFactory($moid);
  565. $oids=$mod->xset->browseOids(array('_filter'=>'(modid="'.$this->_moid.'" OR KOID="'.$oid.'")','_options'=>array('local'=>true)));
  566. if($mod->object_sec) $oidsrights=$GLOBALS['XUSER']->getObjectsAccess($mod,XShell::getLangData(),$oids);
  567. foreach($oids as $i=>$toid){
  568. $foo1=$mod->xset->rDisplay($toid);
  569. if(!$mod->object_sec || array_key_exists('ro',$oidsrights[$i])) $foo1['_rwsecure']=true;
  570. if($foo1['omodid']->raw==$this->_moid) {
  571. $this->doctypes[$toid]=$foo1;
  572. } else {
  573. $foo1['otitle']->html.=' / '.XLabels::getSysLabel('xmoddocmgt.source').' '.$foo1['omodid']->html;
  574. }
  575. if($foo1['oid']==$oid) $foooid=$foo1;
  576. }
  577. }
  578. if(empty($oid)) return $this->doctypes;
  579. elseif(!empty($foooid)) return $foooid;
  580. else return $this->doctypes[$oid];
  581. }
  582. function protectedOids() {
  583. $oidtoprotect=array('_TYPES:root-'.$this->_moid,
  584. '_TYPES:lostandfound-'.$this->_moid,
  585. '_TYPES:trash-'.$this->_moid,
  586. '_TYPES:archive-'.$this->_moid);
  587. return $oidtoprotect;
  588. }
  589. /// Suppression du module
  590. function delete($ar=NULL) {
  591. parent::delete($ar);
  592. // Suppression des types de docs du module
  593. updateQuery('delete from _TYPES where modid="'.$this->_moid.'"');
  594. }
  595. /// Initialisation des propriétés
  596. public function initOptions() {
  597. parent::initOptions();
  598. $slabel=XLabels::getSysLabel('general','security','text');
  599. $this->_options->setOpt('Gerer la securite sur les documents', 'documentssec', 'boolean', NULL, true, $slabel);
  600. $tlabel=XLabels::getSysLabel('xmodule.tracking');
  601. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','trackaccess'),'trackaccess','boolean',NULL,NULL,$tlabel);
  602. $this->_options->setOpt('Préfixe','prefix','text');
  603. $this->_options->setOpt('Table par défaut des repertoires','defaultFolderTable','table');
  604. }
  605. /// securite des fonctions accessibles par le web
  606. function secGroups($function, $group=NULL) {
  607. $g=array();
  608. $g['index']=array('list','ro','rw','rwv','admin');
  609. $g['index2']=array('list','ro','rw','rwv','admin');
  610. $g['index2Light']=array('list','ro','rw','rwv','admin');
  611. $g['viewDir']=array('list', 'ro','rw','rwv','admin');
  612. $g['ajaxLoadDir']=array('list','ro','rw','rwv','admin');
  613. $g['ajaxLoadDirTree']=array('list','ro','rw','rwv','admin');
  614. $g['input']=array('rw','rwv','admin');
  615. $g['procInput']=array('rw','rwv','admin');
  616. $g['journal']=array('ro','rw','rwv','admin');
  617. $g['edit']=array('rw','rwv','admin');
  618. $g['display']=array('ro','rw','rwv','admin');
  619. $g['procEdit']=array('rw','rwv','admin');
  620. $g['del']=array('rw','rwv','admin');
  621. $g['search']=array('list','ro','rw','rwv','admin');
  622. $g['advsearch']=array('list','ro','rw','rwv','admin');
  623. $g['linkTo']=array('list', 'ro', 'rw','rwv','admin');
  624. $g['getLast']=array('list','ro','rw','rwv','admin');
  625. $g['getUnread']=array('list','ro','rw','rwv','admin');
  626. $g['markAsRead']=array('list','ro','rw','rwv','admin');
  627. $g['subscribe']=array('ro','rw','rwv','admin');
  628. $g['preSubscribe']=array('ro','rw','rwv','admin');
  629. $g['admin']=array('admin');
  630. $g['documentsDownload']=array('ro','rw','rwv','admin');
  631. $g['export']=array('ro','rw','rwv','admin');
  632. $g['exportFTP']=array('ro','rw','rwv','admin');
  633. $g['exportBatch']=array('ro','rw','rwv','admin');
  634. $g['procSendACopyTo']=array('list', 'ro','rw','rwv','admin');
  635. $g['prePrintDisplay']=array('list','ro','rw','rwv','admin');
  636. $g['printDisplay']=array('ro','rw','rwv','admin');
  637. $g['share']=array('rw','rwv','admin');
  638. $g['procShare']=array('rw','rwv','admin');
  639. $g['setRootOid']=array('ro','rw','rwv','admin');
  640. $g['clearRootOid']=array('ro','rw','rwv','admin');
  641. if(isset($g[$function])) {
  642. if(!empty($group)) return in_array($group, $g[$function]);
  643. return $g[$function];
  644. }
  645. return parent::secGroups($function,$group);
  646. }
  647. /// Action principale du menu
  648. public function getMainAction(){
  649. return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&_function=index&tplentry=br&template=xmoddocmgt/index2.html&maxlevel=2&'.
  650. 'clear=1&oid='.$this->rootOid();
  651. }
  652. /// Cette fonction est appliquee pour afficher l'ensemble des methodes de ce module
  653. protected function _actionlist(&$my=NULL) {
  654. parent::_actionlist($my);
  655. $myclass=get_class($this);
  656. $moid=$this->_moid;
  657. $uniqid='v'.XShell::uniqid();
  658. $dir='xmoddocmgt';
  659. $myoid = @$_REQUEST['oid'];
  660. $mypoid = @$_REQUEST['_parentoid'];
  661. if(empty($myoid)) $myoid=$this->rootOid();
  662. $ri=XUser::secure8maxlevel($this);
  663. if($ri=='admin'){
  664. $o1=new XModuleAction($this, 'exportfs', XLabels::getSysLabel('general','export','text'),
  665. '&moid='.$moid.
  666. '&_function=index&tplentry=br&'.
  667. 'template='.$dir.'/export.html&_parentoid='.$mypoid.'&oid='.$myoid);
  668. $o1->homepageable=false;
  669. $o1->menuable=true;
  670. $o1->quicklinkable=true;
  671. $o1->group='actions';
  672. $my['exportfs']=$o1;
  673. }
  674. $suid=getSessionVar('SUID');
  675. if(!empty($suid)) {
  676. if(!empty($this->opts['home'])) {
  677. $o1=new XModuleAction($this, 'clearrootoid', XLabels::getSysLabel('xmoddocmgt','clearrootoid','text'),
  678. '&moid='.$moid.'&_function=clearRootOid&tplentry=br&'.'template='.$dir.'/index2.html&maxlevel=2&clear=1',
  679. 'more');
  680. $o1->menuable=true;
  681. $my['setrootoid']=$o1;
  682. } elseif(!empty($myoid)) {
  683. $o1=new XModuleAction($this, 'setrootoid', XLabels::getSysLabel('xmoddocmgt','setrootoid','text'),
  684. '&moid='.$moid.'&_function=setRootOid&tplentry=br&'.'template='.$dir.'/index2.html&maxlevel=2&clear=1&'.
  685. '&oid='.$myoid,'more');
  686. $o1->menuable=true;
  687. $my['setrootoid']=$o1;
  688. }
  689. }
  690. $rw=$this->secure($myoid,'edit');
  691. $admin=$this->secure($myoid,'secEdit');
  692. if(XShell::_function()!='index2') {
  693. // Arbo a plat
  694. $o1=new XModuleAction($this, 'index1', XLabels::getSysLabel('xmoddocmgt','index','text'),
  695. '&moid='.$moid.'&_function=index&tplentry=br&'.'template='.$dir.'/index2.html&maxlevel=2&clear=1&'.
  696. '_parentoid='.$mypoid.'&oid='.$myoid,'display');
  697. $o1->setToolbar('general','browse');
  698. $o1->order=1;
  699. $my['index1']=$o1;
  700. // Arborescence
  701. $o1=new XModuleAction($this, 'index2', XLabels::getSysLabel('general','tree','text'),
  702. '&moid='.$moid.'&_function=index2&tplentry=br&template='.$dir.'/index3.html&maxlevel=10&'.
  703. '_parentoid='.$mypoid.'&oid='.$myoid,'display');
  704. $o1->setToolbar('general','tree');
  705. $o1->order=2;
  706. $my['index2']=$o1;
  707. // Recherche avancée
  708. if($this->secure('','advsearch')){
  709. $o1=new XModuleAction($this,'advsearch', XLabels::getSysLabel('xmoddocmgt','advsearch','text'),
  710. '&moid='.$moid.'&_function=advsearch&tplentry=br&template='.$dir.'/advsearch.html','display');
  711. $o1->setToolbar('xmoddocmgt','advsearch');
  712. $o1->order=3;
  713. $my['advsearch']=$o1;
  714. }
  715. if(!empty($myoid) && Kernel::isAKoid($myoid)) {
  716. $o1=new XModuleAction($this,'display',XLabels::getSysLabel('general', 'view','text'),
  717. '&moid='.$moid.'&_function=display&tplentry=br&'.'template='.$dir.'/display.html&oid='.$myoid,'edit');
  718. $o1->setToolbar('general','display');
  719. $o1->order=1;
  720. $my['display']=$o1;
  721. if($myoid!=$this->rootOid()) {
  722. if($rw){
  723. // Edition
  724. $o1=new XModuleAction($this,'edit',XLabels::getSysLabel('general','edit','text'),
  725. '&moid='.$moid.'&_function=edit&tplentry=br&template='.$dir.'/edit.html&_parentoid='.$mypoid.
  726. '&oid='.$myoid,'edit');
  727. $o1->setToolbar('general','edit');
  728. $o1->order=2;
  729. $my['edit']=$o1;
  730. // Réservation
  731. if(!empty($GLOBALS['XLOCK']) && !$GLOBALS['XLOCK']->locked($myoid,TZR_DEFAULT_LANG)) {
  732. if(!empty($myoid)) $dmyoid=&XDocumentDT::objectFactory($myoid, $this);
  733. if(is_object($dmyoid) && !($dmyoid instanceof XDirectoryDT)) {
  734. $o1=new XModuleAction($this,'lock', XLabels::getSysLabel('general','lock','text'),
  735. '&moid='.$moid.'&_function=edit&tplentry=br&_mode=lock&'.
  736. 'template='.$dir.'/edit.html&_parentoid='.$mypoid.'&oid='.$myoid,'edit');
  737. $o1->setToolbar('general','lock');
  738. $o1->order=3;
  739. $my['lock']=$o1;
  740. }
  741. }
  742. }
  743. // Droits
  744. if($admin) {
  745. $self=$GLOBALS['TZR_SESSION_MANAGER']::complete_self(true);
  746. $o1=new XModuleAction($this,'security',XLabels::getSysLabel('general','security','text'),
  747. 'javascript:TZR.editSec("'.$self.'","'.$moid.'","'.$myoid.'",'.$uniqid.');','edit');
  748. $o1->menuable=true;
  749. $o1->setToolbar('general','security');
  750. $my['security2']=$o1;
  751. }
  752. // Pour ces deux actions les droits dependent de la destination
  753. // Copier
  754. $o1=new XModuleAction($this,'linkTo',XLabels::getSysLabel('general','copy','text'),
  755. 'javascript:'.$uniqid.'.copyselected("'.$myoid.'");','edit');
  756. $o1->menuable=true;
  757. $my['copy']=$o1;
  758. // Liaison
  759. $o1=new XModuleAction($this,'linkTo',XLabels::getSysLabel('xmoddocmgt','link','text'),
  760. 'javascript:'.$uniqid.'.linkselected("'.$myoid.'");','edit');
  761. $o1->menuable=true;
  762. $my['link']=$o1;
  763. // Déplacement
  764. if($rw){
  765. $o1=new XModuleAction($this,'linkTo',XLabels::getSysLabel('general','move','text'),
  766. 'javascript:'.$uniqid.'.moveselected("'.$myoid.'");','edit');
  767. $o1->setToolbar('general','move');
  768. $my['move']=$o1;
  769. }
  770. }
  771. // Suppression
  772. if($this->secure($myoid,'del')){
  773. $o1=new XModuleAction($this,'del',XLabels::getSysLabel('general', 'delete','text'),'javascript:'.$uniqid.'.deleteselected('.($myoid!=$this->rootOid()?'':'true').');',
  774. 'edit');
  775. $o1->setToolbar('general','delete');
  776. $o1->order=4;
  777. $my['delete']=$o1;
  778. }
  779. }
  780. }else{
  781. // Vue a plat du dossier en cours
  782. $o1=new XModuleAction($this, 'index1', XLabels::getSysLabel('xmoddocmgt','index','text'),'javascript:'.$uniqid.'.gotonode();');
  783. $o1->homepageable=$o1->menuable=true;
  784. $o1->quicklinkable=true;
  785. $o1->group='display';
  786. $o1->setToolbar('general','browse');
  787. $my['index1']=$o1;
  788. // Suppression
  789. if($this->secure($myoid,'del')){
  790. $o1=new XModuleAction($this,'del',XLabels::getSysLabel('general','delete','text'),'javascript:'.$uniqid.'.deleteselected();',
  791. 'edit');
  792. $o1->menuable=true;
  793. $o1->setToolbar('general','delete');
  794. $my['delete']=$o1;
  795. }
  796. }
  797. // Téléchargement
  798. $o1=new XModuleAction($this,'download',XLabels::getSysLabel('xmoddocmgt','downloadselected','text'),
  799. 'javascript:'.$uniqid.'.downloadselected();','edit');
  800. $o1->menuable=true;
  801. $my['download']=$o1;
  802. if(!empty($myoid) && Kernel::isAKoid($myoid)){
  803. // Abonnement
  804. $xmodsubmoid=XModule::getMoid(XMODSUB_TOID);
  805. if(!empty($xmodsubmoid) && $this->secure($myoid,'preSubscribe')){
  806. $o1=new XModuleAction($this,'subscribe',XLabels::getSysLabel('xmodsub', 'subscribe', 'text'),
  807. '&moid='.$this->_moid.'&oid='.$myoid.'&_function=preSubscribe&tplentry=br&template=xmoddocmgt/sub.html',
  808. 'more');
  809. $o1->menuable=true;
  810. $my['subscribe']=$o1;
  811. }
  812. if ($this->secure($myoid,'sendACopyTo')){
  813. // Avertir
  814. if(XShell::_function()=='display' || XShell::_function()=='edit'){
  815. $o1=new XModuleAction($this,'sendACopy',XLabels::getSysLabel('xmodule','sendacopyto','text'),
  816. '&moid='.$this->_moid.'&tplentry=br&oid='.$myoid.
  817. '&_function=sendACopyTo&template=xmodule/sendacopyto.html&tplentry=br','more');
  818. }else{
  819. $o1=new XModuleAction($this,'sendACopy',XLabels::getSysLabel('xmodule','sendacopyto','text'),
  820. 'javascript:TZR.applySelected("sendACopyTo",document.forms["browse'.XShell::uniqid().'"],"","xmodule/sendacopyto.html",'.
  821. '"br","'.addslashes(XLabels::getSysLabel('general','error_select_object','text')).'");','more');
  822. }
  823. $o1->menuable=true;
  824. $my['sendacopy']=$o1;
  825. }
  826. }
  827. // Voir les derniers documents
  828. $o1=new XModuleAction($this,'lastdoc',XLabels::getSysLabel('xmoddocmgt','lastdoc','text'),
  829. '&moid='.$this->_moid.'&_function=getLast&tplentry=br&template=xmoddocmgt/getlast.html','display');
  830. $o1->menuable=true;
  831. $my['lastdoc']=$o1;
  832. // Voir les documents non lus
  833. if($this->trackaccess && $this->secure('','getUnread')){
  834. $o1=new XModuleAction($this,'lastdoc',XLabels::getSysLabel('xmodule','unread','text'),
  835. '&moid='.$this->_moid.'&_function=getUnread&tplentry=br&template=xmoddocmgt/getUnread.html','display');
  836. $o1->menuable=true;
  837. $my['unread']=$o1;
  838. }
  839. // Création du contexte si en mode interactif
  840. if($this->interactive) $this->mkContext2($my, $myoid);
  841. }
  842. /// Menu spécifique au display
  843. function al_display(&$my){
  844. $this->getSSMAl($my);
  845. $br=XShell::from_screen('br');
  846. if(method_exists($br['here']->repository,'printDisplay') && $br['here']->repository->secure($oid,'printDisplay')){
  847. $o1=new XModuleAction($this,'print',XLabels::getSysLabel('general','print','text'),
  848. 'javascript:window.open("'.$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&function=prePrintDisplay&moid='.$this->_moid.'&template=xmodtable/preprintview.html&tplentry=br&oid='.$br['oid'].'","print","width=650,height=550,scrollbars=yes,location=no,resizable=yes,menubar=yes");','display');
  849. $o1->setToolbar('general','print');
  850. $o1->order=3;
  851. $my['print']=$o1;
  852. }
  853. }
  854. function al_edit(&$my){
  855. $this->al_display($my);
  856. }
  857. /// duplication d'un module, méthode interne (retour : tables => liste des tables dupliquées par le module (cle : ancienne table, valeur : nouvelle table))
  858. function _duplicateModule($newmoid,&$params,$prefix) {
  859. if(!empty($params['tables']) && is_array($params['tables'])) $mods=$params['mods'];
  860. else $mods=array();
  861. if(!empty($params['tables']) && is_array($params['tables'])) $tables=$params['tables'];
  862. else $tables=array();
  863. // creation des tables dmid et dmidx
  864. $newprefix = XModDocMgtWd::newPrefix();
  865. updateQuery('CREATE TABLE '.$newprefix.'ID like '.$this->id);
  866. updateQuery('CREATE TABLE '.$newprefix.'IDX like '.$this->idx);
  867. XModDocMgtWd::createStructure($newprefix);
  868. $params['prefix']=$newprefix;
  869. $tables[$this->id]=$newprefix.'ID';
  870. $tables[$this->idx]=$newprefix.'IDX';
  871. // copie des donnees dans la structure
  872. updateQuery('INSERT INTO '.$newprefix.'ID select * from '.$this->id);
  873. updateQuery('INSERT INTO '.$newprefix.'IDX select * from '.$this->idx);
  874. // Duplication de toutes les tables de documents et des types de doc
  875. $moid=$this->_moid;
  876. $all=selectQueryGetAll('select KOID,dtab,modidd from _TYPES where modid="'.$this->_moid.'"');
  877. $dstype=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=_TYPES');
  878. foreach($all as $data) {
  879. $tab=$ntab=NULL;
  880. $koid=$data['KOID'];
  881. if(empty($data['modidd']) && !empty($data['dtab'])) {
  882. // duplication du module dans le cas ou le doc est gere par une source de donnees
  883. // Etape 1 : duplication de la table
  884. $tab=$data['dtab'];
  885. if(empty($tables[$tab])){
  886. $ntab=$ar['newtable']=XDSTable::newTableNumber();
  887. $tables[$tab]=$ntab;
  888. $xset=XDataSource::objectFactoryHelper8('SPECS='.$data['dtab']);
  889. if(($pos=strpos($xset->getLabel(),':'))!==false) $ar['mtxt']=$prefix.substr($xset->getLabel(),$pos);
  890. else $ar['mtxt']=$prefix.':'.$xset->getLabel();
  891. $ar['data']=true;
  892. $ar['_options']=array('local'=>1);
  893. $xset2=$xset->procDuplicateDataSource($ar);
  894. }else{
  895. $ntab=$tables[$tab];
  896. }
  897. XLogs::debug('XModDocMgt::_duplicateModule: cloning table '.$tab.' to '.$ntab);
  898. // etape 2 :duplication de l'entree dans la liste des documents type
  899. $ardup=array('_options'=>array('local'=>1));
  900. $ardup['oid']=$koid;
  901. $nkoid=$dstype->duplicate($ardup);
  902. preparedUpdateQuery('UPDATE _TYPES set dtab=?,modid=? where KOID=?',array($ntab,$newmoid,$nkoid));
  903. } elseif(!empty($data['modidd'])) {
  904. // duplication de la table quand les doc sont gere par un un module
  905. if(empty($mods[$data['modidd']])){
  906. $module=XModule::objectFactory($data['modidd']);
  907. // etape 1 : duplication du module
  908. $ret=$module->duplicateModule(array('tables'=>$tables,'group'=>(!empty($params['group'])?$params['group']:$this->group)));
  909. $thenewmoid=$ret['moid'];
  910. $tables=$tables+$ret['duplicatetables'];
  911. $mods=$mods+$ret['duplicatemods'];
  912. }else{
  913. $thenewmoid=$mods[$data['modidd']];
  914. }
  915. // etape 2 : duplication de l'entree dans la liste des documents type
  916. $ardup=array('_options'=>array('local'=>1));
  917. $ardup['oid']=$koid;
  918. $nkoid=$dstype->duplicate($ardup);
  919. preparedUpdateQuery('UPDATE _TYPES set modidd=?,modid=? where KOID=?',array($thenewmoid,$newmoid,$nkoid));
  920. $newmodule=XModule::objectFactory($thenewmoid);
  921. $ntab=$newmodule->table;
  922. $tab=$module->table;
  923. XLogs::debug('XModDocMgt::_duplicateModule: cloning module '.$data['modidd'].' to '.$thenewmoid.' table '.$ntab);
  924. }
  925. // on renomme la racine
  926. if(preg_match('@_TYPES\:root-([0-9]+)@',$koid)) {
  927. $nnkoid='_TYPES:root-'.$newmoid;
  928. preparedUpdateQuery('UPDATE _TYPES set KOID=? where KOID=?',array($nnkoid,$nkoid));
  929. $nkoid=$nnkoid;
  930. // on renseigne la table des dossiers par defaut
  931. $rsroot=selectQuery('SELECT * FROM _TYPES WHERE KOID="'.$nkoid.'"');
  932. if($rsroot && $orsroot=$rsroot->fetch()) {
  933. if(!empty($orsroot['dtab'])) $params['defaultFolderTable']=$orsroot['dtab'];
  934. }
  935. }
  936. if(!empty($ntab) && !empty($tab)) {
  937. // on renomme les oids un peu partout
  938. updateQuery('update '.$newprefix."ID set UPD=UPD,KOID='$ntab:root-$newmoid' where KOID='$tab:root-$moid'");
  939. updateQuery('update '.$newprefix.'ID set UPD=UPD,KOID=replace(KOID,"'.$tab.':","'.$ntab.':")');
  940. updateQuery('update '.$newprefix.'ID set UPD=UPD,DTYPE="'.$nkoid.'" WHERE DTYPE="'.$koid.'"');
  941. updateQuery('update '.$newprefix."IDX set KOIDDST='$ntab:root-$newmoid' WHERE KOIDDST='$tab:root-$moid'");
  942. updateQuery('update '.$newprefix."IDX set KOIDSRC='$ntab:root-$newmoid' WHERE KOIDSRC='$tab:root-$moid'");
  943. updateQuery('update '.$newprefix.'IDX set KOIDSRC=replace(KOIDSRC,"'.$tab.':","'.$ntab.':")');
  944. updateQuery('update '.$newprefix.'IDX set KOIDDST=replace(KOIDDST,"'.$tab.':","'.$ntab.':")');
  945. }
  946. }
  947. return array('duplicatetables'=>$tables,'duplicatemods'=>$moids);
  948. }
  949. function getSSMAl(&$my){
  950. $uniqid='v'.XShell::uniqid();
  951. $br=XShell::from_screen('br');
  952. $myoid=$br['oid'];
  953. $max=count($br['__ssmod']);
  954. $ssmmenu=array();
  955. for($i=0;$i<$max;$i++) {
  956. $f='ssmod'.$i;
  957. $ft=$br['__ssprops'][$i]['modulename'];
  958. $ff=$br['__ssprops'][$i]['linkedfield'];
  959. $fa=$br['__ssprops'][$i]['activate_additem'];
  960. $fmoid=$br['__ssprops'][$i]['_moid'];
  961. if($ff && ($ff!='*none*' && $fa && $br['__ssinsert'][$i])){
  962. $o1=new XModuleAction($this,$f,$br['__ssprops'][$i]['modulename'],
  963. 'javascript:'.$uniqid.'.addTabs("'.$fmoid.'","'.$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$fmoid.'&_linkedfield='.$ff.
  964. '&_parentoid='.$myoid.'&function=insert&template=xmodtable/new.html&tplentry=br&_raw=1&_ajax=1&skip=1'.
  965. '&tabsmode=1","'.XLabels::getSysLabel('general','add','text').' : '.$ft.'");');
  966. $o1->menuable=true;
  967. $ssmmenu[]=$o1;
  968. }
  969. }
  970. if(count($ssmmenu)>1){
  971. $o1=new XModuleAction($this,'alladd',XLabels::getSysLabel('general','add','text'),'#');
  972. $o1->menuable=true;
  973. $o1->newgroup='ssm';
  974. $my['ssm']=$o1;
  975. foreach($ssmmenu as &$o1){
  976. $o1->group='ssm';
  977. $my[$o1->xfunction]=$o1;
  978. }
  979. }else{
  980. foreach($ssmmenu as &$o1){
  981. $o1->name=XLabels::getSysLabel('general','add','text').' : '.$o1->name;
  982. $my[$o1->xfunction]=$o1;
  983. }
  984. }
  985. }
  986. /// Suppression dans le module des documents qui sont effaces depuis d'autres modules
  987. function _removeRegisteredOid($oid) {
  988. updateQuery('delete from '.$this->idx.' where KOIDSRC="'.$oid.'"');
  989. updateQuery('delete from '.$this->id.' where KOID="'.$oid.'"');
  990. $this->delDocFromSearchEngine($oid);
  991. }
  992. function status($ar=NULL) {
  993. // inserez votre code personnalise ici
  994. }
  995. /// Affichage sur deux niveaux des dossiers et des fichiers
  996. function &index($ar=NULL) {
  997. $p=new XParam($ar,array('up'=>1,'down'=>1,'oid'=>'','maxlevel'=>2, 'showfiles'=>1, 'clear'=>false));
  998. $clear=$p->get('clear');
  999. if(!empty($clear)) $this->_clearSession('docmode');
  1000. if($this->_getSession('docmode')=='index2') {
  1001. $GLOBALS['XSHELL']->setTemplates('xmoddocmgt/index3.html');
  1002. return $this->index2($ar);
  1003. }
  1004. $tplentry=$p->get('tplentry');
  1005. $maxlevel=$p->get('maxlevel');
  1006. $showfiles=$p->get('showfiles');
  1007. $fileorder=$p->get('fileorder');
  1008. $directoryorder=$p->get('directoryorder');
  1009. $oid=$p->get('oid');
  1010. // Si pas d'oid, on prend la racine
  1011. if(empty($oid)) $_REQUEST['oid']=$oid=$this->rootOid();
  1012. // Recherche du dossier parent si le document que l'on essaie d'afficher n'est pas un dossier
  1013. $rs=selectQuery('select * from '.$this->id.' left outer join _TYPES on '.$this->id.'.DTYPE=_TYPES.KOID '.
  1014. 'where '.$this->id.'.KOID="'.$oid.'"');
  1015. if($rs && ($ors=$rs->fetch())) {
  1016. if($ors['node']==2) {
  1017. $rs=selectQuery('select * from '.$this->idx.' where KOIDSRC="'.$oid.'"/*6*/');
  1018. if($rs && ($ors=$rs->fetch())) $_REQUEST['oid']=$oid=$ors['KOIDDST'];
  1019. }
  1020. }
  1021. $r['here']=&XDocumentDT::objectFactory($oid, $this);
  1022. // Si l'ordre de tri a changé, on le sauvegarde
  1023. if(!empty($fileorder)) {
  1024. $r['here']->setOption('fileorder',$fileorder);
  1025. $r['here']->saveOptions();
  1026. }
  1027. if(!empty($directoryorder)) {
  1028. $r['here']->setOption('directoryorder',$directoryorder);
  1029. $r['here']->saveOptions();
  1030. }
  1031. // Recupere les details du document
  1032. $r['here']->getContent(true);
  1033. $r['here']->getDocumentsDetails();
  1034. $r['here']->getDirectoriesDetails($maxlevel-1);
  1035. $r['here']->getActions();
  1036. $path=&$this->mkContext($oid);
  1037. if($showfiles==2) {
  1038. foreach($r['here']->directories as &$dir) {
  1039. $dir->getDocumentsDetails();
  1040. }
  1041. }
  1042. $r['path']=&$path;
  1043. $r['oidcurrent']=$r['here']->oid;
  1044. // Liste des types qui peuvent etre ajouté dans le dossier en court
  1045. if($this->getPatternsFolderOid()==$path[0]->oid) $r['here']->getNewTypesM(true,true);
  1046. else $r['here']->getNewTypes(true, true);
  1047. // Liste des tris possible sur les dossiers
  1048. $sorting=@$r['here']->tploptions['dirsorting'];
  1049. if(!empty($sorting)){
  1050. $sortinglist=array();
  1051. $list=explode(';',$sorting);
  1052. foreach($list as $i=>$f){
  1053. $param=explode(',',$f);
  1054. if(count($param)==2) $sortinglist[]=array('name'=>$param[0],'order'=>$param[1]);
  1055. }
  1056. $r['dirsorting']=$sortinglist;
  1057. }
  1058. // Liste des tris possible sur les documents
  1059. $sorting=@$r['here']->tploptions['sorting'];
  1060. if(!empty($sorting)){
  1061. $sortinglist=array();
  1062. $list=explode(';',$sorting);
  1063. foreach($list as $i=>$f){
  1064. $param=explode(',',$f);
  1065. if(count($param)==2) $sortinglist[]=array('name'=>$param[0],'order'=>$param[1]);
  1066. }
  1067. $r['sorting']=$sortinglist;
  1068. }
  1069. if($this->interactive && $this->trackaccess) XLogs::uniqueUpdate('access',$oid);
  1070. return XShell::toScreen1($tplentry, $r);
  1071. }
  1072. // visualisation arborescente partielle
  1073. // -> = index2 mais sur le premier niveau et les dossier du path en cours seulement
  1074. //
  1075. public function &index2Light($ar){
  1076. $p=new XParam($ar,array('up'=>1,'down'=>1,'oid'=>'','maxlevel'=>2, 'showfiles'=>2, 'nosess'=>0));
  1077. $nosess=$p->get('nosess');
  1078. if(empty($nosess)) $this->_setSession('docmode','index2');
  1079. $oid=$p->get('oid');
  1080. if(empty($oid)){
  1081. $oid=$this->rootOid();
  1082. $_REQUEST['oid'] = $oid; // templates au moins index2 utilisent ceci
  1083. }
  1084. $tplentry=$p->get('tplentry');
  1085. $maxlevel=$p->get('maxlevel');
  1086. $actiontotest=$p->get('action');
  1087. if(!in_array($actiontotest, array('linkTo','display'))) $actiontotest='index';
  1088. $showfiles=$p->get('showfiles');
  1089. if($showfiles==1) $docstolist=2;
  1090. else $docstolist=1;
  1091. // Les fils directs de root
  1092. $rets = &$this->subObjects4($this->rootOid(), 1, false, 1, $docstolist);
  1093. // Creation du contexte
  1094. $path=&$this->mkContext($oid);
  1095. $oidcurrent=NULL;
  1096. // Construction des noeuds du chemin
  1097. foreach($path[0] as $i=>&$o2) {
  1098. $oidcurrent=$o2->oid;
  1099. if(($oidcurrent != $this->rootOid()) && !in_array($oidcurrent, $rets['1'])){
  1100. $prets = &$this->subObjects4($path[0][$i-1]->oid, 1, false, $i, 1);
  1101. $dx=array_search($path[0][$i-1]->oid, $rets['1']);
  1102. $rets['1'] = array_merge(array_slice($rets['1'], 0, $dx+1), $prets['1'], array_slice($rets['1'], $dx+1));
  1103. $rets['ors']=array_merge($rets['ors'],$prets['ors']);
  1104. }
  1105. }
  1106. // Recupere les dossiers
  1107. foreach($rets['1'] as $i=>&$myoid) {
  1108. $ors=&$rets['ors'][$myoid];
  1109. if(isset($ors)) {
  1110. $rets['docs'][$i]=&XDocumentDT::objectFactory($myoid, $this);
  1111. $rets['docs'][$i]->getContent();
  1112. // nolinkto est utilisé pour cacher certains dossier pour la fonction de copie, lien...
  1113. // il n'est donc pas necessaire de la calculer si on doit retourner aussi les docs car on ne sera pas dans ce cas
  1114. if($docstolist==1) $rets['ors'][$myoid]['noLinkTo']=($this->secure1($myoid, 'edit', $ors['node'])?0:1);
  1115. }
  1116. }
  1117. // Recupere les documents
  1118. if($docstolist==2){
  1119. foreach($rets['2'] as $j=>&$myoid) {
  1120. $ors=&$rets['ors'][$myoid];
  1121. if(isset($ors)) {
  1122. $rets['docs'][$i+1+$j]=&XDocumentDT::objectFactory($myoid, $this);
  1123. $rets['docs'][$i+1+$j]->getContent();
  1124. }
  1125. }
  1126. }
  1127. $order=array();
  1128. $prev=0;
  1129. $prevlabels=array();
  1130. foreach($rets['1'] as $i=>$oid) {
  1131. $o1=&$rets['ors'][$oid];
  1132. $cur=$o1['level'];
  1133. $prevlabels[$cur]=$rets['docs'][$i]->title;
  1134. if($cur<$prev) {
  1135. foreach($prevlabels as $j=>$v) {
  1136. if($j>$cur) unset($prevlabels[$j]);
  1137. }
  1138. }
  1139. $order[$i]=$prevlabels;
  1140. $prev=$o1['level'];
  1141. }
  1142. $orderstring=array();
  1143. foreach($order as $i=>&$o) {
  1144. // en cas d'egalite il faut un discriminant pour que multisort n'aille pas dans le tableau des docs ?
  1145. $orderstring[$i]=implode('>',$o).$i;
  1146. }
  1147. array_multisort($orderstring, SORT_ASC, $rets['docs']);
  1148. $sors=$rets['ors'];
  1149. $rets['ors']=array();
  1150. foreach($rets['docs'] as $i=>&$o) {
  1151. $rets['ors'][$i]=$sors[$o->oid];
  1152. }
  1153. unset($sors);
  1154. $orderstring=array_values($orderstring);
  1155. $oidcurrent=NULL;
  1156. foreach($path[0] as $i=>&$ob) {
  1157. $oidcurrent=$ob->oid;
  1158. foreach($rets['docs'] as $oid=>&$doc) {
  1159. if($ob->oid==$doc->oid) {
  1160. $foo = 'current find';
  1161. $doc->current=true;
  1162. }
  1163. }
  1164. }
  1165. $rets['docs']=array_values($rets['docs']);
  1166. $rets['ors']=array_values($rets['ors']);
  1167. $rets['path']=&$path;
  1168. $rets['oidcurrent']=$oidcurrent;
  1169. if($this->interactive && $this->trackaccess) XLogs::uniqueUpdate('access',$oid);
  1170. return XShell::toScreen1($tplentry, $rets);
  1171. }
  1172. // visualisation arborescente des repertoires
  1173. //
  1174. function &index2($ar=NULL) {
  1175. $p=new XParam($ar,array('up'=>1,'down'=>1,'oid'=>'','maxlevel'=>2, 'showfiles'=>2, 'nosess'=>0));
  1176. $tpl=$p->get('tplentry');
  1177. // Affichage en arbo, on change de fonction
  1178. if($tpl!=TZR_RETURN_DATA && XShell::getTemplate()=='xmoddocmgt/index3.html'){
  1179. XLogs::notice('XModdocMgt::index2', ' index3 required : call to index2Light');
  1180. return $this->index2Light($ar);
  1181. }
  1182. $nosess=$p->get('nosess');
  1183. if(empty($nosess)) $this->_setSession('docmode','index2');
  1184. $oid=$p->get('oid');
  1185. if(empty($oid)){
  1186. $oid=$this->rootOid();
  1187. $_REQUEST['oid']=$oid;
  1188. }
  1189. $tplentry=$p->get('tplentry');
  1190. $maxlevel=$p->get('maxlevel');
  1191. $actiontotest=$p->get('action');
  1192. $move=$p->get('_move');
  1193. $_selected=$p->get('_selected');
  1194. $except=!empty($move) && empty($_selected) ? array($oid):array();
  1195. if(!in_array($actiontotest, array('linkTo','display'))) $actiontotest='display';
  1196. $showfiles=$p->get('showfiles');
  1197. if($showfiles==1)
  1198. $docstolist=array(1,2);
  1199. else
  1200. $docstolist=array(1);
  1201. $rets=&$this->subObjects2($this->rootOid(),$docstolist,100,true,$actiontotest,$except);
  1202. $todel_level=NULL;
  1203. $cnt=count($rets['ors']);
  1204. $lvlprev=0;
  1205. foreach($rets['ors'] as $i=>&$o){
  1206. $rets['docs'][$i]=&XDocumentDT::objectFactory($o['KOIDSRC'], $this);
  1207. $rets['docs'][$i]->getContent();
  1208. }
  1209. $order=array();
  1210. $prev=0;
  1211. $prevlabels=array();
  1212. foreach($rets['ors'] as $i=>&$o) {
  1213. $cur=$o['level'];
  1214. $prevlabels[$cur]=$rets['docs'][$i]->title;
  1215. if($cur<$prev) {
  1216. foreach($prevlabels as $j=>$v) {
  1217. if($j>$cur) unset($prevlabels[$j]);
  1218. }
  1219. }
  1220. $order[$i]=$prevlabels;
  1221. $prev=$o['level'];
  1222. }
  1223. $orderstring=array();
  1224. foreach($order as $i=>&$o) {
  1225. $orderstring[$i]=implode('>',$o).$i;
  1226. // en cas d'egalite il faut un discriminant pour que multisort n'aille pas dans le tableau des docs ?
  1227. }
  1228. $docs=&$rets['docs'];
  1229. $ors=&$rets['ors'];
  1230. array_multisort($orderstring, SORT_ASC, $docs, $ors);
  1231. $path=&$this->mkContext($oid);
  1232. $oidcurrent=NULL;
  1233. foreach($path[0] as $i=>&$ob) {
  1234. $oidcurrent=$ob->oid;
  1235. foreach($rets['docs'] as $j=>&$doc) {
  1236. if($ob->oid==$doc->oid) {
  1237. $doc->current=true;
  1238. }
  1239. }
  1240. }
  1241. $rets['path']=&$path;
  1242. $rets['oidcurrent']=$oidcurrent;
  1243. if($this->interactive && $this->trackaccess) XLogs::uniqueUpdate('access',$oid);
  1244. return XShell::toScreen1($tplentry, $rets);
  1245. }
  1246. /// Retourne la liste des dossiers fils d'un dossier
  1247. function &viewDirFolders($ar=NULL) {
  1248. $p=new XParam($ar,array('up'=>1,'down'=>1,'oid'=>'','maxlevel'=>2, 'showfiles'=>1));
  1249. $oid=$p->get('oid');
  1250. $tplentry=$p->get('tplentry');
  1251. $doc=&XDocumentDT::objectFactory($oid, $this);
  1252. $doc->getContent();
  1253. $fileorder=$p->get('fileorder');
  1254. if(!empty($fileorder)) $doc->setOption('fileorder',$fileorder);
  1255. $doc->getDirectoriesDetails(1);
  1256. $r['doc']=$doc;
  1257. return XShell::toScreen1($tplentry, $r);
  1258. }
  1259. /// Retourne la liste des dossiers/fichiers fils d'un dossier au format JSON allégé
  1260. function ajaxLoadDirTree(){
  1261. $p=new XParam($ar, array('showfiles'=>0));
  1262. $ar['tplentry']=TZR_RETURN_DATA;
  1263. $r=$this->viewDirFolders($ar);
  1264. $showfiles=$p->get('showfiles');
  1265. // l'objet en reponse JSON
  1266. $ret=(object)array('doc'=>(object)array('oid'=>$p->get('oid')),
  1267. 'directories'=>array(),'documents'=>array());
  1268. foreach($r['doc']->directories as $something => &$dir){
  1269. if(!$showfiles) $noLinkTo=($this->secure1($dir->oid, 'edit', 1)?0:1);
  1270. else $noLinkTo=0;
  1271. $ret->directories[]=(object)array('oid'=>$dir->oid,'title'=>htmlspecialchars($dir->title),'countdirs'=>$dir->countdirs,'countdocs'=>$dir->countdocs,
  1272. 'smalliconurl'=>$dir->smalliconurl,'noLinkTo'=>$noLinkTo);
  1273. }
  1274. if($showfiles){
  1275. $r=$this->viewDir($ar);
  1276. foreach($r['doc']->documents as $something => &$dir){
  1277. $ret->documents[]=(object)array('oid'=>$dir->oid,'title'=>htmlspecialchars($dir->title),
  1278. 'smalliconurl'=>$dir->smalliconurl,'noLinkTo'=>0);
  1279. }
  1280. }
  1281. die(json_encode((object)$ret));
  1282. }
  1283. /// Retourne le contenu d'un repertoire
  1284. function &viewDir($ar=NULL) {
  1285. $p=new XParam($ar,array('up'=>1,'down'=>1,'oid'=>'','maxlevel'=>2, 'showfiles'=>1));
  1286. $oid=$p->get('oid');
  1287. $tplentry=$p->get('tplentry');
  1288. $doc=&XDocumentDT::objectFactory($oid, $this);
  1289. $doc->getContent();
  1290. $doc->getActions();
  1291. $fileorder=$p->get('fileorder');
  1292. if(!empty($fileorder)) $doc->setOption('fileorder',$fileorder);
  1293. $doc->getDocumentsDetails();
  1294. $r['doc']=$doc;
  1295. // dossier modele ou descendant
  1296. $path=&$this->mkContext($oid);
  1297. if ($this->getPatternsFolderOid() == $path[0]->oid) {
  1298. $r['doc']->getNewTypesM(true, true);
  1299. } else {
  1300. $r['doc']->getNewTypes(true, true);
  1301. }
  1302. return XShell::toScreen1($tplentry, $r);
  1303. }
  1304. /// Retourne le contenu d'un repertoire au format JSON allégé
  1305. function ajaxLoadDir(){
  1306. $p=new XParam($ar, array());
  1307. $oid=$p->get('oid');
  1308. $r=$this->viewDir($ar);
  1309. // Simplifier la reponse
  1310. $paths=$mpaths=array();
  1311. $parent='';
  1312. $dpaths=$this->mkContext($oid);
  1313. $nbpaths=count($dpaths);
  1314. $self=$GLOBALS['TZR_SESSION_MANAGER']::complete_self(true,false);
  1315. // Créé le fil d'arianne
  1316. foreach($dpaths as $foo=>$path){
  1317. foreach($path as $foo2=>$node){
  1318. if($foo2>0) $parentoid='&parentoid='.$path[$foo2-1]->oid;
  1319. else $parentoid='';
  1320. $link='<a class="cv8-ajaxlink" href="'.$self.'&oid='.$node->oid.$parentoid.'&moid='.$this->_moid.'&function=index2&'.
  1321. 'template=xmoddocmgt/index3.html&tplentry=br">'.$node->title.'</a>';
  1322. if($foo2>0 && $foo==0){
  1323. $paths[]=$link;
  1324. $parent=$path[$foo2-1]->oid;
  1325. }
  1326. if($nbpaths>1) $mpaths[$foo][]=$link;
  1327. }
  1328. }
  1329. // Prepare la liste
  1330. $sorting=$r['doc']->tploptions['sorting'];
  1331. $sortinglist=array();
  1332. if(!empty($sorting)){
  1333. $list=explode(';',$sorting);
  1334. foreach($list as $i=>$f){
  1335. $param=explode(',',$f);
  1336. if(count($param)==2) $sortinglist[]=array('name'=>$param[0],'order'=>$param[1]);
  1337. }
  1338. }
  1339. $ret=(object)array('tpl'=>(object)array('title'=>$r['doc']->tpl['otitle']->raw),
  1340. 'doc'=>(object)array('title'=>html_entity_decode($r['doc']->title),'parentoid'=>$parent,
  1341. 'comment'=>html_entity_decode($r['doc']->comment),'oid'=>$p->get('oid'),'paths'=>$paths,
  1342. 'mpaths'=>$mpaths,'newdirs'=>array(),'newdocs'=>array(),'documents'=>array(),
  1343. 'sorting'=>$sortinglist,'actions'=>','.implode($r['doc']->actions,',').',')
  1344. );
  1345. foreach($r['doc']->newdirs as $it=>&$tpl){
  1346. $url=$self.'&moid='.$this->_moid.'&function=input&template=xmoddocmgt/input.html&doid='.$tpl['oid'].'&tplentry=br&parentoid='.$oid.
  1347. '&oid='.$oid;
  1348. $ret->doc->newdirs[]=(object)array('title'=>$tpl['otitle']->raw,'url'=>$url);
  1349. }
  1350. foreach($r['doc']->newdocs as $it=>&$tpl){
  1351. $url=$self.'&moid='.$this->_moid.'&function=input&template=xmoddocmgt/input.html&doid='.$tpl['oid'].'&tplentry=br&parentoid='.$oid.
  1352. '&oid='.$oid;
  1353. $ret->doc->newdocs[]=(object)array('title'=>$tpl['otitle']->raw,'url'=>$url);
  1354. }
  1355. foreach($r['doc']->documents as $it=>&$doc){
  1356. $url1=$self.'&moid='.$this->_moid.'&function=edit&template=xmoddocmgt/edit.html&oid='.$doc->oid.'&tplentry=br&findex2=index2';
  1357. $url2=$self.'&moid='.$this->_moid.'&function=display&template=xmoddocmgt/display.html&oid='.$doc->oid.'&tplentry=br&findex2=index2';
  1358. $o=(object)array('oid'=>$doc->oid,'tpltitle'=>$doc->tpl['otitle']->raw,'title'=>html_entity_decode($doc->title),
  1359. 'urledit'=>$url1,'urlview'=>$url2,'docs'=>$doc->countfiles>0?$doc->docs:'','upd'=>$doc->fields['oUPD']->toText(),
  1360. 'actions'=>','.implode(',',$doc->actions).',','lock'=>$doc->fields['_lock_user']
  1361. );
  1362. if(isset($doc->fields['oOWN'])) $o->own=$doc->fields['oOWN']->toText();
  1363. $ret->doc->documents[]=$o;
  1364. }
  1365. die(json_encode((object)$ret));
  1366. }
  1367. // creation des informations sur le chemin d'acces
  1368. //
  1369. protected function &mkContext($doc) {
  1370. $doco = &XDocumentDT::objectFactory($doc,$this);
  1371. $doco->getParents(10);
  1372. $doco->getAllPaths();
  1373. return $doco->paths;
  1374. }
  1375. protected function mkContext2(&$my, $doc) {
  1376. $docmode=$this->_getSession('docmode');
  1377. $doco = &XDocumentDT::objectFactory($doc,$this);
  1378. $doco->getParents(10);
  1379. $doco->getAllPaths();
  1380. foreach($doco->paths[0] as $i=>&$o) {
  1381. if($i==0){
  1382. $title=$this->modulename; // on met le titre du module en avant
  1383. $parentoid = '';
  1384. }else{
  1385. $title=$o->title;
  1386. $parentoid = 'parentoid='.$doco->paths[0][$i-1]->oid.'&';
  1387. }
  1388. if($docmode=='index2'){
  1389. $o1=new XModuleAction($this, 'i'.$i, $title,'&moid='.$this->_moid.'&_function=index2&tplentry=br&'.$parentoid.
  1390. 'template=xmoddocmgt/index3.html&tplentry=br&oid='.$o->oid);
  1391. }else{
  1392. $o1=new XModuleAction($this, 'i'.$i, $title,'&moid='.$this->_moid.'&_function=index&tplentry=br&'.$parentoid.
  1393. 'template=xmoddocmgt/index2.html&tplentry=br&oid='.$o->oid);
  1394. }
  1395. $my['stack'][]=$o1;
  1396. }
  1397. }
  1398. // creation d'un nouveau document
  1399. //
  1400. function input($ar=NULL) {
  1401. $p=new XParam($ar,array());
  1402. $doid=$p->get('doid');
  1403. $poid=$p->get('parentoid');
  1404. $tplentry=$p->get('tplentry');
  1405. // lecture du type de noeud nouveau
  1406. $xt = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'_TYPES');
  1407. $d1 = &$xt->display(array('oid'=>$doid, 'tplentry'=>TZR_RETURN_DATA));
  1408. XShell::toScreen1('brt',$d1);
  1409. $lines = explode("\n", stripslashes($d1['oopts']->toText()));
  1410. $tploptions=array();
  1411. foreach($lines as &$line) {
  1412. @list($var,$val)=explode('=',$line);
  1413. if(!empty($var) && !empty($val)) {
  1414. $var=trim($var);$val=trim($val);
  1415. $tploptions[$var]=$val;
  1416. }
  1417. }
  1418. $path = &$this->mkContext($poid);
  1419. $ar['path'] = &$path; // contexte basedoc pour le repository
  1420. // traitement d'insertion
  1421. $mod=&XDocumentDT::repositoryFactory(NULL, $d1);
  1422. if(!empty($tploptions['peremption'])) {
  1423. $ts=mktime();
  1424. $ts=$ts+$tploptions['peremption']*24*60*60;
  1425. $ar['options']['PRP']['value']=DATE('Y-m-d',$ts);
  1426. }
  1427. $ar['fmoid']=$this->_moid;
  1428. $mod->XMCinput($ar);
  1429. $br=XSHell::from_screen($tplentry);
  1430. XShell::toScreen2($tplentry, 'path', $path);
  1431. }
  1432. function registerDoc($oid, $doctype, $own=true) {
  1433. $q="SELECT COUNT(KOID) FROM {$this->id} WHERE KOID='$oid'";
  1434. $rs=selectQuery($q);
  1435. if($rs && $ors=$rs->fetch()) {
  1436. if($ors['COUNT(KOID)']<=0) {
  1437. if($own) $q='INSERT INTO '.$this->id.' SET KOID="'.$oid.'", DTYPE="'.$doctype.'", ENDO=1, DPARAM=""';
  1438. else $q='INSERT INTO '.$this->id.' SET KOID="'.$oid.'", DTYPE="'.$doctype.'", ENDO=2, DPARAM=""';
  1439. updateQuery($q);
  1440. }
  1441. }
  1442. }
  1443. function newDoc($fields, $typeoid) {
  1444. $xt = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'_TYPES');
  1445. $d1 = &$xt->display(array('oid'=>$typeoid, 'tplentry'=>TZR_RETURN_DATA));
  1446. $mod=&XDocumentDT::repositoryFactory(NULL,$d1);
  1447. $fields['_options']=array('local'=>1);
  1448. $fields['tplentry']=TZR_RETURN_DATA;
  1449. $r1=$mod->XMCprocInput($fields);
  1450. $oidres=$r1['oid'];
  1451. $this->registerDoc($oidres, $typeoid);
  1452. return $oidres;
  1453. }
  1454. // validation de la creation
  1455. //
  1456. function procInput($ar=NULL) {
  1457. $p=new XParam($ar,array());
  1458. $doid=$p->get('doid');
  1459. $auth=$this->getTypes($doid);
  1460. $noworkflow=$p->get('_noworkflow');
  1461. if(empty($auth)){
  1462. XLogs::critical('security',"access type denied |".get_class($this)."|procInput|".$this->_moid."|TYPE ".$doid.
  1463. "| user ".XUser::get_current_user_uid());
  1464. XShell::redirect2auth();
  1465. }
  1466. $parentoid=$p->get('parentoid');
  1467. if(empty($parentoid)) $parentoid=$this->rootOid();
  1468. $xt = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=_TYPES');
  1469. $d1 = &$xt->display(array('oid'=>$doid, 'tplentry'=>TZR_RETURN_DATA));
  1470. $ar['tplentry']=TZR_RETURN_DATA;
  1471. $mod=&XDocumentDT::repositoryFactory(NULL,$d1);
  1472. $r1=$mod->XMCprocInput($ar);
  1473. $oidres=$r1['oid'];
  1474. $this->registerDoc($oidres, $doid);
  1475. $docparent = &XDocumentDT::objectFactory($parentoid, $this);
  1476. $docparent->addChild($oidres);
  1477. if(XModule::getMoid(XMODWORKFLOW_TOID) && empty($noworkflow)) {
  1478. $umod=XModule::singletonFactory(XMODWORKFLOW_TOID);
  1479. $umod->checkAndRun($this, $mod, $oidres, 'new');
  1480. }
  1481. // creation des fils par clone du modele
  1482. if (!empty($d1['opattern']->raw)){
  1483. XLogs::notice(get_class($this), "Pattern");
  1484. $this->cloneChilds($d1['opattern'], $oidres);
  1485. }
  1486. return array('oid'=>$oidres);
  1487. }
  1488. // clone des fils d'un noeud
  1489. //
  1490. protected function cloneChilds($opattern, $parentoid){
  1491. // lire le modele
  1492. $pdoc = $this->index(array('tplentry'=>TZR_RETURN_DATA,
  1493. 'oid'=>$opattern->raw));
  1494. // traiter les fils du modele (dossiers)
  1495. foreach($pdoc['docs'] as $docoid=>$doc){
  1496. XLogs::notice(get_class($this), "cloneChild $doc->title $docoid");
  1497. $oidres = $doc->repository->XMCduplicate($docoid);
  1498. // creer l'id et idx
  1499. $q='insert into '.$this->idx.' set KOIDSRC="'.$oidres.'", KOIDDST="'.$parentoid.'"';
  1500. updateQuery($q);
  1501. $q='insert into '.$this->id.' set KOID="'.$oidres.'", DTYPE="'.$doc->tpl['oid'].'", ENDO=1, DPARAM=""';
  1502. updateQuery($q);
  1503. /* a voir ???
  1504. if (!empty($doc->tpl['opattern']->raw)){
  1505. $this->cloneChilds($doc->tpl['opattern'], $oidres);
  1506. }
  1507. */
  1508. }
  1509. // traiter les fils du modele (documents)
  1510. foreach($pdoc['here']->documents as $docoid=>$doc){
  1511. XLogs::notice(get_class($this), "cloneChild $doc->title $docoid");
  1512. $oidres = $doc->repository->XMCduplicate($docoid);
  1513. // creer l'id et idx
  1514. $q='insert into '.$this->idx.' set KOIDSRC="'.$oidres.'", KOIDDST="'.$parentoid.'"';
  1515. updateQuery($q);
  1516. $q='insert into '.$this->id.' set KOID="'.$oidres.'", DTYPE="'.$doc->tpl['oid'].'", ENDO=1, DPARAM=""';
  1517. updateQuery($q);
  1518. }
  1519. }
  1520. /// Edition d'un document
  1521. function edit($ar=NULL) {
  1522. $p=new XParam($ar,array());
  1523. $oid=$p->get('oid');
  1524. $tplentry=$p->get('tplentry');
  1525. $doc=&XDocumentDT::objectFactory($oid, $this);
  1526. XShell::toScreen1('brt',$doc->tpl);
  1527. $ar['fmoid']=$this->_moid;
  1528. if($this->interactive && $this->trackaccess) $ar['accesslog']=1;
  1529. $d=&$doc->repository->XMCedit($ar);
  1530. $d['path']=&$this->mkContext($oid);
  1531. $d['here']=$doc;
  1532. if($doc->tpl['oshared']->raw==1) {
  1533. $m1=XModule::modlist(array('basic'=>true,'toid'=>XMODDOCMGT_TOID,'tplentry'=>TZR_RETURN_DATA));
  1534. // s'il y a un autre module autorise que le module courant
  1535. if(count($m1['lines_oid'])>1) {
  1536. $d['modlist']=&$m1;
  1537. }
  1538. }
  1539. return XShell::toScreen1($tplentry,$d);
  1540. }
  1541. /// Prépare le partage d'un document entre plusieurs bases documentaires
  1542. function share($ar=NULL){
  1543. $p=new XParam($ar,NULL);
  1544. $oid=$p->get('oid');
  1545. $tplentry=$p->get('tplentry');
  1546. $ret=array();
  1547. $doc=&XDocumentDT::objectFactory($oid, $this);
  1548. if($doc->tpl['oshared']->raw==1) {
  1549. $ret['modlist']=XModule::modlist(array('basic'=>true,'toid'=>XMODDOCMGT_TOID,'tplentry'=>TZR_RETURN_DATA));
  1550. foreach($ret['modlist']['lines_oid'] as $i=>$moid){
  1551. $mod=XModule::objectFactory($moid);
  1552. $f=$mod->father1($oid);
  1553. foreach($f as $foid){
  1554. if($mod->secure($foid,'input')) $dest[$moid][]=XDocumentDT::objectFactory($foid,$mod);
  1555. }
  1556. }
  1557. }
  1558. $ret['doc']=$doc;
  1559. $ret['dest']=$dest;
  1560. return XShell::toScreen1($tplentry,$ret);
  1561. }
  1562. /// Partage un document avec d'autres bases documentaires
  1563. function procShare($ar=NULL){
  1564. $p=new XParam($ar,NULL);
  1565. $oid=$p->get('oid');
  1566. $share=$p->get('_share');
  1567. $doc=&XDocumentDT::objectFactory($oid, $this);
  1568. foreach($share as $moid=>$dests){
  1569. $mod=XModule::objectFactory($moid);
  1570. if(is_object($mod)){
  1571. foreach($dests as $old=>$dest){
  1572. if(empty($dest)){
  1573. if(Kernel::isAKoid($old)){
  1574. // Suppression d'un partage
  1575. if(!$mod->secure($old,'del')) continue;
  1576. $mod->del(array('_options'=>array('local'=>true),'physical'=>0,'oid'=>$oid,'parentoid'=>$old));
  1577. }
  1578. }else{
  1579. if(Kernel::isAKoid($old) && ($old!=$dest)){
  1580. // Modification d'un partage
  1581. if(!$mod->secure($dest,'input') || !$mod->secure($old,'del')) continue;
  1582. $doc2=&XDocumentDT::objectFactory($dest,$mod);
  1583. $doc2->addChild($oid);
  1584. $mod->del(array('_options'=>array('local'=>true),'physical'=>0,'oid'=>$oid,'parentoid'=>$old));
  1585. }else{
  1586. // Insertion d'un partage
  1587. if(!$mod->secure($dest,'input')) continue;
  1588. $mod->registerDoc($oid,$doc->tpl['oid']);
  1589. $doc2=&XDocumentDT::objectFactory($dest,$mod);
  1590. $doc2->addChild($oid);
  1591. }
  1592. }
  1593. }
  1594. }
  1595. }
  1596. }
  1597. /// Visualiser un document ou un repertoire
  1598. function &display($ar=NULL) {
  1599. $p=new XParam($ar,array());
  1600. $oid=$p->get('oid');
  1601. $tplentry=$p->get('tplentry');
  1602. $doc=&XDocumentDT::objectFactory($oid, $this);
  1603. XShell::toScreen1('brt',$doc->tpl);
  1604. $ar['fmoid']=$this->_moid;
  1605. if($this->interactive && $this->trackaccess) $ar['accesslog']=1;
  1606. $d=&$doc->repository->XMCdisplay($ar,false);
  1607. $d['path']=&$this->mkContext($oid);
  1608. $d['here']=$doc;
  1609. return XShell::toScreen1($tplentry,$d);
  1610. }
  1611. /// Validation de la creation
  1612. function procEdit($ar=NULL) {
  1613. $p=new XParam($ar,array());
  1614. $oid=$p->get('oid');
  1615. $share=$p->get('_share');
  1616. $noworkflow=$p->get('_noworkflow');
  1617. $doc=&XDocumentDT::objectFactory($oid, $this);
  1618. XShell::toScreen1('brt',$doc->tpl);
  1619. $doc->repository->XMCprocEdit($ar);
  1620. updateQuery('UPDATE '.$this->id.' SET UPD=NULL WHERE KOID="'.$oid.'"');
  1621. if(XModule::getMoid(XMODWORKFLOW_TOID) && empty($noworkflow)) {
  1622. $umod=XModule::singletonFactory(XMODWORKFLOW_TOID);
  1623. $umod->checkAndRun($this, $doc->repository, $oid, 'edit');
  1624. }
  1625. }
  1626. /// Journal d'un document
  1627. function journal($ar=NULL) {
  1628. $p=new XParam($ar,array());
  1629. $oid=$p->get('oid');
  1630. $tplentry=$p->get('tplentry');
  1631. $doc=&XDocumentDT::objectFactory($oid, $this);
  1632. XShell::toScreen1('brt',$doc->tpl);
  1633. $journal=$doc->journal();
  1634. $journal['_repository']['archive']=$doc->repository->archive;
  1635. $journal['_repository']['trackchanges']=$doc->repository->trackchanges;
  1636. return XShell::toScreen1($tplentry,$journal);
  1637. }
  1638. // suppression
  1639. // si physical on supprime partout y compris physiquement
  1640. // sinon on supprime physiquement si c'est le dernier lien
  1641. //
  1642. // suppression std avec secu
  1643. // si physical on supprime partout y compris physiquement
  1644. // sinon on supprime physiquement si c'est le dernier lien
  1645. //
  1646. function del($ar=NULL) {
  1647. $p=new XParam($ar,array('deldoc'=>true));
  1648. $oid=$p->get('oid');
  1649. $tplentry=$p->get('tplentry');
  1650. $selected=$p->get('_selected');
  1651. $physical=$p->get('physical');
  1652. $delshare=$p->get('delshare');
  1653. $deldoc=$p->get('deldoc');
  1654. $parentoid=$p->get('parentoid');
  1655. if(empty($selected)) {
  1656. $cnt = countSelectQuery('select COUNT(KOIDDST) from '.$this->idx.' where KOIDSRC=\''.$oid.'\'');
  1657. if($cnt<=1) {
  1658. $physical=1;
  1659. } else {
  1660. $q='delete from '.$this->idx.' where KOIDSRC="'.$oid.'" AND KOIDDST="'.$parentoid.'"';
  1661. updateQuery($q);
  1662. }
  1663. if(!empty($physical) && $physical==1) {
  1664. $doc=&XDocumentDT::objectFactory($oid, $this);
  1665. // traiter les fils s'il s'agit de répertoire
  1666. if ($doc->node == true){
  1667. $isadmin = $this->secure1($oid, ':admin', ($doc->node?'1':'2'));
  1668. // dossier vide ou admin
  1669. $v = $this->subObjects1($doc->oid, 99, false);
  1670. $coids = array_merge($v[1], $v[2]);
  1671. if (count($coids)>0 && !$isadmin){ // on n'efface que les dossiers vides
  1672. if($tplentry!=TZR_RETURN_DATA) {
  1673. $message=XLabels::getSysLabel('xmoddocmgt','deletednotempty','text');
  1674. XShell::setNext($GLOBALS['TZR_SESSION_MANAGER']::complete_self()."&oid={$oid}&moid={$this->_moid}&class=".get_class($this).
  1675. "&tplentry=br&template=xmoddocmgt/index2.html&function=index&message=".urlencode($message));
  1676. XShell::toScreen2('', 'message', $message);
  1677. }
  1678. return false;
  1679. }
  1680. // avoir les droits sur les descendants
  1681. foreach($coids as $foo=>$coid){
  1682. if (!$this->secure($coid, 'del')){
  1683. if($tplentry!=TZR_RETURN_DATA) {
  1684. $message=XLabels::getSysLabel('xmoddocmgt','deleteforbidden','text');
  1685. XShell::setNext($GLOBALS['TZR_SESSION_MANAGER']::complete_self()."&oid={$oid}&moid={$this->_moid}&class=".get_class($this).
  1686. "&tplentry=br&template=xmoddocmgt/index2.html&function=index&message=".urlencode($message));
  1687. XShell::toScreen2('', 'message', $message);
  1688. }
  1689. return false; // stop ici
  1690. }
  1691. }
  1692. // on enleve les fils
  1693. $v = $this->subObjects1($doc->oid, 2, false);
  1694. $coids = array_merge($v[1], $v[2]);
  1695. if ($coids){
  1696. foreach($coids as $foo=>$coid){
  1697. $physical = 0;
  1698. // avec phyical = 0, seul les noeuds n'ayant qu'un parent (donc ce noeud) seront enleves
  1699. // rem : on a, au dessus, verifie qu'on a les droits sur tous les descendants
  1700. $this->del(array('oid'=>$coid, 'physical'=>$physical, 'parentoid'=>$oid,
  1701. '_selected'=>array(), 'tplentry'=>TZR_RETURN_DATA));
  1702. }
  1703. }
  1704. }
  1705. // On supprime la fiche du document
  1706. if($deldoc){
  1707. // Si le document est de type commun, on parcourt toutes les bases doc pour savoir si le document doit etre supprimé ou non
  1708. if($doc->tpl['oshared']->raw==1) {
  1709. $del=true;
  1710. $mods=XModule::modlist(array('basic'=>true,'toid'=>XMODDOCMGT_TOID,'noauth'=>true));
  1711. foreach($mods['lines_oid'] as $moid) {
  1712. $mod=XModule::objectFactory($moid);
  1713. $nb=countSelectQuery('select count(*) from '.$mod->id.' where KOID="'.$oid.'"');
  1714. if($nb>0){
  1715. if(!$delshare){
  1716. // On ne veut effacer que dans la base en cours et le document est présent dans une autre base documentaire, on ne l'efface pas
  1717. $del=false;
  1718. break;
  1719. }else{
  1720. // On ne veut effacer partout et le document est présent dans une autre base documentaire, on tente de l'effacer
  1721. if($mod->secure($oid,'del')){
  1722. $ok=$mod->del(array('_options'=>array('local'=>true),'tplentry'=>TZR_RETURN_DATA,'oid'=>$oid,'deldoc'=>false,'physical'=>1));
  1723. if($del) $del=$ok;
  1724. }else{
  1725. $del=false;
  1726. }
  1727. }
  1728. }
  1729. }
  1730. if($del) $doc->del();
  1731. }else{
  1732. $doc->del();
  1733. }
  1734. }
  1735. // On supprime le noeud de la base doc
  1736. updateQuery('delete from '.$this->idx.' where KOIDSRC="'.$oid.'"');
  1737. updateQuery('delete from '.$this->id.' where KOID="'.$oid.'"');
  1738. $this->delDocFromSearchEngine($oid);
  1739. return true;
  1740. }
  1741. } else {
  1742. // RZ un document est supprimable si le pere est en ecriture et si lui-meme est en ecriture
  1743. $parentoid = $oid;
  1744. if($this->secure($oid,':rw')) {
  1745. foreach($selected as $koid=>$foo) {
  1746. if($this->secure($koid,':rw')) {
  1747. $this->del(array('oid'=>$koid, 'physical'=>$physical, 'parentoid'=>$oid, '_selected'=>array(), 'tplentry'=>TZR_RETURN_DATA));
  1748. } else {
  1749. $mess=XLabels::getSysLabel('xmoddocmgt','deleteforbidden','text');
  1750. }
  1751. }
  1752. } else {
  1753. $mess=XLabels::getSysLabel('xmoddocmgt','deleteforbidden','text');
  1754. }
  1755. }
  1756. if($tplentry!=TZR_RETURN_DATA && !XShell::hasNext()){
  1757. XShell::setNext($GLOBALS['TZR_SESSION_MANAGER']::complete_self()."&oid={$parentoid}&moid={$this->_moid}&class=".get_class($this).
  1758. "&tplentry=br&template=xmoddocmgt/index2.html&function=index&message=$mess");
  1759. }
  1760. }
  1761. function &father($oid) {
  1762. if(!isset($this->_f[$oid])) {
  1763. $set=selectQueryGetAll('SELECT * FROM '.$this->idx.','.$this->id.',_TYPES WHERE KOIDSRC="'.$oid.'" and KOIDDST='.$this->id.'.KOID and '.
  1764. $this->id.'.DTYPE=_TYPES.KOID/*X*/');
  1765. $this->_f[$oid]=array();
  1766. foreach($set as &$f1) $this->_f[$oid][$f1['KOIDDST']]=$f1;
  1767. }
  1768. return $this->_f[$oid];
  1769. }
  1770. function &father1($oid) {
  1771. if(!isset($this->_f1[$oid])) {
  1772. $set=selectQueryGetAll('SELECT KOIDDST FROM '.$this->idx.' WHERE KOIDSRC="'.$oid.'"');
  1773. $this->_f1[$oid]=array();
  1774. foreach($set as &$f1) $this->_f1[$oid][]=$f1['KOIDDST'];
  1775. }
  1776. return $this->_f1[$oid];
  1777. }
  1778. protected function getPath($oid) {
  1779. // recherche des parents
  1780. $next=$oid;
  1781. $path=array();
  1782. $i=0;
  1783. while(!empty($next)) {
  1784. $path[$i++]=$next;
  1785. $rs=selectQuery('select * from '.$this->idx.' where KOIDSRC="'.$next.'"');
  1786. $next='';
  1787. if($rs) {
  1788. $ors=$rs->fetch();
  1789. $next=$ors['KOIDDST'];
  1790. }
  1791. }
  1792. $path=array_reverse($path);
  1793. foreach($path as $i=>$koid) {
  1794. $path[$i]=&XDocumentDT::objectFactory($koid, $this);
  1795. }
  1796. return $path;
  1797. }
  1798. // id du dossier qui contient les modele
  1799. //
  1800. protected function getPatternsFolderOid(){
  1801. return $this->defaultFolderTable.':'.$this->patternSuffix;
  1802. }
  1803. // liste des modeles definis pour cette base documentaire
  1804. // -> oid du dossier
  1805. // -> description
  1806. //
  1807. public function getPatterns() {
  1808. $patternOid = $this->getPatternsFolderOid();
  1809. // verif dossier modele existe
  1810. $cnt=selectQuery('select COUNT(*) from '.$this->id.' where KOID=\''.$patternOid.'\'');
  1811. if($cnt<=0) return array();
  1812. // lecture du rep des modeles
  1813. $pf = $this->index(array('tplentry'=>TZR_RETURN_DATA,
  1814. 'oid'=>$patternOid,
  1815. 'maxlevel'=>2,
  1816. 'up'=>1,
  1817. 'down'=>1
  1818. )
  1819. );
  1820. // menu contient les dossiers fils
  1821. if (count($pf['menu']) == 0)
  1822. return array();
  1823. $docs = &$pf['docs'];
  1824. $r = array();
  1825. foreach($pf['menu'] as $foo=>&$menu){
  1826. $r[] = &$docs[$menu[0]];
  1827. }
  1828. return $r;
  1829. }
  1830. /// Recupere les infos d'un objet par l'affichage du résultat d'une recherche
  1831. public function getSearchResult($oid,$filter=NULL){
  1832. $d1=&XDocumentDT::objectFactory($oid,$this);
  1833. $type=@$filter['type'];
  1834. if(in_array($d1->tpl['oid'],$type) || empty($type)) {
  1835. $d1->getParents(2);
  1836. return $d1;
  1837. }else return false;
  1838. }
  1839. /// presentation d'un resultat de recherche dans le module
  1840. public function showSearchResult($oids) {
  1841. $_REQUEST = array(
  1842. 'function' => 'advsearch',
  1843. 'template' => 'xmoddocmgt/advsearch2.html',
  1844. 'moid' => $this->_moid,
  1845. 'tplentry' => 'br',
  1846. 'clearrequest' => 1,
  1847. 'oids' => $oids
  1848. );
  1849. $GLOBALS['XSHELL']->run();
  1850. exit;
  1851. }
  1852. /// Recherche avancée
  1853. function advsearch($ar) {
  1854. $p=new XParam($ar,array());
  1855. $oids=$p->get('oids');
  1856. $doctype=$p->get('type');
  1857. $dosearch=$p->get('dosearch');
  1858. $structsearch=$p->get("structsearch");
  1859. // Recherche des types de documents
  1860. $types=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=_TYPES');
  1861. $doctypes=&$types->browse(array('order'=>'title','pagesize'=>100, 'where'=>"modid = '".$this->_moid."'", '_local'=>true));
  1862. // Si un type est selectionné, on prepare le formulaire de recherche et on effectue la recherche si necessaire
  1863. if(!empty($doctype)) {
  1864. $disp=&$types->display(array('tplentry'=>TZR_RETURN_DATA,'oid'=>$doctype));
  1865. $mod=&XDocumentDT::repositoryFactory(NULL,$disp);
  1866. if(!empty($structsearch)) $mod->XMCquery($ar);
  1867. if(!empty($dosearch)) {
  1868. if(empty($structsearch)) {
  1869. $r1=&$this->search(array('tplentry'=>TZR_RETURN_DATA,'type'=>$doctype));
  1870. XShell::toScreen2('br','docs',$r1['modules'][$this->_moid]['lines_obj']);
  1871. } else {
  1872. $ar['tplentry']=TZR_RETURN_DATA;
  1873. $ar['pagesize']=9999;
  1874. $r1=&$mod->XMCprocQuery($ar);
  1875. }
  1876. }
  1877. }elseif(!empty($oids)){
  1878. if(!$oids[0]) $r1['lines_oid']=array_keys($oids);
  1879. else $r1['lines_oid']=$oids;
  1880. }
  1881. if(!empty($r1['lines_oid'])){
  1882. $idx=0;
  1883. foreach($r1['lines_oid'] as $oid) {
  1884. $d1=&XDocumentDT::objectFactory($oid,$this);
  1885. if(is_object($d1) && ($d1->tpl['oid']==$doctype || empty($doctype)) && $this->secure($d1->oid, 'display')) {
  1886. $docs[$idx]=$d1;
  1887. $docs[$idx]->getParents(2);
  1888. $sort[$idx]=$d1->parents[0]->parents[0]->short.$d1->parents[0]->short.$oid;
  1889. $idx++;
  1890. }
  1891. }
  1892. array_multisort($sort, $docs);
  1893. XShell::toScreen2('br','docs',$docs);
  1894. }
  1895. XShell::toScreen1('doctypes',$doctypes);
  1896. }
  1897. /// Recherche libre
  1898. function search($ar) {
  1899. $p=new XParam($ar,array());
  1900. $type=$p->get('type');
  1901. if(!is_array($type)){
  1902. if(!empty($type)) $type=array($type);
  1903. else $type=array();
  1904. }
  1905. $tplentry=$p->get('tplentry');
  1906. $ar['moidfilter']=$this->_moid;
  1907. $ar['advfilter']['type']=$type;
  1908. $searchEngine=&XSearch::objectFactory();
  1909. return $searchEngine->globalSearch($ar);
  1910. }
  1911. /// Indexation du module dans le moteur de recherche
  1912. public function _buildSearchIndex(&$searchEngine,$checkbefore=true,$limit=NULL,$cond=NULL){
  1913. $done=0;
  1914. if(!empty($cond)){
  1915. if($cond=='UPD'){
  1916. $last=XDbIni::get('lastindexation_'.$this->_moid,'val');
  1917. if(empty($last)) $last=date('2000-01-01 00:00:00');
  1918. XDbIni::set('lastindexation_'.$this->_moid,date('Y-m-d H:i:s'));
  1919. $cond=$this->id.'.UPD>="'.$last.'"';
  1920. }
  1921. $cond=' where '.$cond;
  1922. }else{
  1923. $cond='';
  1924. }
  1925. $rs=selectQuery('SELECT * FROM '.$this->id.' '.
  1926. 'left outer join '.$this->idx.' on '.$this->id.'.KOID=KOIDSRC '.
  1927. 'left outer join _TYPES on '.$this->id.'.DTYPE=_TYPES.KOID '.$cond.' order by rand()');
  1928. while($rs && ($ors=$rs->fetch())) {
  1929. XLogs::debug('XModDocMgt::buildSearchIndex: testing '.$ors['KOIDSRC']);
  1930. if($checkbefore && $searchEngine->docExists($ors['KOIDSRC'],$this->_moid,NULL)) continue;
  1931. XLogs::debug('XModDocMgt::buildSearchIndex: adding '.$ors['KOIDSRC']);
  1932. $mydoc=&XDocumentDT::objectFactory($ors['KOIDSRC'],$this,$ors);
  1933. $mydoc->addToSearchEngine($searchEngine);
  1934. $done++;
  1935. if($done%30==0){
  1936. XLogs::debug('XModDocMgt::buildSearchIndex: commit');
  1937. $searchEngine->index->commit();
  1938. }
  1939. if($limit && $done>$limit){
  1940. XLogs::debug('XModDocMgt::buildSearchIndex: break at '.$done);
  1941. break;
  1942. }
  1943. }
  1944. return true;
  1945. }
  1946. /// Daemon qui lance en particulier l'indexation des champs
  1947. protected function _daemon($at) {
  1948. if($at=="daily") {
  1949. // Verifie que les liens de la base doc pointent toujours sur un objet
  1950. $rs=selectQuery('SELECT * FROM '.$this->id);
  1951. while($rs && ($ors=$rs->fetch())) {
  1952. $table=Kernel::getTable($ors['KOID']);
  1953. $cnt=countSelectQuery('SELECT COUNT(*) FROM '.$table.' WHERE KOID="'.$ors['KOID'].'"');
  1954. if($cnt<=0) {
  1955. updateQuery('DELETE FROM '.$this->id.' WHERE KOID="'.$ors['KOID'].'"');
  1956. updateQuery('DELETE FROM '.$this->idx.' WHERE KOIDSRC="'.$ors['KOID'].'"');
  1957. updateQuery('UPDATE '.$this->idx.' SET KOIDSRC="" WHERE KOIDSRC="'.$ors['KOID'].'"');
  1958. }
  1959. }
  1960. // Supression de toutes les aretes dont les departs sont inexistants
  1961. $rs=selectQuery('SELECT KOIDSRC,KOID FROM '.$this->idx.' LEFT OUTER JOIN '.$this->id.' ON KOID=KOIDSRC WHERE ISNULL(KOID);');
  1962. while($rs && ($ors=$rs->fetch())) updateQuery('DELETE FROM '.$this->idx.' WHERE KOIDSRC="'.$ors['KOIDSRC'].'"');
  1963. }
  1964. }
  1965. /// Supprime un document de l'index
  1966. function delDocFromSearchEngine($oid) {
  1967. $se=&XSearch::objectFactory();
  1968. $se->deleteItem($oid,$this->_moid);
  1969. }
  1970. function goto1($ar=NULL) {
  1971. $p = new XParam($ar,array());
  1972. $oid=$p->get('oid');
  1973. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,true);
  1974. $moid=$this->_moid;
  1975. $rs=selectQuery('select * from '.$this->idx.','.$this->id.',_TYPES where KOIDSRC="'.$oid.'" and '.
  1976. 'KOIDSRC='.$this->id.'.KOID and '.$this->id.'.DTYPE=_TYPES.KOID');
  1977. if($ors=$rs->fetch()) {
  1978. if($ors['node']==1) {
  1979. $right= $this->secure($oid, 'index');
  1980. if(!$right) securityWarning('XModDocMgt (1)::goto1: could not access to objet '.$oid.' in module '.$moid);
  1981. header("Location: {$url}&moid=$moid&template=xmoddocmgt/index2.html&oid=$oid&function=index&tplentry=br&skip=1");
  1982. } else {
  1983. $right= $this->secure($oid, 'display');
  1984. if(!$right) securityWarning('XModDocMgt (2)::goto1: could not access to objet '.$oid.' in module '.$moid);
  1985. header("Location: {$url}&moid=$moid&function=display&template=xmoddocmgt/display.html&oid=$oid&tplentry=br&skip=1");
  1986. }
  1987. }else{
  1988. $last=XDbIni::get('xmoddocmgt:lastindexation');
  1989. if(empty($last)) $last=date('Y-m-d H:i:s',strtotime('-4 hours'));
  1990. XDbIni::set('xmoddocmgt:lastindexation',date('Y-m-d H:i:s'));
  1991. $rs=selectQuery('SELECT '.$this->idx.'.*, '.$this->id.'.*, _TYPES.* FROM '.$this->idx.','.
  1992. $this->id.',_TYPES where '.$this->id.'.UPD >= "'.$last.'" and '.
  1993. 'KOIDSRC='.$this->id.'.KOID and '.$this->id.'.DTYPE=_TYPES.KOID');
  1994. XLogs::notice(get_class($this), get_class($this)."::_daemon indexation des {$rs->rowCount()} depuis $last");
  1995. $searchEngine = XSearch::objectFactory();
  1996. while($ors=$rs->fetch()) {
  1997. if($searchEngine->docExists($ors['KOIDSRC'],$this->_moid,NULL)) continue;
  1998. $mydoc=&XDocumentDT::objectFactory($ors['KOIDSRC'],$this,$ors);
  1999. $mydoc->addToSearchEngine();
  2000. }
  2001. }
  2002. }
  2003. // rend la liste des objets qui se trouvent en dessous de cet objet,
  2004. // independamment des niveaux
  2005. //
  2006. public function &subObjects($oid) {
  2007. $subs=&$this->subObjects1($oid);
  2008. $all=array_merge($subs[1], $subs[2]);
  2009. return $all;
  2010. }
  2011. /// changement du root d'un user
  2012. public function setRootOid($ar=NULL) {
  2013. $p=new XParam($ar, array());
  2014. $oid=$p->get('oid');
  2015. $uid=XUser::get_current_user_uid();
  2016. XOpts::setSubOpt($uid, $this->_moid, 'opts', 'home', $oid);
  2017. }
  2018. /// effacement du root d'un user
  2019. public function clearRootOid($ar=NULL) {
  2020. $p=new XParam($ar, array());
  2021. $uid=XUser::get_current_user_uid();
  2022. XOpts::unsetSubOpt($uid, $this->_moid, 'opts', 'home');
  2023. }
  2024. public function rootOid() {
  2025. if(!empty($this->opts['home'])) return $this->opts['home'];
  2026. return $this->defaultFolderTable.':root-'.$this->_moid;
  2027. }
  2028. // recherche de tous les oids fils d'un objet y compris lui-meme
  2029. // si types=array(1) on ne rend que les repertoires
  2030. // si types=array(1,2) on rend tous les objets
  2031. // si types=array(2) on rend les documents seulements
  2032. //
  2033. public function &subObjects1($oid, $levels=99, $myself=true) {
  2034. if(empty($oid)) $oid=$this->rootOid();
  2035. $open=array($oid);
  2036. $node=array(1);
  2037. $level=array(1);
  2038. $oids=array('1'=>array(),'2'=>array());
  2039. $ooid=$oid;
  2040. $done=array(); /* liste des noeuds examines pour ne pas repasser dessus */
  2041. while(!empty($open)) {
  2042. $oid=array_pop($open);
  2043. $n=array_pop($node);
  2044. $l=array_pop($level);
  2045. $done[]=$oid;
  2046. if(!empty($oid)) {
  2047. if(!$this->secure1($oid, 'index',$n['node'])) continue;
  2048. $oids[$n][]=$oid;
  2049. }
  2050. if(($n==1) && ($l<$levels)) {
  2051. if(!isset($this->adjacence[$oid]))
  2052. $this->adjacence[$oid]=selectQueryGetAll('SELECT DISTINCT KOIDSRC,node,DTYPE FROM '.$this->idx.','.$this->id.
  2053. ',_TYPES WHERE KOIDDST="'.$oid.'"'.
  2054. ' AND '.$this->id.'.KOID=KOIDSRC AND '.$this->id.'.DTYPE=_TYPES.KOID');
  2055. foreach($this->adjacence[$oid] as $oid=>&$ors) {
  2056. $oid=$ors['KOIDSRC'];
  2057. if(!in_array($oid,$done) && !in_array($oid,$open)) {
  2058. $open[]=$oid;
  2059. $node[]=$ors['node'];
  2060. $level[]=$l+1;
  2061. }
  2062. }
  2063. }
  2064. }
  2065. if(!$myself) { /* on vire l'oid d'origine s'il n'est pas demande */
  2066. $dx=array_search($ooid,$oids['1']);
  2067. if(!($dx===FALSE)) {
  2068. unset($oids['1'][$dx]);
  2069. }
  2070. $dx=array_search($ooid,$oids['2']);
  2071. if(!($dx===FALSE)) {
  2072. unset($oids['2'][$dx]);
  2073. }
  2074. }
  2075. return $oids;
  2076. }
  2077. // recherche de tous les oids fils direct d'un objet (types: 1=>seulement dossier, autre=>tous)
  2078. // $myself inutile
  2079. public function &subObjects3($oid, $levels=99, $myself=true,$level=1,$types=0) {
  2080. if(empty($oid)) $oid=$this->rootOid();
  2081. if(isset($this->_s[$oid])) return $this->_s[$oid];
  2082. XLogs::debug("XModDocMgt::subObjects3: $oid");
  2083. $open=array($oid);
  2084. $node=array(1);
  2085. $oids=array('1'=>array(),'2'=>array());
  2086. if($levels==0) return $oids;
  2087. $ooid=$oid;
  2088. $done=array(); /* liste des noeuds examines pour ne pas repasser dessus */
  2089. if(!isset($this->adjacence[$oid]))
  2090. $this->adjacence[$oid]=selectQueryGetAll('SELECT DISTINCT KOIDSRC,node,DTYPE FROM '.$this->idx.' '.
  2091. 'left outer join '.$this->id.' on '.$this->id.'.KOID=KOIDSRC '.
  2092. 'left outer join _TYPES on '.$this->id.'.DTYPE=_TYPES.KOID WHERE KOIDDST="'.$oid.'" /*41*/');
  2093. foreach($this->adjacence[$oid] as $oid2=>&$ors) {
  2094. $oid2=$ors['KOIDSRC'];
  2095. if(empty($ors['node']) || empty($ors['DTYPE'])) continue;
  2096. if(($types==1) && ($ors['node']==2)) continue;
  2097. if(($ors['node']==1) && !$this->secure1($oid2, 'index', $ors['node'])) continue;
  2098. if(($ors['node']==2) && !$this->secure1($oid2, 'display', $ors['node'])) continue;
  2099. // on supprime les fils dossier qui sont vides et sur lesquels on n'a pas le droit de lecture
  2100. if($ors['node']==1){
  2101. $oidssub=&$this->subObjects3($oid2, $levels-1, true, $level+1, $types);
  2102. if(empty($oidssub['1']) && empty($oidssub['2']) && !$this->secure1($oid2, 'display', $ors['node'])) {
  2103. continue;
  2104. }
  2105. }
  2106. $oids[$ors['node']][]=$oid2;
  2107. $ors['level']=$level;
  2108. $oids['ors'][$oid2]=$ors;
  2109. }
  2110. $oids['1']=array_unique($oids['1']);
  2111. $oids['2']=array_unique($oids['2']);
  2112. $this->_s[$oid]=$oids;
  2113. if(!$myself) {
  2114. $dx=array_search($ooid,$oids['1']);
  2115. if(!($dx===FALSE)) {
  2116. unset($oids['1'][$dx]);
  2117. }
  2118. $dx=array_search($ooid,$oids['2']);
  2119. if(!($dx===FALSE)) {
  2120. unset($oids['2'][$dx]);
  2121. }
  2122. }
  2123. return $oids;
  2124. }
  2125. /// recherche de tous les oids fils lisibles d'un objet y compris lui-meme, sans tenir compte de l'action
  2126. public function &subObjects4($oid, $levels=99, $myself=true, $level=1, $types=0) {
  2127. if(empty($oid)) $oid=$this->rootOid();
  2128. if(isset($this->_s[$oid])) return $this->_s[$oid];
  2129. XLogs::debug("XModDocMgt::subObjects4: $oid");
  2130. $open=array($oid);
  2131. $node=array(1);
  2132. $oids=array('1'=>array(),'2'=>array());
  2133. if($levels==0) return $oids;
  2134. $ooid=$oid;
  2135. $done=array(); /* liste des noeuds examines pour ne pas repasser dessus */
  2136. $adj=selectQueryGetAll('SELECT DISTINCT KOIDSRC,node,DTYPE FROM '.$this->idx.' '.
  2137. 'left outer join '.$this->id.' on '.$this->id.'.KOID=KOIDSRC '.
  2138. 'left outer join _TYPES on '.$this->id.'.DTYPE=_TYPES.KOID WHERE KOIDDST="'.$oid.'" /*42*/');
  2139. foreach($adj as $ii=>&$ors) {
  2140. $oid2=$ors['KOIDSRC'];
  2141. if(empty($ors['node']) || empty($ors['DTYPE'])) continue;
  2142. if(($types==1) && ($ors['node']==2)) continue;
  2143. if(($ors['node']==1) && !$this->secure1($oid2, 'index', $ors['node'])) continue;
  2144. if(($ors['node']==2) && !$this->secure1($oid2, 'display', $ors['node'])) continue;
  2145. if(($ors['node']==1) && !$this->secure1($oid2, 'display', $ors['node'])) {
  2146. $any=$this->subObjects4_1($oid2);
  2147. // on supprime les fils qui sont vides et sur lesquels on n'a pas le droit de lecture
  2148. if(!$any) continue;
  2149. }
  2150. $oids[$ors['node']][]=$oid2;
  2151. $ors['level']=$level;
  2152. $oids['ors'][$oid2]=$ors;
  2153. }
  2154. $oids['1']=array_unique($oids['1']);
  2155. $oids['2']=array_unique($oids['2']);
  2156. $this->_s[$oid]=$oids;
  2157. if(!$myself) {
  2158. $dx=array_search($ooid,$oids['1']);
  2159. if(!($dx===FALSE)) {
  2160. unset($oids['1'][$dx]);
  2161. }
  2162. $dx=array_search($ooid,$oids['2']);
  2163. if(!($dx===FALSE)) {
  2164. unset($oids['2'][$dx]);
  2165. }
  2166. }
  2167. return $oids;
  2168. }
  2169. // recherche de tous les oids fils d'un objet y compris lui-meme
  2170. //
  2171. public function subObjects4_1($oid,$actiontotest=':ro',$types=array(1,2)) {
  2172. if(isset($this->_s1[$oid])) return $this->_s1[$oid];
  2173. XLogs::debug("XModDocMgt::subObjects4_1: $oid");
  2174. $adj=selectQueryGetAll('SELECT DISTINCT KOIDSRC,node,DTYPE FROM '.$this->idx.' '.
  2175. 'left outer join '.$this->id.' on '.$this->id.'.KOID=KOIDSRC '.
  2176. 'left outer join _TYPES on '.$this->id.'.DTYPE=_TYPES.KOID WHERE KOIDDST="'.$oid.'" /*43*/');
  2177. foreach($adj as $ii=>&$ors) {
  2178. $oid2=$ors['KOIDSRC'];
  2179. if(empty($ors['node']) || empty($ors['DTYPE'])) continue;
  2180. if(!in_array($ors['node'],$types)) continue;
  2181. // si repertoire et pas de traversee.. on saute
  2182. if(($ors['node']==1) && !$this->secure1($oid2, ':list', $ors['node'])) continue;
  2183. // si fichier et pas de lecture.. on saute
  2184. if(($ors['node']==2) && !$this->secure1($oid2, $actiontotest, $ors['node'])) continue;
  2185. // si repertoire et pas de lecture, on regarde ce qu'il y a en dessous
  2186. if(($ors['node']==1) && !$this->secure1($oid2, $actiontotest, $ors['node'])) {
  2187. if($this->subObjects4_1($oid2,$actiontotest,$types)) {
  2188. $this->_s1[$oid]=true;
  2189. return true;
  2190. }
  2191. continue;
  2192. }
  2193. $this->_s1[$oid]=true;
  2194. return true;
  2195. }
  2196. $this->_s1[$oid]=false;
  2197. return false;
  2198. }
  2199. // recherche de tous les oids et le ors fils d'un objet y compris lui-meme
  2200. // si types=array(1) on ne rend que les repertoires
  2201. // si types=array(1,2) on rend tous les objets
  2202. // si types=array(2) on rend les documents seulements
  2203. // except : tableau d'oid a exclure
  2204. //
  2205. public function &subObjects2($oid, $types=array(1,2), $levels=99, $myself=true, $actiontotest="display", $except=array()) {
  2206. $open=array($oid);
  2207. $node=array(array('node'=>1, 'KOIDSRC'=>$oid));
  2208. //$node=array();
  2209. $level=array(1);
  2210. $oids=array();
  2211. $orss=array();
  2212. $ooid=$oid;
  2213. $done=array(); /* liste des noeuds examines pour ne pas repasser dessus */
  2214. while(!empty($open)) {
  2215. $oid=array_pop($open);
  2216. $done[]=$oid;
  2217. $n=array_pop($node);
  2218. $l=array_pop($level);
  2219. if(!empty($oid)) {
  2220. if(!$this->secure1($oid,$actiontotest,$n['node'])){
  2221. if($this->subObjects4_1($oid,':rw',array(1))) {
  2222. $this->_s1[$oid]=true;
  2223. $n['noLinkTo']=false;
  2224. } else {
  2225. $n['noLinkTo']=true;
  2226. continue;
  2227. }
  2228. }
  2229. if(in_array($n['node'],$types)) {
  2230. $oids[]=$oid;
  2231. $n['level']=$l;
  2232. $orss[]=$n;
  2233. }
  2234. }
  2235. if($l<$levels) {
  2236. if(!isset($this->adjacence[$oid]))
  2237. $this->adjacence[$oid]=selectQueryGetAll('SELECT DISTINCT KOIDSRC,node,DTYPE FROM '.$this->idx.','.$this->id.
  2238. ',_TYPES WHERE KOIDDST="'.$oid.'"'.
  2239. ' AND '.$this->id.'.KOID=KOIDSRC AND '.$this->id.'.DTYPE=_TYPES.KOID');
  2240. foreach($this->adjacence[$oid] as $oid=>&$ors) {
  2241. $oid=$ors['KOIDSRC'];
  2242. if(in_array($oid,$except)) continue;
  2243. if(!in_array($oid,$open) && !in_array($oid,$done)) {
  2244. $open[]=$oid;
  2245. $node[]=$ors;
  2246. $level[]=$l+1;
  2247. }
  2248. }
  2249. }
  2250. }
  2251. if(!$myself) { /* on vire l'oid d'origine s'il n'est pas demande */
  2252. $dx=array_search($ooid,$oids);
  2253. if(!($dx===FALSE)) {
  2254. unset($oids[$dx]);
  2255. unset($orss[$dx]);
  2256. }
  2257. }
  2258. $r=array('oids'=>$oids, 'ors'=>$orss);
  2259. return $r;
  2260. }
  2261. /// Rend les x derniers documents deposés dans la base documentaire
  2262. function getLast($ar=NULL){
  2263. $p=new XParam($ar,array('nb'=>20));
  2264. $nb=$p->get('nb');
  2265. $type=$p->get('type');
  2266. $tplentry=$p->get('tplentry');
  2267. $docs=array();
  2268. if(empty($type)) $cond='1';
  2269. else $cond=' DTYPE="'.$type.'"';
  2270. $rs=selectQuery('SELECT T1.KOID FROM '.$this->id.' as T1,_TYPES WHERE '.$cond.' AND T1.DTYPE=_TYPES.KOID AND '.
  2271. 'T1.KOID!="'.$this->rootOid().'" ORDER BY T1.UPD DESC LIMIT 0,2000');
  2272. $idx=0;
  2273. while($nb-- && $rs && ($ors=$rs->fetch())){
  2274. $oid=$ors['KOID'];
  2275. if(!$this->secure($oid, 'display')){
  2276. $nb++;
  2277. continue;
  2278. }
  2279. $d1=&XDocumentDT::objectFactory($oid,$this);
  2280. $d1->getParents(2);
  2281. $sort[$idx]=$d1->parents[0]->parents[0]->short.$d1->parents[0]->short.$idx;
  2282. $docs[$idx]=$d1;
  2283. $idx++;
  2284. }
  2285. $rs->closeCursor();
  2286. array_multisort($sort,$docs);
  2287. // Liste des types et creation de la liste de pagesize disponible
  2288. $types=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=_TYPES');
  2289. $doctypes=$types->browse(array('order'=>'title','pagesize'=>100, 'tplentry'=>TZR_RETURN_DATA));
  2290. for($i=20;$i<=100;$i+=20) $pagesize[]=$i;
  2291. XShell::toScreen1('doctypes',$doctypes);
  2292. XShell::toScreen2('docs','pagesize',$pagesize);
  2293. if($tplentry==TZR_RETURN_DATA) return $docs;
  2294. else XShell::toScreen2($tplentry,'docs',$docs);
  2295. }
  2296. /// Rend les documents qui n'ont jamais été consultés
  2297. function getUnread($ar=NULL){
  2298. $p=new XParam($ar,array('nb'=>20));
  2299. $tplentry=$p->get('tplentry');
  2300. $docs=array();
  2301. $rs=selectQuery('select '.$this->id.'.* from '.$this->id.' left outer join _TYPES on _TYPES.KOID='.$this->id.'.DTYPE left outer join LOGS on '.$this->id.'.KOID=LOGS.object and LOGS.etype="access" and LOGS.user="'.XUser::get_current_user_uid().'" and LOGS.UPD>'.$this->id.'.UPD where _TYPES.node=2 and LOGS.KOID is null order by '.$this->id.'.UPD');
  2302. while($rs && $ors=$rs->fetch()){
  2303. $oid=$ors['KOID'];
  2304. if(!$this->secure($oid,'display')) continue;
  2305. $docs[]=&XDocumentDT::objectFactory($oid,$this);
  2306. }
  2307. return XShell::toScreen2($tplentry,'docs',$docs);
  2308. }
  2309. /// Marque des documents comme lu
  2310. function markAsRead($ar=NULL){
  2311. $p=new XParam($ar,NULL);
  2312. $oids=$p->get('_selected');
  2313. $selectedok=$p->get('_selectedok');
  2314. if($selectedok!='ok' || empty($oids)) $oids=$p->get('oid');
  2315. else $oids=array_keys($oids);
  2316. if(!is_array($oids)) $oids=array($oids);
  2317. foreach($oids as $i=>$oid){
  2318. XLogs::uniqueUpdate('access',$oid);
  2319. }
  2320. }
  2321. function preSubscribe($ar=NULL) {
  2322. $p=new XParam($ar,array());
  2323. $oid=$p->get("oid");
  2324. $tplentry=$p->get("tplentry");
  2325. $subdir=$p->get("subdir");
  2326. $here=XDocumentDT::objectFactory($oid, $this);
  2327. $here->getDocumentsDetails();
  2328. $br['here']=$here;
  2329. if($this->secure($here->oid, 'admin')) {
  2330. list($acl_user, $acl_grp)=XUser::getUsersAndGroups();
  2331. XShell::toScreen1('users',$acl_user);
  2332. XShell::toScreen1('grps',$acl_grp);
  2333. }
  2334. return XShell::toScreen1($tplentry, $br);
  2335. }
  2336. /// Preparation de l'impression d'un document
  2337. function prePrintDisplay($ar=NULL){
  2338. $p=new XParam($ar,NULL);
  2339. $oid=$p->get('oid');
  2340. $doc=&XDocumentDT::objectFactory($oid, $this);
  2341. $doc->repository->prePrintDisplay($ar);
  2342. }
  2343. /// Impression d'un document
  2344. function printDisplay($ar=NULL){
  2345. $p=new XParam($ar,NULL);
  2346. $oid=$p->get('oid');
  2347. $doc=&XDocumentDT::objectFactory($oid, $this);
  2348. $doc->repository->printDisplay($ar);
  2349. }
  2350. /// Abonnement à un document
  2351. function subscribe($ar=NULL) {
  2352. $p=new XParam($ar,array());
  2353. $oid=$p->get("oid");
  2354. $subdir=$p->get("subdir");
  2355. $uid=$p->get("uid");
  2356. if(empty($uid)) $uid=XUser::get_current_user_uid();
  2357. if(empty($subdir)) $subdir="0";else $subdir="1";
  2358. $xmodsub = new XModSub(array('interactive'=>false));
  2359. $xmodsub->addSub(array($uid), $this->_moid, $oid.';'.$subdir);
  2360. }
  2361. function linkTo($ar=NULL) {
  2362. $p = new XParam($ar,array());
  2363. $move=$p->get('_move');
  2364. $copy=$p->get('_copy');
  2365. $oids=array_keys($p->get('_selected'));
  2366. $oid=$p->get('oid');
  2367. if(empty($oids)) {
  2368. if(!empty($oid)) $oids=array($oid);
  2369. $parentoid=$p->get('parentoid');
  2370. if(empty($parentoid)){
  2371. $ors=selectQueryGetAll('SELECT KOIDDST FROM '.$this->idx.' WHERE KOIDSRC="'.$oid.'"');
  2372. if(count($ors)==1) $parentoid=$ors[0]['KOIDDST'];
  2373. }
  2374. } else {
  2375. $parentoid=$oid;
  2376. }
  2377. if(empty($parentoid)) $parentoid=$this->rootOid();
  2378. $oiddst=$p->get('targetoid');
  2379. // droits en ecriture sur la destination ... quel que soit le cas
  2380. if (!$this->secure1($oiddst, 'edit', 1)){
  2381. XLogs::critical(get_class($this), get_class($this).'::linkTo trying to move|copy|link to ro target '.$oiddst);
  2382. if (!empty($oid))
  2383. XShell::setNextData('oid', $oid);
  2384. XShell::setNextData('message', XLabels::getSysLabel('security.default'));
  2385. } else {
  2386. if(!empty($move)) {
  2387. // droits en ecriture sur le parent ... dans le cas du move
  2388. if (!$this->secure1($parentoid, 'edit', 1)){
  2389. XLogs::critical(get_class($this), get_class($this).'::linkTo trying to move|copy|link to ro target '.$oiddst);
  2390. if (!empty($oid))
  2391. XShell::setNextData('oid', $oid);
  2392. XShell::setNextData('message', XLabels::getSysLabel('security.default'));
  2393. } else {
  2394. foreach($oids as $i=>$oid) {
  2395. $notok=$this->subObjects2($oid,array(1,2));
  2396. if(!in_array($oiddst,$notok['oids']) && $oid!=$oiddst)
  2397. updateQuery('UPDATE '.$this->idx.' SET KOIDDST="'.$oiddst.'" WHERE KOIDSRC="'.$oid.'" AND KOIDDST="'.$parentoid.'"');
  2398. }
  2399. }
  2400. } elseif(!empty($copy)) {
  2401. foreach($oids as $i=>$oid) {
  2402. // droits en lecture sur la source : ne se produira que pour des dossiers
  2403. if (!$this->secure1($oid, 'display', 1)){
  2404. XLogs::critical(get_class($this), get_class($this).'::linkTo trying to move|copy|link not readable source '.$oid);
  2405. XShell::setNextData('message', XLabels::getSysLabel('security.default'));
  2406. continue;
  2407. }
  2408. if($oid!=$oiddst){
  2409. $this->copyTo($oid,$oiddst);
  2410. }
  2411. }
  2412. } else {
  2413. foreach($oids as $i=>$oid) {
  2414. // droits en lecture sur la source : ne se produira que pour des dossiers
  2415. if (!$this->secure1($oid, 'display', 1)){
  2416. XLogs::critical(get_class($this), get_class($this).'::linkTo trying to move|copy|link not readable source '.$oid);
  2417. XShell::setNextData('message', XLabels::getSysLabel('security.default'));
  2418. continue;
  2419. }
  2420. if($oid!=$oiddst) updateQuery('INSERT INTO '.$this->idx.' SET KOIDDST="'.$oiddst.'", KOIDSRC="'.$oid.'"');
  2421. }
  2422. }
  2423. }
  2424. }
  2425. /// Copie d'un noeud
  2426. function copyTo($oid,$oiddst){
  2427. // Duplication du noeud
  2428. $doc=XDocumentDT::objectFactory($oid, $this, NULL);
  2429. $oidres=$doc->repository->XMCduplicate(array('oid'=>$oid,'lastonly'=>false,'changeown'=>true));
  2430. updateQuery('insert into '.$this->idx.' set KOIDSRC="'.$oidres.'", KOIDDST="'.$oiddst.'"');
  2431. updateQuery('insert into '.$this->id.' set KOID="'.$oidres.'", DTYPE="'.$doc->tpl['oid'].'", ENDO=1, DPARAM=""');
  2432. // Duplication des fils
  2433. $subobj=$this->subObjects3($oid);
  2434. foreach($subobj['ors'] as $oiddoc=>$ors) $this->copyTo($oiddoc,$oidres);
  2435. }
  2436. protected function _lasttimestamp() {
  2437. $rs=selectQueryByNum('select MAX(UPD) from '.$this->id);
  2438. if($ors=$rs->fetch()) {
  2439. $rs->closeCursor();
  2440. return $ors[0];
  2441. }
  2442. return 0;
  2443. }
  2444. protected function _whatsNew($ts,$user, $group=NULL, $specs=NULL,$timestamp=NULL) {
  2445. list($koid,$subdir) = explode(';',$specs);
  2446. if($subdir) {
  2447. $subobjects=$this->subobjects1($koid,10);
  2448. $oids=$subobjects[1];
  2449. } else {
  2450. $oids=array($koid);
  2451. }
  2452. $condoid=join('","',$oids);
  2453. $rs=selectQuery('select * from '.$this->id.','.$this->idx.' where UPD>="'.$ts.'" and UPD<"'.$timestamp.'" '.
  2454. 'and KOID=KOIDSRC and (KOIDDST IN ("'.$condoid.'") OR KOIDSRC="'.$koid.'")');
  2455. $txt='';
  2456. while($rs && ($ors=$rs->fetch())) {
  2457. $oid=$ors['KOID'];
  2458. $d2=&XDocumentDT::objectFactory($oid,$this);
  2459. if(!$this->secure($d2->oid,'display')) continue;
  2460. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,false).'&moid='.$this->_moid.'&function=goto1&oid='.$oid.'&tplentry=br&template=xmoddocmgt/display.html&_direct=1';
  2461. $d1=&$d2->fields;
  2462. if(is_array($d1) && ($d1['lst_upd']['user']!=$user)) {
  2463. $when=$d1['oUPD']->raw;
  2464. $who=$d1['lst_upd']['usernam'];
  2465. $txt.='<li><a href="'.$url.'">'.$d2->title.'</a> ('.$when.', '.$who.')</li>';
  2466. }
  2467. }
  2468. return $txt;
  2469. }
  2470. // rend une chaine qui représente l'abonnement
  2471. //
  2472. function _getSubTitle($oid) {
  2473. $rs=selectQuery("select * from OPTS where KOID='$oid'");
  2474. if($rs && ($ors=$rs->fetch())) {
  2475. list($koid,$subdir)=explode(';',$ors['specs']);
  2476. if(Kernel::objectExists($koid)) {
  2477. $d1=&XDocumentDT::objectFactory($koid,$this);
  2478. $d1->getParents(10);
  2479. $path='';
  2480. foreach($d1->parents as &$doc) {
  2481. $path.=$doc->title.' > ';
  2482. }
  2483. $url=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$this->_moid.'&_function=goto1&oid='.$koid.'&tplentry=br';
  2484. if(!empty($subdir)) {
  2485. $subdir=' et sous dossiers';
  2486. } else $subdir='';
  2487. return XLabels::getSysLabel('xmoddocmgt','defaultsdir').' <A HREF="'.$url.'">'.$path.$d1->title.'</A> '.$subdir;
  2488. } else {
  2489. // l'abonnement concerne une donnee qui n'existe plus. on le supprimer
  2490. updateQuery("delete from OPTS where KOID='$oid'");
  2491. }
  2492. }
  2493. return NULL;
  2494. }
  2495. function &getTasklet() {
  2496. // recherche de tous les documents qui ont été verrouillés et qui sont en attente
  2497. $now=date("YmdHis",time());
  2498. $rs=selectQuery('select * from '.$this->id.',_LOCKS WHERE '.$this->id.'.KOID=_LOCKS.KOID AND '.
  2499. '_LOCKS.OWN="'.XUser::get_current_user_uid().'" AND _LOCKS.DEND<"'.$now.'" order by _LOCKS.DSTART ASC');
  2500. $lines=array();
  2501. $users=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'USERS');
  2502. $i=0;
  2503. $txt='';
  2504. while($ors=$rs->fetch()) {
  2505. $oid=$ors['KOID'];
  2506. $t=XDocumentDT::objectFactory($oid,$this);
  2507. if($this->secure($t->oid, 'display')) {
  2508. $url=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$this->_moid.'&_function=goto1&oid='.$oid.'&tplentry=br';
  2509. $txt.='<p>'.$t->smallicon.' <a href="'.$url.'">'.$t->short.'</A> réservé le '.XDateTimeDef::dateFormat($t->fields['_lock']['DSTART']).' jusqu\'au '.XDateTimeDef::dateFormat($t->fields['_lock']['DEND']).'</p>';
  2510. }
  2511. }
  2512. if(!empty($txt)) $txt='<h2>Vos réservations de documents en cours</h2><div>'.$txt.'</div>';
  2513. return $txt;
  2514. }
  2515. function chk($message) {
  2516. // OID,OID type,Nom type,Nom dossier,OID destination,Module,Node type
  2517. $idtocheck=array(array($this->defaultFolderTable.':root-'.$this->_moid,'_TYPES:root-'.$this->_moid,'Root','Dossiers',NULL,$this->_moid,1));
  2518. /*
  2519. array($this->defaultFolderTable.':lostandfound','_TYPES:lostandfound','Lost and found','Perdus ou retrouvés', $rootoid),
  2520. array($this->defaultFolderTable.':trash','_TYPES:trash','Trash','Poubelle',$rootoid),
  2521. array($this->defaultFolderTable.':archives','_TYPES:archives','Archives','Archives',$rootoid));
  2522. */
  2523. foreach($idtocheck as $idsbis) {
  2524. $rootid=$idsbis[0];
  2525. $roottemplateid=$idsbis[1];
  2526. if($rootid){
  2527. // Creation dans $this->id
  2528. $cnt=countSelectQuery('SELECT COUNT(*) FROM '.$this->id.' WHERE KOID="'.$rootid.'"');
  2529. if(!$cnt) {
  2530. updateQuery('INSERT INTO '.$this->id.' SET KOID="'.$rootid.'", DTYPE="'.$roottemplateid.'", ENDO=0, UPD=NULL');
  2531. }
  2532. // Création dans la table des repertoires
  2533. $cnt=countSelectQuery('SELECT COUNT(*) FROM '.$this->defaultFolderTable.' WHERE KOID="'.$rootid.'"');
  2534. if(!$cnt) {
  2535. updateQuery('INSERT INTO '.$this->defaultFolderTable.' SET KOID="'.$rootid.'", UPD=NULL, LANG="'.TZR_DEFAULT_LANG.'",'.
  2536. 'title="'.$idsbis[3].'"');
  2537. }
  2538. }
  2539. // Création type
  2540. $cnt=countSelectQuery('SELECT COUNT(*) FROM _TYPES WHERE KOID="'.$roottemplateid.'"');
  2541. if(!$cnt) {
  2542. updateQuery('INSERT INTO _TYPES SET KOID="'.$roottemplateid.'", LANG="'.TZR_DEFAULT_LANG.'", modid="'.$idsbis[5].'",'.
  2543. 'UPD=NULL, dtab="'.$this->defaultFolderTable.'", node='.$idsbis[6].', title="'.$idsbis[2].'"');
  2544. }
  2545. // Création dans $this->idx
  2546. if(!empty($idsbis[4])) {
  2547. $cnt=countSelectQuery('SELECT COUNT(*) FROM '.$this->idx.' WHERE KOIDSRC="'.$rootid.'"');
  2548. if(!$cnt) {
  2549. updateQuery('INSERT INTO '.$this->idx.' SET KOIDSRC="'.$rootid.'", '.
  2550. 'KOIDDST="'.$idsbis[4].'"');
  2551. }
  2552. }
  2553. }
  2554. updateQuery('update '.$this->idx.' set KOIDDST="'.$this->rootOid().'" where KOIDDST is NULL or KOIDDST=""');
  2555. updateQuery('update '.$this->idx.' set KOIDDST="'.$this->rootOid().'" where KOIDDST ="'.$this->defaultFolderTable.':0"');
  2556. return true;
  2557. }
  2558. /// recherche fils de niveau d'accès demandé, parent supposé accessible
  2559. /// parcours de toute l'arborescence pour l'élaguer en plaçant des règles dans le cache des acl
  2560. public function hasSubObject($oid, $levels=99, $user=null, $right=':ro') {
  2561. if(empty($oid)) $oid=$this->rootOid();
  2562. $open=array($oid);
  2563. $node=array(1);
  2564. $level=array(1);
  2565. $ooid=$oid;
  2566. $done=array(); /* liste des noeuds examines pour ne pas repasser dessus */
  2567. $return = false;
  2568. $this->adjacence = selectQuery('SELECT DISTINCT KOIDDST,KOIDDST,KOIDSRC,node,DTYPE FROM '.$this->idx.','.$this->id.',_TYPES '.
  2569. 'WHERE '.$this->id.'.KOID=KOIDSRC AND '.$this->id.'.DTYPE=_TYPES.KOID')->fetchAll(PDO::FETCH_GROUP);
  2570. while(!empty($open)) {
  2571. $oid=array_pop($open);
  2572. $n=array_pop($node);
  2573. $l=array_pop($level);
  2574. $done[]=$oid;
  2575. $acls[$oid] = array(
  2576. $right => XUser::secure8oid($right, $this, $oid, $user, null, true),
  2577. ':rw' => XUser::secure8oid(':rw', $this, $oid, $user, null, true),
  2578. );
  2579. if($n==1 && $l<$levels && XUser::secure8oid('index', $this, $oid, $user, null, true)) {
  2580. $acls[$oid]['index'] = true;
  2581. foreach($this->adjacence[$oid] as $ors) {
  2582. $childOid=$ors['KOIDSRC'];
  2583. $this->_f1[$childOid][] = $oid; // _f1 cache des parents
  2584. if(!in_array($childOid,$done) && !in_array($childOid,$open)){
  2585. $open[]=$childOid;
  2586. $node[]=$ors['node'];
  2587. $level[]=$l+1;
  2588. }
  2589. }
  2590. }
  2591. }
  2592. $acls = $this->_acls($ooid, $acls, $right);
  2593. foreach ($acls as $oid => $acl) {
  2594. $return |= $acl['visible'];
  2595. if (!$acl['visible'] && !$acl[$right] && !$acl[':rw']) {
  2596. $need = false;
  2597. foreach ($this->_f1[$oid] as $parentOid) // si un parent est visible, on a besoin de la règle
  2598. $need |= $acls[$parentOid]['visible'];
  2599. if ($need) {
  2600. XUser::setCache(null, 'index', null, $this->_moid, $oid, 0, 'hasSubObject', 'none');
  2601. XUser::setCache(null, ':list', null, $this->_moid, $oid, 0, 'hasSubObject', 'none');
  2602. }
  2603. }
  2604. }
  2605. return $return;
  2606. }
  2607. /// calcul la visibilité
  2608. private function _acls($oid, $acls, $right) {
  2609. foreach ($this->adjacence[$oid] as $node) {
  2610. $nodeoid = $node['KOIDSRC'];
  2611. if ($node['node'] == 1 && !isset($acls[$nodeoid]['visible']))
  2612. $acls = $this->_acls($nodeoid, $acls, $right);
  2613. // visible si un fils visible ou lecture ou plus
  2614. $acls[$oid]['visible'] |= ($acls[$nodeoid][$right] || $acls[$nodeoid][':rw']
  2615. || $acls[$nodeoid]['visible']);
  2616. }
  2617. return $acls;
  2618. }
  2619. // Alias de secure pour garder la compatibilité d'avant la refonte de droits
  2620. function secure1($oid, $function, $node=0, &$user=NULL) {
  2621. return parent::secure($oid,$function,$user);
  2622. }
  2623. /// ok si accessible et non vide (cas des dossier)
  2624. function secureNotEmpty($oid, $function, $user=null, $lang=TZR_DEFAULT_LANG) {
  2625. if (XShell::isRoot())
  2626. return true;
  2627. return $this->hasSubObject($oid, 99, $user, ':ro');
  2628. }
  2629. /// Définit si la sécurité sur les objets est activé
  2630. public function objectSecurityEnabled(){
  2631. if($this->object_sec || $this->documentssec) return true;
  2632. return false;
  2633. }
  2634. /// Définit si le cache des droits doit être activé ou pas.
  2635. public function rightCacheEnabled(){
  2636. return $this->objectSecurityEnabled();
  2637. }
  2638. /// Retourne le parent direct de chaque oid passé en paramètre
  2639. public function getParentsOids($oids){
  2640. $ret=array();
  2641. foreach($oids as $oid){
  2642. if(!$oid) continue;
  2643. $parents=$this->father1($oid);
  2644. if(!$parents) $ret[]='';
  2645. else $ret=array_merge($ret,$parents);
  2646. }
  2647. return $ret;
  2648. }
  2649. // telechargement dans un zip d'un ensembl de documents
  2650. function documentsDownload($ar=NULL) {
  2651. $p=new XParam($ar,array());
  2652. $selected=$p->get('_selected');
  2653. if(empty($selected)) $selected=array($p->get('oid')=>1);
  2654. $dir=TZR_TMP_DIR.'download-'.uniqid();
  2655. @mkdir($dir);
  2656. $nbfiles=0;
  2657. foreach($selected as $koid=>$foo) {
  2658. $doc=&XDocumentDT::objectFactory($koid, $this);
  2659. $details=$doc->getFilesDetails();
  2660. $asciify=rewriteToAscii($doc->title);
  2661. $path=$dir.'/'.$asciify;
  2662. @mkdir($path);
  2663. foreach($details as &$e) {
  2664. copy($e['filename'], $path.'/'.$e['name']);
  2665. $nbfiles++;
  2666. }
  2667. }
  2668. exec('(cd '.$dir.';zip -r '.$dir.'.zip .)2>&1 > '.TZR_TMP_DIR.'errorlog');
  2669. $size=filesize($dir.'.zip');
  2670. header('Content-type: application/zip');
  2671. header('Content-disposition: attachment; filename=download.zip');
  2672. header('Accept-Ranges: bytes');
  2673. header('Content-Length: '.$size);
  2674. @readfile($dir.'.zip');
  2675. XDir::unlink($dir);
  2676. unlink($dir.'.zip');
  2677. exit(0);
  2678. }
  2679. function &portlet2() {
  2680. $txt ='<h1>'.$this->modulename.'</h1>';
  2681. $txt.='<p><form action="'.$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'" method="post" onsubmit="return TZR.ajaxSubmitForm(this,\'#cv8-content\');">';
  2682. $txt.='<input type="hidden" name="moid" value="'.$this->_moid.'">';
  2683. $txt.='<input type="hidden" name="function" value="search">';
  2684. $txt.='<input type="hidden" name="template" value="xmoddocmgt/query2.html">';
  2685. $txt.='<input type="hidden" name="tplentry" value="br">';
  2686. $txt.='<input type="text" name="query">';
  2687. $txt.='<input type="submit" value="'.XLabels::getSysLabel('xmoddocmgt','search','text').'">';
  2688. $txt.='</form></p>';
  2689. return $txt;
  2690. }
  2691. function &export($ar=NULL) {
  2692. $p=new XParam($ar, array());
  2693. $o['ftphost']=$p->get('ftphost');
  2694. $o['ftpuser']=$p->get('ftpuser');
  2695. $o['ftppass']=$p->get('ftppass');
  2696. $o['ftproot']=$p->get('ftproot');
  2697. $o['oid']=$p->get('oid');
  2698. $o['function']='exportBatch';
  2699. $scheduler= new XModScheduler(array('tplentry'=>TZR_RETURN_DATA));
  2700. $roid=$scheduler->createJob($this->_moid, NULL,'Export XModDoc',$o,'', NULL, NULL);
  2701. XShell::toScreen2('br','message','L\'export de données a été programmé et sera rapidement disponible');
  2702. }
  2703. function exportBatch(XModScheduler &$scheduler, &$o, &$more) {
  2704. $ftphost=$more->ftphost;
  2705. $ftpuser=$more->ftpuser;
  2706. $ftppass=$more->ftppass;
  2707. $ftproot=$more->ftproot;
  2708. $oid=$more->oid;
  2709. $this->exportFTP(array('ftphost'=>$ftphost, 'ftpuser'=>$ftpuser, 'ftppass'=>$ftppass, 'ftproot'=>$ftproot,
  2710. 'oid'=>$oid,'tplentry'=>TZR_RETURN_DATA));
  2711. }
  2712. function &exportFTP($ar=NULL) {
  2713. $p=new XParam($ar, array());
  2714. $ftphost = $p->get('ftphost');
  2715. $ftpuser = $p->get('ftpuser');
  2716. $ftppass = $p->get('ftppass');
  2717. $ftproot = $p->get('ftproot');
  2718. $oid = $p->get('oid');
  2719. if(empty($oid)) $oid=$this->rootOid();
  2720. $ftphost=str_replace('ftp://','',$ftphost);
  2721. $conn_id = ftp_connect($ftphost);
  2722. if (!$conn_id) return 'Unable to connect to '.$ftphost;
  2723. $login_result = ftp_login($conn_id, $ftpuser, $ftppass);
  2724. if(!$login_result) return 'Error logging into '.$ftphost;
  2725. if(!empty($ftproot)) {
  2726. ftp_mkdir($conn_id, $ftproot);
  2727. ftp_chdir($conn_id, $ftproot);
  2728. }
  2729. $this->exportFTP1($conn_id, $oid);
  2730. ftp_close($conn_id);
  2731. }
  2732. function &exportFTP1(&$conn_id, $oid) {
  2733. $br=$this->index(array('tplentry'=>TZR_RETURN_DATA, 'oid'=>$oid));
  2734. $node=&$br['here'];
  2735. $title=$node->title;
  2736. $title=cleanFilename($title);
  2737. ftp_mkdir($conn_id, $title);
  2738. ftp_chdir($conn_id, $title);
  2739. foreach($node->dirsoids as $i=>$oid1) {
  2740. $this->exportFTP1($conn_id, $oid1);
  2741. }
  2742. foreach($node->docsoids as $i=>$oid1) {
  2743. $this->exportFTP2($conn_id, $oid1);
  2744. }
  2745. ftp_cdup($conn_id);
  2746. }
  2747. /// export d'un document de type document
  2748. function &exportFTP2(&$conn_id, $oid) {
  2749. $node=&XDocumentDT::objectFactory($oid, $this);
  2750. $details=$node->getFilesDetails();
  2751. $asciify=rewriteToAscii($node->title);
  2752. $dir=TZR_TMP_DIR.'download-'.uniqid();
  2753. @mkdir($dir);
  2754. $path=$dir.'/'.$asciify;
  2755. @mkdir($path);
  2756. $xt = new XTemplate(TZR_SHARE_DIR.'xmoddocmgt/template-display.txt');
  2757. $tpldata['br']=&$node->repository->XMCdisplay(array('oid'=>$oid, 'tplentry'=>TZR_RETURN_DATA));
  2758. $r3=array();
  2759. $notice=$xt->parse($tpldata,$r3,NULL);
  2760. foreach($details as &$e) {
  2761. copy($e['filename'], $path.'/'.$e['name']);
  2762. $nbfiles++;
  2763. }
  2764. file_put_contents($path.'/notice.txt', $notice);
  2765. exec('(cd '.$dir.';zip -r '.$dir.'.zip .)2>&1 > '.TZR_TMP_DIR.'errorlog');
  2766. ftp_put ($conn_id, $asciify.'.zip', $dir.'.zip', FTP_BINARY);
  2767. XDir::unlink($dir);
  2768. unlink($dir.'.zip');
  2769. }
  2770. /// liste des tables utilisees par ce module
  2771. function tablesToTrack() {
  2772. $rs=selectQuery('SELECT distinct dtab FROM _TYPES');
  2773. $res=array();
  2774. while($rs && $ors=$rs->fetch()) {
  2775. if(!empty($ors['dtab'])) $res[]=$ors['dtab'];
  2776. }
  2777. return $res;
  2778. }
  2779. /// Recupere des infos sur le module : nom (modulename), nombre d'enregistrement (cnt), espace occupé (size)
  2780. function getInfos($ar=NULL){
  2781. $p=new XParam($ar,array('tplentry'=>TZR_RETURN_DATA));
  2782. $tplentry=$p->get('tplentry');
  2783. $ar['tplentry']=TZR_RETURN_DATA;
  2784. $ret=parent::getInfos($ar);
  2785. // Nombre de documents
  2786. $ret['infos']['cnt']=(object)array('label'=>XLabels::getSysLabel('xmoddocmgt','docs','text'),
  2787. 'html'=>$ret['cnt']=countSelectQuery('select count(*) from '.$this->id));
  2788. // Espace occupé
  2789. $tabs=$this->usedMainTables();
  2790. $tot=0;
  2791. foreach($tabs as $t){
  2792. $s=XDbIni::get('xmodadmin:workspacesize_'.$t,'val');
  2793. if($s===NULL){
  2794. $tot=NULL;
  2795. continue;
  2796. }
  2797. $tot+=$s*1024;
  2798. }
  2799. $ret['infos']['size']->label=XLabels::getSysLabel('xmodule','workspace','text');
  2800. if($tot!==NULL){
  2801. $ret['size'] = $tot;
  2802. $ret['infos']['size']->html=getStringBytes($ret['size']);
  2803. }
  2804. else $ret['infos']['size']->html=XLabels::getSysLabel('xmodule','infonotcalculate','text');
  2805. return XShell::toScreen1($tplentry,$ret);
  2806. }
  2807. }
  2808. ?>