PageRenderTime 95ms CodeModel.GetById 19ms RepoModel.GetById 1ms app.codeStats 1ms

/class.xmodtable.inc

https://github.com/jcplat/console-seolan
PHP | 4658 lines | 4000 code | 247 blank | 411 comment | 778 complexity | 55424be8b9a6697202b4b2a0f9d9c4c8 MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause
  1. <?php
  2. /****c* tzr-5/XModTable
  3. * NAME
  4. * XModTable -- gestion d'un ensemble de fiches
  5. * DESCRIPTION
  6. * Affichage edition et manipulations diverses sur une ensemble de fiches.
  7. * SYNOPSIS
  8. * La creation d'un module est realisee par utilisation de la methode de classe XModule::objectFactory.
  9. * PARAMETERS
  10. ****/
  11. /// Module de gestion de fiches, base sur une simple table SQL
  12. class XModTable extends XModule implements XModuleContainerInterface, XCalInterface {
  13. static $_templates;
  14. public $xset=NULL;
  15. public $fieldssec=array();
  16. public $boid;
  17. public $table='T001';
  18. public $multipleedit=true;
  19. public $owner_sec=true;
  20. public $filter='';
  21. public $order='UPD DESC';
  22. public $quickquery=true;
  23. public $stored_query=false;
  24. public $pagesize=TZR_XMODTABLE_BROWSE_PAGESIZE;
  25. public $templates='';
  26. public $btemplates='';
  27. public $captcha=false;
  28. public $savenext='standard';
  29. public $showsystprop='show';
  30. public $persistentquery=false;
  31. public $trackaccess=false;
  32. public $trackchanges=true;
  33. public $archive=false;
  34. public $searchtemplate='xmodtable/searchResult.html';
  35. public $submodsearch=false;
  36. private $secOids_cache;
  37. private $navActions = NULL;
  38. function __construct($ar=NULL) {
  39. parent::__construct($ar);
  40. XLabels::loadLabels('xmodtable');
  41. $this->xset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->table);
  42. if (!is_object($this->xset)) {
  43. throw new Exception('Non existent table: "'.$this->table.'"');
  44. }
  45. $this->boid=$this->xset->getBoid();
  46. if(XShell::admini_mode() && empty($this->_templates) && (!empty($this->templates) || !empty($this->btemplates)))
  47. $this->_templates=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=TEMPLATES');
  48. if(!XShell::isRoot() && !empty($GLOBALS['XUSER'])) $this->loadFieldsSec($this->fieldssec);
  49. }
  50. /// Duplication d'un module, méthode interne
  51. /// Retour : duplicatetables => liste des tables dupliquées par le module (cle : ancienne table, valeur : nouvelle table))
  52. /// Retour : duplicatemods => liste des modules dupliqués par le module (cle : ancien moid, valeur : nouveau moid))
  53. function _duplicateModule($newmoid,&$params,$prefix) {
  54. if(!is_array($params['tables'])) $params['tables']=array();
  55. if(!$params['noduplicatetable']){
  56. if(empty($params['tables'][$this->table])){
  57. $ar['newtable']=XDSTable::newTableNumber();
  58. if(($pos=strpos($this->xset->getLabel(),':'))!==false) $ar['mtxt']=$prefix.substr($this->xset->getLabel(),$pos);
  59. else $ar['mtxt']=$prefix.':'.$this->xset->getLabel();
  60. $ar['data']=true;
  61. $ar['_options']=array('local'=>1);
  62. $xset2=$this->xset->procDuplicateDataSource($ar);
  63. $params['table']=$ar['newtable'];
  64. }else{
  65. $params['table']=$params['tables'][$this->table];
  66. }
  67. }
  68. unset($params['noduplicatetable']);
  69. return array('duplicatetables'=>array($this->table=>$params['table']),'duplicatemods'=>array());
  70. }
  71. /// securite des fonctions accessibles par le web
  72. function secGroups($function, $group=NULL) {
  73. $g=array();
  74. $g['browse']=array('list','ro','rw','rwv','admin');
  75. $g['browseFiles']=array('list','ro','rw','rwv','admin');
  76. $g['del']=array('rw','rwv','admin');
  77. $g['delAll']=array('rw','rwv','admin');
  78. $g['delStoredQuery']=array('rw','rwv','admin');
  79. $g['display']=array('ro','rw','rwv','admin');
  80. $g['XMCdisplay']=array('ro','rw','rwv','admin');
  81. $g['edit']=array('rw','rwv','admin');
  82. $g['editSelection']=array('rw','rwv','admin');
  83. $g['editAll']=array('rw','rwv','admin');
  84. $g['export']=array('list','ro','rw','rwv','admin');
  85. $g['exportDisplay']=array('ro','rw','rwv','admin');
  86. $g['exportFilesBatch']=array('ro','rw','rwv','admin');
  87. $g['gDisplay']=array('admin');
  88. $g['insert']=array('rw','rwv','admin');
  89. $g['journal']=array('ro','rw','rwv','admin');
  90. $g['prePrintBrowse']=array('list','ro','rw','rwv','admin');
  91. $g['prePrintDisplay']=array('list','ro','rw','rwv','admin');
  92. $g['preExportBrowse']=array('list','ro','rw','rwv','admin');
  93. $g['preExportDisplay']=array('list','ro','rw','rwv','admin');
  94. $g['printBrowse']=array('list','ro','rw','rwv','admin');
  95. $g['printDisplay']=array('ro','rw','rwv','admin');
  96. $g['procEdit']=array('rw','rwv','admin');
  97. $g['procEditDup']=array('rw','rwv','admin');
  98. $g['procEditAllLang']=array('rw','rwv','admin');
  99. $g['procEditSelection']=array('rw','rwv','admin');
  100. $g['procInsert']=array('rw','rwv','admin');
  101. $g['procQuery']=array('list','ro','rw','rwv','admin');
  102. $g['procQueryFiles']=array('list','ro','rw','rwv','admin');
  103. $g['publish']=array('rwv','admin');
  104. $g['query']=array('list', 'ro','rw','rwv','admin');
  105. $g['quickquery']=array('list','ro','rw','rwv','admin');
  106. $g['adminSubscribe']=array('admin');
  107. $g['getUnread']=array('list','ro','rw','rwv','admin');
  108. $g['markAsRead']=array('list','ro','rw','rwv','admin');
  109. self::getGetAdminSecGroups($g);
  110. if(isset($g[$function])) {
  111. if(!empty($group)) return in_array($group, $g[$function]);
  112. return $g[$function];
  113. }
  114. return parent::secGroups($function,$group);
  115. }
  116. /// Complete le tableau des focntion du module avec les fonction d'administration
  117. function getGetAdminSecGroups(&$g){
  118. $g['adminBrowseFields']=array('admin');
  119. $g['adminPrint']=array('admin');
  120. $g['adminClear']=array('admin');
  121. $g['adminDuplicate']=array('admin');
  122. $g['adminProcDuplicate']=array('admin');
  123. $g['adminChk']=array('admin');
  124. $g['adminEditSourceProperties']=array('admin');
  125. $g['adminProcEditSourceProperties']=array('admin');
  126. $g['adminNewField']=array('admin');
  127. $g['adminProcNewField']=array('admin');
  128. $g['adminEditField']=array('admin');
  129. $g['adminProcEditField']=array('admin');
  130. $g['adminProcEditFields']=array('admin');
  131. $g['adminDelField']=array('admin');
  132. $g['adminBrowseStrings']=array('admin');
  133. $g['adminNewString']=array('admin');
  134. $g['adminProcNewString']=array('admin');
  135. $g['adminEditString']=array('admin');
  136. $g['adminProcEditString']=array('admin');
  137. $g['adminDelString']=array('admin');
  138. $g['adminSortStrings']=array('admin');
  139. $g['adminClearStrings']=array('admin');
  140. $g['adminPreImportFieldsSec']=array('admin');
  141. $g['adminImportFieldsSec']=array('admin');
  142. $g['adminResetChrono']=array('admin');
  143. }
  144. /* Webservice du module */
  145. /// Sous fonction chargée d'ajouter les types necessaires
  146. function _SOAPWSDLTypes(&$wsdl){
  147. $fields=array(array('minOccurs'=>1,'maxOccurs'=>1,'name'=>'oid','type'=>'xsd:string'));
  148. foreach($this->xset->desc as $n=>&$f){
  149. $type=$f->getSoapType();
  150. $fields[]=array('minOccurs'=>0,'maxOccurs'=>1,'name'=>$n,'type'=>$type['name']);
  151. if(!empty($type['descr'])) $this->_SOAPAddTypes($wsdl,$type['descr']);
  152. }
  153. $this->_SOAPAddTypes($wsdl,array('browseParam'=>array(array('name'=>'filter','minOccurs'=>0,'maxOccurs'=>1,'type'=>'xsd:string'),
  154. array('name'=>'fields','minOccurs'=>0,'maxOccurs'=>1,'type'=>'xsd:string')),
  155. 'displayParam'=>array(array('name'=>'oid','minOccurs'=>1,'maxOccurs'=>1,'type'=>'xsd:string')),
  156. 'displayResult'=>$fields,
  157. 'browseResult'=>array(array('name'=>'line','minOccurs'=>0,'maxOccurs'=>'unbounded','type'=>'tns:displayResult'))));
  158. return;
  159. }
  160. /// Sous fonction chargée d'ajouter les messages necessaires
  161. function _SOAPWSDLMessages(&$wsdl){
  162. $wsdl->addMessage('browseIn',array('context'=>'tns:contextParam','param'=>'tns:browseParam'));
  163. $wsdl->addMessage('browseOut',array('return'=>'tns:browseResult'));
  164. $wsdl->addMessage('displayIn',array('context'=>'tns:contextParam','param'=>'tns:displayParam'));
  165. $wsdl->addMessage('displayOut',array('return'=>'tns:displayResult'));
  166. return;
  167. }
  168. /// Sous fonction chargée d'ajouter les ports necessaires
  169. function _SOAPWSDLPortOps(&$wsdl,&$pt){
  170. $wsdl->addPortOperation($pt,'browse','tns:browseIn','tns:browseOut');
  171. $wsdl->addPortOperation($pt,'display','tns:displayIn','tns:displayOut');
  172. return;
  173. }
  174. /// Sous fonction chargée d'ajouter les operations necessaires
  175. function _SOAPWSDLBindingOps(&$wsdl,&$b){
  176. $bo=$wsdl->addBindingOperation($b,'browse',array('use'=>'literal'),array('use'=>'literal'));
  177. $o=$wsdl->addSoapOperation($bo,'');
  178. $o->setAttribute('style','rpc');
  179. $bo=$wsdl->addBindingOperation($b,'display',array('use'=>'literal'),array('use'=>'literal'));
  180. $o=$wsdl->addSoapOperation($bo,'');
  181. $o->setAttribute('style','rpc');
  182. return;
  183. }
  184. /// Sous fonction declarant les fonctions du module
  185. function _SOAPRequestFunctions(&$server) {
  186. function browse($context,$params){
  187. global $soapmod;
  188. $LANG_DATA = XShell::getLangData();
  189. XLogs::debug("SOAPRequest function browse LANG:$LANG_DATA filter:".$params->filter." fields:".$params->fields);
  190. $soapmod->SOAPContext($context,'browse');
  191. $ar=array('tplentry'=>TZR_RETURN_DATA,'pagesize'=>999999);
  192. if(!empty($params->fields)){
  193. if($params->fields=='all' || $params->fields=='*') $ar['selectedfields']='all';
  194. else $ar['selectedfields']=explode(',',$params->fields);
  195. }
  196. if(!empty($params->filter)){
  197. $translatable = $soapmod->xset->getTranslatable();
  198. if(!$translatable) $LANG_DATA=TZR_DEFAULT_LANG;
  199. $ar['select']='select * from '.$soapmod->table.' where LANG="'.$LANG_DATA.'" AND ('.str_ireplace(' select ','',$params->filter).')';
  200. }
  201. $ar['nocount'] = 1;
  202. foreach($ar['selectedfields'] as $fieldname){
  203. $ar['options'][$fieldname]['nofollowlinks']=1;
  204. }
  205. $br=$soapmod->browse($ar);
  206. $lines=array();
  207. foreach($br['lines_oid'] as $i=>$oid){
  208. $line=array('oid'=>$oid);
  209. foreach($br['header_fields'] as $j=>&$f){
  210. $line[$f->field]=$br['lines_o'.$f->field][$i]->getSoapValue();
  211. }
  212. $lines[]=$line;
  213. }
  214. return array('line'=>$lines);
  215. }
  216. function display($context,$params){
  217. global $soapmod;
  218. XLogs::debug("SOAPRequest function display oid:".$params->oid);
  219. $soapmod->SOAPContext($context,'display',$params->oid);
  220. $ar=array('tplentry'=>TZR_RETURN_DATA,'oid'=>$params->oid);
  221. $br=$soapmod->display($ar);
  222. $ret=array('oid'=>$br['oid']);
  223. foreach($br['fields_object'] as $j=>&$f){
  224. $ret[$f->field]=$br['o'.$f->field]->getSoapValue();
  225. }
  226. return $ret;
  227. }
  228. $server->addFunction(array('browse','display'));
  229. }
  230. /// Rend la liste des fonctions utilisables dans le gestionnaire de rubriques en mode fonction (tableau de paires fonction=>label)
  231. function getUIFunctionList() {
  232. return array('display'=>XLabels::getSysLabel('xmodtable','uidisplay','text'),
  233. 'procQuery'=>XLabels::getSysLabel('xmodtable','uiquery','text'),
  234. 'insert'=>XLabels::getSysLabel('xmodtable','uiinsert','text'));
  235. }
  236. /// Suppression du module
  237. function delete($ar=NULL) {
  238. return parent::delete($ar);
  239. }
  240. /// Initialisation des propriétés
  241. public function initOptions() {
  242. parent::initOptions();
  243. $genlabel=XLabels::getSysLabel('xmodule.general');
  244. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','multipleedit'),'multipleedit','boolean',NULL,NULL,$genlabel);
  245. $slabel=XLabels::getSysLabel('general','security','text');
  246. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','owner_sec'),'owner_sec','boolean',NULL,NULL,$slabel);
  247. $alabel = XLabels::getSysLabel('xmodtable.modulename');
  248. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','table'),'table','table',array('validate'=>true),NULL,$alabel);
  249. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','filter'),'filter','text',NULL,NULL,$alabel);
  250. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.order'),'order','text',NULL,NULL,$alabel);
  251. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.quickquery'),'quickquery','boolean',NULL,NULL,$alabel);
  252. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.stored_query'),'stored_query','boolean',NULL,NULL,$alabel);
  253. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.pagesize'),'pagesize','text',NULL,NULL,$alabel);
  254. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.templates'),'templates','template',array('moid'=>$this->_moid, 'cond'=>"(gtype like '%')"),
  255. NULL,$alabel);
  256. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.btemplates'),'btemplates','template',array('moid'=>$this->_moid, 'cond'=>"(gtype like '%')"),
  257. NULL,$alabel);
  258. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.captcha'),'captcha','boolean',NULL,NULL,$alabel);
  259. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.savenext'),'savenext','list',
  260. array('values'=>array('standard','display','edit'),
  261. 'labels'=>array(XLabels::getSysLabel('xmodtable.savenext_std'),
  262. XLabels::getSysLabel('xmodtable.savenext_display'),
  263. XLabels::getSysLabel('xmodtable.savenext_edit'))),
  264. NULL, $alabel);
  265. $this->_options->setOpt(XLabels::getSysLabel('general.systemproperties'),'showsystprop','list',
  266. array('values'=>array('show','hide'),
  267. 'labels'=>array(XLabels::getSysLabel('general.yes'),
  268. XLabels::getSysLabel('general.no'))),
  269. NULL,$alabel);
  270. $this->_options->setOpt(XLabels::getSysLabel('xmodtable.persistentquery'),'persistentquery','boolean',NULL,NULL,$alabel);
  271. $slabel=XLabels::getSysLabel('xmodule.ssmod');
  272. $tlabel=XLabels::getSysLabel('general','title','text');
  273. $flabel=XLabels::getSysLabel('general','field','text');
  274. $ilabel=XLabels::getSysLabel('xmodtable','activate_additem');
  275. $dlabel=XLabels::getSysLabel('xmodtable','dependentfiles');
  276. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','submodmax'),'submodmax','text',NULL,NULL,$slabel);
  277. $this->_options->setOpt(XLabels::getSysLabel('xmodtable','submodsearch'),'submodsearch','boolean',NULL,NULL,$slabel);
  278. if(!empty(XModule::$_mcache[$this->_moid]['MPARAM']['submodmax']))
  279. $this->_options->set($this,'submodmax',XModule::$_mcache[$this->_moid]['MPARAM']['submodmax']);
  280. for($i=1;$i<=$this->submodmax;$i++) {
  281. $this->_options->setOpt($tlabel.' '.$i,'ssmodtitle'.$i,'text',NULL,'',$slabel);
  282. $this->_options->setOpt($flabel.' '.$i,'ssmodfield'.$i,'text',NULL,'',$slabel);
  283. $this->_options->setOpt($slabel.' '.$i,'ssmod'.$i,'module',array('validate'=>true),'', $slabel);
  284. $this->_options->setOpt($ilabel.' '.$i,'ssmodactivate_additem'.$i,'boolean',NULL,true,$slabel);
  285. $this->_options->setOpt($dlabel.' '.$i,'ssmoddependent'.$i,'boolean',NULL,false,$slabel);
  286. }
  287. $tlabel=XLabels::getSysLabel('xmodule.tracking');
  288. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','trackchanges'),'trackchanges','boolean',NULL,NULL,$tlabel);
  289. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','trackaccess'),'trackaccess','boolean',NULL,NULL,$tlabel);
  290. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','archive'),'archive','boolean',NULL,NULL,$tlabel);
  291. }
  292. /// Cette fonction est appliquee pour afficher l'ensemble des methodes de ce module
  293. protected function _actionlist(&$my) {
  294. parent::_actionlist($my);
  295. $myclass=get_class($this);
  296. $moid=$this->_moid;
  297. $myoid=@$_REQUEST['oid'];
  298. $user=&XUser::get_user();
  299. $f=XShell::_function();
  300. $uniqid='v'.XShell::uniqid();
  301. $submodcontext=NULL;
  302. // Parcourir
  303. if($this->secure('','browse')){
  304. // recupération du contexte sous module
  305. $submodcontext = $this->subModuleContext(array(), true);
  306. // en sous fiche, le browse est un retour à la fiche parent
  307. if($this->dependant_module && $submodcontext) {
  308. $o1=new XModuleAction($this,'browse',XLabels::getSysLabel('general','browse','text'),
  309. '&moid='.$this->dependant_module.'&_function=display&template=xmodtable/view.html&tplentry=br&oid='.
  310. $submodcontext['_parentoids'][0].$submodcontext['urlparms'],'display');
  311. } else {
  312. $o1=new XModuleAction($this,'browse',XLabels::getSysLabel('general','browse','text'),
  313. '&moid='.$moid.'&_function=browse&template=xmodtable/browse.html&tplentry=br','display');
  314. }
  315. $o1->containable=true;
  316. $o1->setToolbar('general','browse');
  317. $my['browse']=$o1;
  318. }
  319. // Recherche
  320. if((!$this->dependant_module || !$submodcontext) && $this->secure('','query')) {
  321. $o1=new XModuleAction($this,'query',XLabels::getSysLabel('general','query','text'),
  322. '&moid='.$moid.'&_function=query&template=xmodtable/query2.html&tplentry=br&querymode=query2','display');
  323. $o1->containable=true;
  324. $o1->setToolbar('general','query');
  325. $my['query']=$o1;
  326. }
  327. // Recherche en cours
  328. if($this->isThereAQueryActive()) {
  329. $o1=new XModuleAction($this,'procQuery',XLabels::getSysLabel('general','currentquery','text'),
  330. '&moid='.$moid.'&_function=procQuery&template=xmodtable/browse.html&tplentry=br','display');
  331. $o1->setToolbar('general','currentquery');
  332. $my['procquery']=$o1;
  333. }
  334. // Insert
  335. $lang_data=XShell::getLangData();
  336. $foo=NULL;
  337. if($this->xset->getTranslatable()==3) $sec=$this->secure($myoid,'insert',$foo,$lang_data);
  338. else $sec=$this->secure($myoid,'insert');
  339. if($sec && (!$this->dependant_module || !$submodcontext)) {
  340. $o1=new XModuleAction($this,'insert',XLabels::getSysLabel('general','new','text'),
  341. '&moid='.$moid.'&_function=insert&template=xmodtable/new.html&tplentry=br','edit');
  342. $o1->setToolbar('general','new');
  343. $o1->order=1;
  344. $my['insert']=$o1;
  345. }
  346. // Actions de navigation de fiche en fiche : nous ne sommes pas en sous module
  347. if(!empty($this->navActions) && !$submodcontext){
  348. foreach($this->navActions as $ak=>$o){
  349. $my[$ak] = $o;
  350. }
  351. }
  352. // Avertir
  353. $oid=@$_REQUEST['oid'];
  354. if ($this->secure('', 'sendACopyTo')){
  355. if(!empty($oid)) {
  356. $o1=new XModuleAction($this,'sendACopy',XLabels::getSysLabel('xmodule','sendacopyto','text'),
  357. '&moid='.$moid.'&tplentry=br&oid='.$oid.'&_function=sendACopyTo&template=xmodule/sendacopyto.html&tplentry=br');
  358. }else{
  359. $o1=new XModuleAction($this,'sendACopy',XLabels::getSysLabel('xmodule','sendacopyto','text'),
  360. 'javascript:'.$uniqid.'.applyfunction("sendACopyTo","",{template:"xmodule/sendacopyto.html"},true,true);');
  361. }
  362. $o1->menuable=true;
  363. $o1->group='more';
  364. $my['sendacopy']=$o1;
  365. }
  366. // Impression
  367. if(in_array(XShell::_function(),array('display','edit'))) $printfct='printDisplay';
  368. else $printfct='printBrowse';
  369. if(XShell::_function()!='insert' && $this->secure($myoid,$printfct)){
  370. $o1=new XModuleAction($this,'print',XLabels::getSysLabel('general','print','text'),
  371. 'javascript:'.$uniqid.'.printselected();','display');
  372. $o1->setToolbar('general','print');
  373. $my['print']=$o1;
  374. }
  375. // Export
  376. if(in_array(XShell::_function(),array('display','edit'))) $expfct='exportDisplay';
  377. else $expfct='export';
  378. if(XShell::_function()!='insert' && $this->secure($myoid,$expfct)){
  379. $o1=new XModuleAction($this,'export',XLabels::getSysLabel('general','export','text'),'javascript:'.$uniqid.'.exportselected();',
  380. 'edit');
  381. $o1->menuable=true;
  382. $my['sexport']=$o1;
  383. }
  384. //Import
  385. if($this->secure('','manage')){
  386. $o1=new XModuleAction($this,'manage',XLabels::getSysLabel('general','import','text'),
  387. $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$this->_moid.'&function=manage&template=xmodule/manage.html','edit');
  388. $o1->menuable=true;
  389. $my['import']=$o1;
  390. }
  391. // Voir les documents non lus
  392. if($this->trackaccess && $this->secure('','getUnread')){
  393. $o1=new XModuleAction($this,'lastdoc',XLabels::getSysLabel('xmodule','unread','text'),
  394. '&moid='.$this->_moid.'&_function=getUnread&tplentry=br&template=xmodtable/getUnread.html','more');
  395. $o1->menuable=true;
  396. $my['unread']=$o1;
  397. }
  398. // Abonnements
  399. $modsubmoid=XModule::getMoid(XMODSUB_TOID);
  400. if(!empty($modsubmoid)){
  401. $o1=new XModuleAction($this, 'subscribe', XLabels::getSysLabel('xmodsub','subadd','text'),
  402. '&amoid='.$this->_moid.'&moid='.$modsubmoid.
  403. '&_function=preSubscribe&tplentry=br&template=xmodsub/sub.html&aoid='.$myoid);
  404. $o1->menuable=true;
  405. $o1->group='more';
  406. $my['subscribe']=$o1;
  407. }
  408. // Regles workflow
  409. if($this->stored_query){
  410. $modrulemoid=XModule::getMoid(XMODRULE_TOID);
  411. if(!empty($modrulemoid)){
  412. $o1=new XModuleAction($this, 'rule', XLabels::getSysLabel('xmodrule','addrule','text'),
  413. '&amoid='.$this->_moid.'&moid='.$modrulemoid.
  414. '&_function=insertRule&tplentry=br&template=xmodrule/newRule.html&atemplate=xmodtable/editSelection.html');
  415. $o1->menuable=true;
  416. $o1->group='more';
  417. $my['rule']=$o1;
  418. }
  419. }
  420. // Mode conception et administration
  421. if($this->secure('','adminBrowseFields')){
  422. $o1=new XModuleAction($this, 'administration', XLabels::getSysLabel('general', 'administration', 'text'),
  423. '&moid='.$this->_moid.'&function=adminBrowseFields&template=xmodule/admin/browseFields.html','admin');
  424. $o1->setToolBar('general', 'administration');
  425. $my['administration']=$o1;
  426. }
  427. // Chemin
  428. if($this->interactive) {
  429. if($this->dependant_module && $submodcontext) {
  430. $mod1=XModule::objectFactory($this->dependant_module);
  431. $o1=new XModuleAction($this,'browse',$mod1->modulename,
  432. '&moid='.$this->dependant_module.'&_function=browse&template=xmodtable/browse.html&tplentry=br');
  433. $my['stack'][]=$o1;
  434. $d1=&$mod1->xset->rDisplayText($submodcontext['_parentoids'][0], array());
  435. $o1=new XModuleAction($this,'d1',$d1['link'],
  436. '&moid='.$this->dependant_module.'&_function=display&template=xmodtable/view.html&tplentry=br&oid='.
  437. $submodcontext['_parentoids'][0]);
  438. $my['stack'][]=$o1;
  439. } else {
  440. $o1=new XModuleAction($this,'browse',$this->modulename,
  441. '&moid='.$moid.'&_function=browse&template=xmodtable/browse.html&tplentry=br','display');
  442. $my['stack'][]=$o1;
  443. $f=XShell::_function();
  444. if(strpos($f,'admin')===0){
  445. $o1=new XModuleAction($this,'adminBrowseFields',XLabels::getSysLabel('xmodule','browsefields','text').' ('.$this->xset->getTable().')',
  446. '&moid='.$moid.'&_function=adminBrowseFields&template=xmodule/admin/browseFields.html','display');
  447. $my['stack'][]=$o1;
  448. }
  449. }
  450. if(!empty($oid) && !is_array($oid)) {
  451. $br=&XShell::from_screen('br');
  452. $br=&$this->xset->rDisplayText($oid, array());
  453. if($submodcontext) {
  454. $o1=new XModuleAction($this,'browse',$br['link'],
  455. '&moid='.$moid.$submodcontext['urlparms'].
  456. '&_function=display&template=xmodtable/view.html&tplentry=br&oid='.$oid,'display');
  457. } else {
  458. $o1=new XModuleAction($this,'browse',$br['link'],
  459. '&moid='.$moid.'&_function=display&template=xmodtable/view.html&tplentry=br&oid='.$oid,'display');
  460. }
  461. $my['stack'][]=$o1;
  462. }
  463. }
  464. }
  465. /// Action principale du menu
  466. public function getMainAction(){
  467. return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&function=browse&tplentry=br&template=xmodtable/browse.html&_persistent=1';
  468. }
  469. /**
  470. * Contruit la liste des actions relatives aux sous-modules
  471. * @param &$my array() Liste de XModuleAction
  472. */
  473. function getSSMAl(&$my){
  474. $uniqid='v'.XShell::uniqid();
  475. $myoid=@$_REQUEST['oid'];
  476. $ssmmenu=array();
  477. for($i=1;$i<=$this->submodmax;$i++) {
  478. $f='ssmod'.$i;
  479. $ff='ssmodfield'.$i;
  480. $fa='ssmodactivate_additem'.$i;
  481. if(!$this->$fa || !$this->$f) continue;
  482. if(empty($this->$ff)){
  483. $smod=XModule::objectFactory($this->$f);
  484. $links=$smod->xset->getXLinkDefs(NULL,$this->table);
  485. if(!empty($links)) list($foo,$linkfield)=each($links);
  486. } else {
  487. $linkfield = $this->$ff;
  488. }
  489. $ssm=XModule::objectFactory($this->$f);
  490. if(!$ssm->secure('','insert')) continue;
  491. $submodcontext=$this->subModuleContext($ar); // ???? sert pas
  492. $o1=new XModuleAction($this,$f,$ssm->modulename,
  493. 'javascript:'.$uniqid.'.addTabs("'.$this->$f.'","'.$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$this->$f.'&function=insert&template=xmodtable/new.html&tplentry=br&_linkedfields[]='.$linkfield.
  494. '&_parentoids[]='.$myoid.'&_parentoid='.$myoid.'&_linkedfield='.$linkfield.'&_raw=1&_ajax=1&skip=1'.
  495. '&tabsmode=1","'.XLabels::getSysLabel('general','add','text').' : '.addslashes($ssm->modulename).'");');
  496. $o1->menuable=true;
  497. $ssmmenu[]=$o1;
  498. }
  499. if(count($ssmmenu)>1){
  500. $o1=new XModuleAction($this,'alladd',XLabels::getSysLabel('general','add','text'),'#');
  501. $o1->menuable=true;
  502. $o1->newgroup='ssm';
  503. $my['ssm']=$o1;
  504. foreach($ssmmenu as &$o1){
  505. $o1->group='ssm';
  506. $my[$o1->xfunction]=$o1;
  507. }
  508. }else{
  509. foreach($ssmmenu as &$o1){
  510. $o1->name=XLabels::getSysLabel('general','add','text').' : '.$o1->name;
  511. $my[$o1->xfunction]=$o1;
  512. }
  513. }
  514. }
  515. /**
  516. * Construit la liste des actions à rendre disponible lors de l'affichage d'une fiche (display)
  517. * @param &$my array() Liste de XModuleAction
  518. */
  519. function al_display(&$my){
  520. $uniqid='v'.XShell::uniqid();
  521. $moid=$this->_moid;
  522. $myoid=@$_REQUEST['oid'];
  523. $sec=$this->secure($myoid,'edit');
  524. if($sec) {
  525. // recuperation contexte sous module
  526. $submodcontext=$this->subModuleContext();
  527. $o1=new XModuleAction($this,'edit',XLabels::getSysLabel('general','edit','text'),
  528. '&function=edit&moid='.$moid.'&template=xmodtable/edit.html&tplentry=br&oid='.$myoid.$submodcontext['urlparms'],'edit');
  529. $o1->order=2;
  530. $o1->setToolbar('general','edit');
  531. $my['edit']=$o1;
  532. }
  533. $sec=$this->secure($myoid,'del');
  534. if($sec){
  535. $o1=new XModuleAction($this,'del',XLabels::getSysLabel('general','delete','text'),'javascript:'.$uniqid.'.deleterecord();','edit');
  536. $o1->order=3;
  537. $o1->setToolbar('general','delete');
  538. $my['del']=$o1;
  539. }
  540. $this->getSSMAl($my);
  541. }
  542. /**
  543. * Construit la liste des actions à rendre disponible lors de la préparation à l'édition d'une fiche (edit)
  544. * @param &$my array() Liste de XModuleAction
  545. */
  546. function al_edit(&$my){
  547. $uniqid='v'.XShell::uniqid();
  548. $myoid=@$_REQUEST['oid'];
  549. $o1=new XModuleAction($this,'save',XLabels::getSysLabel('general','save','text'),'javascript:'.$uniqid.'.saverecord();','edit');
  550. $o1->order=1;
  551. $o1->setToolbar('general','save');
  552. $my['save']=$o1;
  553. // recuperation contexte sous module
  554. $submodcontext=$this->subModuleContext();
  555. $o1=new XModuleAction($this,'display',XLabels::getSysLabel('general','display','text'),
  556. '&function=display&moid='.$this->_moid.'&template=xmodtable/view.html&tplentry=br&oid='.$myoid.$submodcontext['urlparms'],
  557. 'edit');
  558. $o1->order=2;
  559. $o1->setToolbar('general','display');
  560. $my['display']=$o1;
  561. $sec=$this->secure($myoid,'del');
  562. if($sec){
  563. $o1=new XModuleAction($this,'del',XLabels::getSysLabel('general','delete','text'),'javascript:'.$uniqid.'.deleterecord();','edit');
  564. $o1->order=3;
  565. $o1->setToolbar('general','delete');
  566. $my['del']=$o1;
  567. }
  568. $this->getSSMAl($my);
  569. }
  570. /**
  571. * Construit la liste des actions à rendre disponible lors de l'édition d'une fiche (procEdit)
  572. * @param &$my array() Liste de XModuleAction
  573. */
  574. function al_procEdit(&$my){
  575. $this->al_edit($my);
  576. }
  577. /**
  578. * Construit la liste des actions à rendre disponible lors de la duplication d'une fiche (procEditDup)
  579. * @param &$my array() Liste de XModuleAction
  580. */
  581. function al_procEditDup(&$my){
  582. $this->al_insert($my);
  583. }
  584. /**
  585. * Construit la liste des actions à rendre disponible lors de la préparation à l'insertion d'une fiche (insert)
  586. * @param &$my array() Liste de XModuleAction
  587. */
  588. function al_insert(&$my){
  589. $uniqid='v'.XShell::uniqid();
  590. $o1=new XModuleAction($this,'save',XLabels::getSysLabel('general','save','text'),'javascript:'.$uniqid.'.saverecord();','edit');
  591. $o1->order=1;
  592. $o1->setToolbar('general','save');
  593. $my['save']=$o1;
  594. }
  595. /**
  596. * Construit la liste des actions à rendre disponible lors de l'insertion d'une fiche (procInsert)
  597. * @param &$my array() Liste de XModuleAction
  598. */
  599. function al_procInsert(&$my){
  600. $this->al_insert($my);
  601. }
  602. /**
  603. * Construit la liste des actions à rendre disponible lors du listing des fiches du module (browse)
  604. * @param &$my array() Liste de XModuleAction
  605. */
  606. function al_browse(&$my){
  607. $uniqid='v'.XShell::uniqid();
  608. $moid=$this->_moid;
  609. $myoid=@$_REQUEST['oid'];
  610. if($this->secure($myoid,'del')){
  611. $o1=new XModuleAction($this,'del',XLabels::getSysLabel('general','delete','text'),'javascript:'.$uniqid.'.deleteselected();','edit');
  612. $o1->setToolbar('general','delete');
  613. $o1->order=3;
  614. $my['del']=$o1;
  615. }
  616. if($this->objectSecurityEnabled() && $this->secure($myoid,'secEditSimple')){
  617. $o1=new XModuleAction($this,'seceditsimple',XLabels::getSysLabel('general','security','text'),
  618. 'javascript:TZR.editSec("'.$GLOBALS['TZR_SESSION_MANAGER']::complete_self(true).'","'.$this->_moid.'","",'.$uniqid.');','edit');
  619. $o1->setToolbar('general','security');
  620. $o1->order=4;
  621. $my['secEditSimple']=$o1;
  622. }
  623. if(isset($this->xset->desc['PUBLISH'])){
  624. if($this->secure($myoid,'publish')){
  625. $o1=new XModuleAction($this,'approve',XLabels::getSysLabel('general','approve','text'),
  626. 'javascript:'.$uniqid.".applyfunction('publish','',{value:1});",'edit');
  627. $o1->menuable=true;
  628. $my['approve']=$o1;
  629. $o1=new XModuleAction($this,'unapprove',XLabels::getSysLabel('general','unapprove','text'),
  630. 'javascript:'.$uniqid.".applyfunction('publish','',{value:2});",'edit');
  631. $o1->menuable=true;
  632. $my['unapprove']=$o1;
  633. }
  634. }
  635. // Affichage (changement taille page, ajout de champ...)
  636. $o1=new XModuleAction($this,'fieldgrp',XLabels::getSysLabel('xmodtable','field_label','text'),'#','display');
  637. $o1->menuable=true;
  638. $o1->newgroup='fieldgrp';
  639. $my['fieldgrp']=$o1;
  640. foreach($this->xset->orddesc as $i=>$fn){
  641. $f=$this->xset->getField($fn);
  642. $o1=new XModuleAction($this,'field'.$fn,$f->label,'javascript:'.$uniqid.'.add_field(\''.$fn.'\');'.$uniqid.'.go_browse(\'\',0);','fieldgrp');
  643. $o1->menuable=true;
  644. $my['field'.$fn]=$o1;
  645. }
  646. $o1=new XModuleAction($this,'pgmore',XLabels::getSysLabel('xmodtable','page_size','text').' * 2',
  647. 'javascript:'.$uniqid.'.go_browse("start","*2");','display');
  648. $o1->menuable=true;
  649. $my['pgmore']=$o1;
  650. $o1=new XModuleAction($this,'pgless',XLabels::getSysLabel('xmodtable','page_size','text').' / 2',
  651. 'javascript:'.$uniqid.'.go_browse("start","/2");','display');
  652. $o1->menuable=true;
  653. $my['pgless']=$o1;
  654. if($this->multipleedit && $this->secure('','editSelection')){
  655. $o1=new XModuleAction($this,'editselection',XLabels::getSysLabel('xmodmedia','editselection','text'),
  656. 'javascript:'.$uniqid.'.applyfunction("editSelection","",{template:"xmodtable/editSelection.html"},true,true);','edit');
  657. $o1->order=2;
  658. $o1->setToolbar('general','edit');
  659. $my['editselection']=$o1;
  660. }
  661. // Edition/suppression sur le resultat d'une recherche
  662. if($this->isThereAQueryActive()){
  663. if($this->secure('','editAll')){
  664. $o1=new XModuleAction($this,'editall',XLabels::getSysLabel('general','editall','text'),
  665. 'javascript:'.$uniqid.'.applyfunction("editAll","",{template:"xmodmedia/editSelection.html"},false,true);','edit');
  666. $o1->order=2;
  667. $o1->menuable=true;
  668. $my['editall']=$o1;
  669. }
  670. if($this->secure('','delAll')){
  671. $o1=new XModuleAction($this,'delall',XLabels::getSysLabel('general','delall','text'),
  672. 'javascript:'.$uniqid.'.applyfunction("delAll","'.XLabels::getSysLabel('general','confirm_delete_object','text').'","");','edit');
  673. $o1->order=3;
  674. $o1->menuable=true;
  675. $my['delall']=$o1;
  676. }
  677. }
  678. }
  679. /**
  680. * Construit la liste des actions à rendre disponible lors d'une recherche sur les fiches du module (procQuery)
  681. * @param &$my array() Liste de XModuleAction
  682. */
  683. function al_procQuery(&$my){
  684. $this->al_browse($my);
  685. }
  686. /// Fonctions sur gestion des champs
  687. function al_adminBrowseFields(&$my){
  688. $uniqid='v'.XShell::uniqid();
  689. $o1=new XModuleAction($this,'importfieldssec',XLabels::getSysLabel('xmodule','importfieldssec','text'),
  690. '&moid='.$this->_moid.'&_function=adminPreImportFieldsSec&template=xmodule/admin/preimportfieldssec.html&tplentry=br','more');
  691. $o1->menuable=true;
  692. $my['importfieldssec']=$o1;
  693. $o1=new XModuleAction($this,'newfield',XLabels::getSysLabel('xdatasource','new_field','text'),
  694. '&moid='.$this->_moid.'&function=adminNewField&template=xmodule/admin/newField.html');
  695. $o1->menuable=true;
  696. $my['newfield']=$o1;
  697. $o1=new XModuleAction($this,'emptydata',XLabels::getSysLabel('xdatasource','empty_data','text'),
  698. 'javascript:'.$uniqid.'.emptybase();','more');
  699. $o1->menuable=true;
  700. $my['emptydata']=$o1;
  701. $o1=new XModuleAction($this,'clonebase',XLabels::getSysLabel('general','clone','text'),
  702. '&moid='.$this->_moid.'&function=adminDuplicate&template=xmodule/admin/duplicate.html&tplentry=br','more');
  703. $o1->menuable=true;
  704. $my['clonebase']=$o1;
  705. $o1=new XModuleAction($this,'checkbase',XLabels::getSysLabel('general','check','text'),
  706. '&moid='.$this->_moid.'&function=adminChk&skip=1&_next='.rawurlencode($GLOBALS['XSHELL']->get_back_url(0)),'more');
  707. $o1->menuable=true;
  708. $my['checkbase']=$o1;
  709. $o1=new XModuleAction($this,'checkrbase',XLabels::getSysLabel('general','check_and_repair','text'),
  710. '&moid='.$this->_moid.'&function=adminChk&skip=1&repair=1&_next='.rawurlencode($GLOBALS['XSHELL']->get_back_url(0)),'more');
  711. $o1->menuable=true;
  712. $my['checkrbase']=$o1;
  713. $o1=new XModuleAction($this,'propbase',XLabels::getSysLabel('general','properties','text'),
  714. '&moid='.$this->_moid.'&function=adminEditSourceProperties&template=xmodule/admin/editSource.html','more');
  715. $o1->menuable=true;
  716. $my['propbase']=$o1;
  717. $o1=new XModuleAction($this,'printbase',XLabels::getSysLabel('general','print','text'),
  718. 'javascript:'.$uniqid.'.printselected();');
  719. $o1->menuable=true;
  720. $my['printbase']=$o1;
  721. }
  722. /// Fonctions sur gestion des champs
  723. function al_adminBrowseStrings(&$my){
  724. $uniqid='v'.XShell::uniqid();
  725. $o1=new XModuleAction($this,'alphasort',XLabels::getSysLabel('general','alpha_sort','text'),
  726. '&moid='.$this->_moid.'&function=adminSortStrings&skip=1&field='.$_REQUEST['field'].'&_next='.rawurlencode($GLOBALS['XSHELL']->get_back_url(0)));
  727. $o1->menuable=true;
  728. $my['alphasort']=$o1;
  729. $o1=new XModuleAction($this,'deletebase',XLabels::getSysLabel('general','delete_all','text'),
  730. 'javascript:'.$uniqid.'.deleteall();');
  731. $o1->menuable=true;
  732. $my['deleteall']=$o1;
  733. $o1=new XModuleAction($this,'newstring',XLabels::getSysLabel('general','new','text'),
  734. '&moid='.$this->_moid.'&function=adminNewString&template=xmodule/admin/newString.html&field='.$_REQUEST['field']);
  735. $o1->menuable=true;
  736. $my['newstring']=$o1;
  737. }
  738. /// Fonctions sur gestion des champs
  739. function al_adminEditField(&$my){
  740. $uniqid='v'.XShell::uniqid();
  741. $br=&XShell::from_screen('');
  742. $o1=new XModuleAction($this,'resetchrono','Reset',
  743. '&moid='.$this->_moid.'&_function=adminResetChrono&field='.$br['field'].'&boid='.$br['boid'].'&skip=1&_next='.
  744. rawurlencode($GLOBALS['XSHELL']->get_back_url(0)),'more');
  745. $o1->menuable=true;
  746. $my['resetchrono']=$o1;
  747. }
  748. function nav($ar=NULL){
  749. parent::nav($ar);
  750. if(substr(XShell::_function(),0,5)=='admin') {
  751. $this->pushNav(XLabels::getSysLabel('general','administration','text'),
  752. '&function=adminBrowseFields&moid='.$this->_moid.'&template=xmodule/admin/browseFields.html&boid='.$this->boid);
  753. }
  754. }
  755. function isDependant() {
  756. return XDbIni::get('dependant:'.$this->_moid,'val');
  757. }
  758. /// Preparartion des donnees pour ecran de parametrage d'impression
  759. public function prePrintBrowse($ar) {
  760. $p=new XParam($ar,array());
  761. $order=$p->get('order');
  762. $tplentry=$p->get('tplentry');
  763. if(empty($order)) $order=$this->order;
  764. $ar['order']=$order;
  765. $ar['table']=$this->table;
  766. // Recherche des templates d'impression
  767. if(empty($this->_templates)) $this->_templates=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=TEMPLATES');
  768. if(!empty($this->_templates)) {
  769. $q1=$this->_templates->select_query(array('cond'=>array('modid'=>array('=',$this->_moid),
  770. 'gtype'=>array('=','xmodtable_browse_print'))));
  771. $r=&$this->_templates->browse(array('select'=>$q1,'pagesize'=>100,'tplentry'=>TZR_RETURN_DATA));
  772. XShell::toScreen1($tplentry.'t',$r);
  773. }
  774. // recherche des donnees
  775. $ar['_filter']=$this->getFilter(true,$ar);
  776. $ar['tplentry']=TZR_RETURN_DATA;
  777. $ar['fieldssec']=$this->getFieldsSec($ar);
  778. $ar['selectedfields']='all';
  779. $ar['pagesize']=1;
  780. $ar['ssmoid']='all';
  781. for($i=1;$i<=$this->submodmax;$i++) {
  782. $f='ssmod'.$i;
  783. $ar['options'][$this->$f]['selectedfields']='all';
  784. }
  785. // cas module ayant lui meme en sous modules
  786. $mycurrentquery = NULL;
  787. if($this->isThereAQueryActive())
  788. $mycurrentquery = $this->_getSession('query');
  789. $r=&$this->xset->browse($ar);
  790. $this->setSubModules($ar,$r);
  791. if ($mycurrentquery != NULL)
  792. $this->_setSession('query', $mycurrentquery);
  793. // calcul du nombre d'enregistrements impactes (passage d'oid, browseSelection ou browse/query classique)
  794. $r['_selected']=$p->get('_selected');
  795. if(is_array($r['_selected'])) {
  796. $r['record_count']=count($r['_selected']);
  797. }elseif($p->get('fromfunction')=='browseSelection') {
  798. $selection=getSessionVar('selection');
  799. $r['_selected']=$selection[$this->_moid];
  800. $r['record_count']=count($r['_selected']);
  801. }else{
  802. $context=$this->getContextQuery($ar,false);
  803. $ar['select']=$context['query'];
  804. $q=$this->xset->getSelectQuery($ar);
  805. $r['record_count']=countSelectQuery($q[1],true);
  806. $r['queryfields']=$context['all']['queryfields'];
  807. }
  808. return XShell::toScreen1($tplentry,$r);
  809. }
  810. /// Retourne la requete permattant de recuperer tous les objets suivant le contexte (selection, recherche en cours...)
  811. function getContextQuery($ar,$queryonly=true){
  812. $p=new XParam($ar,array());
  813. $oidsel=$p->get('_selected');
  814. $noreg=$p->get('noreg');
  815. $from=$p->get('fromfunction');
  816. if(is_array($oidsel)) {
  817. $oid=array_keys($oidsel);
  818. $q=$this->xset->select_query(array('cond'=>array('KOID'=>array('=',$oid))));
  819. }elseif($this->isThereAQueryActive() && ($from=='procQuery')) {
  820. $_storedquery=$this->_getSession('query');
  821. $ar1=array_merge($_storedquery,$ar);
  822. if($queryonly){
  823. $ar1['getselectonly']=true;
  824. $q=$this->xset->procQuery($ar1);
  825. }else{
  826. $ar1['getselectonly']=false;
  827. $ar1['pagesize']=1;
  828. $r=$this->xset->procQuery($ar1);
  829. $q=$r['select'];
  830. $params=array('queryobject'=>$r['queryobject']);
  831. }
  832. if(!$noreg) $q=preg_replace('@select (.*) from (.*)$@i','select '.$this->table.'.* from $2',$q);
  833. }else{
  834. $q=$this->xset->select_query(array("cond"=>array()));
  835. }
  836. if($queryonly) return $q;
  837. else return array('query'=>$q,'all'=>$r);
  838. }
  839. /// Impression sur un browse
  840. public function printBrowse($ar) {
  841. $p=new XParam($ar,array());
  842. $title=$p->get('title');
  843. $email=$p->get('dest');
  844. $target=$p->get('_target');
  845. $linkedfield=$p->get('_linkedfield');
  846. $fmt=$p->get('fmt');
  847. $context=$this->getContextQuery($ar,false);
  848. $q=$context['query'];
  849. $ar['selected']='0';
  850. $ar['pagesize']='100000';
  851. $ar['select']=$q;
  852. $ar['_format']='text/html';
  853. $ar['tplentry']=TZR_RETURN_DATA;
  854. $tpldata['param']=array('title'=>$title,'queryfields'=>$context['all']['queryfields']);
  855. $oldinteractive=$this->interactive;
  856. $this->interactive=false;
  857. if(!empty($target) && $target!=$this->_moid){
  858. $mod=XModule::objectFactory($target);
  859. if($mod->secure('','export')){
  860. $ar2=$ar;
  861. $ar['selectedfields']=array('xx');
  862. $ar['order']=$this->order;
  863. $b=$this->browse($ar);
  864. $q='select * from '.$mod->table.' where '.$linkedfield.' in ("'.implode('","',$b['lines_oid']).'")';
  865. $ar2['select']=$q;
  866. $ar2['tplentry']=$tplentry;
  867. if($fmt=='pdf') $ar2['_format']='application/prince';
  868. $res=$mod->browse($ar2);
  869. }
  870. }else{
  871. if($fmt=='pdf') $ar['_format']='application/prince';
  872. $res=$this->browse($ar);
  873. $mod=&$this;
  874. }
  875. $this->interactive=$oldinteractive;
  876. if($fmt=='pdf') {
  877. // Impression PDF par defaut
  878. if(!empty($this->_templates) && !empty($this->btemplates)) {
  879. $r=&$this->_templates->display(array('oid'=>$this->btemplates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  880. if(!empty($r['oprintp']->filename)) $filename=$r['oprintp']->filename;
  881. }
  882. $this->_printBrowsePDF($ar,$filename);
  883. }elseif(Kernel::isAKoid($fmt)) {
  884. // Impression via un template d'impressions
  885. $t=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$fmt);
  886. $dispfmt=$t->rDisplay($fmt);
  887. $displayformats=explode(',',$dispfmt['odfmt']->raw);
  888. if(in_array('text/html',$displayformats) || empty($dispfmt['odfmt']->raw)) $this->_printBrowseHTML($ar,$dispfmt['oprint']->filename);
  889. elseif(in_array('application/prince',$displayformats)) $this->_printBrowsePDF($ar,$dispfmt['oprint']->filename);
  890. }else{
  891. // Impression HTML par defaut
  892. $template=$p->get('template');
  893. $this->_printBrowseHTML($ar,$template);
  894. }
  895. }
  896. /// Sous fonction d'impression au format HTML
  897. function _printBrowseHTML($ar=NULL,$filename=NULL){
  898. $p=new XParam($ar,NULL);
  899. $email=$p->get('dest');
  900. if(empty($filename)) $filename='xmodtable/print.html';
  901. $content=$this->_printGetContent($ar,$filename,'browse');
  902. if(!empty($email)) $this->sendMail2User('print','',$email,NULL,false,NULL,'report.html',$content);
  903. echo $content;
  904. exit(0);
  905. }
  906. /// Sous fonction d'impression au format PDF
  907. function _printBrowsePDF($ar=NULL,$filename=NULL){
  908. $p=new XParam($ar,array('pdfname'=>'browse.pdf'));
  909. $email=$p->get('dest');
  910. if(empty($filename)) $filename='xmodtable/print.xml';
  911. $ar['_format']='application/prince';
  912. $content=$this->_printGetContent($ar,$filename,'browse');
  913. $tmpname=princeTidyXML2PDF(NULL,$content);
  914. if(!empty($email) && !empty($tmpname)) {
  915. $content=file_get_contents($tmpname);
  916. $this->sendMail2User('print','',$email,NULL,false,NULL,'browse.pdf',$content,'application/pdf');
  917. }
  918. $pdfname=$p->get('pdfname');
  919. header('Content-type: application/pdf');
  920. header('Content-disposition: attachment; filename='.$pdfname);
  921. $size=filesize($tmpname);
  922. header('Accept-Ranges: bytes');
  923. header('Content-Length: '.$size);
  924. readfile($tmpname);
  925. unlink($tmpname);
  926. exit(0);
  927. }
  928. /// Impression d'une fiche
  929. public function printDisplay($ar) {
  930. $p=new XParam($ar,array('pdfname'=>'view.pdf'));
  931. $tplentry=$p->get('tplentry');
  932. $ar['tplentry']=TZR_RETURN_DATA;
  933. $ar['ssmoid']='all';
  934. $fmt=$p->get('fmt');
  935. if($fmt=='pdf') {
  936. // Impression PDF par defaut
  937. if(!empty($this->_templates) && !empty($this->templates)) {
  938. $r=&$this->_templates->display(array('oid'=>$this->templates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  939. if(!empty($r['oprintp']->filename)) $filename=$r['oprintp']->filename;
  940. }
  941. $this->_printDisplayPDF($ar,$filename);
  942. }elseif(Kernel::isAKoid($fmt)) {
  943. // Impression via un template d'impressions
  944. $t=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$fmt);
  945. $dispfmt=$t->display(array('oid'=>$fmt,'tplentry'=>TZR_RETURN_DATA));
  946. $displayformats=explode(',',$dispfmt['odfmt']->raw);
  947. if(in_array('text/html',$displayformats) || empty($dispfmt['odfmt']->raw)) $this->_printDisplayHTML($ar,$dispfmt['oprint']->filename);
  948. elseif(in_array('application/prince',$displayformats)) $this->_printDisplayPDF($ar,$dispfmt['oprint']->filename);
  949. }else{
  950. // Impression HTML par defaut
  951. $template=$p->get('template');
  952. $this->_printDisplayHTML($ar,$template);
  953. }
  954. }
  955. /// Sous fonction d'impression au format HTML
  956. function _printDisplayHTML($ar=NULL,$filename=NULL){
  957. $p=new XParam($ar,NULL);
  958. $email=$p->get('dest');
  959. if(empty($filename)) $filename='xmodtable/printdisplay.html';
  960. $content=$this->_printGetContent($ar,$filename,'display');
  961. if(!empty($email)) $this->sendMail2User('print','',$email,NULL,false,NULL,'report.html',$content);
  962. echo $content;
  963. exit(0);
  964. }
  965. /// Sous fonction d'impression au format PDF
  966. function _printDisplayPDF($ar=NULL,$filename=NULL){
  967. $p=new XParam($ar,array('pdfname'=>'view.pdf'));
  968. $email=$p->get('dest');
  969. if(empty($filename)) $filename='xmodtable/print-view.xml';
  970. $ar['_format']='application/prince';
  971. $content=$this->_printGetContent($ar,$filename,'display');
  972. $tmpname=princeTidyXML2PDF(NULL,$content);
  973. if(!empty($email) && !empty($tmpname)) {
  974. $content=file_get_contents($tmpname);
  975. $this->sendMail2User('print','',$email,NULL,false,NULL,'view.pdf',$content,'application/pdf');
  976. }
  977. $pdfname=$p->get('pdfname');
  978. header('Content-type: application/pdf');
  979. header('Content-disposition: attachment; filename='.$pdfname);
  980. $size=filesize($tmpname);
  981. header('Accept-Ranges: bytes');
  982. header('Content-Length: '.$size);
  983. readfile($tmpname);
  984. unlink($tmpname);
  985. exit(0);
  986. }
  987. /// Recupere le contenu pour une impression
  988. function &_printGetContent($ar,$filename,$f,$tpldata=array()){
  989. $p=new XParam($ar,NULL);
  990. $title=$p->get('title');
  991. $res=&$this->$f($ar);
  992. $xt=new XTemplate('file:'.$filename);
  993. $labels=&$GLOBALS['XSHELL']->labels->get_labels(array('selectors'=>array('global'),'local'=>true));
  994. $xt->set_glob(array('labels'=>&$labels));
  995. $r3=array();
  996. $tpldata['param']=array('title'=>$title);
  997. $tpldata['br']=$res;
  998. $tpldata['imod']=&XShell::from_screen('imod');
  999. $content=$xt->parse($tpldata,$r3,NULL);
  1000. return $content;
  1001. }
  1002. /// Exporte une fiche
  1003. public function exportDisplay($ar=NULL){
  1004. $p= new XParam($ar,array());
  1005. $fmt=$p->get('fmt');
  1006. $ar['norow']=1;
  1007. $ar['nodef']=1;
  1008. $ar['ssmoid']='all';
  1009. $ar['_options']=array('genpublishtag'=>false);
  1010. if($fmt=='xl' || $fmt=='xl07') $ar['_format']='application/excel';
  1011. $this->display($ar);
  1012. if($fmt=='xl' || $fmt=='xl07') $this->_exportXLSDisplay($ar);
  1013. if($fmt=='html') $this->printDisplay($ar);
  1014. if($fmt=='csv') $this->_exportCSVDisplay($ar);
  1015. }
  1016. /// Exporte une fiche au format excel
  1017. public function _exportXLSDisplay($ar){
  1018. require_once('add-ons/PHPExcel/PHPExcel.php');
  1019. $p=new XParam($ar,NULL);
  1020. $fmt=$p->get('fmt');
  1021. $br=&XShell::from_screen('br');
  1022. $ss=new PHPExcel();
  1023. $ss->setActiveSheetIndex(0);
  1024. $ws=$ss->getActiveSheet();
  1025. $ws->setTitle('Main');
  1026. $ws->SetCellValue('A1','OID');
  1027. $ws->SetCellValue('B1',$br['oid']);
  1028. $row=2;
  1029. foreach($br['fields_object'] as $j => &$f) {
  1030. if(!$f->sys){
  1031. $l=$f->fielddef->label;
  1032. $c=$f->field;
  1033. convert_charset($l,TZR_INTERNAL_CHARSET,'UTF-8');
  1034. $ws->setCellValueByColumnAndRow(0,$row,$l);
  1035. $f1=&$this->xset->getField($c);
  1036. $f1->writeXLS($ws,$row++,1,$br['o'.$c],0,$ss);
  1037. }
  1038. }
  1039. $ws->getStyle('A1:A'.($row-1))->getFont()->setBold(true);
  1040. foreach($br['__ssmod'] as $i=>&$ssr){
  1041. $ssmod=XModule::objectFactory($br['__ssprops'][$i]['_moid']);
  1042. $l=$br['__ssprops'][$i]['modulename'];
  1043. convert_charset($l,TZR_INTERNAL_CHARSET,'UTF-8');
  1044. $ss->createSheet($i+1);
  1045. $ss->setActiveSheetIndex($i+1);
  1046. $ws=$ss->getActiveSheet();
  1047. $ws->setTitle($l);
  1048. foreach($ssr['header_fields'] as $j => &$f) {
  1049. $l=$ssr['header_fields'][$j]->label;
  1050. convert_charset($l,TZR_INTERNAL_CHARSET,'UTF-8');
  1051. $ws->setCellValueByColumnAndRow($j,1,$l);
  1052. }
  1053. foreach($ssr['lines_oid'] as $j=>$oid){
  1054. foreach($ssr['header_fields'] as $k=>&$f) {
  1055. $f->writeXLS($ws,$j+2,$k,$ssr['lines_o'.$f->field][$j],0,$ss);
  1056. }
  1057. }
  1058. $ws->getStyle('A1:'.PHPExcel_Cell::stringFromColumnIndex($k).'1')->getFont()->setBold(true);
  1059. }
  1060. $ss->setActiveSheetIndex(0);
  1061. sendPHPExcelFile($ss,$fmt,'export');
  1062. }
  1063. /// Exporte une fiche et ses sous fiches au format csv (si sous fiches, un fichier csv par sous modules, le tout dans un zip)
  1064. public function _exportCSVDisplay($ar=NULL){
  1065. $p= new XParam($ar,array('fname'=>'Export'));
  1066. $fsep=$p->get('csvfsep');
  1067. $textsep=stripslashes($p->get('csvtextsep'));
  1068. $charset=stripslashes($p->get('csvcharset'));
  1069. $fname=$p->get('fname');
  1070. $br=&XShell::from_screen('br');
  1071. $csv=$headers=$row=array();
  1072. foreach($br['fields_object'] as $j => &$f) {
  1073. if(!$f->sys){
  1074. $f1=&$this->xset->getField($f->field);
  1075. $headers[]=$textsep.$f->fielddef->label.$textsep;
  1076. $row[]=$f1->writeCSV($br['o'.$f->field],$textsep);
  1077. }
  1078. }
  1079. $csv[]=implode($fsep,$headers);
  1080. $csv[]=implode($fsep,$row);
  1081. $csv=implode("\r\n",$csv);
  1082. convert_charset($csv,TZR_INTERNAL_CHARSET,$charset);
  1083. if(empty($br['__ssmod'])){
  1084. ob_clean();
  1085. header('Content-Type: text/csv; charset='.$charset);
  1086. header('Content-Transfer-Encoding:'.$charset);
  1087. header('Content-disposition: attachment; filename='.str_replace(' ','_',removeaccents($fname)).'.csv');
  1088. header('Content-Length: '.strlen($csv));
  1089. echo $csv;
  1090. exit(0);
  1091. }else{
  1092. $dir=TZR_TMP_DIR.'exportdisp'.uniqid();
  1093. @mkdir($dir);
  1094. file_put_contents($dir.'/Main.csv',$csv);
  1095. foreach($br['__ssmod'] as $i=>&$ssr){
  1096. $csv=$headers=$row=array();
  1097. $ssmod=XModule::objectFactory($br['__ssprops'][$i]['_moid']);
  1098. $l=$br['__ssprops'][$i]['modulename'];
  1099. $fields=array();
  1100. foreach($ssr['header_fields'] as $j=>&$f) {
  1101. $headers[]=$textsep.$f->label.$textsep;
  1102. }
  1103. $csv[]=implode($fsep,$headers);
  1104. foreach($ssr['lines_oid'] as $j=>$oid){
  1105. $row=array();
  1106. foreach($ssr['header_fields'] as $k=>&$f) {
  1107. $row[]=$f->writeCSV($ssr['lines_o'.$f->field][$j],$textsep);
  1108. }
  1109. $csv[]=implode($fsep,$row);
  1110. }
  1111. $csv=implode("\r\n",$csv);
  1112. convert_charset($csv,TZR_INTERNAL_CHARSET,$charset);
  1113. file_put_contents($dir.'/'.removeaccents($l).'.csv',$csv);
  1114. }
  1115. exec('(cd '.$dir.'; zip -r '.$dir.'.zip .)2>&1 > '.TZR_TMP_DIR.'errorlog');
  1116. $size=filesize($dir.'.zip');
  1117. header('Content-type: application/zip');
  1118. header('Content-disposition: attachment; filename='.str_replace(' ','_',removeaccents($fname)).'.zip');
  1119. header('Accept-Ranges: bytes');
  1120. header('Content-Length: '.$size);
  1121. @readfile($dir.'.zip');
  1122. XDir::unlink($dir);
  1123. unlink($dir.'.zip');
  1124. exit(0);
  1125. }
  1126. }
  1127. /// Suppression de toutes les entrées correspondant à la recherche en cours
  1128. function delAll($ar) {
  1129. $p=new XParam($ar,NULL);
  1130. $tplentry=$p->get('tplentry');
  1131. if($this->isThereAQueryActive() && empty($clearrequest)) {
  1132. $_storedquery=$this->_getSession('query');
  1133. $ar=array_merge($_storedquery,$ar);
  1134. $ar['fmoid']=$this->_moid;
  1135. $ar['tplentry']=TZR_RETURN_DATA;
  1136. $ar['selectedfields']=array('KOID');
  1137. $ar['pagesize']=999999;
  1138. $r1=$this->xset->procQuery($ar);
  1139. if(count($r1['lines_oid'])){
  1140. $this->del(array('oid'=>$r1['lines_oid']));
  1141. }
  1142. }
  1143. }
  1144. /// Suppression d'un objet ou d'une ensemble d'objet
  1145. function del($ar) {
  1146. $p=new XParam($ar,array('onlyssm'=>false,'ssmnottodel'=>array()));
  1147. $nolog=$p->get('_nolog','local');
  1148. $onlyssm=$p->get('onlyssm');
  1149. $noworkflow=$p->get('_noworkflow');
  1150. $ssmnottodel=$p->get('ssmnottodel');
  1151. $ar['table']=$this->table;
  1152. $ar['action']='OK';
  1153. // traitement du contexte sous module
  1154. $subMods = $this->getSubModules();
  1155. $p=new XParam($ar,array());
  1156. // faire une requete de delete pour chacun des sous modules sur chaque oid
  1157. $oids=Kernel::getSelectedOids($p);
  1158. foreach($oids as $parentoid){
  1159. /// application du workflow
  1160. if(empty($noworkflow) && XModule::getMoid(XMODWORKFLOW_TOID)) {
  1161. $umod=XModule::singletonFactory(XMODWORKFLOW_TOID);
  1162. $umod->checkAndRun($this, $this, $parentoid, 'delete');
  1163. }
  1164. foreach($subMods as $i=>$subMod) {
  1165. // si sous module dépendant, on supprime toutes les sous-fiches en relation avec cette fiche
  1166. // si sous module avec lien obl et multiple (donc pas considéré comme dependant), on edite ou supprime toutes les sous-fiches
  1167. if(in_array($subMod['moid'],$ssmnottodel)) continue;
  1168. if(!empty($subMod['mod']->dependant_module) || $this->{'ssmoddependent'.$i}) {
  1169. $sel=$subMod['xset']->select_query(array('cond'=>array($subMod['linkfield']=>array('=',$parentoid))));
  1170. $ssRecords=$subMod['xset']->browse(array('select'=>$sel, 'tplentry'=>TZR_RETURN_DATA,
  1171. 'selected'=>'0','selectedfields'=>$subMod['linkfield']));
  1172. if(!empty($ssRecords)) {
  1173. foreach($ssRecords['lines_oid'] as $i=>$ssoid){
  1174. $subMod['mod']->del(array('tplentry'=>TZR_RETURN_DATA, 'oid'=>$ssoid,'_selectedok'=>'','_selected'=>''));
  1175. }
  1176. }
  1177. }else{
  1178. $sel=$subMod['xset']->select_query(array('cond'=>array($subMod['linkfield']=>array('LIKE','%'.$parentoid.'%'))));
  1179. $ssRecords=$subMod['xset']->browse(array('select'=>$sel,'tplentry'=>TZR_RETURN_DATA,
  1180. 'selected'=>'0','selectedfields'=>$subMod['linkfield']));
  1181. if(!empty($ssRecords)) {
  1182. foreach($ssRecords['lines_oid'] as $i=>$ssoid){
  1183. $links=$ssRecords['lines_o'.$subMod['linkfield']][$i]->raw;
  1184. if($subMod['xset']->desc[$subMod['linkfield']]->compulsory && preg_match("/^\|*".$parentoid."\|*$/",$links)){
  1185. $subMod['mod']->del(array('tplentry'=>TZR_RETURN_DATA, 'oid'=>$ssoid,'_selectedok'=>'','_selected'=>'','_nolog'=>$nolog));
  1186. }else{
  1187. $subMod['mod']->procEdit(array('tplentry'=>TZR_RETURN_DATA,'oid'=>$ssoid,'_nolog'=>$nolog,
  1188. $subMod['linkfield']=>str_replace($parentoid,'',$links)));
  1189. }
  1190. }
  1191. }
  1192. }
  1193. }
  1194. }
  1195. if (!$onlyssm)
  1196. $this->xset->del($ar);
  1197. return true;
  1198. }
  1199. /// Positinne si necessaire l'oid dans le tri pour dedoublonner
  1200. function checkOrderFields(&$order){
  1201. $t=$this->xset->getTable();
  1202. if(empty($order)) $order=$this->order;
  1203. $decorder=explode(',',$order);
  1204. $allDesc = true;
  1205. $koidFound = false;
  1206. foreach ($decorder as $_order) {
  1207. $allDesc &= (bool)strripos($_order, ' DESC'); // permet d'utiliser les index
  1208. $koidFound |= (stripos($_order, 'KOID') !== false);
  1209. }
  1210. if (!$koidFound)
  1211. $decorder[] = $t.'.KOID' . ($allDesc?' DESC':'');
  1212. $order=implode(',',$decorder);
  1213. }
  1214. /// Contruction des actions de navigation
  1215. function setNavActions($myoid,$navfunction,$navtemplate){
  1216. $moid=$this->_moid;
  1217. $o1=new XModuleAction($this,'navprev',XLabels::getSysLabel('general','previous','text'),
  1218. '&moid='.$moid.'&_function='.$navfunction.'&template='.$navtemplate.'&tplentry=br&oid='.$myoid.'&navdir=prev',
  1219. 'display');
  1220. $o1->setToolBar('general', 'previous');
  1221. $this->navActions['prev']=$o1;
  1222. $o1=new XModuleAction($this,'navnext',XLabels::getSysLabel('general','next','text'),
  1223. '&moid='.$moid.'&_function='.$navfunction.'&template='.$navtemplate.'&tplentry=br&oid='.$myoid.'&navdir=next',
  1224. 'display');
  1225. $o1->setToolBar('general', 'next');
  1226. $this->navActions['next']=$o1;
  1227. }
  1228. /// Recherche des infos sur la position d'un oid dans un browse. Retourn : array(oid precedent,oid suivant, oid actuel, prec le premier, suiv le dernier)
  1229. function mkNavParms($ar){
  1230. $p=new XParam($ar, array());
  1231. $oid=$p->get('oid');
  1232. // Lecture de l'ordre en cour
  1233. if($this->_issetSession('lastorder')) $order=$this->_getSession('lastorder');
  1234. if(empty($order)) $order=$this->order;
  1235. $ar['order']=$order;
  1236. $ar['table']=$this->table;
  1237. $ar['_filter']=$this->getFilter(true,$ar);
  1238. // Cas ou on a une requete
  1239. if($this->isThereAQueryActive()){
  1240. $_storedquery=$this->_getSession('query');
  1241. $ar2=array();
  1242. $ar2=array_merge($ar, $_storedquery);
  1243. $ar2['getselectonly']=true;
  1244. $q=$this->xset->procQuery($ar2);
  1245. $ar['select']=str_replace('*','KOID',$q);
  1246. }
  1247. $this->checkOrderFields($order);
  1248. $oids=$this->xset->browseOids($ar);
  1249. // Appliquer les droits si necessaire
  1250. if($this->object_sec) {
  1251. $lang_data=XShell::getLangData();
  1252. $oidsrights=$GLOBALS['XUSER']->getObjectsAccess($this,$lang_data,$oids);
  1253. foreach($oidsrights as $i=>&$rights) {
  1254. if(!array_key_exists('ro',$rights)) unset($oids[$i]);
  1255. }
  1256. }
  1257. if($oid) $myi=array_search($oid,$oids);
  1258. else $myi=0;
  1259. $mylst=count($oids)-1;
  1260. if($myi==0) $navprev=$oids[$mylst];
  1261. else $navprev=$oids[$myi-1];
  1262. if($myi==$mylst) $navnext=$oids[0];
  1263. else $navnext = $oids[$myi+1];
  1264. $navact=$oids[$myi];
  1265. return array($navprev,$navnext,$navact,$myi-1==0,$myi+1==$mylst);
  1266. }
  1267. /// Prépare l'ensemble des éléments d'affichage des fiches
  1268. public function &browse($ar) {
  1269. $p=new XParam($ar,array());
  1270. $order=$p->get('order');
  1271. $select=$p->get('select');
  1272. $tplentry=$p->get('tplentry');
  1273. $editfields=$p->get('editfields');
  1274. $persistent=$p->get('_persistent');
  1275. $assubmodule=$p->get('assubmodule');
  1276. $this->checkOrderFields($order);
  1277. if($this->persistentquery && $persistent) clearSessionVar('filterquery'.$this->_moid);
  1278. // pour gestion de la navigation de page/page en display et edit
  1279. if($this->interactive){
  1280. $this->_setSession('lastorder',$order);
  1281. if($this->isThereAQueryActive()) $this->_clearSession('query');
  1282. }
  1283. $ar['order']=$order;
  1284. $ar['table']=$this->table;
  1285. $pagesize=$p->get('pagesize');
  1286. if(empty($pagesize)) $pagesize=$this->pagesize;
  1287. if(empty($pagesize)) $pagesize=TZR_XMODTABLE_BROWSE_MAXPAGESIZE;
  1288. $ar['pagesize']=$pagesize;
  1289. if(!empty($this->_templates) && !empty($this->btemplates)) {
  1290. $r=&$this->_templates->display(array('oid'=>$this->btemplates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  1291. XShell::toScreen1($tplentry.'t',$r);
  1292. }
  1293. // recherche des donnees
  1294. $ar['_filter']=$this->getFilter(true,$ar);
  1295. if($this->object_sec) {
  1296. $oids=$this->xset->browseOids($ar);
  1297. // calcul des droits sur les objets retournés
  1298. $lang_data = XShell::getLangData();
  1299. $oidsrights=$GLOBALS['XUSER']->getObjectsAccess($this, $lang_data, $oids);
  1300. $oidsrigths2=$noeditoids=array();
  1301. foreach($oidsrights as $i => $rights) {
  1302. if(!array_key_exists('ro',$rights)) unset($oids[$i]);
  1303. else{
  1304. $oidsrights2[$oids[$i]]=$rights;
  1305. if(!empty($editfields) && !array_key_exists('rw',$rights)) $noeditoids[]=$oids[$i];
  1306. }
  1307. }
  1308. if(!empty($oids)){
  1309. if(preg_match('/order[ ]+by/i',$select)) $order='field(KOID,"'.implode('","',$oids).'")';
  1310. else $order=$ar['order'];
  1311. $ar['select']=$this->xset->select_query(array('order'=>$order, 'cond'=>array('KOID'=>array('=',$oids))));
  1312. $ar['noeditoids']=$noeditoids;
  1313. }
  1314. }
  1315. $ar['tplentry']=TZR_RETURN_DATA;
  1316. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  1317. $ar['fieldssec']=$this->getFieldsSec($ar);
  1318. $r=&$this->xset->browse($ar);
  1319. $r['function']='browse';
  1320. $r['_fieldssec']=$ar['fieldssec'];
  1321. if($this->object_sec){
  1322. $r['objects_sec']=array();
  1323. foreach($r['lines_oid'] as $i=>$oid){
  1324. $r['objects_sec'][$i]=$oidsrights2[$oid];
  1325. }
  1326. }else{
  1327. $lang_data = XShell::getLangData();
  1328. $r['objects_sec']=$GLOBALS['XUSER']->getObjectsAccess($this, $lang_data, $r['lines_oid']);
  1329. }
  1330. if(XShell::admini_mode()) {
  1331. // passage du contexte sous module
  1332. $submodcontext = $this->subModuleContext($ar);
  1333. $r['urlparms'] = @$submodcontext['urlparms'];
  1334. if (!$p->get('without_actions')) $this->browse_actions($r, false, $ar);
  1335. if ($this->quickquery && !$assubmodule) {
  1336. $ar['tplentry']=TZR_RETURN_DATA;
  1337. $r['_qq']=$this->quickquery($ar);
  1338. }
  1339. }
  1340. $this->browseSumFields($ar, $r, true);
  1341. return XShell::toScreen1($tplentry,$r);
  1342. }
  1343. /// Parcours le module pour la selection d'un fichier
  1344. public function &browseFiles($ar) {
  1345. $fields = array();
  1346. //cinq champ publié max et les champ fichier
  1347. foreach($this->xset->desc as $fname=>$fdef){
  1348. if( (count($fields) < 5 && $fdef->get_published()) || ($fdef->get_ftype() == 'XFileDef' || $fdef->get_ftype() == 'XImageDef')){
  1349. $fields[]=$fname;
  1350. }
  1351. }
  1352. $ar['selectedfields']=$fields;
  1353. return $this->browse($ar);
  1354. }
  1355. /// Preparartion des donnees pour ecran de parametrage d'impression
  1356. public function prePrintDisplay($ar) {
  1357. $p = new XParam($ar,array());
  1358. $order=$p->get('order');
  1359. $tplentry=$p->get('tplentry');
  1360. if(empty($order)) $order=$this->order;
  1361. $ar['order']=$order;
  1362. $ar['table']=$this->table;
  1363. // recherche des templates d'impression
  1364. if(empty($this->_templates)) $this->_templates=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=TEMPLATES');
  1365. if(!empty($this->_templates)) {
  1366. $q1=$this->_templates->select_query(array('cond'=>array('modid'=>array('=',$this->_moid),
  1367. 'gtype'=>array('=','xmodtable_display_print'))));
  1368. $r=&$this->_templates->browse(array('select'=>$q1,'pagesize'=>100,'tplentry'=>TZR_RETURN_DATA));
  1369. XShell::toScreen1($tplentry.'t',$r);
  1370. }
  1371. $ar['ssmoid']='all';
  1372. for($i=1;$i<=$this->submodmax;$i++) {
  1373. $f='ssmod'.$i;
  1374. $ar['options'][$this->$f]['selectedfields']='all';
  1375. }
  1376. return $this->display($ar);
  1377. }
  1378. function preExportBrowse($ar=NULL){
  1379. $this->prePrintBrowse($ar);
  1380. }
  1381. function preExportDisplay($ar=NULL){
  1382. $this->prePrintDisplay($ar);
  1383. }
  1384. function browse_actions(&$r, $assubmodule=false, $ar=null) {
  1385. $p = new XParam($ar);
  1386. $noeditoids = $p->get('noeditoids');
  1387. if(!is_array($noeditoids)) $noeditoids=array();
  1388. $self=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().'&moid='.$this->_moid.'&oid=<oid>&tplentry=br&function=';
  1389. if(!is_array($r['lines_oid'])) return;
  1390. $approved=XLabels::getSysLabel('general','approved');
  1391. $not_approved=XLabels::getSysLabel('general','not_approved');
  1392. $viewico = XLabels::getSysLabel('general','view');
  1393. $viewtxt = XLabels::getSysLabel('general','view','text');
  1394. $editico = XLabels::getSysLabel('general','edit');
  1395. $edittxt = XLabels::getSysLabel('general','edit','text');
  1396. $delico = XLabels::getSysLabel('general','delete');
  1397. $deltxt = XLabels::getSysLabel('general','delete','text');
  1398. $secico = XLabels::getSysLabel('general','security');
  1399. $sectxt = XLabels::getSysLabel('general','security','text');
  1400. $editlvl=$this->secGroups('edit');
  1401. $dellvl=$this->secGroups('del');
  1402. $hassubmodules=$this->hasSubModules();
  1403. foreach($r['lines_oid'] as $i =>$oid) {
  1404. $oidlvl=array_keys($r['objects_sec'][$i]);
  1405. $self1=str_replace('<oid>',$oid,$self);
  1406. $url=$self1.'display&template=xmodtable/view.html'.$r['urlparms'];
  1407. $r['actions'][$i][0]='<a class="cv8-ajaxlink cv8-dispaction" href="'.$url.'" title="'.$viewtxt.'">'.$viewico.'</a>';
  1408. $r['actions_url'][$i][0]=$url;
  1409. $r['actions_label'][$i][0]=$viewico;
  1410. // edition
  1411. $inter=array_intersect($editlvl,$oidlvl);
  1412. if(!empty($inter) && !in_array($oid, $noeditoids)){
  1413. $url=$self1.'edit&template=xmodtable/edit.html'.$r['urlparms'];
  1414. $r['actions'][$i][1]='<a class="cv8-ajaxlink cv8-editaction" href="'.$url.'" title="'.$edittxt.'">'.$editico.'</a>';
  1415. $r['actions_url'][$i][1]=$url;
  1416. $r['actions_label'][$i][1]=$editico;
  1417. }
  1418. // suppression
  1419. $inter=array_intersect($dellvl,$oidlvl);
  1420. if(!empty($inter) && !in_array($oid, $noeditoids)){
  1421. $url=$self1.'del&template=basic/message.html&skip=1';
  1422. $r['actions'][$i][2]='<a class="cv8-delaction" href="'.$url.'" title="'.$deltxt.'">'.$delico.'</a>';
  1423. $r['actions_url'][$i][2]=$url;
  1424. $r['actions_label'][$i][2]=$deltxt;
  1425. }
  1426. // securité
  1427. if($this->object_sec && !empty($r['objects_sec'][$i]['admin'])) {
  1428. $url='TZR.editSec(\''.$GLOBALS['TZR_SESSION_MANAGER']::complete_self(true).'\',\''.$this->_moid.'\',\''.$oid.'\')';
  1429. $r['actions'][$i][9]='<a href="#" onclick="'.$url.'; return false;" title="'.$sectxt.'">'.
  1430. $secico.'</a>';
  1431. $r['actions_url'][$i][9]=$self1.'secEditSimple&template=xmodule/edit-sec.html';
  1432. $r['actions_label'][$i][9]=$sectxt;
  1433. }
  1434. }
  1435. }
  1436. /// Edition d'une fiche
  1437. function edit($ar) {
  1438. $p=new XParam($ar,array());
  1439. $tplentry=$p->get('tplentry');
  1440. $navdir=$p->get('navdir');
  1441. $ar['table']=$this->table;
  1442. $ar['tplentry']=TZR_RETURN_DATA;
  1443. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  1444. $ar['fieldssec']=$this->getFieldsSec($ar);
  1445. if($this->interactive){
  1446. if($this->trackaccess) $ar['accesslog']=1;
  1447. // Gestion de la nav page/page
  1448. if(!empty($navdir)){
  1449. list($navprev,$navnext,$foo,$isfirst,$islast)=$this->mkNavParms($ar);
  1450. if($navdir=='next') $_REQUEST['oid']=$navnext;
  1451. else $_REQUEST['oid']=$navprev;
  1452. }
  1453. }
  1454. $r2=$this->xset->edit($ar);
  1455. if(!empty($navdir)){
  1456. $r2['_isfirst']=$isfirst;
  1457. $r2['_islast']=$islast;
  1458. }
  1459. // Choix du templates d'affichage s'il existe
  1460. if(!empty($this->_templates) && !empty($this->templates)) {
  1461. $this->_templates->display(array('oid'=>$this->templates,'_options'=>array('error'=>'return'),'tplentry'=>$tplentry.'t'));
  1462. }
  1463. $this->setSubModules($ar, $r2);
  1464. if(XShell::admini_mode()) {
  1465. // calcul des droits
  1466. if ($this->object_sec) {
  1467. $acl=$GLOBALS['XUSER']->listObjectAccess($this, XShell::getLangData(), $p->get('oid'));
  1468. $r3=array_merge($r2, $acl);
  1469. $sec=$GLOBALS['XUSER']->getObjectAccess($this, XShell::getLangData(), $r2['oid']);
  1470. $sec=array_flip($sec[0]);
  1471. $r2['object_sec']=$sec;
  1472. }
  1473. // passage du context sous module
  1474. $submodcontext = $this->subModuleContext($ar);
  1475. $r2['urlparms'] = @$submodcontext['urlparms'];
  1476. }
  1477. if($this->captcha && (!XShell::admini_mode() || XUser::isNobody())) $r2['captcha']=$this->createCaptcha($ar);
  1478. if($tplentry!=TZR_RETURN_DATA) XShell::toScreen1('iacl',$r3);
  1479. return XShell::toScreen1($tplentry,$r2);
  1480. }
  1481. /// Prepare l'edition par lot
  1482. function &editSelection($ar=NULL){
  1483. $p=new XParam($ar,NULL);
  1484. $tplentry=$p->get('tplentry');
  1485. $oids=Kernel::getSelectedOids($p);
  1486. $ar['editbatch']=true;
  1487. $ar['fmoid']=$this->_moid;
  1488. $result=$this->xset->input($ar);
  1489. $result['oids']=$oids;
  1490. return XShell::toScreen1($tplentry,$result);
  1491. }
  1492. /// Prepare l'edition par lot de tout le resultat de la recherche active
  1493. function &editAll($ar=NULL){
  1494. $p=new XParam($ar,NULL);
  1495. $tplentry=$p->get('tplentry');
  1496. if($this->isThereAQueryActive() && empty($clearrequest)) {
  1497. $_storedquery=$this->_getSession('query');
  1498. $ar=array_merge($_storedquery,$ar);
  1499. $ar['editbatch']=true;
  1500. $ar['fmoid']=$this->_moid;
  1501. $ar['tplentry']=TZR_RETURN_DATA;
  1502. $ar['selectedfields']=array('KOID');
  1503. $ar['pagesize']=10000;
  1504. $r1=$this->xset->procQuery($ar);
  1505. $result=$this->editSelection(array('oid'=>$r1['lines_oid']));
  1506. }
  1507. return XShell::toScreen1($tplentry,$result);
  1508. }
  1509. /// Fonction de controle du formulaire
  1510. function procEditCtrl($ar) {
  1511. $p = new XParam($ar,array());
  1512. $captcha_ok = $p->get('captcha_ok','local');
  1513. if($this->captcha && (!XShell::admini_mode() || XUser::isNobody()) && !$captcha_ok){
  1514. $captcha_key = md5($p->get('captcha_key'));
  1515. $captcha_id = $p->get('captcha_id');
  1516. $cnt=countSelectQuery('SELECT COUNT(*) FROM _VARS WHERE name = "CAPTCHA_'.$captcha_id.'" AND value = "'.$captcha_key.'" ');
  1517. updateQuery('DELETE FROM _VARS WHERE name="CAPTCHA_'.$captcha_id.'" or (UPD<"'.date('YmdHis',strtotime('- 20 minutes')).'" AND '.
  1518. 'name LIKE "CAPTCHA_%")');
  1519. if($cnt) {
  1520. return true;
  1521. }else{
  1522. $onerror=$p->get('onerror');
  1523. if(!empty($onerror)) {
  1524. if(!preg_match('@(^http://|^/)@',$onerror)) $onerror=$GLOBALS['TZR_SESSION_MANAGER']::complete_self().$onerror;
  1525. header('Location: '.$onerror);
  1526. die();
  1527. }
  1528. return false;
  1529. }
  1530. }
  1531. return true;
  1532. }
  1533. /// Fonction de controle du formulaire avant insertion
  1534. function procInsertCtrl($ar) {
  1535. return $this->procEditCtrl($ar);
  1536. }
  1537. /// Fonction de controle du formulaire avant duplication
  1538. function procEditDupCtrl($ar) {
  1539. return $this->procEditCtrl($ar);
  1540. }
  1541. /****m* XModTable/procEdit
  1542. * NAME
  1543. * XModTable::procEdit - traitement d'une formulaire préparé avec la méthode edit.
  1544. * DESCRIPTION
  1545. * Traitement d'une formulaire préparé avec la méthode edit. Les données sont modifiées
  1546. * en base de donnée
  1547. * INPUTS
  1548. * Passage de paramètre indirect via $ar
  1549. ****/
  1550. function procEdit($ar) {
  1551. $p=new XParam($ar,array('applyrules'=>true));
  1552. $ar['table']=$this->table;
  1553. $ar['_track']=$this->trackchanges;
  1554. $ar['_archive']=$this->archive;
  1555. $ar['fieldssec']=$this->getFieldsSec($ar);
  1556. $oid = $p->get('oid');
  1557. $tplentry = $p->get('tplentry');
  1558. $applyrules=$p->get('applyrules');
  1559. $noworkflow=$p->get('_noworkflow');
  1560. $langs=$p->get('_langs');
  1561. if (isset($this->xset->desc['PUBLISH']) && !$this->secure('', ':rwv'))
  1562. unset($_REQUEST['PUBLISH'], $_REQUEST['PUBLISH_HID']);
  1563. if(is_array($oid)) {
  1564. $P1=array();
  1565. $reeditone=$p->get('reeditone');
  1566. $editfields = $p->get('editfields');
  1567. $editbatch=$p->get('editbatch');
  1568. foreach($this->xset->desc as $f => $o) {
  1569. if(($editfields=='all') || in_array($f,$editfields)){
  1570. $P1[$f]=$p->get($f);
  1571. $P1[$f.'_HID']=$p->get($f.'_HID');
  1572. }
  1573. }
  1574. foreach($oid as $i=>$oid1) {
  1575. $ar1=array();
  1576. if(!$editbatch){
  1577. foreach($this->xset->desc as $f => $o) {
  1578. if(($editfields=='all') || in_array($f,$editfields)){
  1579. if(isset($P1[$f][$i]) || isset($P1[$f.'_HID'][$i])) {
  1580. $ar1[$f]=$P1[$f][$i];
  1581. $ar1[$f.'_HID']=$P1[$f.'_HID'][$i];
  1582. }
  1583. }
  1584. }
  1585. }else{
  1586. $ar1=$P1;
  1587. }
  1588. $ar1['_options'] = array('local'=>true);
  1589. $ar1['oid']=$oid1;
  1590. $ar1['editfields']=$editfields;
  1591. $ar1['editbatch']=$editbatch;
  1592. $ar1['applyrules']=$applyrules;
  1593. $this->procEdit($ar1);
  1594. }
  1595. if($reeditone){
  1596. $_storedquery=$this->xset->captureQuery(array('_options'=>array('local'=>true),'oids'=>$oid,'order'=>'KOID'));
  1597. $this->_setSession('query',$_storedquery);
  1598. $this->_setSession('lastorder','KOID');
  1599. list($p,$n,$a)=$this->mkNavParms(array('_options'=>array('local'=>true)));
  1600. XShell::setNext('moid='.$this->_moid.'&function=edit&template=xmodtable/edit.html&tplentry=br&oid='.$a.'&usenav=1');
  1601. }
  1602. return;
  1603. }
  1604. if($this->procEditCtrl($ar)) {
  1605. // Traitement des cas ou l'on veut sauver dans plusieurs langues
  1606. $ar['_langs']=$this->getAuthorizedLangs($langs,$oid,'procEdit');
  1607. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  1608. $r=$this->xset->procEdit($ar);
  1609. if($applyrules) {
  1610. XModRule::applyRules($this,$oid);
  1611. }
  1612. /// application du workflow
  1613. if(empty($noworkflow) && XModule::getMoid(XMODWORKFLOW_TOID)) {
  1614. $umod=XModule::singletonFactory(XMODWORKFLOW_TOID);
  1615. $umod->checkAndRun($this, $this, $oid, 'edit');
  1616. }
  1617. if($this->savenext && in_array($this->savenext,array('display','edit')) && $tplentry!=TZR_RETURN_DATA){
  1618. $editfields=$p->get('editfields');
  1619. if(empty($editfields) || count($editfields)==0){
  1620. $submodcontext=$this->subModuleContext($ar);
  1621. XShell::setnext($GLOBALS['TZR_SESSION_MANAGER']::complete_self(true, true).'&moid='.$this->_moid.
  1622. '&function='.$this->savenext.'&template=xmodtable/'.($this->savenext == 'display' ? 'view' : 'edit').'.html&tplentry=br&oid='.
  1623. $oid.@$submodcontext['urlparms']);
  1624. }
  1625. }
  1626. } else {
  1627. if (XShell::admini_mode()) {
  1628. unset($_REQUEST['skip'], $_REQUEST['_skip']);
  1629. XShell::changeTemplate('xmodtable/edit.html');
  1630. XShell::setNext();
  1631. }
  1632. $ar['options']=$this->xset->prepareReEdit($ar);
  1633. $ar['tplentry']= 'br';
  1634. return $this->edit($ar);
  1635. }
  1636. return $r;
  1637. }
  1638. /// Mise à jour de toutes les langues pour lesquel l'utilisateur à les droits
  1639. function procEditAllLang($ar) {
  1640. $ar['_langs']='all';
  1641. return $this->procEdit($ar);
  1642. }
  1643. /// Duplique une fiche à partir d'une edition
  1644. function procEditDup($ar) {
  1645. $p = new XParam($ar, NULL);
  1646. $tplentry = $p->get('tplentry');
  1647. $oid=$p->get('oid');
  1648. $ar['table']=$this->table;
  1649. if($this->procEditDupCtrl($ar)) {
  1650. $ret=$this->xset->procEditDup($ar);
  1651. $this->duplicateSubModules($oid,$ret['oid']);
  1652. if ($this->savenext && in_array($this->savenext,array('display','edit')) && $tplentry!=TZR_RETURN_DATA){
  1653. $oid = $ret['oid'];
  1654. $submodcontext = $this->subModuleContext($ar);
  1655. XShell::setnext($GLOBALS['TZR_SESSION_MANAGER']::complete_self(true, true).'&class='.get_class($this).'&moid='.$this->_moid.'&function='.$this->savenext.'&template=xmodtable/'.($this->savenext == 'display' ? 'view' : 'edit').'.html&tplentry=br&oid='.$oid.@$submodcontext['urlparms']/* vide si pas sous module */);
  1656. }
  1657. } else {
  1658. $options=&$this->xset->prepareReInput($ar);
  1659. $t='xmodtable/new.html';
  1660. XShell::changeTemplate($t);
  1661. XShell::setNext();
  1662. $ar['options']=$options;
  1663. $ar['tplentry']= 'br';
  1664. $this->insert($ar);
  1665. unset($_REQUEST['_skip'],$_REQUEST['skip']);
  1666. return;
  1667. }
  1668. return XShell::toScreen1($tplentry, $ret);
  1669. }
  1670. /// Traitement d'une edition par lot
  1671. function procEditSelection($ar){
  1672. $ar['editbatch']=true;
  1673. return $this->procEdit($ar);
  1674. }
  1675. /// Duplique une fiche
  1676. function duplicate($ar=NULL){
  1677. $p=new XParam($ar);
  1678. $oid=$p->get('oid');
  1679. $ar['oid']=$oid;
  1680. $noid=$this->xset->duplicate($ar);
  1681. $this->duplicateSubModules($oid,$noid);
  1682. return $noid;
  1683. }
  1684. /// Duplication des sous fiches d'une fiche
  1685. function duplicateSubModules($oid,$oiddst) {
  1686. $oids=array();
  1687. $subMods=$this->getSubModules(true);
  1688. foreach($subMods as $subMod) {
  1689. $sel=$subMod['xset']->select_query(array('cond'=>array($subMod['linkfield']=>array('LIKE','%'.$oid.'%'))));
  1690. $ssRecords=$subMod['xset']->browse(array('select'=>$sel,'tplentry'=>TZR_RETURN_DATA,
  1691. 'selected'=>'0','selectedfields'=>$subMod['linkfield']));
  1692. foreach($ssRecords['lines_oid'] as $i=>$ssoid){
  1693. $oids[]=$n=$subMod['mod']->duplicate(array('oid'=>$ssoid,'_options'=>array('local')));
  1694. updateQuery('update '.$subMod['mod']->table.' set '.$subMod['linkfield'].'="'.$oiddst.'" where KOID="'.$n.'"');
  1695. }
  1696. }
  1697. return $oids;
  1698. }
  1699. /****m* XModTable/query
  1700. * NAME
  1701. * XModTable::query - génération du formulaire de requête
  1702. * DESCRIPTION
  1703. * Calcul des éléments du formalaire de requête pour l'ensemble de fichier. Le traitement
  1704. * du formulaire est ensuite assuré par XModTable::procQuery ()
  1705. * INPUTS
  1706. * Passage de paramètre indirect via $ar
  1707. ****/
  1708. function query($ar) {
  1709. $p = new XParam($ar,array());
  1710. $tplentry=$p->get('tplentry');
  1711. $ar['table']=$this->table;
  1712. $ar['fieldssec']=$this->getFieldsSec($ar);
  1713. if($this->interactive && $this->_issetSession('query')) $this->_clearSession('query');
  1714. if($this->interactive && !$this->stored_query) $ar['searchmode']='simple';
  1715. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  1716. $ar['module_filter']=$this->getFilter(true,$ar); // filtre pour les SelectBox
  1717. $r=$this->xset->query($ar);
  1718. if($tplentry!=TZR_RETURN_DATA && XShell::admini_mode() && $this->interactive && XDataSource::sourceExists('QUERIES')) {
  1719. $r1=$this->storedQueries();
  1720. XShell::toScreen1('queries',$r1);
  1721. }
  1722. return XShell::toScreen1($tplentry,$r);
  1723. }
  1724. /// Recherches sauvegardées
  1725. function storedQueries() {
  1726. $queries = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=QUERIES');
  1727. $q=$queries->select_query(array('order'=>'grp',
  1728. 'cond'=>array('modid'=>array('=',$this->_moid),'rtype'=>array('=','table'))));
  1729. $r1=&$queries->browse(array('select'=>$q,'selected'=>0,'tplentry'=>TZR_RETURN_DATA,'pagesize'=>'100'));
  1730. return $r1;
  1731. }
  1732. /****m* XModTable/quickquery
  1733. * NAME
  1734. * XModTable::quickquery - génération du formulaire de requête
  1735. * DESCRIPTION
  1736. * Calcul des éléments du formalaire de requête pour l'ensemble de fichier. Le traitement
  1737. * du formulaire est ensuite assuré par XModTable::procQuery ()
  1738. * INPUTS
  1739. * Passage de paramètre indirect via $ar
  1740. ****/
  1741. function &quickquery($ar) {
  1742. $p = new XParam($ar,array());
  1743. $ar['table']=$this->table;
  1744. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  1745. $r=&$this->xset->quickquery($ar);
  1746. // recherche sur les sous-fiches
  1747. if ($this->submodsearch) {
  1748. // liste id/title
  1749. for($i=1; $i<=$this->submodmax; $i++) {
  1750. $ssmod = 'ssmod'.$i;
  1751. $ssmoid = $this->$ssmod;
  1752. if ($ssmoid) {
  1753. $mod = XModule::objectFactory($ssmoid);
  1754. $sec = $mod->getAccess();
  1755. if (isset($sec['list'])) {
  1756. $title = 'ssmodtitle'.$i;
  1757. $ssmod_title = $this->$title;
  1758. if (empty($ssmod_title))
  1759. $ssmod_title = $mod->modulename;
  1760. $r['submodules'][$i] = $ssmod_title;
  1761. }
  1762. }
  1763. }
  1764. // les criteres retenus dans la recherche
  1765. $r['submodules_searchselected'] = $this->_submodules_searchselected;
  1766. }
  1767. return $r;
  1768. }
  1769. /// Supprime une requete sauvegardée
  1770. function delStoredQuery($ar=NULL) {
  1771. $p=new XParam($ar,array());
  1772. if(XDataSource::sourceExists('QUERIES')) {
  1773. $storename=$p->get('oidr');
  1774. if(!empty($storename)) {
  1775. $queries=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.'QUERIES');
  1776. $queries->del(array('oid'=>$storename));
  1777. }
  1778. }
  1779. }
  1780. /**
  1781. * Affiche le formulaire d'édition des sections fonction de type "Liste"
  1782. * @param $ar array Paramètres de la section précédemment sauvegardés
  1783. * @return $ret array Ensemble des champs d'édition des paramètres de la section fonction
  1784. */
  1785. public function &UIEdit_procQuery($ar=NULL){
  1786. // Récupération des champs de filtrage et ajout dans le groupe "Filtre"
  1787. $ret = $this->query($ar);
  1788. foreach ($ret['fields_object'] as $f) {
  1789. $ret['o'.$f->field]->fielddef->fgroup = $f->fgroup = XLabels::getSysLabel('general','filter','text');
  1790. }
  1791. // Construction des options génériques d'affichage de la liste
  1792. $grp=XLabels::getSysLabel('general','result','text');
  1793. $fs['___storedquery']=XFieldDef::objectFactory((object)array('FIELD'=>'___storedquery','FTYPE'=>'XLinkDef','MULTIVALUED'=>0,
  1794. 'COMPULSORY'=>false,'TARGET'=>'QUERIES',
  1795. 'LABEL'=>XLabels::getSysLabel('xmodtable','stored_query','text')));
  1796. $fs['___storedquery']->filter='modid="'.$this->_moid.'"';
  1797. $fs['___storedquery']->fgroup=$grp;
  1798. $fs['__viewheader']=XFieldDef::objectFactory((object)array('FIELD'=>'__viewheader','FTYPE'=>'XBoolDef','MULTIVALUED'=>0,
  1799. 'COMPULSORY'=>false,
  1800. 'LABEL'=>XLabels::getSysLabel('xmodtable','viewheader','text')));
  1801. $fs['__viewheader']->default=1;
  1802. $fs['__viewheader']->fgroup=$grp;
  1803. $fs['__selectedfields']=XFieldDef::objectFactory((object)array('FIELD'=>'__selectedfields','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  1804. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1805. 'LABEL'=>XLabels::getSysLabel('general','fields','text')));
  1806. $fs['__selectedfields']->doublebox=true;
  1807. $fs['__selectedfields']->fgroup=$grp;
  1808. $fs['__order']=XFieldDef::objectFactory((object)array('FIELD'=>'__order','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  1809. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1810. 'LABEL'=>XLabels::getSysLabel('general','order','text')));
  1811. $fs['__order']->doublebox=$fs['__order']->withorder=$fs['__order']->allowrandom=true;
  1812. $fs['__order']->fgroup=$grp;
  1813. $fs['__filterfields']=XFieldDef::objectFactory((object)array('FIELD'=>'__filterfields','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  1814. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1815. 'LABEL'=>XLabels::getSysLabel('xmodinfotree','filterfields','text')));
  1816. $fs['__filterfields']->doublebox=$fs['__filterfields']->onlyqueryable=true;
  1817. $fs['__filterfields']->fgroup=$grp;
  1818. $fs['__filterlabelin']=XFieldDef::objectFactory((object)array('FIELD'=>'__filterlabelin','FTYPE'=>'XBoolDef','MULTIVALUED'=>0,
  1819. 'COMPULSORY'=>false,
  1820. 'LABEL'=>XLabels::getSysLabel('general','filter','text') .' : '. XLabels::getSysLabel('xfielddef','label_in','text')));
  1821. $fs['__filterlabelin']->default=2;
  1822. $fs['__filterlabelin']->fgroup=$grp;
  1823. $fs['__sortfields']=XFieldDef::objectFactory((object)array('FIELD'=>'__sortfields','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  1824. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1825. 'LABEL'=>XLabels::getSysLabel('xmodinfotree','weborderselector','text')));
  1826. $fs['__sortfields']->doublebox=true;
  1827. $fs['__sortfields']->fgroup=$grp;
  1828. $fs['__sortAscDesc']=XFieldDef::objectFactory((object)array('FIELD'=>'__sortAscDesc','FTYPE'=>'XBoolDef','MULTIVALUED'=>0,
  1829. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1830. 'LABEL'=>XLabels::getSysLabel('xmodinfotree','sortascdesc','text')));
  1831. $fs['__sortAscDesc']->default=2;
  1832. $fs['__sortAscDesc']->fgroup=$grp;
  1833. $fs['__groupfields']=XFieldDef::objectFactory((object)array('FIELD'=>'__groupfields','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  1834. 'COMPULSORY'=>false,'TARGET'=>$this->table,
  1835. 'LABEL'=>XLabels::getSysLabel('xmodinfotree','groupfields','text')));
  1836. $fs['__groupfields']->doublebox=true;
  1837. $fs['__groupfields']->fgroup=$grp;
  1838. $fs['__pagesize']=XFieldDef::objectFactory((object)array('FIELD'=>'__pagesize','FTYPE'=>'XShortTextDef','COMPULSORY'=>false,
  1839. 'LABEL'=>XLabels::getSysLabel('xmodinfotree','max_nb','text')));
  1840. $fs['__pagesize']->default=$this->pagesize;
  1841. $fs['__pagesize']->listbox=false;
  1842. $fs['__pagesize']->fgroup=$grp;
  1843. $fs['__linktodetail']=XFieldDef::objectFactory((object)array('FIELD'=>'__linktodetail','FTYPE'=>'XShortTextDef','COMPULSORY'=>false,
  1844. 'FCOUNT'=>255, 'LABEL'=>XLabels::getSysLabel('xmodinfotree','linktodetail','text')));
  1845. $fs['__linktodetail']->fgroup=$grp;
  1846. $fs['__linktodetail']->listbox=false;
  1847. $fs['__linktodetaillabel']=XFieldDef::objectFactory((object)array('FIELD'=>'__linktodetaillabel','FTYPE'=>'XShortTextDef','COMPULSORY'=>false,
  1848. 'FCOUNT'=>255, 'LABEL'=>XLabels::getSysLabel('xmodinfotree','linktodetaillabel','text')));
  1849. $fs['__linktodetaillabel']->fgroup=$grp;
  1850. $fs['__linktodetaillabel']->listbox=false;
  1851. $fs['__viewpagination']=XFieldDef::objectFactory((object)array('FIELD'=>'__viewpagination','FTYPE'=>'XBoolDef','MULTIVALUED'=>0,
  1852. 'COMPULSORY'=>false,
  1853. 'LABEL'=>XLabels::getSysLabel('xmodtable','viewpagination','text')));
  1854. $fs['__viewpagination']->default=2;
  1855. $fs['__viewpagination']->fgroup=$grp;
  1856. foreach($fs as $fn=>&$f){
  1857. if( empty($ar[$fn]) ){
  1858. $value = $f->default;
  1859. }elseif(is_array($ar[$fn])){
  1860. $value = implode('||',$ar[$fn]);
  1861. }else{
  1862. $value = $ar[$fn];
  1863. }
  1864. $o = $f->edit($value);
  1865. $ret['o'.$fn] = $ret['fields_object'][] = $o;
  1866. }
  1867. // Définit les champs disponibles uniquement en mode expert (caché par défaut aux non admin)
  1868. $ret['__advancedfields'] = array(
  1869. '__viewheader',
  1870. '__filterfields',
  1871. '__filterlabelin',
  1872. '__sortfields',
  1873. '__sortAscDesc',
  1874. '__sortAscDesc',
  1875. '__groupfields',
  1876. '__viewpagination',
  1877. '__linktodetail',
  1878. '__linktodetaillabel',
  1879. '___storedquery',
  1880. '__selectedfields',
  1881. );
  1882. return $ret;
  1883. }
  1884. /**
  1885. * Enregistre les paramètres des sections fonction de type "Liste"
  1886. * @param $ar array Récupère les paramètres par défaut
  1887. * @return $params array Liste des paramètres transformés à enregistrer
  1888. */
  1889. public function &UIProcEdit_procQuery($ar=NULL){
  1890. $p=new XParam($ar,NULL);
  1891. $xbool=new XBoolDef();
  1892. $params=$this->xset->captureQuery($ar);
  1893. $params['___storedquery']=$p->get('___storedquery');
  1894. $params['__selectedfields']=implode('||',$p->get('__selectedfields'));
  1895. $params['__order']=implode('||',$p->get('__order'));
  1896. $params['__filterfields']=implode('||',$p->get('__filterfields'));
  1897. $xbool->field='__filterlabelin';
  1898. $tmp=$xbool->post_edit($p->get('__filterlabelin'),$opt=array('__filterlabelin_HID'=>$p->get('__filterlabelin_HID')));
  1899. $params['__filterlabelin']=$tmp->raw;
  1900. $params['__sortfields']=implode('||',$p->get('__sortfields'));
  1901. $xbool->field='__sortAscDesc';
  1902. $tmp=$xbool->post_edit($p->get('__sortAscDesc'),$opt=array('__sortAscDesc_HID'=>$p->get('__sortAscDesc_HID')));
  1903. $params['__sortAscDesc']=$tmp->raw;
  1904. $params['__groupfields']=implode('||',$p->get('__groupfields'));
  1905. $params['__pagesize']=$p->get('__pagesize');
  1906. $params['__linktodetail']=$p->get('__linktodetail');
  1907. // si on a un alias détail, stoker l'oid correspondant
  1908. if ($params['__linktodetail']) {
  1909. list($ittable) = preg_split('/:/', $p->get('oidit'));
  1910. $params['__linktodetail_oidit'] = selectQuery('select koid from '.$ittable.' where alias="'.$params['__linktodetail'].'"')->fetch(PDO::FETCH_COLUMN);
  1911. // si alias incorect, supprimer
  1912. if (!$params['__linktodetail_oidit'])
  1913. $params['__linktodetail'] = '';
  1914. }
  1915. $params['__linktodetaillabel']=$p->get('__linktodetaillabel');
  1916. $xbool->field='__viewheader';
  1917. $tmp=$xbool->post_edit($p->get('__viewheader'),$opt=array('__viewheader_HID'=>$p->get('__viewheader_HID')));
  1918. $params['__viewheader']=$tmp->raw;
  1919. $xbool->field='__viewpagination';
  1920. $tmp=$xbool->post_edit($p->get('__viewpagination'),$opt=array('__viewpagination_HID'=>$p->get('__viewpagination_HID')));
  1921. $params['__viewpagination']=$tmp->raw;
  1922. return $params;
  1923. }
  1924. /**
  1925. * Affiche une section fonction de type "Liste" dans un gestionnaire de rubriques
  1926. * @param $ar array Récupère les paramètres de la section
  1927. * @return $result array Liste des résultats
  1928. */
  1929. public function &UIView_procQuery($ar=NULL){
  1930. $params = $_REQUEST['sectionopts'][$ar['itoid']];
  1931. $ar['_storedquery'] = $ar['___storedquery'];
  1932. if(!empty($ar['__selectedfields']))
  1933. $selectedfields = explode('||',$ar['__selectedfields']);
  1934. else
  1935. $selectedfields = $this->xset->browsableFields();
  1936. $groupfields = preg_split('/\|\|/', $ar['__groupfields'], 0, PREG_SPLIT_NO_EMPTY);
  1937. $sortfields = preg_split('/\|\|/', $ar['__sortfields'], 0, PREG_SPLIT_NO_EMPTY);
  1938. $orderfields = preg_split('/\|\|/', $ar['__order'], 0, PREG_SPLIT_NO_EMPTY);
  1939. $ar['order'] = implode(',', $orderfields);
  1940. // nb de réponses
  1941. $pagesizes = explode(',', $ar['__pagesize']);
  1942. if ($params['pagesize']) {
  1943. $pagesize = $params['pagesize'];
  1944. $_SESSION['pagesize_'.$ar['itoid']] = $pagesize;
  1945. } else {
  1946. if (issetSessionVar('pagesize_'.$ar['itoid']))
  1947. $pagesize = getSessionVar('pagesize_'.$ar['itoid']);
  1948. elseif($pagesizes[0])
  1949. $pagesize = $pagesizes[0];
  1950. }
  1951. if (!isset($pagesize))
  1952. $pagesize = TZR_XMODTABLE_BROWSE_PAGESIZE;
  1953. // recupération des parametres postés (pagination, ordre, )
  1954. if ($params)
  1955. $ar = array_merge($ar, $params);
  1956. // ajouter les champs de groupage en premier dans l'ordre
  1957. // permettre de trier sur ces champs
  1958. $sqlorder = $ar['order'];
  1959. if ($groupfields) {
  1960. $grpfields = $groupfields;
  1961. $sqlorderfields = preg_split('/\|\|/', $sqlorder, 0, PREG_SPLIT_NO_EMPTY);
  1962. foreach ($sqlorderfields as $i => $orderfield) {
  1963. $field = preg_replace('/( ASC| DESC)/i', '', $orderfield);
  1964. if (($index = array_search($field, $grpfields)) !== false) {
  1965. $grpfields[$index] = $orderfield;
  1966. unset($sqlorderfields[$i]);
  1967. }
  1968. }
  1969. $ar['order'] = implode(',', array_merge($grpfields, $sqlorderfields));
  1970. }
  1971. // retour depuis une fiche
  1972. if (!isset($_SESSION['oids_'.$ar['itoid']])) {
  1973. $do_select = true;
  1974. $first = 0;
  1975. } else {
  1976. // les oids
  1977. $oids = $_SESSION['oids_'.$ar['itoid']];
  1978. if ($params['oid']
  1979. && ($index = array_search($params['oid'], $oids)) !== false) {
  1980. $do_select = false;
  1981. $first = floor($index/$pagesize) * $pagesize;
  1982. }
  1983. // on ne poste pas le filtre (pagination)
  1984. elseif($params && !$params['insidefilter']) {
  1985. $do_select = false;
  1986. $storedfilter = $_SESSION['filter_'.$ar['itoid']];
  1987. $first = $params['first'];
  1988. } else {
  1989. $do_select = true;
  1990. $first = 0;
  1991. }
  1992. }
  1993. // calcul des filtres et récupération des valeurs
  1994. if(!empty($ar['__filterfields'])) {
  1995. $filterfields = preg_split('/\|\|/', $ar['__filterfields'], 0, PREG_SPLIT_NO_EMPTY);
  1996. $filter = array('_preparedquery' => $ar, 'tplentry' => TZR_RETURN_DATA);
  1997. $filter['searchmode'] = 'simple';
  1998. if ($params['insidefilter']) {
  1999. foreach ($filterfields as $field) {
  2000. if ($_REQUEST[$field] && $_REQUEST[$field] != array('0' => '')
  2001. && $_REQUEST[$field]!= array('0' => 'Foo')) {
  2002. $filter[$field] = $_REQUEST[$field];
  2003. $filter[$field.'_empty'] = $_REQUEST[$field.'_empty'];
  2004. $filter[$field.'_op'] = $_REQUEST[$field.'_op'];
  2005. $filter[$field.'_HID'] = $_REQUEST[$field.'_HID'];
  2006. $filter[$field.'_FMT'] = $_REQUEST[$field.'_FMT'];
  2007. $filter[$field.'_PAR'] = $_REQUEST[$field.'_PAR'];
  2008. }
  2009. }
  2010. $ar = array_merge($ar, $filter);
  2011. }
  2012. // pagination
  2013. elseif ($storedfilter) {
  2014. $filter = array_merge($filter, $storedfilter);
  2015. $ar = array_merge($ar, $storedfilter);
  2016. }
  2017. // préparation des inputs
  2018. $filter['selectedfields'] = $filterfields;
  2019. if ($ar['__filterlabelin'] == 1)
  2020. foreach ($filterfields as $field)
  2021. $filter['options'][$field]['labelin'] = true;
  2022. $queryfields = $this->query($filter);
  2023. // mise dans l'ordre du select
  2024. $ordered_filterfields = array_flip($filterfields);
  2025. foreach ($queryfields as $ofield) {
  2026. if ($ofield->field)
  2027. $ordered_filterfields[$ofield->field] = $ofield;
  2028. }
  2029. }
  2030. if ($do_select) {
  2031. // calcul du select
  2032. $quickquery_value = $this->quickquery;
  2033. $this->quickquery = false;
  2034. $ar['getselectonly'] = true;
  2035. $select = $this->procQuery($ar);
  2036. $this->quickquery = $quickquery_value;
  2037. // calcul des oids
  2038. $select = preg_replace('/^select .* from '.$this->table.'/', 'select '.$this->table.'.KOID from '.$this->table, $select);
  2039. if ($rs = selectQuery($select))
  2040. $oids = $rs->fetchAll(PDO::FETCH_COLUMN);
  2041. // verification des droits sur les enregistrements
  2042. if($this->object_sec) {
  2043. $tmp = array('lines_oid' => $oids);
  2044. $this->applyObjectsSec($tmp);
  2045. $oids = $tmp['lines_oid'];
  2046. }
  2047. // sauvegarde des oids en session
  2048. $_SESSION['oids_'.$ar['itoid']] = $oids;
  2049. }
  2050. $result = $this->xset->browse(array(
  2051. 'tplentry' => TZR_RETURN_DATA,
  2052. 'selectedfields' => array_merge($selectedfields, $groupfields),
  2053. 'nocount' => 1,
  2054. 'tlink' => 1,
  2055. 'pagesize' => $pagesize,
  2056. 'where' => 'KOID in ("'.implode('","', array_slice($oids, $first, $pagesize)).'")',
  2057. 'order' => 'field(koid, "'.implode('","', array_slice($oids, $first, $pagesize)).'")',
  2058. 'options' => $ar['options'],
  2059. '_options' => array('genpublishtag' => false)
  2060. ));
  2061. // calcul de la pagination
  2062. $result['pagesize'] = $pagesize;
  2063. $result['first'] = $first;
  2064. $result['last'] = count($oids);
  2065. if ($pagesize < $result['last']) {
  2066. for ($p=0, $i=0; ($i<$result['last']); $p++, $i+=$pagesize)
  2067. $result['pages'][$p] = $i;
  2068. }
  2069. // asciify keywords (url detail)
  2070. for ($i=0; $i<count($result['lines_tlink']); $i++)
  2071. $result['lines_tlink'][$i] = rewriteToAscii(trim($result['lines_tlink'][$i]));
  2072. // passer le filtre au résultat
  2073. $result['filterfields'] = $ordered_filterfields;
  2074. // trie
  2075. $result['defaultOrder'] = implode(',', $orderfields);
  2076. foreach ($sortfields as $field) {
  2077. if ($ar['__sortAscDesc'] == 1) {
  2078. $result['sortfields'][$field] = array(
  2079. 'label' => $this->xset->desc[$field]->label . ' +',
  2080. 'selected' => $field == $sqlorder ? 'selected="selected"' : '');
  2081. $result['sortfields']["$field DESC"] = array(
  2082. 'label' => $this->xset->desc[$field]->label . ' -',
  2083. 'selected' => "$field DESC" == $sqlorder ? 'selected="selected"' : '');
  2084. } else
  2085. $result['sortfields'][$field] = array(
  2086. 'label' => $this->xset->desc[$field]->label,
  2087. 'selected' => $field == $sqlorder ? 'selected="selected"' : '');
  2088. }
  2089. if (count($pagesizes) > 1)
  2090. $result['pagesizes'] = $pagesizes;
  2091. // grouper
  2092. if ($groupfields) {
  2093. $result['groups'] = $this->group($groupfields, $selectedfields, $result);
  2094. // supprimer les champs de groupage (dans le header)
  2095. for ($i=count($result['header_fields'])-1; $i>=0; $i--) {
  2096. if (in_array($result['header_fields'][$i]->field, $groupfields))
  2097. unset($result['header_fields'][$i]);
  2098. }
  2099. $result['header_fields'] = array_values($result['header_fields']);
  2100. }
  2101. // stocker le filtre pour la pagination
  2102. if($params['insidefilter']) {
  2103. $filter['order'] = $ar['order'];
  2104. unset($filter['selectedfields']);
  2105. $_SESSION['filter_'.$ar['itoid']] = $filter;
  2106. }
  2107. // la page ne peut pas être mise en cache
  2108. $GLOBALS['XSHELL']->_cache = false;
  2109. return $result;
  2110. }
  2111. // groupe le résultat d'un browse
  2112. function group($groupfields, $selectedfields, $browse, $limit_characters = 0) {
  2113. $groupfield = array_shift($groupfields);
  2114. $neededfields = array_unique(array_merge($selectedfields, $groupfields));
  2115. foreach ($browse['lines_oid'] as $i => $oid) {
  2116. $line_groupfield = $browse['lines_o'.$groupfield][$i];
  2117. // Dans le cas d'un champ multivalué
  2118. if ($line_groupfield->collection) {
  2119. foreach ($line_groupfield->oidcollection as $j => $oidgroup) {
  2120. $group_label = $line_groupfield->collection[$j]->html;
  2121. if ($limit_characters) $group_label = substr($group_label, 0, $limit_characters);
  2122. if (in_array($oid, $groups[$group_label]['lines_oid'])) continue;
  2123. $groups[$group_label]['lines_oid'][] = $oid;
  2124. $groups[$group_label]['olabel'] = $line_groupfield->collection[$j];
  2125. foreach ($neededfields as $field) {
  2126. $groups[$group_label]['lines_o'.$field][] = &$browse['lines_o'.$field][$i];
  2127. }
  2128. }
  2129. // Champ non multivalué
  2130. } else {
  2131. $group_label = $line_groupfield->html;
  2132. if ($limit_characters) $group_label = substr($group_label, 0, $limit_characters);
  2133. if (in_array($oid, $groups[$group_label]['lines_oid'])) continue;
  2134. $groups[$group_label]['lines_oid'][] = $oid;
  2135. $groups[$group_label]['olabel'] = $browse['lines_o'.$groupfield][$i];
  2136. foreach ($neededfields as $field) {
  2137. $groups[$group_label]['lines_o'.$field][] = &$browse['lines_o'.$field][$i];
  2138. }
  2139. }
  2140. }
  2141. // appel recursif
  2142. if (count($groupfields)) {
  2143. foreach ($groups as $group_label => $group)
  2144. $groups[$group_label] = $this->group($groupfields, $selectedfields, $group);
  2145. }
  2146. ksort($groups);
  2147. return $groups;
  2148. }
  2149. /// Traitement d'une recherche
  2150. function procQuery($ar) {
  2151. $p=new XParam($ar,array('_FIELDS'=>array(),'first'=>0));
  2152. $tplentry=$p->get('tplentry');
  2153. $clearrequest=$p->get('clearrequest');
  2154. $storedquery=$p->get('_storedquery');
  2155. if(!empty($storedquery)) $clearrequest=1;
  2156. $first=$p->get('first');
  2157. $getselectonly=$p->get('getselectonly');
  2158. $persistent=$p->get('_persistent');
  2159. // traitement de la taille des pages
  2160. $pagesize=$p->get('pagesize');
  2161. if(empty($pagesize)) $pagesize=$this->pagesize;
  2162. if(empty($pagesize)) $pagesize=TZR_XMODTABLE_BROWSE_MAXPAGESIZE;
  2163. $ar['pagesize']=$pagesize;
  2164. // Ordre
  2165. $order=$p->get('order');
  2166. $this->checkOrderFields($order);
  2167. $ar['order']=$order;
  2168. $ar['table']=$this->table;
  2169. $ar['tplentry']=TZR_RETURN_DATA;
  2170. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  2171. // Filtre
  2172. if($this->persistentquery && $persistent) clearSessionVar('filterquery'.$this->_moid);
  2173. $ar['_filter']=$this->getFilter(true,$ar);
  2174. $ar['fieldssec']=$this->getFieldsSec($ar);
  2175. // Pour gestion de la navigation page/page en display et edit
  2176. if($this->interactive) $this->_setSession('lastorder',$p->get('order'));
  2177. // Stockage des requêtes nommées
  2178. if(XDataSource::sourceExists('QUERIES')) {
  2179. $storename=$p->get('_storename');
  2180. $storegroup=$p->get('_storegroup');
  2181. // Sauvegarde éventuelle de la requête
  2182. if(!empty($storename)) {
  2183. $st=$this->xset->captureQuery($ar);
  2184. $queries = XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=QUERIES');
  2185. $queries->procInput(array('title'=>$storename, 'rtype'=>'table', 'modid'=>$this->_moid,'grp'=>$storegroup,
  2186. 'query'=>addslashes(serialize($st))));
  2187. }
  2188. }
  2189. // recherche sous fiches
  2190. if ($this->submodsearch)
  2191. $this->checkSSmodFilter($ar);
  2192. // Mode de recherche
  2193. if($this->isThereAQueryActive() && empty($clearrequest) && $this->interactive) {
  2194. // Recuperation de la requete active s'il y en a une
  2195. $_storedquery=$this->_getSession('query');
  2196. $ar=array_merge($_storedquery,$ar);
  2197. } elseif (!empty($storedquery)){
  2198. // Recherche sauvegardée
  2199. $_storedquery = $this->xset->prepareQuery($ar, $storedquery);
  2200. $_storedquery=$this->xset->captureQuery($ar);
  2201. $this->_setSession('query',$_storedquery);
  2202. $ar=array_merge($_storedquery,$ar);
  2203. $ar['_storedquery']='';
  2204. } elseif($this->interactive && sessionActive()) {
  2205. $_storedquery=$this->xset->captureQuery($ar);
  2206. // Mode affinage
  2207. if((int)$clearrequest=='2'){
  2208. $_storedquery2=$this->_getSession('query');
  2209. $_storedquery['_FIELDS']=array_merge($_storedquery2['_FIELDS'],$_storedquery['_FIELDS']);
  2210. $_storedquery=array_merge($_storedquery2,$_storedquery);
  2211. }
  2212. $this->_setSession('query',$_storedquery);
  2213. $ar=array_merge($_storedquery,$ar);
  2214. }
  2215. $r=$this->xset->procQuery($ar);
  2216. if(!empty($getselectonly)) return $r;
  2217. elseif($this->persistentquery && $persistent) setSessionVar('filterquery'.$this->_moid,$r['select']);
  2218. if($this->object_sec) $this->applyObjectsSec($r);
  2219. else $r['objects_sec']=$GLOBALS['XUSER']->getObjectsAccess($this, XShell::getLangData(), $r['lines_oid']);
  2220. $r['function']='procQuery';
  2221. if(!empty($this->_templates) && !empty($this->btemplates)) {
  2222. $r=&$this->_templates->display(array('oid'=>$this->btemplates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  2223. XShell::toScreen1($tplentry.'t',$r);
  2224. }
  2225. if(XShell::admini_mode()) {
  2226. // passage du contexte sous module
  2227. $submodcontext = $this->subModuleContext($ar);
  2228. $r['urlparms'] = @$submodcontext['urlparms'];
  2229. $this->browse_actions($r, false, $ar);
  2230. if ($this->quickquery && !$assubmodule) {
  2231. $ar['tplentry']=TZR_RETURN_DATA;
  2232. $r['_qq']=$this->quickquery($ar);
  2233. }
  2234. }
  2235. $this->browseSumFields($ar,$r,!$this->object_sec);
  2236. return XShell::toScreen1($tplentry, $r);
  2237. }
  2238. /// Parcours le module pour la selection d'un fichier
  2239. public function &procQueryFiles($ar) {
  2240. return $this->procQuery($ar);
  2241. }
  2242. /// traite les filtres sur les sous fiches (présence/absence)
  2243. /// disponible dans le qquery uniquement
  2244. /// complète $ar['_select']
  2245. function checkSSmodFilter(&$ar) {
  2246. $p = new XParam($ar);
  2247. $ssmods_search = $p->get('ssmods_search');
  2248. for ($i=1; $i<=$this->submodmax; $i++) {
  2249. if (in_array("$i", $ssmods_search)) {
  2250. $op = 'in';
  2251. $this->_submodules_searchselected[$i] = $i;
  2252. } elseif (in_array("$i:not", $ssmods_search)) {
  2253. $op = 'not in';
  2254. $this->_submodules_searchselected["$i:not"] = "$i:not";
  2255. } else
  2256. continue;
  2257. $moid = $this->{'ssmod'.$i};
  2258. $linkfield = $this->{'ssmodfield'.$i};
  2259. $ssmod = XModule::objectFactory($moid);
  2260. $table = $ssmod->table;
  2261. // recherche des liens qui pointent vers moi
  2262. if (empty($linkfield)){
  2263. $links = $ssmod->xset->getXLinkDefs(NULL, $this->table);
  2264. if (!empty($links))
  2265. list($foo, $linkfield) = each($links);
  2266. else
  2267. continue;
  2268. }
  2269. if ($ssmod->xset->isTranslatable())
  2270. $cond[] = 'LANG="'.XShell::getLangData().'"';
  2271. $filter = $ssmod->getFilter(true,$ar);
  2272. if (!empty($filter))
  2273. $cond[] = $filter;
  2274. if (!XShell::admini_mode() && $this->xset->fieldExists('PUBLISH'))
  2275. $cond[] = 'PUBLISH=1';
  2276. if (!empty($cond))
  2277. $cond = ' where ' . implode(' and ', $cond);
  2278. else
  2279. $cond = '';
  2280. $ar['_select'][] = "KOID $op (select distinct $linkfield from $table $cond)";
  2281. }
  2282. }
  2283. function UIParam_insert(){
  2284. $ret['__selectedfields']=XFieldDef::objectFactory((object)array('FIELD'=>'__selectedfields','FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  2285. 'TARGET'=>$this->table,
  2286. 'LABEL'=>XLabels::getSysLabel('general','fields','text')));
  2287. $ret['__selectedfields']->doublebox=true;
  2288. $ret['__dispfgroup']=XFieldDef::objectFactory((object)array('FIELD'=>'__dispfgroup','FTYPE'=>'XBoolDef','COMPULSORY'=>1,
  2289. 'LABEL'=>XLabels::getSysLabel('xmodtable','uiinsert_dispfgroup','text')));
  2290. $ret['__labelvalidate']=XFieldDef::objectFactory((object)array('FIELD'=>'__labelvalidate','FTYPE'=>'XShortTextDef','COMPULSORY'=>0,
  2291. 'LABEL'=>XLabels::getSysLabel('xmodtable','uiinsert_btvalidate','text')));
  2292. $ret['__labelvalidate']->listbox=false;
  2293. $ret['__nextalias']=XFieldDef::objectFactory((object)array('FIELD'=>'__nextalias','FTYPE'=>'XShortTextDef','COMPULSORY'=>1,
  2294. 'LABEL'=>XLabels::getSysLabel('xmodtable','uiinsert_okalias','text')));
  2295. $ret['__nextalias']->listbox=false;
  2296. return $ret;
  2297. }
  2298. /// Prepare l'insertion d'une fiche
  2299. function insert($ar) {
  2300. $p=new XParam($ar,array());
  2301. $ar['table']=$this->table;
  2302. $options=$p->get('options');
  2303. $options['PUBLISH']['value']=($this->defaultispublished?'1':'2');
  2304. $ar['options']=$options;
  2305. $tplentry=$p->get('tplentry');
  2306. $ar['tplentry']=TZR_RETURN_DATA;
  2307. $ar['fieldssec']=$this->getFieldsSec($ar);
  2308. $ar['module_filter']=$this->getFilter(true,$ar); // filtre pour les SelectBox
  2309. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  2310. $submodcontext=$this->subModuleContext($ar);
  2311. // insertion en sous fiche, remplir le lien
  2312. if($submodcontext)
  2313. $ar['options'][$submodcontext['_linkedfields'][0]]['value']=$submodcontext['_parentoids'][0];
  2314. $r2=$this->xset->input($ar);
  2315. // choix du templates d'affichage s'il existe
  2316. if(!empty($this->_templates) && !empty($this->templates)) {
  2317. $r=$this->_templates->display(array('oid'=>$this->templates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  2318. XShell::toScreen1($tplentry.'t',$r);
  2319. }
  2320. if($this->captcha) $r2['captcha']=$this->createCaptcha($ar);
  2321. return XShell::toScreen1($tplentry,$r2);
  2322. }
  2323. /// Insere une nouvelle fiche
  2324. function procInsert($ar) {
  2325. $p=new XParam($ar,array('_applyrules'=>true));
  2326. $tplentry=$p->get('tplentry');
  2327. $noworkflow=$p->get('_noworkflow');
  2328. $applyrules=$p->get('_applyrules');
  2329. if($this->procInsertCtrl($ar)) {
  2330. $ar['table']=$this->table;
  2331. $ar['tplentry']=TZR_RETURN_DATA;
  2332. $ar['fieldssec']=$this->getFieldsSec($ar);
  2333. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  2334. // recuperation du contexte sous module
  2335. $submodcontext=$this->subModuleContext($ar);
  2336. if($submodcontext) // insertion en sous fiche, autoriser le champ lien
  2337. $ar['fieldssec'][$submodcontext['_linkedfield'][0]]='rw';
  2338. if(!$p->is_set('PUBLISH')) $ar['PUBLISH']=($this->defaultispublished?1:2);
  2339. $r=$this->xset->procInput($ar);
  2340. if(empty($noworkflow) && XModule::getMoid(XMODWORKFLOW_TOID)) {
  2341. $umod=XModule::singletonFactory(XMODWORKFLOW_TOID);
  2342. $umod->checkAndRun($this, $this, $r['oid'], 'new');
  2343. }
  2344. if($applyrules) {
  2345. XModRule::applyRules($this,$r['oid']);
  2346. }
  2347. if($this->object_sec && $this->owner_sec)
  2348. $GLOBALS['XUSER']->setUserAccess(get_class($this),$this->_moid,XShell::getLangData(),$r['oid'],'admin');
  2349. if(in_array($this->savenext,array('display','edit')) && $tplentry!=TZR_RETURN_DATA){
  2350. XShell::setnext($GLOBALS['TZR_SESSION_MANAGER']::complete_self(true, true).'&moid='.$this->_moid.'&function='.$this->savenext.'&'.
  2351. 'template=xmodtable/'.($this->savenext == 'display' ? 'view' : 'edit').'.html&tplentry=br&oid='.
  2352. $r['oid'].@$submodcontext['urlparms']/* vide si pas sous module */);
  2353. }elseif($p->get('_nextmode')=='edit') {
  2354. if(XShell::admini_mode()) {
  2355. XShell::setNext('&moid='.$this->_moid.'&function=edit&template=xmodtable/edit.html&tplentry=br&oid='.$r['oid'].@$submodcontext['urlparms']/* vide si pas sous module */);
  2356. }else{
  2357. XShell::setTemplates('xmodtable/edit.html');
  2358. XShell::setNext('');
  2359. return $this->edit(array('oid'=>$r['oid'],'tplentry'=>'br','_parentoids'=>$subModuleContext['_parentoids'],
  2360. '_linkedfields'=>$subModuleContext['_linkedfields']));
  2361. }
  2362. }
  2363. }else{
  2364. if (XShell::admini_mode()) {
  2365. unset($_REQUEST['skip'], $_REQUEST['_skip']);
  2366. XShell::changeTemplate('xmodtable/new.html');
  2367. XShell::setNext();
  2368. }
  2369. $ar['options']=$this->xset->prepareReEdit($ar);
  2370. $ar['tplentry']='br';
  2371. return $this->insert($ar);
  2372. }
  2373. return XShell::toScreen1($tplentry, $r);
  2374. }
  2375. public function UIEdit_display($ar) {
  2376. $fs['__oid']=XFieldDef::objectFactory((object)array(
  2377. 'FIELD'=>'__oid', 'FTYPE'=>'XLinkDef', 'COMPULSORY'=>1, 'TARGET'=>$this->table,
  2378. 'LABEL'=>XLabels::getSysLabel('xmodtable','record','text')));
  2379. $fs['__oid']->autocomplete=0;
  2380. $fs['__selectedfields']=XFieldDef::objectFactory((object)array(
  2381. 'FIELD'=>'__selectedfields', 'FTYPE'=>'XTableFieldDef', 'MULTIVALUED'=>1,
  2382. 'TARGET'=>$this->table,
  2383. 'LABEL'=>XLabels::getSysLabel('general','fields','text')));
  2384. $fs['__selectedfields']->doublebox=1;
  2385. $fs['__usegroup']=XFieldDef::objectFactory((object)array(
  2386. 'FIELD'=>'__usegroup', 'FTYPE'=>'XBoolDef', 'MULTIVALUED'=>0, 'COMPULSORY'=>false,
  2387. 'LABEL'=>XLabels::getSysLabel('xmodtable','uiinsert_dispfgroup','text')));
  2388. $fs['__usegroup']->default = 2;
  2389. // choix des sous-modules et de leurs champs
  2390. $ssmod_grp = XLabels::getSysLabel('xmodule','ssmod','text');
  2391. for($i=1; $i<=$this->submodmax; $i++) {
  2392. if ($this->{'ssmod'.$i}) {
  2393. $mod = XModule::objectFactory($this->{'ssmod'.$i});
  2394. $fs['__view_'.$this->{'ssmod'.$i}]=XFieldDef::objectFactory((object)array(
  2395. 'FIELD'=>'__view_'.$this->{'ssmod'.$i}, 'FTYPE'=>'XBoolDef', 'MULTIVALUED'=>0,
  2396. 'COMPULSORY'=>false,
  2397. 'LABEL'=>XLabels::getSysLabel('general','view','text').' '.$mod->modulename));
  2398. $fs['__view_'.$this->{'ssmod'.$i}]->default = 2;
  2399. $fs['__view_'.$this->{'ssmod'.$i}]->fgroup = $ssmod_grp;
  2400. $fs['__selectedfields_'.$this->{'ssmod'.$i}]=XFieldDef::objectFactory((object)array(
  2401. 'FIELD'=>'__selectedfields_'.$this->{'ssmod'.$i}, 'FTYPE'=>'XTableFieldDef','MULTIVALUED'=>1,
  2402. 'TARGET'=>$mod->table,
  2403. 'LABEL'=>XLabels::getSysLabel('general','fields','text').' '.$mod->modulename));
  2404. $fs['__selectedfields_'.$this->{'ssmod'.$i}]->doublebox = 1;
  2405. $fs['__selectedfields_'.$this->{'ssmod'.$i}]->fgroup = $ssmod_grp;
  2406. }
  2407. }
  2408. foreach($fs as $fn=>&$f){
  2409. $value=(is_array($ar[$fn])?implode('||',$ar[$fn]):$ar[$fn]);
  2410. $o=$f->edit($ar[$fn]);
  2411. $ret['o'.$fn]=$ret['fields_object'][]=$o;
  2412. }
  2413. return $ret;
  2414. }
  2415. public function UIProcEdit_display($ar) {
  2416. $p = new XParam($ar);
  2417. $params['__oid'] = $p->get('__oid');
  2418. if(is_array($p->get('__selectedfields'))) $params['__selectedfields'] = implode('||', $p->get('__selectedfields'));
  2419. else $params['__selectedfields']=$p->get('__selectedfields');
  2420. $xbool=new XBoolDef();
  2421. $xbool->field='__usegroup';
  2422. $tmp=$xbool->post_edit($p->get('__usegroup'),$opt=array('__usegroup_HID'=>$p->get('__usegroup_HID')));
  2423. $params['__usegroup']=$tmp->raw;
  2424. for($i=1; $i<=$this->submodmax; $i++) {
  2425. if ($this->{'ssmod'.$i}) {
  2426. $xbool->field = '__view_'.$this->{'ssmod'.$i};
  2427. $tmp = $xbool->post_edit($p->get('__view_'.$this->{'ssmod'.$i}), $opt = array('__view_'.$this->{'ssmod'.$i}.'_HID' => $p->get('__view_'.$this->{'ssmod'.$i}.'_HID')));
  2428. $params['__view_'.$this->{'ssmod'.$i}] = $tmp->raw;
  2429. $params['__selectedfields_'.$this->{'ssmod'.$i}] = implode('||', $p->get('__selectedfields_'.$this->{'ssmod'.$i}));
  2430. }
  2431. }
  2432. return $params;
  2433. }
  2434. public function UIView_display($params) {
  2435. $p = new XParam($params);
  2436. $showsubmodules = 0 ;
  2437. $requested_submodules=array();
  2438. $options=array();
  2439. $oid = $p->get('__oid');
  2440. if (!empty($_REQUEST['oid'])) {
  2441. $oid = $_REQUEST['oid'];
  2442. }
  2443. // controle des droits
  2444. if (!$this->secure($oid, 'display'))
  2445. return false;
  2446. // gestion des sous-modules
  2447. for($i=1; $i<=$this->submodmax; $i++) {
  2448. if ($this->{'ssmod'.$i} && $params['__view_'.$this->{'ssmod'.$i}] == 1) {
  2449. $requested_submodules[] = $this->{'ssmod'.$i};
  2450. $options[$this->{'ssmod'.$i}]['selectedfields'] = explode('||', $params['__selectedfields_'.$this->{'ssmod'.$i}]);
  2451. $showsubmodules = 1;
  2452. }
  2453. }
  2454. $result = $this->display(array(
  2455. 'tplentry' => TZR_RETURN_DATA,
  2456. 'oid' => $oid,
  2457. 'selectedfields' => explode('||',$params['__selectedfields']),
  2458. 'ssmoid' => 'all',
  2459. 'requested_submodules' => $requested_submodules,
  2460. 'options' => $options,
  2461. '_options' => array('genpublishtag' => false, 'error'=>'return')
  2462. ));
  2463. if(!is_array($result))
  2464. $result = array('message'=>$result);
  2465. // canonical link
  2466. if (!empty($_REQUEST['alias']))
  2467. header('Link: <'.$GLOBALS['HOME_ROOT_URL'].$_REQUEST['alias'].'.html?oid='.$oid.'&keywords='.rewriteToAscii($result['link']).'>; rel="canonical"');
  2468. // si on vient d'une liste
  2469. if (!empty($_REQUEST['from']) && !empty($_REQUEST['oid'])) {
  2470. // test que l'oid appartient à une liste
  2471. $oids = $_SESSION['oids_'.$_REQUEST['from']['itoid']];
  2472. if (($current_index = array_search($oid, $oids)) !== false) {
  2473. $result['_from']['alias'] = $_REQUEST['from']['alias'];
  2474. $result['_from']['oidit'] = $_REQUEST['from']['oidit'];
  2475. $result['_from']['itoid'] = $_REQUEST['from']['itoid'];
  2476. $result['_prev_oid'] = $oids[$current_index-1];
  2477. $result['_next_oid'] = $oids[$current_index+1];
  2478. }
  2479. }
  2480. // indiquer au template d'afficher les sous-modules
  2481. $result['_showsubmodules'] = $showsubmodules;
  2482. return $result;
  2483. }
  2484. public function &display($ar) {
  2485. $p=new XParam($ar,array());
  2486. $oid=$p->get('oid');
  2487. $tplentry=$p->get('tplentry');
  2488. $ssmoid=$p->get('ssmoid');
  2489. // On demande l'affiche d'un sous module d'une fiche seulement
  2490. if(!empty($ssmoid) || $ssmoid=='all'){
  2491. $ssmods=array();
  2492. for($i=1;$i<=$this->submodmax;$i++) {
  2493. $f='ssmod'.$i;
  2494. $ssmods[$i]=$this->$f;
  2495. }
  2496. if($ssmoid!='all' && !in_array($ssmoid,$ssmods)) return;
  2497. $r2=array('oid'=>$oid);
  2498. }
  2499. if(empty($ssmoid) || $ssmoid=='all'){
  2500. // Gestion de la nav page/page
  2501. if($this->interactive){
  2502. if($p->is_set('navdir')){
  2503. list($navprev, $navnext)=$this->mkNavParms($ar);
  2504. if($p->get('navdir')=='next') $_REQUEST['oid']=$navnext;
  2505. else $_REQUEST['oid']=$navprev;
  2506. }
  2507. $this->setNavActions($p->get('oid'), 'display', 'xmodtable/view.html');
  2508. if($this->trackaccess) $ar['accesslog']=1;
  2509. }
  2510. $oid=$p->get('oid');
  2511. $ar['table']=$this->table;
  2512. $ar['tplentry']=TZR_RETURN_DATA;
  2513. if(empty($ar['fmoid'])) $ar['fmoid']=$this->_moid;
  2514. $ar['fieldssec']=$this->getFieldsSec($ar);
  2515. $ar['_filter'] = $this->getFilter(true,$ar);
  2516. $r2=$this->xset->display($ar);
  2517. // choix du templates d'affichage s'il existe
  2518. if(!empty($this->_templates) && !empty($this->templates)) {
  2519. $r=&$this->_templates->display(array('oid'=>$this->templates,'_options'=>array('error'=>'return'),'tplentry'=>TZR_RETURN_DATA));
  2520. XShell::toScreen1($tplentry.'t',$r);
  2521. }
  2522. if(XShell::admini_mode() && $this->object_sec) {
  2523. $acl=$GLOBALS['XUSER']->listObjectAccess($this, XShell::getLangData(),$oid);
  2524. $r2=array_merge($r2, $acl);
  2525. $sec=$GLOBALS['XUSER']->getObjectAccess($this, XShell::getLangData(),$oid);
  2526. $sec=array_flip($sec[0]);
  2527. $r2['object_sec']=$sec;
  2528. }
  2529. }
  2530. // passage du context sous module
  2531. if (XShell::admini_mode()) {
  2532. $submodcontext = $this->subModuleContext($ar);
  2533. $r2['urlparms'] = @$submodcontext['urlparms'];
  2534. }
  2535. if(is_array($r2)) $this->setSubModules($ar, $r2);
  2536. return XShell::toScreen1($tplentry,$r2);
  2537. }
  2538. /// Recupere la securité des champs
  2539. function getFieldsSec($ar){
  2540. if(!empty($ar['fieldssec']) && is_array($ar['fieldssec'])) return array_merge($this->fieldssec,$ar['fieldssec']);
  2541. else return $this->fieldssec;
  2542. }
  2543. /// Recherche les data (browse) des sous modules
  2544. function getSubModules($dependentOnly = false) {
  2545. $ssmods=array();
  2546. for($i=1;$i<=$this->submodmax;$i++) {
  2547. if ($dependentOnly && !$this->{'ssmoddependent'.$i})
  2548. continue;
  2549. $f='ssmod'.$i;
  2550. $ssmods[$i]=$this->$f;
  2551. }
  2552. $r = array();
  2553. foreach($ssmods as $i=>$mymoid) {
  2554. if(!empty($mymoid)) {
  2555. $mod1=XModule::objectFactory($mymoid);
  2556. if(!is_object($mod1)) continue;
  2557. $tab1=&$mod1->xset;
  2558. // recherche des liens qui pointent vers moi
  2559. unset($linkfield);
  2560. unset($fieldname);
  2561. $fieldname=$this->{'ssmodfield'.$i};
  2562. if(!empty($fieldname)) {
  2563. $o=$tab1->getField($fieldname);
  2564. if(!empty($o)) {
  2565. $linkfield = $fieldname;
  2566. }
  2567. }
  2568. if(empty($linkfield)) {
  2569. $links1=$tab1->getXLinkDefs();
  2570. foreach($links1 as $j=>$field) {
  2571. $o=$tab1->getField($field);
  2572. if($o->get_target()==$this->table)
  2573. $linkfield = $field;
  2574. }
  2575. }
  2576. if (!empty($linkfield)) {
  2577. $r[]= array('moid'=>$mymoid, 'xset'=>$tab1, 'linkfield'=>$linkfield, 'mod'=>$mod1);
  2578. }
  2579. }
  2580. }
  2581. return $r;
  2582. }
  2583. function hasSubModules($moid=NULL){
  2584. for($i=1;$i<=$this->submodmax;$i++) {
  2585. $f='ssmod'.$i;
  2586. $tmoid=$this->$f;
  2587. if(!empty($tmoid) && (empty($moid) || $tmoid==$moid)) return true;
  2588. }
  2589. return false;
  2590. }
  2591. /// Recherche des données dans les sous-modules, en lecture
  2592. /// ssmoid => all pour calculer tous les sous-modules,
  2593. /// ou moid du sous-module demandé
  2594. /// requested_submodules => tableau des moid des sous-modules à calculer (défaut tous)
  2595. /// l'ordre des sous-modules est conservé
  2596. function setSubModules($ar, &$r) {
  2597. $p=new XParam($ar,array());
  2598. $options=$p->get('options');
  2599. $ssmoid=$p->get('ssmoid');
  2600. // traitement des sous modules
  2601. $ssmods=array();
  2602. for($i=1;$i<=$this->submodmax;$i++) {
  2603. $f='ssmod'.$i;
  2604. $moid=$this->$f;
  2605. if(!empty($ssmoid) && $ssmoid!='all' && $moid!=$ssmoid) continue;
  2606. $ssmods[$i]=$moid;
  2607. }
  2608. $requested_submodules = $p->get('requested_submodules');
  2609. $ssfield=array();
  2610. foreach($ssmods as $i=>$mymoid) {
  2611. if (isset($requested_submodules) && !in_array($mymoid, $requested_submodules)) {
  2612. $r['__ssmod'][]=array();
  2613. $r['__ssaccess'][]=array();
  2614. $r['__ssinsert'][]=false;
  2615. $r['__ssprops'][]=array();
  2616. continue;
  2617. }
  2618. if(!empty($mymoid)) {
  2619. // recherche du module concerné par la sous-fiche
  2620. $mod1=XModule::objectFactory($mymoid);
  2621. if(!is_object($mod1)) continue;
  2622. $sec=$mod1->getAccess();
  2623. $ins=$mod1->secure(NULL,'insert');
  2624. if(isset($sec['ro']) || (isset($sec['list']) && $mod1->object_sec)){
  2625. // recherche de la table qui contient les données
  2626. $tab1=&$mod1->xset;
  2627. // on change le titre si nécessaire
  2628. if(!empty($this->{'ssmodtitle'.$i})) $mod1->modulename=$this->{'ssmodtitle'.$i};
  2629. // on regarde si le champ a ete fixe
  2630. $linkfield=$this->{'ssmodfield'.$i};
  2631. if(!$tab1->fieldExists($linkfield)) $linkfield=NULL;
  2632. // recherche des liens qui pointent vers moi
  2633. if(empty($linkfield)) $links1=&$tab1->getXLinkDefs(NULL,$this->table);
  2634. if(!empty($links1)) list($foo,$linkfield)=each($links1);
  2635. // on fait le browse si on a trouve le champ
  2636. if(!empty($linkfield)) {
  2637. $order1=$p->get('_order');
  2638. $order1=$order1[$mod1->_moid];
  2639. if(empty($order1)) $order1=$mod1->order;
  2640. if(!empty($ssmoid) || !XShell::admini_mode()){
  2641. if(!empty($options[$mymoid]['selectedfields'])){
  2642. if($listfield=$options[$mymoid]['selectedfields']=='all') $listfield=$tab1->getFieldsList();
  2643. else $listfield=$options[$mymoid]['selectedfields'];
  2644. } else {
  2645. $listfield=$tab1->browsableFields();
  2646. }
  2647. }else{
  2648. $listfield=array('KOID');
  2649. }
  2650. $tmp1=array_flip($listfield);
  2651. if(isset($tmp1[$linkfield])) unset($tmp1[$linkfield]);
  2652. $tmp2=array_flip($tmp1);
  2653. // donneer une chance a une classe fille d'étendre le browse des sous fiches
  2654. if (isset($options[$mymoid]['cond'])) {
  2655. $cond = $options[$mymoid]['cond'];
  2656. $cond[$linkfield] = array('=',$r['oid']);
  2657. } else
  2658. $cond = array($linkfield=>array('=',$r['oid']));
  2659. if(!empty($r['oid'])){
  2660. $select=$tab1->select_query(array('order'=>$order1, 'cond'=>$cond, 'where' => $options[$mymoid]['where']));
  2661. $params=array('ssmodule'=>&$mod1,
  2662. 'issmodule'=>$i,
  2663. 'parentoid'=>$r['oid'],
  2664. 'linkedfield'=>$linkfield,
  2665. 'select'=>$select,
  2666. 'selectedfields'=>$tmp2,
  2667. 'selectedtypes'=>array(),
  2668. 'selectedprops'=>array(),
  2669. 'options' => $options[$mymoid]);
  2670. $b1 = &$this->browseSubModule($ar, $params, $r);
  2671. }else{
  2672. $params=array('ssmodule'=>&$mod1,
  2673. 'issmodule'=>$i,
  2674. 'parentoid'=>'',
  2675. 'linkedfield'=>$linkfield,
  2676. 'select'=>'select KOID from '.$mod1->table.' order by KOID limit 1',
  2677. 'selectedfields'=>$tmp2,
  2678. 'selectedtypes'=>array(),
  2679. 'selectedprops'=>array(),
  2680. 'options' => $options[$mymoid]);
  2681. $b1 = &$this->browseSubModule($ar, $params, $r);
  2682. }
  2683. // preparation des données pour affichage
  2684. $r['__ssmod'][]=$b1;
  2685. $r['__ssaccess'][]=$sec;
  2686. $r['__ssinsert'][]=$ins;
  2687. $r['__ssprops'][]=get_object_vars($mod1);
  2688. $r['__ssprops'][count($r['__ssprops'])-1]['linkedfield']= $linkfield;
  2689. $r['__ssprops'][count($r['__ssprops'])-1]['activate_additem']= $this->{'ssmodactivate_additem'.$i};
  2690. }
  2691. }else{
  2692. $r['__ssmod'][]=array();
  2693. $r['__ssaccess'][]=$sec;
  2694. $r['__ssinsert'][]=$ins;
  2695. $r['__ssprops'][]=get_object_vars($mod1);
  2696. $r['__ssprops'][count($r['__ssprops'])-1]['linkedfield']= $linkfield;
  2697. $r['__ssprops'][count($r['__ssprops'])-1]['activate_additem']= $this->{'ssmodactivate_additem'.$i};
  2698. }
  2699. }
  2700. }
  2701. }
  2702. /// Appel au browse d'un module dans le cadre de l'edition ou de la visualisation de la fiche parente
  2703. function &browseSubModule(&$ar, &$browseparm, &$result){
  2704. $p = new XParam($ar, array());
  2705. // champ de tri
  2706. $orderfield = $p->get('orderfield');
  2707. // module trie
  2708. $ordermoid = $p->get('ssmodorder');
  2709. // champ en edition demande(s)
  2710. $editfield = $p->get('editfield');
  2711. // module en edition
  2712. $editmoid = $p->get('ssmoidedit');
  2713. // module en enregistrement
  2714. $savemoid = $p->get('ssmoidsave');
  2715. // faudrait extaire les champs du champ editer pour pas avoir de conflits ...
  2716. $editfields = false;
  2717. $select = $browseparm['select'];
  2718. $selectedfields = $browseparm['selectedfields'];
  2719. $ssmodule = &$browseparm['ssmodule'];
  2720. $filter = $browseparm['filter'];
  2721. $order = '';
  2722. $editfields = '';
  2723. // traitement de la mise jour des sous fiches
  2724. if (!empty($editfield) && $savemoid == $browseparm['ssmodule']->_moid) {
  2725. if ($editfield != 'all')
  2726. $editfieldsname = array($editfield);
  2727. else
  2728. $editfieldsname = $browseparm['selectedfields'];
  2729. $lar = array();
  2730. // on construit toutes les valeurs dans un contexte qui sera local
  2731. foreach($editfieldsname as $foo=>$fn){
  2732. $lar[$fn] = $p->get($fn);
  2733. $lar[$fn.'_HID'] = $p->get($fn.'_HID');
  2734. // a completer pour les champs complexes etc ?
  2735. // semble ok texte, oui/non, date, liens liste de valeurs
  2736. }
  2737. $lar['tplentry']=TZR_RETURN_DATA;
  2738. $lar['editfields']=$editfieldsname;
  2739. // Selection des oid uniquement du module concerné
  2740. $lar['oid']=$p->get('ssoid'.$savemoid);
  2741. $lar['_options']=array('local'=>true);
  2742. if($browseparm['ssmodule']->object_sec){
  2743. foreach($lar['oid'] as $i=>$foo){
  2744. $sec=$browseparm['ssmodule']->secure($foo,'procEdit');
  2745. if(!$sec) unset($lar['oid'][$i]);
  2746. }
  2747. }else{
  2748. $sec=$browseparm['ssmodule']->secure('','procEdit');
  2749. if(!$sec) $lar['oid']=array();
  2750. }
  2751. if(!empty($lar['oid'])){
  2752. $browseparm['ssmodule']->procEdit($lar);
  2753. }
  2754. // ajout des prop pour focus
  2755. $browseparm['ssmodule']->focused=true;
  2756. }
  2757. // traitement du passage en mode edit
  2758. if (!empty($editfield) && $editmoid == $browseparm['ssmodule']->_moid) {
  2759. if ($editfield == 'all')
  2760. $editfields = $browseparm['selectedfields'];
  2761. else
  2762. $editfields = array($editfield);
  2763. // ajout des prop
  2764. $browseparm['ssmodule']->focused=true;
  2765. $browseparm['ssmodule']->edited=true;
  2766. $browseparm['ssmodule']->editfield=$editfield;
  2767. }
  2768. // traitement du tri
  2769. if (!empty($orderfield) && $ordermoid == $browseparm['ssmodule']->_moid){
  2770. $order = $orderfield;
  2771. $browseparm['ssmodule']->focused=true;
  2772. }
  2773. // traitement du contexte sous module
  2774. if ($submodcontext = $this->subModuleContext($ar)) {
  2775. $parentoids = $submodcontext['_parentoids'];
  2776. array_unshift($parentoids, $browseparm['parentoid']);
  2777. $linkedfields = $submodcontext['_linkedfields'];
  2778. array_unshift($linkedfields, $browseparm['linkedfield']);
  2779. } else {
  2780. $parentoids = array($browseparm['parentoid']);
  2781. $linkedfields = array($browseparm['linkedfield']);
  2782. }
  2783. // browse std du sous module avec les editfields et order
  2784. return $ssmodule->browse(array('_options'=>array('local'=>true),
  2785. 'select'=>$select,
  2786. 'tplentry'=>TZR_RETURN_DATA,
  2787. 'selected'=>'0',
  2788. 'selectedfields'=>$selectedfields,
  2789. 'pagesize'=>'200',
  2790. 'editfields'=>$editfields,
  2791. 'order'=>$order,
  2792. 'assubmodule'=>true,
  2793. 'selectedfields'=>$selectedfields,
  2794. 'options'=>$browseparm['options'],
  2795. 'nocount'=>$browseparm['options']['nocount'],
  2796. '_parentoids'=>$parentoids,
  2797. '_linkedfields'=>$linkedfields
  2798. )
  2799. );
  2800. }
  2801. function status($ar=NULL) {
  2802. parent::status($ar);
  2803. $b1=&XShell::from_screen('br');
  2804. $nb=0;
  2805. if(!empty($b1['lines_oid']))
  2806. $nb=max(count($b1['lines_oid']),$b1['last']);
  2807. if($nb==1)
  2808. $msg=$nb.' '.XLabels::getSysLabel('xmodtable','record','text');
  2809. elseif($nb>1)
  2810. $msg=$nb.' '.XLabels::getSysLabel('xmodtable','records','text');
  2811. $msg1=XShell::from_screen('imod','status');
  2812. if(empty($msg)) $msg1=array();
  2813. if(!empty($msg)) $msg1[]=$msg;
  2814. XShell::toScreen2('imod','status',$msg1);
  2815. }
  2816. /// Liste des tables utilisé par le module
  2817. public function usedTables() {
  2818. return array($this->table);
  2819. }
  2820. /// Liste des tables dont les objects sont consultables dans le module
  2821. public function usedMainTables() {
  2822. return array($this->table);
  2823. }
  2824. /// Liste des boid utilisés par le module
  2825. function usedBoids() {
  2826. return array($this->xset->getBoid());
  2827. }
  2828. protected function _exportXLS(&$ar) {
  2829. require_once('add-ons/PHPExcel/PHPExcel.php');
  2830. $p=new XParam($ar);
  2831. $fmt=$p->get('fmt');
  2832. $tplentry=$p->get('tplentry');
  2833. $oidisvisible=$p->get('oidisvisible');
  2834. $fname=$p->get('fname');
  2835. if(empty($fname)){
  2836. if(!empty($this->modulename)) $fname='Export '.$this->modulename;
  2837. else $fname='Export '.$this->xset->table_title;
  2838. $fname = rewriteToAscii($fname);
  2839. }
  2840. $fname=str_replace(' ','_',removeaccents($fname));
  2841. $br=&XShell::from_screen('br');
  2842. $ss=new PHPExcel();
  2843. $ss->setActiveSheetIndex(0);
  2844. $ws=$ss->getActiveSheet();
  2845. $ws->setTitle('Main');
  2846. if (isset($oidisvisible)) {
  2847. $ws->SetCellValue('A1','OID');
  2848. $pad = 1;
  2849. } else
  2850. $pad = 0;
  2851. foreach($br['header_fields'] as $j => &$f1) {
  2852. $l=$f1->get_label();
  2853. convert_charset($l,TZR_INTERNAL_CHARSET,'UTF-8');
  2854. $ws->setCellValueByColumnAndRow($j+$pad,1,$l);
  2855. }
  2856. $ws->getStyle('A1:'.PHPExcel_Cell::stringFromColumnIndex($j+$pad).'1')->getFont()->setBold(true);
  2857. foreach($br['lines_oid'] as $i=>$oid) {
  2858. if($pad == 1) $ws->SetCellValue('A'.($i+2),$oid);
  2859. foreach($br['header_fields'] as $j => &$f1) {
  2860. $f1->writeXLS($ws,$i+2,$j+$pad,$br['lines_o'.$f1->field][$i],0,$ss);
  2861. }
  2862. }
  2863. if($fmt=='xl07'){
  2864. require_once('add-ons/PHPExcel/PHPExcel/Writer/Excel2007.php');
  2865. $objWriter=new PHPExcel_Writer_Excel2007($ss);
  2866. }else{
  2867. require_once('add-ons/PHPExcel/PHPExcel/Writer/Excel5.php');
  2868. $objWriter=new PHPExcel_Writer_Excel5($ss);
  2869. }
  2870. if($tplentry==TZR_RETURN_DATA) {
  2871. $fname=TZR_TMP_DIR.uniqid().'-'.$fname;
  2872. if($fmt=='xl07')
  2873. $fname .= '.xlsx';
  2874. else
  2875. $fname .= '.xls';
  2876. $objWriter->save($fname);
  2877. return $fname;
  2878. }else{
  2879. ob_clean();
  2880. if($fmt=='xl07'){
  2881. header('Content-Disposition: attachment;filename="'.$fname.'.xlsx"');
  2882. header('Cache-Control: max-age=0');
  2883. header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  2884. $objWriter->save('php://output');
  2885. }else{
  2886. header('Content-Disposition: attachment;filename="'.$fname.'.xls"');
  2887. header('Cache-Control: max-age=0');
  2888. header('Content-Type: application/vnd.ms-excel');
  2889. $objWriter->save('php://output');
  2890. }
  2891. die();
  2892. }
  2893. }
  2894. protected function _exportHTML(&$ar) {
  2895. $p=new XParam($ar,array());
  2896. $tplentry=$p->get('tplentry');
  2897. $fname=$p->get('fname');
  2898. if(empty($fname)){
  2899. if(!empty($this->modulename)) $fname='Export '.$this->modulename;
  2900. else $fname='Export '.$this->xset->table_title;
  2901. }
  2902. $fname=str_replace(' ','_',removeaccents($fname)).'.html';
  2903. $txt='<html>';
  2904. $txt.='<style type="text/css">';
  2905. $txt.='TH {text-align: right;vertical-align:top;}';
  2906. $txt.='</style>';
  2907. $txt.='<body>';
  2908. $br=&XShell::from_screen('br');
  2909. $table = $p->get('table');
  2910. $oidisvisible = $p->get('oidisvisible');
  2911. if($table=='table') {
  2912. $txt.='<table>';
  2913. if($oidisvisible) $ext='OID';
  2914. $txt.='<tr><th><!-- OID -->'.$ext.'</th>';
  2915. foreach($br['header_fields'] as $j => &$f1) {
  2916. $l=$f1->get_label();
  2917. $txt.='<th class="tzr-exp-header">'.$l.'<!-- Field:'.$j.' --></th>';
  2918. }
  2919. $txt.='</tr>'."\n";
  2920. for($i=0;$i<count($br['lines_oid']);$i++) {
  2921. $oid=$br['lines_oid'][$i];
  2922. if($oidisvisible) $ext=$oid;
  2923. $txt.='<tr><td><!-- '.$oid.' -->'.$ext.'</td>';
  2924. foreach($br['header_fields'] as $j => &$f1) {
  2925. $c=$f1->field;
  2926. $txt.='<td class="export-'.$c.'">';
  2927. if(!empty($br['lines_o'.$c][$i]->url)) {
  2928. $lab=$br['lines_o'.$c][$i]->text;
  2929. if(empty($lab)) $lab='Link';
  2930. $txt2='<a href="'.$GLOBALS['HOME_ROOT_URL'].$br['lines_o'.$c][$i]->url.'">'.$lab.'</a>';
  2931. $txt.=$br['lines_o'.$c][$i]->html;
  2932. }else{
  2933. $txt.=$br['lines_o'.$c][$i]->html;
  2934. }
  2935. $txt.='</td>';
  2936. }
  2937. $txt.='</tr>'."\n";
  2938. }
  2939. $txt.='</table></body></html>';
  2940. }elseif($table=='file') {
  2941. for($i=0;$i<count($br['lines_oid']);$i++) {
  2942. $txt.='<table border="0" bgcolor="#DDDDDD" width="100%"><tr><td>Page #'.$i.'</td></tr></table>';
  2943. $txt.='<table id="'.$br['lines_oid'][$i].'">';
  2944. $txt.='<tr><th><label id="label-KOID">Object ID</label></th><td ID="content-KOID">'.$br['lines_oid'][$i].'</td></tr>';
  2945. foreach($br['header_fields'] as $j => &$f1) {
  2946. $c=$f1->field;
  2947. $txt.='<tr><th><label id="label-'.$c.'">'.$f1->label.'</label></th>';
  2948. $txt.='<td ID="content-'.$c.'">'.$br['lines_o'.$c][$i]->html.'</td></tr>'."\n";
  2949. }
  2950. $txt.='</table>'."\n";
  2951. }
  2952. $txt.='</body></html>';
  2953. }
  2954. if($tplentry==TZR_RETURN_DATA){
  2955. $fname=TZR_TMP_DIR.uniqid().'-'.$fname;
  2956. file_put_contents($fname,$txt);
  2957. return $fname;
  2958. }else{
  2959. die($txt);
  2960. }
  2961. }
  2962. // Export d'un browse au format csv
  2963. public function _exportCSV(&$ar) {
  2964. $p= new XParam($ar,array());
  2965. $tplentry=$p->get('tplentry');
  2966. $fsep=$p->get('csvfsep');
  2967. $textsep=$p->get('csvtextsep');
  2968. $charset=stripslashes($p->get('csvcharset'));
  2969. $oidisvisible=$p->get('oidisvisible');
  2970. $exportfiles=$p->get('exportfiles');
  2971. $selectedfields=$p->get('selectedfields');
  2972. $fname=$p->get('fname');
  2973. if(empty($fname)){
  2974. if(!empty($this->modulename)) $fname='Export '.$this->modulename;
  2975. else $fname='Export '.$this->xset->table_title;
  2976. }
  2977. $fname=str_replace(' ','_',removeaccents($fname)).'.csv';
  2978. $br=&XShell::from_screen('br');
  2979. $csv=$headers=array();
  2980. if($oidisvisible) $headers[]='OID';
  2981. foreach($br['header_fields'] as $j => &$f1) {
  2982. $headers[]=$textsep.$f1->get_label().$textsep;
  2983. }
  2984. $csv[]=implode($fsep,$headers);
  2985. foreach($br['lines_oid'] as $i=>$oid){
  2986. $row=array();
  2987. if($oidisvisible) $row[]=$br['lines_oid'][$i];
  2988. foreach($br['header_fields'] as $j => &$f1) {
  2989. $row[]=$f1->writeCSV($br['lines_o'.$f1->field][$i],$textsep);
  2990. }
  2991. $csv[]=implode($fsep,$row);
  2992. }
  2993. $csv=implode("\r\n",$csv);
  2994. convert_charset($csv,TZR_INTERNAL_CHARSET,$charset);
  2995. if($tplentry==TZR_RETURN_DATA){
  2996. $fname=TZR_TMP_DIR.uniqid().'-'.$fname;
  2997. file_put_contents($fname,$txt);
  2998. return $fname;
  2999. }else{
  3000. ob_clean();
  3001. header('Content-Type: text/csv; charset='.$charset);
  3002. header('Content-Transfer-Encoding:'.$charset);
  3003. header('Content-disposition: attachment; filename='.$fname);
  3004. header('Content-Length: '.strlen($csv));
  3005. echo $csv;
  3006. exit(0);
  3007. }
  3008. }
  3009. public function export($ar) {
  3010. $p=new XParam($ar,array());
  3011. $fmt=$p->get('fmt');
  3012. $target=$p->get('_target');
  3013. $linkedfield=$p->get('_linkedfield');
  3014. $tplentry=$p->get('tplentry');
  3015. $exportfiles=$p->get('exportfiles');
  3016. $exportftp=$p->get('exportftp');
  3017. $selectedfields=$p->get('selectedfields');
  3018. $ar['selected']='0';
  3019. $ar['pagesize']='100000';
  3020. $ar['norow']=1;
  3021. $ar['nodef']=1;
  3022. $ar['_options']=array('genpublishtag'=>false);
  3023. if($fmt=='xl' || $fmt=='xl07') $ar['_format']='application/excel';
  3024. $oldinteractive=$this->interactive;
  3025. $this->interactive=false;
  3026. $query = $this->getContextQuery($ar);
  3027. if(!empty($target) && ($target!=$this->_moid)){
  3028. $mod=XModule::objectFactory($target);
  3029. if($mod->secure('','export')){
  3030. $oids = $this->xset->browseOids(array('select' => $query, 'local' => true));
  3031. $rs = selectQuery('select KOID from '.$mod->table.' where '.$linkedfield.' in ("'.implode('","',$oids).'")');
  3032. unset( $ar['_selected']);
  3033. while($ors=$rs->fetch()) {
  3034. $ar['_selected'][$ors['KOID']] = 'on';
  3035. }
  3036. return $mod->export($ar);
  3037. } else {
  3038. XShell::redirect2auth();
  3039. }
  3040. }
  3041. $ar['select']=$query;
  3042. $browse = $this->browse($ar);
  3043. $this->interactive=$oldinteractive;
  3044. if($exportfiles || $exportftp) $ar['tplentry']=TZR_RETURN_DATA;
  3045. if($fmt=='xl' || $fmt=='xl07') $file_name=$this->_exportXLS($ar);
  3046. if($fmt=='html') $file_name=$this->_exportHTML($ar);
  3047. if($fmt=='csv') $file_name=$this->_exportCSV($ar);
  3048. if($exportftp){
  3049. $scheduler=new XModScheduler();
  3050. $o=array();
  3051. $o['function']='exportFilesBatch';
  3052. $o['uid']=getSessionVar('UID');
  3053. $o['ftpserver']=$p->get('ftpserver');
  3054. $o['ftplogin']=$p->get('ftplogin');
  3055. $o['ftppassword']=$p->get('ftppassword');
  3056. $o['select']=$query;
  3057. $o['selectedfields']=$selectedfields;
  3058. $o['fname']=$file_name;
  3059. $roid=$scheduler->createJob($this->_moid,date('Y-m-d H:i:s'),'Export with files',$o,'',$file_name,NULL);
  3060. XShell::setNext('template=basic/message-popup.html&message='.rawurlencode(XLabels::getSysLabel('xmodtable','exportfilescreated')).'&popupmode=1');
  3061. }
  3062. elseif($exportfiles) {
  3063. $zip = $this->exportToZip($file_name, $browse);
  3064. if ($zip['error']) {
  3065. XShell::setNext('template=basic/message-popup.html&message='.rawurlencode($zip['message']).'&popupmode=1');
  3066. return;
  3067. }
  3068. $zipsize = filesize(TZR_TMP_DIR.$zip['zipname']);
  3069. if (!empty($GLOBALS['TZR_DLSTATS'][$this->table])
  3070. && $GLOBALS['TZR_DLSTATS'][$this->table] == '_all')
  3071. XModDLStats::trace($GLOBALS['XUSER']->_curoid, $this->_moid, $zip['zipname'], $zipsize);
  3072. header('Content-type: application/zip');
  3073. header('Content-Disposition: attachment; filename="' . $zip['zipname'] . '"');
  3074. header('Content-length: ' . $zipsize);
  3075. readfile(TZR_TMP_DIR.$zip['zipname']);
  3076. unlink(TZR_TMP_DIR.$zip['zipname']);
  3077. }
  3078. }
  3079. /// Permet d'exporter les fichiers via scheduler (est appelé suite à un export browse avec export des fichiers)
  3080. function exportFilesBatch(XModScheduler &$scheduler,&$o,&$more){
  3081. $ar=(array)$more;
  3082. $ftpserver=$ar['ftpserver'];
  3083. $ftplogin=$ar['ftplogin'];
  3084. $ftppass=$ar['ftppassword'];
  3085. $ftp=ftp_connect($ftpserver);
  3086. if(!$ftp) $msg='Unable to connect to '.$ftpserver;
  3087. else{
  3088. $ftpl=ftp_login($ftp,$ftplogin,$ftppass);
  3089. if(!$ftpl) $msg='Error logging into '.$ftpserver;
  3090. else{
  3091. $browse = $this->browse($ar);
  3092. $zip = $this->exportToZip($ar['fname'], $browse);
  3093. if($ret['error']){
  3094. $msg=$ret['message'];
  3095. }else{
  3096. $dir=$ret['dir'];
  3097. $ftpp=ftp_put($ftp,$zip['zipname'],TZR_TMP_DIR.$zip['zipname'],FTP_BINARY);
  3098. if(!$ftpp)
  3099. $msg='Unable to send file '.$zip['zipname'].' on the ftp server '.$ftpserver;
  3100. elseif (!empty($GLOBALS['TZR_DLSTATS'][$this->table])
  3101. && $GLOBALS['TZR_DLSTATS'][$this->table] == '_all')
  3102. XModDLStats::trace($GLOBALS['XUSER']->_curoid, $this->_moid, $zip['zipname'], filesize($zip['zipname']));
  3103. }
  3104. }
  3105. }
  3106. ftp_close($ftp);
  3107. unlink(TZR_TMP_DIR.$zip['zipname']);
  3108. if(!empty($msg))
  3109. $msg=sprintf(XLabels::getSysLabel('xmodtable','exportfileserror'),$msg);
  3110. else
  3111. $msg=sprintf(XLabels::getSysLabel('xmodtable','exportfilesok'),$zip['zipname']);
  3112. $GLOBALS['XUSER']->sendMail2User(sprintf(XLabels::getSysLabel('xmodtable','exportfilessub'),$this->modulename),$msg,$GLOBALS['XUSER']->email());
  3113. return $msg;
  3114. }
  3115. /// Cree une archive zip avec le fichier d'export et les fichiers du module
  3116. /// @param $file fichier exporte
  3117. /// @param $browse browse des fiches a exporter
  3118. /// @return array
  3119. function exportToZip($file, &$browse){
  3120. $ret = $this->exportFiles($browse);
  3121. if($ret['error'])
  3122. return $ret;
  3123. $dir = $ret['dir'];
  3124. $file_name = basename($file);
  3125. $file_name = substr($file_name,strpos($file_name,'-')+1);
  3126. $file_name = str_replace('.', '_'.date('Y-m-d_H-i-s').'.', $file_name);
  3127. rename($file, TZR_TMP_DIR.$dir.'/'.$file_name);
  3128. $zipname = $file_name.'.zip';
  3129. exec('(cd '.TZR_TMP_DIR.$dir.';zip -rm ../'.$zipname.' . )2>&1 > /dev/null');
  3130. rmdir(TZR_TMP_DIR.$dir);
  3131. return array('zipname'=>$zipname,'error'=>false);
  3132. }
  3133. /// Exporte les fichiers du module (copie dans un repertoire)
  3134. /// @param $browse browse des fiches a exporter
  3135. function exportFiles(&$browse){
  3136. ini_set('max_execution_time', 600);
  3137. $dirname = uniqid('exportfiles').'/';
  3138. $dir=TZR_TMP_DIR.$dirname;
  3139. $ret=mkdir($dir);
  3140. if(!$ret){
  3141. XDir::unlink($dir);
  3142. return array('error'=>true,'message'=>'Can\'t create export dir');
  3143. }
  3144. $fields=array();
  3145. foreach($browse['header_fields'] as $j=>$f) {
  3146. if(in_array($f->ftype,array('XImageDef','XFileDef','XFolderDef'))){
  3147. $fields[$f->field]=$f->ftype;
  3148. $ret=mkdir($dir.$f->field.'/');
  3149. if(!$ret){
  3150. XDir::unlink($dir);
  3151. return array('error'=>true,'message'=>'Can\'t create export dir');
  3152. }
  3153. }
  3154. }
  3155. foreach($browse['lines_oid'] as $i=>$oid) {
  3156. foreach($fields as $field_name => $field_type) {
  3157. $ofile = $browse['lines_o'.$field_name][$i];
  3158. if($field_type=='XImageDef' || $field_type=='XFileDef'){
  3159. if(empty($ofile->filename)) continue;
  3160. // a voir, nom du fichier dans le zip
  3161. // $ext=substr($ofile->originalname,strrpos($ofile->originalname,'.'));
  3162. // $fn=basename($ofile->filename).$ext;
  3163. $fn = $ofile->originalname;
  3164. if ($ofile->filedef->gzipped == 1) {
  3165. $fh = gzopen($ofile->filename, 'r');
  3166. $content = gzread($fh, 100000000);
  3167. gzclose($fh);
  3168. $ret = file_put_contents($dir.$field_name.'/'.$fn, $content);
  3169. } else
  3170. $ret=copy($ofile->filename,$dir.$field_name.'/'.$fn);
  3171. if(!$ret){
  3172. XDir::unlink($dir);
  3173. return array('error'=>true,'message'=>'Can\'t copy '.$ofile->filename);
  3174. }
  3175. }elseif($field_type=='XFolderDef'){
  3176. if(empty($ofile->catalog[0])) continue;
  3177. $_ofile=$ofile->catalog[0];
  3178. $dir2=basename(dirname($_ofile->filename)).'/';
  3179. $ret=mkdir($dir.$dir2);
  3180. if(!$ret){
  3181. XDir::unlink($dir);
  3182. return array('error'=>true,'message'=>'Can\'t copy '.$ofile->filename);
  3183. }
  3184. foreach($ofile->catalog as $k => $ofile_inside){
  3185. // a voir, nom du fichier dans le zip
  3186. // $ext=substr($ofile_inside->originalname,strrpos($ofile_inside->originalname,'.'));
  3187. // $fn=basename($ofile_inside->filename).$ext;
  3188. $fn = $ofile_inside->originalname;
  3189. if ($ofile_inside->filedef->gzipped == 1) {
  3190. $fh = gzopen($ofile_inside->filename, 'r');
  3191. $content = gzread($fh, 100000000);
  3192. gzclose($fh);
  3193. $ret = file_put_contents($dir.$dir2.$fn, $content);
  3194. } else{
  3195. if (file_exists($ofile_inside->filename))
  3196. $ret=copy($ofile_inside->filename,$dir.$dir2.$fn);
  3197. }
  3198. if(!$ret){
  3199. XDir::unlink($dir);
  3200. return array('error'=>true,'message'=>'Can\'t copy '.$ofile_inside->filename);
  3201. }
  3202. }
  3203. }
  3204. }
  3205. }
  3206. return array('dir'=>$dirname,'error'=>false);
  3207. }
  3208. /// Fonction d'import automatisé des données
  3209. function import($ar=NULL) {
  3210. $p=new XParam($ar, array());
  3211. $linestoskip=$p->get('linestoskip');
  3212. $spec=$p->get('spec');
  3213. $fieldsname=$p->get('fieldsname');
  3214. if($spec=='default'){
  3215. $infos=pathinfo($_FILES['file']['name']);
  3216. if($infos['extension']=='xls') $format='xl';
  3217. elseif($infos['extension']=='xlsx') $format='xl07';
  3218. else $format='csv';
  3219. $sxml='<?xml version="1.0"?><import><general format="'.$format.'" fieldsinheader="true"><linestoskip value="'.$linestoskip.'"></linestoskip><location></location><quote>"</quote><separator>;</separator><endofline></endofline><strategy clearbefore="false" updateifexists="true"></strategy><key></key></general><catalog><field tzr="KOID" name="KOID"></field><field tzr="KOID" name="OID"></field><field tzr="LANG" name="LANG"></field>';
  3220. foreach($this->xset->desc as $fn=>&$f){
  3221. if($fieldsname=='label') $sxml.='<field tzr="'.$fn.'" name="'.$f->label.'"></field>';
  3222. else $sxml.='<field tzr="'.$fn.'" name="'.$fn.'"></field>';
  3223. }
  3224. $sxml.='</catalog></import>';
  3225. $xml=simplexml_load_string($sxml);
  3226. $file=$_FILES['file']['tmp_name'];
  3227. $this->_import(array('spec'=>$xml,'file'=>$file));
  3228. }else{
  3229. return parent::import($ar);
  3230. }
  3231. }
  3232. /// Sous fonction pour l'import automatisé
  3233. function _import($ar=NULL) {
  3234. $p=new XParam($ar, array());
  3235. $spec=$p->get('spec');
  3236. $imported=false;
  3237. $dirpath=(string)$p->get('dir');
  3238. if(empty($dirpath)) $dirpath=(string)$spec->general[0]->location;
  3239. $file=$p->get('file');
  3240. $lockfile=NULL;
  3241. if(empty($file)) {
  3242. $file=(string)$spec->general[0]->file;
  3243. $lockfile=$file.'.ok';
  3244. }
  3245. // Manage actionbefore here
  3246. if(property_exists($spec,'action') && property_exists($spec->action,'before')){
  3247. $moidBefore = property_exists($spec->action->before,'moid')?(string)$spec->action->before->moid:false;
  3248. $functionBefore = property_exists($spec->action->before,'function')?(string)$spec->action->before->function:false;
  3249. if($moidBefore && $functionBefore){
  3250. XLogs::notice('XModTable::_import','Try to execute moid: '.$moidBefore.' function:'.$functionBefore);
  3251. $mod = XModule::objectFactory($moidBefore);
  3252. $mod->$functionBefore($ar);
  3253. }
  3254. }
  3255. // Import d'un fichier
  3256. if(!empty($file) && (empty($lockfile) || file_exists($lockfile))) {
  3257. $ar['spec']=$spec;
  3258. $ar['file']=$file;
  3259. $imported=$this->_import_data($ar);
  3260. if(!empty($lockfile)) @unlink($lockfile);
  3261. }elseif(in_array($spec->general[0]['format'],array('csv','xl','xl07'))){
  3262. // Import de csv depuis un repertoire
  3263. XLogs::notice('XModTable::_import','module '.$this->_moid." $dirpath");
  3264. $dir=opendir($dirpath);
  3265. while($dir!==false && ($file=readdir($dir))!==false) {
  3266. if(preg_match('/(.*).(txt|csv|xml)/i',$file)) {
  3267. $ar['file']=$dirpath.$file;
  3268. $ar['spec']=$spec;
  3269. $imported = $this->_import_data($ar);
  3270. }
  3271. }
  3272. }elseif($spec->general[0]['format']=='files'){
  3273. // Import de fichier
  3274. $ar['spec']=$spec;
  3275. $imported=$this->_import_files($ar);
  3276. }
  3277. // Manage actionafter here
  3278. if($imported){
  3279. if(property_exists($spec,'action') && property_exists($spec->action,'after')){
  3280. $moidAfter = property_exists($spec->action->after,'moid')?(string)$spec->action->after->moid:false;
  3281. $functionAfter = property_exists($spec->action->after,'function')?(string)$spec->action->after->function:false;
  3282. if($moidAfter && $functionAfter){
  3283. XLogs::notice('XModTable::_import','Try to execute After function moid: '.$moidAfter.' function:'.$functionAfter);
  3284. $mod = XModule::objectFactory($moidAfter);
  3285. $mod->$functionAfter($ar);
  3286. }
  3287. }
  3288. }
  3289. }
  3290. /// Import des fichiers d'un dossier et ses sous dossiers (retourne true si au moins un fichier est importé)
  3291. function _import_files($ar=NULL) {
  3292. ini_set('max_execution_time', 600);
  3293. $p=new XParam($ar, array());
  3294. $found=false;
  3295. $specs=$p->get('spec');
  3296. $location=(string)$specs->general->location;
  3297. @$filefield=(string)$specs->general->filefield;
  3298. if(empty($filefield)){
  3299. $flist=$this->xset->getFieldsList(array('XImageDef'));
  3300. if(!empty($flist)) $filefield=$flist[0];
  3301. else return false;
  3302. }
  3303. if(!empty($specs->general->authext)){
  3304. $authext=explode(',',$specs->general->authext);
  3305. foreach($authext as $i=>$ext) $authext[$i]=strtolower($ext);
  3306. }
  3307. @$titlefield=(string)$specs->general->titlefield;
  3308. @$importedfield=(string)$specs->general->importedfield;
  3309. @$unique=(string)$specs->general[0]->strategy[0]['unique'];
  3310. @$updateifexist=(boolean)$specs->general[0]->strategy[0]['updateifexists'];
  3311. @$notdel=(string)$specs->general[0]->strategy[0]['notdeletefiles'];
  3312. if($unique && $unique!='false') $unique=true;
  3313. else $unique=false;
  3314. if($updateifexist && $updateifexist!='false') $updateifexist=true;
  3315. else $updateifexist=false;
  3316. if($notdel && $notdel!='false') $notdel=true;
  3317. else $notdel=false;
  3318. $return=false;
  3319. $xmime=XMimeTypes::getInstance();
  3320. $files=XDir::scan($location);
  3321. foreach($files as $i=>$file) {
  3322. $filename=$file;
  3323. $info=pathinfo($filename);
  3324. if(!empty($authext)){
  3325. if(!in_array(strtolower($info['extension']),$authext)) continue;
  3326. }
  3327. if(filetype($filename)=='file') {
  3328. $return=true;
  3329. $ar1=array();
  3330. $value=array('tmp_name'=>$filename,'type'=>$xmime->getValidMime('',$filename,$filename),'name'=>$info['basename'],'title'=>'',
  3331. 'size'=>filesize($filename));
  3332. $ar1[$filefield]=$value;
  3333. if(!empty($titlefield)){
  3334. $ar1[$titlefield]=$info['filename'];
  3335. if($unique) $ar1['_unique']=array($titlefield);
  3336. if($updateifexist) $ar1['_updateifexists']=1;
  3337. }
  3338. if($importedfield){
  3339. $f1=&$this->xset->getField($importedfield);
  3340. if($f1->get_ftype()=='XBoolDef') $ar1[$importedfield]=1;
  3341. else $ar1[$importedfield]=date('Y-m-d H:i:s');
  3342. }
  3343. if($notdel) $ar1['options'][$filefield]['del']=false;
  3344. $ar1['_allfields']=true;
  3345. $ret=$this->xset->procInput($ar1);
  3346. }
  3347. }
  3348. return $return;
  3349. }
  3350. /// Importe un fichier (csv/xls/xlsx) dans la base. Renvoie true si au moins une ligne est importée
  3351. function _import_data($ar=NULL) {
  3352. $p=new XParam($ar, array());
  3353. $found=false;
  3354. $file=$p->get('file');
  3355. XLogs::notice('XModTable::_import_data','module '.$this->_moid.' file='.$file);
  3356. $specs=$p->get('spec');
  3357. $data=@file_get_contents($file);
  3358. if(file_exists($file)) {
  3359. $format=(string)$specs->general[0]['format'];
  3360. if($format=='csv'){
  3361. $charset=(string)$specs->general[0]['charset'];
  3362. if($charset) convert_charset($data,$charset,TZR_INTERNAL_CHARSET);
  3363. $data=_getCSVData($data,$specs);
  3364. }elseif($format=='xl'){
  3365. $data=_getXLSData($file,'Excel5');
  3366. }elseif($format=='xl07'){
  3367. $data=_getXLSData($file,'Excel2007');
  3368. }
  3369. if(!empty($data)) $found = $this->_doImportData($data, $specs);
  3370. @unlink($file);
  3371. }
  3372. return $found;
  3373. }
  3374. ///effective import data from array ($data) returned by getXXXdata
  3375. protected function _doImportData(&$data, &$specs) {
  3376. $unique=array();
  3377. $found=false;
  3378. $koid=(string)$specs->general[0]->koid[0];
  3379. $updateifexists=(string)$specs->general[0]->strategy[0]['updateifexists'];
  3380. if(!empty($updateifexists) && $updateifexists!='false') $updateifexists=true;
  3381. else $updateifexists=false;
  3382. $keys=$specs->general[0]->key;
  3383. $unique=array();
  3384. foreach($specs->general->key as $i=>$u){
  3385. if(!empty($u)) $unique[]=(string)$u;
  3386. }
  3387. if(!empty($unique)) $unique[]='LANG';
  3388. // Vide la table si demandé
  3389. $clearbefore=(string)$specs->general[0]->strategy[0]['clearbefore'];
  3390. if(!empty($clearbefore) && ($clearbefore!='false')) {
  3391. XLogs::notice('XModTable::_import_data','clearing before importing');
  3392. $deleterequest=(string)$specs->general[0]->strategy[0]->clearrequest[0];
  3393. if(!empty($deleterequest)) $this->xset->clear($deleterequest);
  3394. else $this->xset->clear();
  3395. }
  3396. // Creation des entetes
  3397. $head=array();
  3398. $fieldsinheader=(string)$specs->general[0]['fieldsinheader'];
  3399. if(!empty($fieldsinheader) && $fieldsinheader!='false') $fieldsinheader=true;
  3400. else $fieldsinheader=false;
  3401. if($fieldsinheader){
  3402. $line=$data[0];
  3403. foreach($line as $i=>$field){
  3404. if($field) $head[mb_strtoupper($field,TZR_INTERNAL_CHARSET)]=$i;
  3405. }
  3406. unset($data[0]);
  3407. }else{
  3408. $j=0;
  3409. foreach($specs->catalog->field as $i=>$field){
  3410. $head[(string)$field['tzr']]=$j;
  3411. $j++;
  3412. }
  3413. }
  3414. // Supprime les lignes à ne pas importer
  3415. $linestoskip=(string)$specs->general[0]->linestoskip[0]['value'];
  3416. if(!empty($linestoskip)) {
  3417. for($i=0;$i<$linestoskip;$i++) unset($data[$i]);
  3418. }
  3419. $message='<dl>';
  3420. $tot=$ok=$nok=$update=0;
  3421. $incompletelines=$emptylines=array();
  3422. foreach($data as $line=>&$tuple) {
  3423. $tot++;
  3424. $message.='<dt><strong>- Line '.($line+1).'</strong></dt>';
  3425. if(count($tuple)<count($head)){
  3426. $message.='<dd>Incomplete line</dd>';
  3427. $incompletelines[]=$line+1;
  3428. continue;
  3429. }
  3430. $isempty=true;
  3431. foreach($tuple as $i=>$value){
  3432. if(!empty($value)){
  3433. $isempty=false;
  3434. break;
  3435. }
  3436. }
  3437. if($isempty){
  3438. $message.='<dd>Empty line</dd>';
  3439. $emptylines[]=$linet+1;
  3440. continue;
  3441. }
  3442. $input=array();
  3443. $refsql= array();
  3444. $input['_unique']=$unique;
  3445. // Specifie la langue par defaut de l'entrée
  3446. if($specs->general[0]->lang[0]) $input['LANG']=$specs->general[0]->lang[0];
  3447. else $input['LANG']=TZR_DEFAULT_LANG;
  3448. foreach($specs->catalog->field as $i=>$field) {
  3449. $tzrfield=(string)$field['tzr'];
  3450. $namefield=(string)$field['name'];
  3451. $skip=(string)$field['skip'];
  3452. if(!empty($skip) && $skip!='false') continue;
  3453. if($fieldsinheader && $namefield) $value=$tuple[$head[mb_strtoupper($namefield, TZR_INTERNAL_CHARSET)]];
  3454. else $value=$tuple[$head[$tzrfield]];
  3455. if($tzrfield != 'LANG' AND in_array($tzrfield,$unique)){
  3456. $refsql[] = "$tzrfield like '".trim($value)."'";
  3457. }
  3458. // On passe les champs du catalogue qui ne sont pas dans le fichier
  3459. if($value===NULL) continue;
  3460. $defaultvalue=(string)$field->default[0];
  3461. if(!empty($tzrfield)) {
  3462. if($tzrfield=='KOID'){
  3463. if(empty($value)) break;
  3464. if(strpos($value,$this->table.':')===0) $input[$tzrfield]=$value;
  3465. else $input[$tzrfield]=$this->table.':'.$value;
  3466. }elseif($tzrfield=='LANG') $input[$tzrfield]=$value;
  3467. else{
  3468. $v=$this->xset->getField($tzrfield);
  3469. if(!is_object($v)){
  3470. $message='Error : field "'.$tzrfield.'" doesn\'t exists<br>';
  3471. break 2;
  3472. }
  3473. $ret=$v->import($value,$field);
  3474. $input[$tzrfield]=$ret['value'];
  3475. if(empty($input[$tzrfield]) && !empty($defaultvalue)) $input[$tzrfield]=$defaultvalue;
  3476. if(!empty($ret['message'])) $message.='<dd>'.$ret['message'].'</dd>';
  3477. }
  3478. }
  3479. }
  3480. // Recupere un eventuel oid
  3481. if(!empty($koid)){
  3482. if(strpos($input[$koid],':')) $input['newoid']=$input[$koid];
  3483. else $input['newoid']=$this->table.':'.rewriteToAscii($input[$koid]);
  3484. }elseif(!empty($input['KOID'])){
  3485. if(strpos($input['KOID'],':')) $input['newoid']=$input['KOID'];
  3486. else $input['newoid']=$this->table.':'.rewriteToAscii($input['KOID']);
  3487. }elseif(!empty($refsql) && !empty($updateifexists)){
  3488. $sele = 'SELECT KOID FROM '.$this->table.' WHERE LANG = \''.TZR_DEFAULT_LANG.'\' AND '.implode(' AND ',$refsql);
  3489. $rsk = &selectQuery($sele);
  3490. $Koid ='';
  3491. if($rsk && $rsk->rowCount()==1 && $orsk = $rsk->fetch(PDO::FETCH_ASSOC)){
  3492. $input['newoid'] = $orsk['KOID'];
  3493. }
  3494. }
  3495. $input['_updateifexists']=$updateifexists;
  3496. $input['_delayed']=false;
  3497. $input['_nolog']=true;
  3498. $input['tplentry']=TZR_RETURN_DATA;
  3499. if(empty($input['LANG']) || $input['LANG']==TZR_DEFAULT_LANG || $this->xset->getTranslatable()==3){
  3500. if(!empty($input['LANG']) && $input['LANG']!=TZR_DEFAULT_LANG && !$this->secure('','procInsert',$u=NULL,$input['LANG'])){
  3501. $message.='<dd>Write in '.$input['LANG'].' is not allowed</dd>';
  3502. $nok++;
  3503. }else{
  3504. $input['LANG_DATA']=$input['LANG'];
  3505. $r=&$this->xset->procInput($input);
  3506. if(!empty($r['oid'])){
  3507. if(!$found) $found=true;
  3508. $message.='<dd>Insert : success -> '.$r['oid'].'</dd>';
  3509. $ok++;
  3510. }elseif(empty($r['error'])){
  3511. $message.='<dd>Insert : update an existing entry</dd>';
  3512. $update++;
  3513. }else{
  3514. $message.='<dd>Insert : error ('.$r['message'].')</dd>';
  3515. $nok++;
  3516. }
  3517. }
  3518. }elseif(!empty($input['newoid']) ){
  3519. if(!array_key_exists($input['LANG'],$GLOBALS['TZR_LANGUAGES'])){
  3520. $message.='<dd>Lang '.$input['LANG'].' does not exist</dd>';
  3521. $nok++;
  3522. }elseif($this->secure('','procEdit',$u=NULL,$input['LANG'])){
  3523. $input['LANG_DATA']=$input['LANG'];
  3524. if(!empty($input['newoid'])) $input['oid']=$input['newoid'];
  3525. $r=&$this->xset->procEdit($input);
  3526. $message.='<dd>Update '.$input['oid'].' in '.$input['LANG'].'</dd>';
  3527. $update++;
  3528. }else{
  3529. $message.='<dd>Write in '.$input['LANG'].' is not allowed</dd>';
  3530. $nok++;
  3531. }
  3532. }else{
  3533. $message.='<dd>Not default lang and no KOID</dd>';
  3534. $nok++;
  3535. }
  3536. unset($input);
  3537. }
  3538. $message.='</dl>';
  3539. $message='Total : '.$tot.'<br>Insert : '.$ok.'<br>Update : '.$update.'<br>Error : '.$nok.'<br>'.
  3540. 'Empty lines : '.count($emptylines).' ('.implode(', ',$emptylines).')<br>'.
  3541. 'Incomplete line : '.count($incompletelines).' ('.implode(', ',$incompletelines).')<br>'.$message;
  3542. XShell::toScreen2('','message',$message);
  3543. return $found;
  3544. }
  3545. function sub($ar) {
  3546. return parent::sub($ar);
  3547. }
  3548. protected function _lasttimestamp() {
  3549. $upd=countSelectQuery('select ifnull(MAX(UPD),0) from '.$this->table);
  3550. if($this->trackchanges && !$this->getFilter() && !$this->object_sec)
  3551. $upd2=countSelectQuery('select ifnull(MAX(UPD),0) from LOGS where etype="delete" and comment like "%('.$this->table.':%"');
  3552. else
  3553. $upd2=0;
  3554. return max($upd,$upd2);
  3555. }
  3556. /// rend la liste des fiches modifiees depuis ts et jusqu'a timestamp
  3557. protected function _whatsNew($ts,$user, $group=NULL, $specs=NULL,$timestamp=NULL) {
  3558. @list($oid,$details)=explode(';',$specs);
  3559. $query='select KOID from '.$this->table.' where UPD >= "'.$ts. '" and UPD<"'.$timestamp.'"';
  3560. $oids = $this->xset->browseOids(array('select'=>$query, 'pagesize'=>'99', 'tplentry'=>TZR_RETURN_DATA, '_filter'=>$this->getFilter()));
  3561. $txt='';
  3562. foreach ($oids as $oid) {
  3563. $d1=$this->xset->display(array('_lastupdate'=>true,'tplentry'=>TZR_RETURN_DATA,'tlink'=>true,'oid'=>$oid,'_options'=>array('error'=>'return')));
  3564. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,false).'&moid='.$this->_moid.'&function=display&oid='.$oid.'&tplentry=br&template=xmodtable/view.html&_direct=1';
  3565. if(is_array($d1) && ($d1['lst_upd']['user']!=$user)) {
  3566. $when=$d1['oUPD']->html;
  3567. $who=$d1['lst_upd']['usernam'];
  3568. $what=XLabels::getSysLabel('general',$d1['lst_upd']['etype'],'text');;
  3569. $j=XLogs::getJournal($oid,NULL,$ts,$timestamp,$this->xset);
  3570. $modifs="<br/>";
  3571. $whoarray=array();
  3572. foreach($j['lines_journal'] as $entry=>$log) {
  3573. if(!in_array($j['lines_ousernam'][$entry]->text, $whoarray))
  3574. $whoarray[]=$j['lines_ousernam'][$entry]->text;
  3575. $modifs.=implode('<br/>',$log);
  3576. $modifs.='<br/>';
  3577. }
  3578. // construction du texte
  3579. $who=implode(', ',$whoarray);
  3580. $txt.='<li><a href="'.$url.'">'.$d1['tlink'].'</a> ('.$when.
  3581. ($this->trackchanges?(', '.$who.', '.$what):'').')';
  3582. // on ajoute le detail des logs si abonnement avec detail
  3583. if($details && $this->trackchanges) {
  3584. $txt.=$modifs;
  3585. }
  3586. $txt.='</li>';
  3587. }
  3588. }
  3589. if($this->trackchanges && !$this->getFilter() && !$this->object_sec){
  3590. $x=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS=LOGS');
  3591. $rs=selectQuery('select * from LOGS where UPD>="'.$ts. '" and UPD<"'.$timestamp.'" and etype="delete" and comment like "%('.$this->table.':%)"');
  3592. while($rs && $ors=$rs->fetch()){
  3593. $d=$x->rDisplay($ors['KOID'],$ors,false);
  3594. $txt.='<li>'.$d['ocomment']->text.' ('.$d['oUPD']->html.', '.$d['ousernam']->html.', '.$d['oetype']->html.')</li>';
  3595. }
  3596. }
  3597. return $txt;
  3598. }
  3599. function goto1($ar=NULL) {
  3600. $p=new XParam($ar,array());
  3601. $oid=$p->get('oid');
  3602. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(false,true);
  3603. $moid=$this->_moid;
  3604. $right= $this->secure($oid, 'display');
  3605. if(!$right) securityWarning('XModTable::goto1: could not access to objet '.$oid.' in module '.$moid);
  3606. header("Location: {$url}&moid=$moid&template=xmodtable/view.html&oid=$oid&function=display&tplentry=br");
  3607. }
  3608. function gDisplay($ar=NULL) {
  3609. self::developer($ar);
  3610. $p=new XParam($ar,array());
  3611. $tplentry=$p->get('tplentry');
  3612. }
  3613. function developer($ar=NULL) {
  3614. parent::developer($ar);
  3615. $r['lines_title'][]='Display template';
  3616. $r['lines_url'][]='&function=gDisplay';
  3617. XShell::toScreen1('dev',$r);
  3618. }
  3619. // rend le journal des modifs d'un objet
  3620. //
  3621. public function &journal($ar) {
  3622. $p = new XParam($ar, array());
  3623. $tplentry=$p->get('tplentry');
  3624. $oid=$p->get('oid');
  3625. $r=&XLogs::getJournal($oid,array('etype'=>array('=',array('create','update','rule'))),NULL,NULL,$this->xset, $this->fieldssec);
  3626. $this->browseSumFields($ar, $r, true);
  3627. return XShell::toScreen1($tplentry,$r);
  3628. }
  3629. /// Validation des oid ou des rubriques
  3630. public function publish($ar) {
  3631. $p=new XParam($ar,array());
  3632. $oids=Kernel::getSelectedOids($p);
  3633. foreach($oids as $oid) {
  3634. if($this->secure($oid,'publish')){
  3635. $ar1['_selected'] = array();
  3636. $ar1['value'] = $p->get('value');
  3637. $ar1['_local'] = true;
  3638. $ar1['oid']= $oid;
  3639. $this->xset->publish($ar1);
  3640. }
  3641. }
  3642. }
  3643. /// Retourne le filtre du module
  3644. public function getFilter($instanciate=true,$ar=array()) {
  3645. $q=getSessionVar('filterquery'.$this->_moid);
  3646. // Pas très beau, mais afin de contourner le filtre dans les actions venant de la selection, si on est dans l'admin et ques des oids sont fournis, alors on ne l'applique pas.
  3647. if(XShell::admini_mode()){
  3648. $oids=Kernel::getSelectedOids($ar);
  3649. if(!empty($oids) && Kernel::getTable($oids[0])==$this->table){
  3650. $q=null;
  3651. }
  3652. }
  3653. if(!empty($q)){
  3654. // si pas de jointure on renvoie un filtre simple
  3655. if (preg_match('/select .* from (.*) where (.*)/i', $q, $matches) && $matches[1] == $this->table) {
  3656. $q=preg_replace('/order by .*$/i','',$matches[2]);
  3657. $filter='('.$q.')';
  3658. } else { // sinon un subselect
  3659. $q=preg_replace('/select .* from/i','select '.$this->table.'.KOID from',$q);
  3660. $q=preg_replace('/order by .*$/i','',$q);
  3661. $filter=$this->table.'.KOID in ('.$q.')';
  3662. }
  3663. }else{
  3664. $filter=$this->filter;
  3665. if($instanciate) {
  3666. $context=array();
  3667. $u=XUser::get_user();
  3668. $context['/(\$\(user\))/']=XUser::get_current_user_uid();
  3669. if(!empty($u->_cur['alias'])) $context['/(\$\(user\.alias\))/']=$u->_cur['alias'];
  3670. $filter=preg_replace(array_keys($context),array_values($context),$filter);
  3671. }
  3672. }
  3673. if(!empty($ar['_filter'])){
  3674. if($filter) $filter='('.$filter.') AND ('.$ar['_filter'].')';
  3675. else $filter=$ar['_filter'];
  3676. }
  3677. return $filter?'('.$filter.')':'';
  3678. }
  3679. /// Filtre sql utilisé par les xfielddef pour filtrer les valeurs utilisées
  3680. function getUsedValuesFilter(){
  3681. return $this->getFilter();
  3682. }
  3683. public function isThereAQueryActive() {
  3684. if(sessionActive()) {
  3685. $_storedquery=$this->_getSession('query');
  3686. if($_storedquery['_table']==$this->table) {
  3687. return true;
  3688. }
  3689. }
  3690. return false;
  3691. }
  3692. /// gestion du contexte sous module
  3693. /// $shift dépile le premier élément dans l'url, pour un retour à la fiche parente
  3694. protected function subModuleContext($ar=array(), $shift=false){
  3695. $p = new XParam($ar, array());
  3696. $_parentoids = $p->get('_parentoids');
  3697. $_linkedfields = $p->get('_linkedfields');
  3698. $ret = false;
  3699. if (!empty($_parentoids) && !empty($_linkedfields)) {
  3700. $urlparms = '';
  3701. foreach ($_parentoids as $i => $parentoid) {
  3702. if (!$i && $shift)
  3703. continue;
  3704. $urlparms .= '&_parentoids[]='.$parentoid;
  3705. }
  3706. foreach ($_linkedfields as $i => $linkedfield) {
  3707. if (!$i && $shift)
  3708. continue;
  3709. $urlparms .= '&_linkedfields[]='.$linkedfield;
  3710. }
  3711. // deprecated, backward compatibility
  3712. $urlparms .= '&_parentoid='.$_parentoids[0].'&_linkedfield='.$_linkedfields[0];
  3713. $ret = array('_parentoids' => $_parentoids,
  3714. '_linkedfields' => $_linkedfields,
  3715. 'urlparms' => $urlparms);
  3716. }
  3717. return $ret;
  3718. }
  3719. /// Prepare le HTML pour l'affichage d'un captcha dans un formulaire
  3720. function createCaptcha($ar,$force=false){
  3721. $p=new XParam($ar,NULL);
  3722. $tplentry=$p->get('tplentry');
  3723. if($this->captcha || $force){
  3724. XLogs::notice('XModTable::_createcaptcha','module '.$this->_moid." ");
  3725. $varid=uniqid('c');
  3726. $color = XIni::get('error_color');
  3727. $captcha['html']='<div class="tzrDivCaptcha"><img id="cimg'.$varid.'"/>'.
  3728. '<a id="ca'.$varid.'" href="#" onclick="TZR.actualizeCaptcha(\''.TZR_CAPTCHA.'\',\''.$varid.'\'); return false;">'.
  3729. XLabels::getSysLabel('xmodtable','captcha_reload').'</a>'.
  3730. '<input type="text" id="'.$varid.'" name="captcha_key" maxlength="'.TZR_CAPTCHA_LENGTH.'" size="'.TZR_CAPTCHA_LENGTH.'" />'.
  3731. '<input type="hidden" name="captcha_id" value="'.$varid.'" />'.
  3732. "<script type=\"text/javascript\">TZR.actualizeCaptcha('".TZR_CAPTCHA."','$varid'); ".
  3733. "TZR.addValidator(['$varid','','Captcha','$color','Captcha']);</script></div>";
  3734. $captcha['label'] = XLabels::getSysLabel('xmodtable','captcha_label');
  3735. return XShell::toScreen1($tplentry,$captcha);
  3736. }
  3737. }
  3738. // implementation de l'interface des documents
  3739. function &XMCinput($ar) {
  3740. return $this->insert($ar);
  3741. }
  3742. function &XMCprocInput($ar) {
  3743. return $this->procInsert($ar);
  3744. }
  3745. function &XMCedit($ar) {
  3746. return $this->edit($ar);
  3747. }
  3748. function &XMCprocEdit($ar) {
  3749. $e = &$this->procEdit($ar);
  3750. return $e;
  3751. }
  3752. function &XMCprocEditDup($ar) {
  3753. return $this->procEditDup($ar);
  3754. }
  3755. function &XMCdisplay($ar) {
  3756. return $this->display($ar);
  3757. }
  3758. function &XMCdel($ar) {
  3759. return $this->del($ar);
  3760. }
  3761. function &XMCduplicate($oidsrc){
  3762. if(!is_array($oidsrc)) $oidsrc=array('oid'=>$oidsrc);
  3763. return $this->duplicate($oidsrc);
  3764. }
  3765. function &XMCquery($ar){
  3766. return $this->query($ar);
  3767. }
  3768. function &XMCprocQuery($ar){
  3769. return $this->procQuery($ar);
  3770. }
  3771. function tablesToTrack() {
  3772. if($this->trackchanges) return array($this->table);
  3773. }
  3774. function apply($f) {
  3775. $rs=selectQuery('SELECT DISTINCT KOID FROM '.$this->table);
  3776. while($ors=$rs->fetch()) {
  3777. $d=&$this->xset->rDisplay($ors['KOID']);
  3778. $f($this, $d);
  3779. }
  3780. $rs->closeCursor();
  3781. }
  3782. // verification qu'un module est bien installé. Si le parametre
  3783. // repair est a oui, on fait les reparations si possible.
  3784. //
  3785. public function chk($ar=NULL) {
  3786. parent::chk($ar);
  3787. // Créer des index sur tous les champs servant de lien dans des sous fiches
  3788. for($i=1;$i<=$this->submodmax;$i++) {
  3789. $l='ssmod'.$i;
  3790. $moid=$this->$l;
  3791. $l='ssmodfield'.$i;
  3792. $f=$this->$l;
  3793. if(!empty($moid) && !empty($f)){
  3794. $mod=XModule::objectFactory($moid);
  3795. $l=$mod->xset->desc[$f]->multivalued?300:40;
  3796. updateQuery('CREATE INDEX '.$f.' ON '.$mod->table.' ('.$f.'('.$l.'))');
  3797. }
  3798. }
  3799. return true;
  3800. }
  3801. /// recherche si on oid est autorise dans le module
  3802. protected function secOidOk($oid) {
  3803. if(substr($oid,0,7)=='_field-') return true;
  3804. if(isset($this->secOids_cache[$oid])) return $this->secOids_cache[$oid];
  3805. // Vérifie que l'oid est dans la selection. Si oui, c'est que l'utilisateur a accès à celui ci
  3806. $selection=$this->getSelectionFromSession();
  3807. if($selection && array_key_exists($oid,$selection)) return true;
  3808. // Applique le filtre du module pour vérifier sir l'oid est accessible
  3809. $filter=$this->getFilter(true);
  3810. if(!empty($filter)) {
  3811. // dans le cas d'un filtre, on verifie si on appartient au filtre
  3812. $rs=selectQuery('select KOID from '.$this->table.' where KOID="'.$oid.'" AND '.$filter);
  3813. if($rs && ($ors=$rs->fetch())) {
  3814. $this->secOids_cache[$oid] = !empty($ors['KOID']);
  3815. return $this->secOids_cache[$oid];
  3816. }
  3817. } else {
  3818. return true;
  3819. }
  3820. }
  3821. /// Calcul des champs totalisés suite à un browse
  3822. function browseSumFields($ar, &$r, $withtotal){
  3823. $p = new XParam($ar, array());
  3824. $tpl = $p->get('tplentry');
  3825. // totalisation des champs numériques listés
  3826. $numfields = array();
  3827. $fsums = ""; $sep = '';
  3828. foreach($r['header_fields'] as $if=>$fd){
  3829. if (!$fd->is_summable()) continue;
  3830. $numfield = (object)array('if'=>$if,
  3831. 'fc'=>$fd->field,
  3832. 'ffc'=>$this->table . '.' . $fd->field,
  3833. 'ffa'=>'sumof_'.$this->table . '_' . $fd->field,
  3834. );
  3835. $numfields[$fd->field] = $numfield;
  3836. $fsums = $fsums . $sep . 'ifnull('.$fd->sqlsumfunction().', 0) as '.$numfield->ffa;
  3837. $sep = ',';
  3838. }
  3839. if (count($numfields) == 0)
  3840. return;
  3841. // requete de base
  3842. $selectsum = preg_replace('/select (.*) from (.*)$/Ui','select '.$fsums.' from $2',$r['select']);
  3843. // total de la selection en cours
  3844. if ($withtotal){
  3845. $srs = selectQuery($selectsum);
  3846. $osrs = $srs->fetch();
  3847. } else {
  3848. $osrs = NULL;
  3849. }
  3850. // total de la page en cours
  3851. // -> liste des oid de la page
  3852. // -> l'ordre n'a pas d'importance
  3853. $pagesize=$p->get('pagesize');
  3854. if(empty($pagesize)) {
  3855. $pagesize=$this->pagesize;
  3856. }
  3857. if(empty($pagesize))
  3858. $pagesize=TZR_XMODTABLE_BROWSE_MAXPAGESIZE;
  3859. $ar['pagesize']=$pagesize;
  3860. $last = $p->get('last');
  3861. if (empty($last)){
  3862. $last = $r['last'];
  3863. }
  3864. if ($last > $pagesize || !$withtotal){
  3865. // calcul du total page par iteration sur les lignes
  3866. $osprs = array();
  3867. foreach($r['header_fields'] as $foo=>&$fd){
  3868. if (isset($numfields[$fd->field])){
  3869. $osprs[$fd->field]=0;
  3870. foreach($r['lines_o'.$fd->field] as $il=>&$fv){
  3871. $osprs[$numfields[$fd->field]->ffa]+=$fv->raw;
  3872. }
  3873. }
  3874. }
  3875. unset($foo);
  3876. }
  3877. // mise en forme des totaux
  3878. $linetot = $linepage = '';
  3879. foreach($r['header_fields'] as $foo=>&$fd){
  3880. if (isset($numfields[$fd->field])){
  3881. if ($withtotal)
  3882. $linetot.='<td style="text-align:'.$fd->align.';">'.$fd->my_display($osrs[$numfields[$fd->field]->ffa])->html.'</td>';
  3883. if ($last > $pagesize || !$withtotal)
  3884. $linepage.='<td style="text-align:'.$fd->align.';">'.$fd->my_display($osprs[$numfields[$fd->field]->ffa])->html.'</td>';
  3885. else
  3886. $linepage.='<td></td>';
  3887. } else {
  3888. if ($withtotal)
  3889. $linetot.='<td></td>';
  3890. $linepage.='<td></td>';
  3891. }
  3892. }
  3893. if (!$withtotal)
  3894. $linetot = NULL;
  3895. if ($last <= $pagesize && $withtotal)
  3896. $linepage = NULL;
  3897. $sums = array();
  3898. $sums['line_tot'] = $linetot;
  3899. $sums['line_page'] = $linepage;
  3900. if ($tpl != TZR_RETURN_DATA){
  3901. XShell::toScreen2($tpl, 'sums', $sums);
  3902. } else {
  3903. $r['sums']['line_tot'] = $linetot;
  3904. $r['sums']['line_page'] = $linepage;
  3905. }
  3906. }
  3907. /// Sous fonctions de parcours de la selection
  3908. function &_browseUserSelection($oid,&$data){
  3909. if(!$this->object_sec || $this->secure($oid,'display')){
  3910. return $this->xset->rDisplay($oid,array(),true,'','',array('fmoid'=>$this->_moid));
  3911. }
  3912. return false;
  3913. }
  3914. /// Liste des fonctions utilisable sur la selection du module
  3915. function userSelectionActions(){
  3916. $actions=array();
  3917. if($this->secure('','procQuery')){
  3918. $viewtxt=XLabels::getSysLabel('general','view','text');
  3919. $actions['view']='<a href="#" onclick="TZR.SELECTION.viewselected'.$this->_moid.'(); return false;">'.$viewtxt.'</a>';
  3920. }
  3921. if($this->secure('','editSelection')) {
  3922. $editalltxt=XLabels::getSysLabel('xmodtable','editselection','text');
  3923. $actions['editselection']='<a href="#" onclick="TZR.SELECTION.applyToInContentDiv('.$this->_moid.',\'editSelection\',false,{template:\'xmodtable/editSelection.html\',tplentry:\'br\'}); return false;">'.$editalltxt.'</a>';
  3924. }
  3925. if($this->secure('','del')) {
  3926. $deltxt=XLabels::getSysLabel('general','delete','text');
  3927. $actions['del']='<a href="#" onclick="TZR.SELECTION.applyTo('.$this->_moid.',\'del\',null,null,TZR.confirmDelete); return false;">'.$deltxt.'</a>';
  3928. }
  3929. if($this->secure('','sendACopyTo')){
  3930. $sendtxt=XLabels::getSysLabel('xmodule','sendacopyto','text');
  3931. $actions['sendacopy']='<a href="#" onclick="TZR.SELECTION.applyToInContentDiv('.$this->_moid.',\'sendACopyTo\',false,{template:\'xmodule/sendacopyto.html\'}); return false;">'.$sendtxt.'</a>';
  3932. }
  3933. if($this->secure('','export')) {
  3934. $exportselectiontext = XLabels::getSysLabel('xmodtable','exportselection','text');
  3935. $actions['exportSelection'] = '<a href="#" onclick="TZR.SELECTION.exportSelection('.$this->_moid.');return false;">'.$exportselectiontext.'</a>';
  3936. }
  3937. if($this->object_sec && $this->secure('','secEditSimple')) {
  3938. $sectxt=XLabels::getSysLabel('general','security','text');
  3939. $actions['secselection']='<a href="#" onclick="TZR.editSec(\''.$GLOBALS['TZR_SESSION_MANAGER']::complete_self(true).'\',\''.$this->_moid.'\',\'\',\'selectionform'.$this->_moid.'\'); return false;">'.$sectxt.'</a>';
  3940. }
  3941. return $actions;
  3942. }
  3943. /// Indexation du module dans le moteur de recherche
  3944. public function _buildSearchIndex(&$searchEngine,$checkbefore=true,$limit=NULL,$cond=NULL){
  3945. $done=0;
  3946. if(!empty($cond)){
  3947. if($cond=='UPD'){
  3948. $last=XDbIni::get('lastindexation_'.$this->_moid,'val');
  3949. if(empty($last)) $last=date('2000-01-01 00:00:00');
  3950. XDbIni::set('lastindexation_'.$this->_moid,date('Y-m-d H:i:s'));
  3951. $cond='UPD>="'.$last.'"';
  3952. }
  3953. $cond=' where '.$cond;
  3954. }else{
  3955. $cond=' where 1';
  3956. }
  3957. $filter=$this->getFilter(true);
  3958. if($filter) $cond.=' AND '.$filter;
  3959. $rs=selectQuery('SELECT * FROM '.$this->table.' '.$cond);
  3960. while($rs && ($ors=$rs->fetch())) {
  3961. XLogs::debug('XModTable'.$this->_moid.'::buildSearchIndex: testing '.$ors['KOID']);
  3962. if($checkbefore && $searchEngine->docExists($ors['KOID'],$this->_moid,NULL)) continue;
  3963. XLogs::debug('XModTable'.$this->_moid.'::buildSearchIndex: adding '.$ors['KOID']);
  3964. $this->addToSearchEngine($searchEngine,$ors['KOID']);
  3965. $done++;
  3966. if($done%30==0){
  3967. XLogs::debug('XModTable'.$this->_moid.'::buildSearchIndex: commit');
  3968. $searchEngine->index->commit();
  3969. }
  3970. if($limit && $done>$limit){
  3971. XLogs::debug('XModTable'.$this->_moid.'::buildSearchIndex: break at '.$done);
  3972. break;
  3973. }
  3974. }
  3975. $searchEngine->commit();
  3976. return true;
  3977. }
  3978. /// Recupere les infos d'un objet par l'affichage du résultat d'une recherche
  3979. public function getSearchResult($oid,$filter=NULL){
  3980. return parent::getSearchResult($oid,$filter);
  3981. }
  3982. /// presentation d'un resultat de recherche dans le module
  3983. public function showSearchResult($oids) {
  3984. $_REQUEST = array(
  3985. 'function' => 'procQuery',
  3986. 'template' => 'xmodtable/browse.html',
  3987. 'moid' => $this->_moid,
  3988. 'tplentry' => 'br',
  3989. 'clearrequest' => 1,
  3990. 'oids' => $oids
  3991. );
  3992. $GLOBALS['XSHELL']->run();
  3993. exit;
  3994. }
  3995. /// Ajout d'une fiche au moteur de recherche : données
  3996. function &getSearchEngineData($oid) {
  3997. // selected fields = published + indexables
  3998. $indexables = $this->xset->getIndexablesFields();
  3999. $publisheds = $this->xset->getPublished(true);
  4000. $selecteds = array_merge($indexables, $publisheds);
  4001. $d=$this->xset->display(array('tplentry'=>TZR_RETURN_DATA,'oid'=>$oid,'tlink'=>true, 'selectedfields'=>$selecteds));
  4002. // filtrer les indexables ?
  4003. $text=getFilesContent($d, $indexables);
  4004. $files = getFilesDetails($d);
  4005. $notice = NULL;
  4006. foreach($indexables as $f){
  4007. if (!$this->xset->desc[$f]->get_published()
  4008. && !($this->xset->desc[$f] instanceof XFileDef)
  4009. && !($this->xset->desc[$f] instanceof XFolderDef)
  4010. ) {
  4011. $notice .= ' '.$d['o'.$f]->toText();
  4012. }
  4013. }
  4014. foreach($files as $afile){
  4015. if (in_array($afile['field'], $indexables)){
  4016. $notice .= ' '.$afile['title'];
  4017. if ($afile['name'] != $afile['title'])
  4018. $notice .= ' '.$afile['name'];
  4019. }
  4020. }
  4021. $fields = array('title'=>$d['tlink'], 'notice'=>$notice, 'contents'=>&$text);
  4022. return $fields;
  4023. }
  4024. /// Ajout d'une fiche au moteur de recherche
  4025. function addToSearchEngine(&$searchEngine,$oid) {
  4026. $fields = $this->getSearchEngineData($oid);
  4027. $searchEngine->addItem($oid,$fields,$this->_moid, NULL);
  4028. unset($fields);
  4029. XLogs::notice(get_class($this),get_class($this).'::addToSearchEngine lucene');
  4030. }
  4031. /// Action effectuée à chaque suppression d'un oid de la base
  4032. function _removeRegisteredOid($oid) {
  4033. // Suppression du moteur de recherche
  4034. if($this->insearchengine && Kernel::getTable($oid)==$this->table){
  4035. $se=&XSearch::objectFactory();
  4036. $se->deleteItem($oid,$this->_moid);
  4037. }
  4038. }
  4039. ////////////////////////////////////
  4040. // FONCTIONS INTERFACE XCAL //
  4041. ////////////////////////////////////
  4042. /// Retourne la liste des champs pouvant servir à la consolidation
  4043. function XCalParamsConsolidation($ar){
  4044. $ar1=$ar2=array();
  4045. $p=new XParam($ar,array());
  4046. $tplentry=$p->get('tplentry');
  4047. $datefields=$this->xset->getFieldsList(array('XDateDef','XDateTimeDef','XTimestampDef'));
  4048. $stextfields=$this->xset->getFieldsList(array('XShortTextDef','XLinkDef'));
  4049. $textfields=$this->xset->getFieldsList();
  4050. foreach($datefields as $opt){
  4051. $info=$this->xset->getField($opt);
  4052. $ar1[$opt]=$info->label;
  4053. }
  4054. foreach($stextfields as $opt){
  4055. $info=$this->xset->getField($opt);
  4056. $ar2[$opt]=$info->label;
  4057. }
  4058. foreach($textfields as $opt){
  4059. $info=$this->xset->getField($opt);
  4060. $ar3[$opt]=$info->label;
  4061. }
  4062. XShell::toScreen2($tplentry,'date',$ar1);
  4063. XShell::toScreen2($tplentry,'stexte',$ar2);
  4064. XShell::toScreen2($tplentry,'texte',$ar3);
  4065. }
  4066. function XCalGetConsolidationQuery(&$diary,$params,$fields,$begin,$end,$type='all'){
  4067. $vals=array('visib'=>'PU','DKOID'=>$this->_moid,'DNAME'=>$this->modulename);
  4068. if($this->xset->desc[$params['begin']]->ftype=="XDateDef" || $this->xset->desc[$params['end']]->ftype=="XDateDef"){
  4069. if($type=='event') return NULL;
  4070. $vals['allday']=1;
  4071. }else{
  4072. $datetime=true;
  4073. if($type=='event'){
  4074. $vals['allday']=0;
  4075. $begin=date('Y-m-d H:i:s',strtotime($begin.' GMT'));
  4076. $end=date('Y-m-d H:i:s',strtotime($end.' GMT'));
  4077. }elseif($type=='note'){
  4078. $vals['allday']=1;
  4079. }
  4080. }
  4081. $filter=$this->getFilter(true);
  4082. if(!empty($filter)) $filter=' AND '.$filter;
  4083. $filter.=' AND (date_format('.$params['begin'].',"%Y-%m-%d %H:%i:%s") BETWEEN "'.$begin.'" AND "'.$end.'" OR '.
  4084. '"'.$begin.'" BETWEEN date_format('.$params['begin'].',"%Y-%m-%d %H:%i:%s") AND '.
  4085. 'date_format('.$params['end'].',"%Y-%m-%d %H:%i:%s"))';
  4086. if($datetime){
  4087. if($type=='event'){
  4088. $filter.=' AND (date_format('.$params['begin'].',"%H:%i")!="00:00" OR date_format('.$params['end'].',"%H:%i")!="00:00")';
  4089. }elseif($type=='note'){
  4090. $filter.=' AND date_format('.$params['begin'].',"%H:%i")="00:00" AND date_format('.$params['end'].',"%H:%i")="00:00"';
  4091. }
  4092. }
  4093. $rq=$this->xset->select_query(array('local'=>true,'getselectonly'=>true)).$filter;
  4094. if($this->object_sec){
  4095. $oids=$this->xset->browseOids(array('select'=>$rq,'local'=>true));
  4096. $lang_data=XShell::getLangData();
  4097. $oidsrights=$GLOBALS['XUSER']->getObjectsAccess($this,$lang_data,$oids);
  4098. foreach($oidsrights as $i=>$rights) {
  4099. if(!array_key_exists('ro',$rights)) unset($oids[$i]);
  4100. }
  4101. $rq.=' AND KOID IN("'.implode('","',$oid).'")';
  4102. }
  4103. $select='select KOID,LANG';
  4104. foreach($fields as $f){
  4105. if($f=='begin' || $f=='end'){
  4106. if($vals['allday']!=1) $select.=',convert_tz(date_format('.$params[$f].',"%Y-%m-%d %H:%i:%s"),"'.date("P").'","+00:00") as '.$f;
  4107. else $select.=',date_format('.$params[$f].',"%Y-%m-%d %H:%i:%s") as '.$f;
  4108. }
  4109. elseif(isset($vals[$f])) $select.=',"'.$vals[$f].'" as '.$f;
  4110. elseif(!empty($params[$f])) $select.=','.$params[$f].' as '.$f;
  4111. else $select.=', NULL as '.$f;
  4112. }
  4113. $select.=',"'.$this->_moid.'" as MOID';
  4114. $rq=preg_replace('/select .+ from /i',$select.' from ',$rq);
  4115. return $rq;
  4116. }
  4117. function XCalGetUrl($type){
  4118. if($type=='display') return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&oid=%s&function=display&tplentry=br&template=xmodtable/view.html';
  4119. else return $GLOBALS['TZR_SESSION_MANAGER']::complete_self().'moid='.$this->_moid.'&function=browse&tplentry=br&template=xmodtable/browse.html';
  4120. }
  4121. function XCalRDisplay($oid,$params){
  4122. $opts['selectedfields']=array_values($params);
  4123. $d=$this->xset->rDisplay($oid,array(),false,'','',$opts);
  4124. foreach($params as $evf=>$f){
  4125. if(isset($d['o'.$f])){
  4126. $d['o'.$evf]=&$d['o'.$f];
  4127. }
  4128. }
  4129. return $d;
  4130. }
  4131. /// Rend les documents qui n'ont jamais été consultés
  4132. function getUnread($ar=NULL){
  4133. $p=new XParam($ar,array('nb'=>20));
  4134. $tplentry=$p->get('tplentry');
  4135. $docs=array();
  4136. $rs=selectQuery('select '.$this->table.'.* from '.$this->table.' left outer join LOGS on '.$this->table.'.KOID=LOGS.object and LOGS.etype="access" and LOGS.user="'.XUser::get_current_user_uid().'" and LOGS.UPD>'.$this->table.'.UPD where LOGS.KOID is null order by '.$this->table.'.UPD');
  4137. while($rs && $ors=$rs->fetch()){
  4138. $oid=$ors['KOID'];
  4139. if(!$this->secure($oid,'display')) continue;
  4140. $docs[]=$this->xset->rDisplay($oid,array(),false,'','');
  4141. }
  4142. return XShell::toScreen2($tplentry,'docs',$docs);
  4143. }
  4144. /// Marque des documents comme lu
  4145. function markAsRead($ar=NULL){
  4146. Kernel::getSelectedOids($ar);
  4147. foreach($oids as $i=>$oid){
  4148. XLogs::uniqueUpdate('access',$oid);
  4149. }
  4150. }
  4151. /// Recupere des infos sur le module
  4152. function getInfos($ar=NULL){
  4153. $p=new XParam($ar,array('tplentry'=>TZR_RETURN_DATA));
  4154. $tplentry=$p->get('tplentry');
  4155. $ar['tplentry']=TZR_RETURN_DATA;
  4156. $ret=parent::getInfos($ar);
  4157. // Nombre d'enregistrement dans la table
  4158. $filter=$this->getFilter(true,$ar);
  4159. $ret['infos']['cnt']=(object)array('label'=>XLabels::getSysLabel('xmodtable','records','text'),
  4160. 'html'=>countSelectQuery('select count(distinct KOID) from '.$this->table.($filter?' where '.$filter:'')));
  4161. // Place occupé sur le disque par les data : Appliquer le filtre au calcul...
  4162. $s=XDbIni::get('xmodadmin:workspacesize_'.$this->table,'val');
  4163. $ret['infos']['size']->label=XLabels::getSysLabel('xmodule','workspace','text');
  4164. if($s!==NULL) $ret['infos']['size']->html=getStringBytes($s*1024);
  4165. else $ret['infos']['size']->html=XLabels::getSysLabel('xmodule','infonotcalculate','text');
  4166. return XShell::toScreen1($tplentry,$ret);
  4167. }
  4168. ////////////////////////////////////
  4169. // FONCTIONS D'ADMINISTRATION //
  4170. ////////////////////////////////////
  4171. /// Liste des champs d'une table du module
  4172. public function adminBrowseFields($ar=NULL) {
  4173. $p=new XParam($ar, array());
  4174. $tplentry=$p->get('tplentry');
  4175. $r1=$this->xset->browseFields($ar);
  4176. $tablesec=array();
  4177. $this->anyFieldsSec($tablesec);
  4178. $r1['tableSec']=$tablesec;
  4179. XShell::toScreen1($tplentry, $r1);
  4180. }
  4181. /// Imprime la liste des champs d'une table
  4182. public function adminPrint($ar=NULL) {
  4183. $p = new XParam($ar, array());
  4184. $tplentry=$p->get('tplentry');
  4185. $r1=$this->xset->browseFields($ar);
  4186. XShell::toScreen1($tplentry, $r1);
  4187. }
  4188. /// Ecran de generation d'un nouveau champ
  4189. public function adminNewField($ar=NULL) {
  4190. $p=new XParam($ar,NULL);
  4191. $tplentry=$p->get('tplentry');
  4192. $r1=$this->xset->newField($ar);
  4193. XShell::toScreen1($tplentry,$r1);
  4194. }
  4195. /// Créér un nouveau champ
  4196. public function adminProcNewField($ar=NULL) {
  4197. $p=new XParam($ar,NULL);
  4198. $tplentry=$p->get('tplentry');
  4199. $r1=$this->xset->procNewField($ar);
  4200. XShell::toScreen1($tplentry, $r1);
  4201. }
  4202. /// Ecran edition d'un champ
  4203. public function adminEditField($ar=NULL) {
  4204. $p=new XParam($ar,NULL);
  4205. $tplentry=$p->get('tplentry');
  4206. $r1=$this->xset->editField($ar);
  4207. XShell::toScreen1($tplentry,$r1);
  4208. }
  4209. /// Enregistre les modification sur un champ
  4210. public function adminProcEditField($ar=NULL) {
  4211. $p=new XParam($ar,NULL);
  4212. $tplentry=$p->get('tplentry');
  4213. $r1=$this->xset->procEditField($ar);
  4214. XShell::toScreen1($tplentry,$r1);
  4215. }
  4216. /// Edition des champs multiple à partir du browse
  4217. public function adminProcEditFields($ar=NULL) {
  4218. $p=new XParam($ar,NULL);
  4219. $tplentry=$p->get('tplentry');
  4220. $r1=$this->xset->procEditFields($ar);
  4221. XShell::toScreen1($tplentry,$r1);
  4222. }
  4223. /// Supprime un champ
  4224. public function adminDelField($ar=NULL) {
  4225. $p=new XParam($ar,NULL);
  4226. $tplentry=$p->get('tplentry');
  4227. $r1=$this->xset->delField($ar);
  4228. XShell::toScreen1($tplentry,$r1);
  4229. }
  4230. /// Vide la table
  4231. public function adminClear($ar=NULL){
  4232. $p=new XParam($ar,NULL);
  4233. $tplentry=$p->get('tplentry');
  4234. $ret=$this->xset->clear(array('tplentry'=>TZR_RETURN_DATA));
  4235. if(XShell::hasNext()) setSessionVar('message',$ret['message']);
  4236. return XShell::toScreen1($tplentry,$ret);
  4237. }
  4238. /// Prepare la duplication d'une source
  4239. public function adminDuplicate($ar=NULL){
  4240. $p=new XParam($ar,NULL);
  4241. $tplentry=$p->get('tplentry');
  4242. $ret=$this->xset->duplicateDataSource($ar);
  4243. return XShell::toScreen1($tplentry, $ret);
  4244. }
  4245. /// Duplique une table du module
  4246. public function adminProcDuplicate($ar=NULL){
  4247. $p=new XParam($ar,NULL);
  4248. $tplentry=$p->get('tplentry');
  4249. $ret=$this->xset->procDuplicateDataSource($ar);
  4250. if(XShell::hasNext()) setSessionVar('message',$ret['message']);
  4251. return XShell::toScreen1($tplentry, $ret);
  4252. }
  4253. /// Check/repare une table du module
  4254. public function adminChk($ar=NULL){
  4255. $p=new XParam($ar,NULL);
  4256. $tplentry=$p->get('tplentry');
  4257. $ret=$this->xset->chk($ar);
  4258. if(XShell::hasNext()) setSessionVar('message',$ret['message']);
  4259. return XShell::toScreen1($tplentry, $ret);
  4260. }
  4261. /// Prepare l'edition des propriétés d'une source du module
  4262. public function adminEditSourceProperties($ar=NULL){
  4263. $p=new XParam($ar,NULL);
  4264. $tplentry=$p->get('tplentry');
  4265. $ret=$this->xset->editProperties($ar);
  4266. return XShell::toScreen1($tplentry, $ret);
  4267. }
  4268. /// Enregistre les modifications des propriétés d'une source du module
  4269. public function adminProcEditSourceProperties($ar=NULL){
  4270. $p=new XParam($ar,NULL);
  4271. $tplentry=$p->get('tplentry');
  4272. $ret=$this->xset->procEditProperties($ar);
  4273. return XShell::toScreen1($tplentry, $ret);
  4274. }
  4275. /// Parcours les valeurs d'un XStringSetDef
  4276. public function adminBrowseStrings($ar=NULL) {
  4277. $p=new XParam($ar,NULL);
  4278. $tset=new XTSet(array('boid'=>$this->boid,'field'=>$field));
  4279. $tset->browse($ar);
  4280. }
  4281. /// Prepare l'ajout d'une valeur à un XStringSetDef
  4282. public function adminNewString($ar=NULL) {
  4283. $p=new XParam($ar,NULL);
  4284. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4285. $tset->newString($ar);
  4286. }
  4287. /// Ajout d'une valeur à un XStringSetDe
  4288. public function adminProcNewString($ar=NULL) {
  4289. $p=new XParam($ar,NULL);
  4290. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4291. $tset->procNewString($ar);
  4292. if($ret['error']) setSessionVar('message',$ret['message']);
  4293. }
  4294. /// Prepare l'edition d'une valeur d'un XStringSetDef
  4295. public function adminEditString($ar=NULL) {
  4296. $p=new XParam($ar,NULL);
  4297. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4298. $tset->editString($ar);
  4299. }
  4300. /// Enregistre les modification d'une valeur d'un XStringSetDef
  4301. public function adminProcEditString($ar=NULL) {
  4302. $p=new XParam($ar,NULL);
  4303. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4304. $ret=$tset->procEditString($ar);
  4305. if($ret['error']) setSessionVar('message',$ret['message']);
  4306. }
  4307. /// Supprime une valeur d'un XStringSetDef
  4308. public function adminDelString($ar=NULL) {
  4309. $p=new XParam($ar,NULL);
  4310. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4311. $tset->delString($ar);
  4312. }
  4313. /// Supprime toutes les valeurs d'un XStringSetDef
  4314. public function adminClearStrings($ar=NULL) {
  4315. $p=new XParam($ar,NULL);
  4316. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4317. $tset->clearStrings($ar);
  4318. }
  4319. /// Reoordonne les valeurs d'un XStringSetDef par ordre alphabétique
  4320. public function adminSortStrings($ar=NULL) {
  4321. $p=new XParam($ar,NULL);
  4322. $boid=$p->get('boid');
  4323. $tset=new XTSet(array('boid'=>$this->boid,'_options'=>array('local'=>true)));
  4324. $tset->sortStrings($ar);
  4325. }
  4326. /// Réinitialise un chrono
  4327. public function adminResetChrono($ar=NULL){
  4328. $p=new XParam($ar, array());
  4329. $table=$this->table;
  4330. $field=$p->get('field');
  4331. XDBIni::clear('Chrono::'.$table.'::'.$field);
  4332. }
  4333. /// Prepare l'importation d'un csv contenant les regles de securité sur les champs
  4334. public function adminPreImportFieldsSec($ar=NULL){
  4335. }
  4336. /// Importe d'un csv contenant les regles de securité sur les champs
  4337. /// Colonne en entete : AKOID => nom sql du champ, AFUNCTION => niveau de droit, AGRP => uid ou gid ou chaine de ugrpnames (voir param)
  4338. public function adminImportFieldsSec($ar=NULL){
  4339. $p=new XParam($ar,array('delallfields'=>0,'delotherfields'=>0,'file'=>$_FILES['file']['tmp_name'],
  4340. 'endofline'=>"\r\n",'separator'=>';','quote'=>"\"",
  4341. 'ugrpnames'=>array('AUTH'=>TZR_GROUPID_AUTH,'ALL'=>TZR_USERID_NOBODY)));
  4342. $ugrpnames=$p->get('ugrpnames');
  4343. $delbefore=$p->get('delbefore');
  4344. if(!empty($delbefore)){
  4345. updateQuery('delete from ACL4 where AMOID="'.$this->_moid.'" and AKOID like "_field-%"');
  4346. XLogs::update('security', XUser::get_current_user_uid(), 'Delete all fields security rules for '.$this->_moid);
  4347. }
  4348. $file=$p->get('file');
  4349. $message='';
  4350. $spec->general->endofline=$p->get('endofline');
  4351. $spec->general->separator=$p->get('separator');
  4352. $spec->general->quote=$p->get('quote');
  4353. $rawdata=@file_get_contents($file);
  4354. $data=_getCSVData($rawdata,$spec);
  4355. $head=$data[0];
  4356. $l=count($data);
  4357. $tot=0;
  4358. for($i=1;$i<$l;$i++){
  4359. $row=array();
  4360. foreach($head as $j=>$h){
  4361. if($data[$i][$j]==='') continue;
  4362. $pos=strpos($h,'[');
  4363. if($pos) $tmp='['.substr($h,0,$pos).']'.substr($h,$pos);
  4364. else $tmp='['.$h.']';
  4365. $tmp=str_replace(array('[',']'),array("['","']"),$tmp);
  4366. $data[$i][$j]=addslashes($data[$i][$j]);
  4367. eval('$row'.$tmp.'="'.str_replace('"','\"',$data[$i][$j]).'";');
  4368. }
  4369. if(empty($row['AKOID']) || empty($row['AFUNCTION']) || empty($row['AGRP'])){
  4370. $message.='AKOID, AFUNCTION ou AGRP manquant ligne '.($i+1).'<br>';
  4371. continue;
  4372. }
  4373. if(empty($this->xset->desc[$row['AKOID']])){
  4374. $message.='Le champ '.$row['AKOID'].' n\'existe pas à la ligne '.($i+1).'<br>';
  4375. continue;
  4376. }
  4377. if(!in_array($row['AFUNCTION'],array('none','ro','rw'))){
  4378. $message.='Les droits doivent être none, ro ou rw à la ligne '.($i+1).'<br>';
  4379. continue;
  4380. }
  4381. if(!empty($ugrpnames[$row['AGRP']])) $row['AGRP']=$ugrpnames[$row['AGRP']];
  4382. if(in_array(Kernel::getTable($row['AGRP']),array('USERS','GRP'))){
  4383. $rs=selectQuery('select KOID from '.Kernel::getTable($row['AGRP']).' where KOID="'.$row['AGRP'].'"');
  4384. if($rs->rowCount()!=1){
  4385. $message.='La cible des droits n\'existe pas à la ligne '.($i+1).'<br>';
  4386. continue;
  4387. }
  4388. }else{
  4389. $message.='La cible des droits n\'est ni un USERS ni un GRP à la ligne '.($i+1).'<br>';
  4390. continue;
  4391. }
  4392. $tot++;
  4393. $this->procSecEdit(array('oid'=>'_field-'.$row['AKOID'],'level'=>$row['AFUNCTION'],'uid'=>$row['AGRP']));
  4394. }
  4395. $message.='Nombre de règle importée : '.$tot.'<br>';
  4396. XShell::toScreen2('','message',$message);
  4397. }
  4398. }
  4399. /// Verifie la validité d'un captcha
  4400. function xmodtable_captcha(){
  4401. $value=$_REQUEST['value'];
  4402. $id=$_REQUEST['id'];
  4403. if(!preg_match('/^[a-z0-9A-Z]+$/', $value)) die('0');
  4404. if(!preg_match('/^[a-z0-9A-Z]+$/', $id)) die('0');
  4405. $cnt=countSelectQuery('SELECT COUNT(*) from _VARS where name="CAPTCHA_'.$id.'" and value="'.md5($value).'"');
  4406. if($cnt) die('1');
  4407. else die('0');
  4408. }