PageRenderTime 50ms CodeModel.GetById 11ms RepoModel.GetById 0ms app.codeStats 1ms

/class.xlinkdef.inc

https://github.com/jcplat/console-seolan
PHP | 1290 lines | 1148 code | 62 blank | 80 comment | 407 complexity | f6d50794166646f80df9b804c9d3ff1d MD5 | raw file
Possible License(s): LGPL-2.0, LGPL-2.1, GPL-3.0, Apache-2.0, BSD-3-Clause

Large files files are truncated, but you can click here to view the full file

  1. <?php
  2. define('XLINKDEF_MAXLINKS',3);
  3. define('XLINKDEF_MAXPOPUPLINKS',100);
  4. @require_once 'pack.autocomplete.inc';
  5. /// Gestion des champs Lien entre les objets des tables
  6. class XLinkDef extends XFieldDef {
  7. public $filter='';
  8. public $query='';
  9. public $boxsizxe=6;
  10. public $usedefault=true;
  11. public $checkbox=true;
  12. public $doublebox=false;
  13. public $doubleboxorder=false;
  14. public $checkbox_limit=30;
  15. public $autocomplete=true;
  16. public $autocomplete_limit=200;
  17. public $generate_link = true;
  18. public $checkbox_cols=3;
  19. private $_cache=array();
  20. protected $modsUsingTable=NULL;
  21. public $query_formats=array('classic','listbox-one','listbox','autocomplete');
  22. public $advanceeditbatch=true;
  23. public $display_format='';
  24. public $display_text_format='';
  25. protected $fieldlist=NULL;
  26. /// Types de champs à ignorer lors de l'affichage de l'objet au format texte
  27. public $display_text_unwanted_ftypes = array('XColorDef','XFileDef','XImageDef','XFolderDef');
  28. function __construct($obj=NULL) {
  29. parent::__construct($obj);
  30. }
  31. function cacheable() { return false; }
  32. function clearCache(){ $this->_cache=array(); }
  33. function initOptions() {
  34. parent::initOptions();
  35. $this->_options->delOpt('aliasmodule');
  36. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','sourcemodule'),'sourcemodule','module',array('emptyok'=>true));
  37. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','usedefault'), "usedefault", "boolean", array(),true);
  38. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','filter'), 'filter', 'text',array('rows'=>2,'cols'=>60));
  39. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','query'), 'query', 'text',array('rows'=>2,'cols'=>60));
  40. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','display_format'), 'display_format', 'text', array('rows'=>3,'cols'=>50));
  41. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','display_text_format'), 'display_text_format', 'text', array('size'=>50));
  42. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','checkbox'), 'checkbox', 'boolean');
  43. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','checkbox_limit'), 'checkbox_limit', 'text');
  44. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','checkbox_cols'), 'checkbox_cols', 'text');
  45. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','autocomplete'), 'autocomplete', 'boolean',NULL,true);
  46. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','autocomplete_limit'), 'autocomplete_limit', 'text',NULL,200);
  47. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','doublebox'), 'doublebox', 'boolean',NULL,false);
  48. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','doubleboxorder'), 'doubleboxorder', 'boolean',NULL,false);
  49. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','boxsize'), 'boxsize', 'text', NULL, 6);
  50. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','grouplist'), 'grouplist', 'boolean', NULL, false);
  51. $this->_options->setOpt(XLabels::getSysLabel('xfielddef','generate_link'), 'generate_link', 'boolean',NULL, true);
  52. }
  53. /**
  54. * Génère le formulaire d'édition des options du champs
  55. * @see XOptions::getDialog()
  56. */
  57. function getOptions($block='opt') {
  58. // Ajoute la liste des champs utilisable pour l'affichage des données
  59. $desc = selectQuery('SELECT FIELD,FTYPE FROM DICT WHERE DTAB="'.$this->target.'" ORDER BY FORDER')->fetchAll(PDO::FETCH_UNIQUE | PDO::FETCH_GROUP | PDO::FETCH_COLUMN);
  60. $this->_options->setComment(XLabels::getSysLabel('general','tokens_available').' :<br>%_KOID<br>%_'.implode('<br>%_',array_keys($desc)),'display_format');
  61. // Suppression des types de champs interdit à l'affichage texte
  62. foreach ($desc as $field => $ftype) {
  63. if (in_array($ftype,$this->display_text_unwanted_ftypes)) {
  64. unset($desc[$field]);
  65. }
  66. }
  67. $this->_options->setComment(XLabels::getSysLabel('general','tokens_available').' :<br>%_'.implode('<br>%_',array_keys($desc)),'display_text_format');
  68. return parent::getOptions($block);
  69. }
  70. function get_sqlValue($value) {
  71. // Fabrique une valeur de colonne pour SQL à partir d'une valeur issue de PHP
  72. // $value est ici un tableau. 1 seul valeur si champ single value, n valeurs si multi value
  73. if ( !is_array($value) ) return $value;
  74. $nb = count($value);
  75. if ( $nb == 0 ) return '';
  76. if ( (!$this->get_multivalued()) || ($nb==1) ) {
  77. return $value;
  78. }
  79. else {
  80. $val = '||';
  81. for ($i=0;$i<$nb;$i++) {
  82. $val .= $value[$i] . '||';
  83. }
  84. return $val;
  85. }
  86. }
  87. function my_export($value, $options=NULL) {
  88. return $value;
  89. }
  90. function &getValues($filter2, $options=array()) {
  91. $mod=&$options['mod'];
  92. $max=$options['max'];
  93. $lang=XShell::getLangUser();
  94. $lang_data=XShell::getLangData();
  95. $result=array();
  96. if($this->target==TZR_DEFAULT_TARGET || !XDataSource::sourceExists($this->target)) return $result;
  97. // Liste des champs à recuperer
  98. list($myliste,$my_flist,$first)=$this->getFieldList($options,false);
  99. // Création de la requete
  100. $textfilter2=(count($myliste)>0)?'concat("'.preg_replace('/%[_a-z0-9]+/','%s',$df).'")':'';
  101. $fromcomp='';
  102. $filterarray=array();
  103. $i=0;
  104. foreach($myliste as $fn=>$obj){
  105. $i++;
  106. if($filter2){
  107. if(in_array($obj->get_ftype(),array('XTextDef','XShortTextDef','XRichTextDef')))
  108. $filterarray[]='",ifnull('.$this->target.'.'.$fn.',""),"';
  109. elseif($obj->isObjectLink() && !empty($obj->target) && $obj->target!='%'){
  110. $tablealias=$obj->target.'_'.$i;
  111. $fromcomp.=' left outer join '.$obj->target.' as '.$tablealias.' on '.$tablealias.'.KOID='.$this->target.'.'.$fn.' and '.$tablealias.'.LANG="'.TZR_DEFAULT_LANG.'" ';
  112. $rslink=&cacheSelectQuery('select * from DICT where PUBLISHED=1 and DTAB="'.$obj->target.'" and FTYPE="XShortTextDef" ORDER BY FORDER');
  113. $tmp='';
  114. while($rslink && ($orslink=$rslink->fetch())) $tmp.='ifnull('.$tablealias.'.'.$orslink['FIELD'].',""),\' \',';
  115. $filterarray[]='",'.substr($tmp,0,-5).',"';
  116. $rslink->CloseCursor();
  117. }elseif($obj->get_ftype()=='XStringSetDef'){
  118. $tablealias='SETS_'.$i;
  119. $fromcomp.=' LEFT OUTER JOIN SETS AS '.$tablealias.' ON '.$tablealias.'.SOID='.$this->target.'.'.$fn.' AND '.
  120. $tablealias.'.SLANG="'.TZR_DEFAULT_LANG.'" AND '.$tablealias.'.STAB="'.$this->target.'" AND '.$tablealias.'.FIELD="'.$fn.'" ';
  121. $filterarray[]='",IFNULL('.$tablealias.'.STXT,""),"';
  122. }
  123. }
  124. }
  125. if($this->display_format) $df=$this->display_format;
  126. else $df=str_repeat('%s ',count($filterarray));
  127. $textfilter2 = (count($filterarray)>0) ? 'concat("'.preg_replace('/%[_a-z0-9]+/','%s',$df).'")' : '';
  128. $textfilter2 = '('.substr(vsprintf($textfilter2,$filterarray),0).' LIKE "%'.$filter2.'%") AND ';
  129. $filter=$this->filter;
  130. if(!empty($options['filter'])) $filter='('.$options['filter'].')';
  131. if(!empty($filter)) $filter.=' AND ';
  132. // Dans le cas d'une recherche, on récupère les valeurs déjà utilisé pour n'afficher qu'elles
  133. $used_values=null;
  134. if($options['query_format']==XFieldDef::QUICKQUERY_FORMAT && !XShell::admini_mode()){
  135. $used_values=$this->_getUsedValues(null,null,$options);
  136. }
  137. $rs2=selectQuery('select distinct '.$my_flist.' FROM '.$this->target.' '.$fromcomp.
  138. ' WHERE '.$textfilter2.' '.$filter.' '.$this->target.'.LANG="'.TZR_DEFAULT_LANG.'" '.
  139. (!empty($myliste)?'order by '.$this->target.'.'.implode(','.$this->target.'.',array_keys($myliste)):''));
  140. // Generation de la boite de saisie
  141. $state='ok';
  142. $tot=0;
  143. $opts=array('_published'=>'all', '_charset'=>$options['_charset']);
  144. while($ors2=$rs2->fetch()) {
  145. if(!empty($max) && $tot>$max){
  146. $state='toomuch';
  147. break;
  148. }
  149. $my_oid=$ors2['KOID'];
  150. // Filtre sur les valeurs deja utilisées
  151. if($used_values!==null && !$used_values[$my_oid]) continue;
  152. if(!empty($mod) && $mod->object_sec && Kernel::getTable($my_oid)==$mod->table && !$mod->secure($my_oid,':ro')) continue;
  153. $result[$my_oid]=trim($this->format_display($myliste,$ors2,$opts,null,'text'));
  154. $tot++;
  155. }
  156. return array('values'=>$result,'state'=>$state);;
  157. }
  158. function sqltype() {
  159. return 'text';
  160. }
  161. /**
  162. * Affichage du champ lien, appel rDisplay sur la cible
  163. * (traitement multivalue dans xfielddef)
  164. * ! effet de bord : si l'objet est introuvable, supprime tous les liens vers cet objet
  165. * sauf si XDbIni[disable_xlinkclean] est positionné à 1
  166. * @param KOID $value unique dans la table cible ou 'UNPUBLISHED',
  167. * @param array $options [
  168. * string _format application/excel, application/prince
  169. * string _charset charset passé au rDisplay
  170. * mixed target_fields tableau des champs ramenés ou 'all' (rDisplay selectedfields)
  171. * boolean nocache n'utilise pas le cache
  172. * boolean nofollowlinks retourne juste l'oid sans appel au rdisplay
  173. * ]
  174. * @return XFieldVal
  175. */
  176. function my_display(&$value, &$options) {
  177. $_format = @$options['_format'];
  178. $LANG_DATA = XShell::getLangData();
  179. $lang = XShell::getLangUser();
  180. $olddisplayformat=NULL;
  181. // Verifie le cache
  182. if(isset($this->_cache[$value]) && @$options['nocache']!==true) {
  183. $r=clone $this->_cache[$value];
  184. return $r;
  185. }
  186. // OID valide
  187. $r=&$this->_newXFieldVal($options);
  188. if(empty($value) || strpos($value,'VOID:')) return $r;
  189. // l'oid sans la cible
  190. if(!empty($options['nofollowlinks'])) {
  191. $r->raw=$value;
  192. $r->html='';
  193. return $r;
  194. }
  195. // Table existe
  196. $target=Kernel::getTable($value);
  197. if(!XSystem::tableExists($target)) return $r;
  198. // Droit sur le module source de données
  199. if($this->sourcemodule){
  200. $mod=XModule::objectFactory($this->sourcemodule);
  201. if($mod->object_sec && !$mod->secure($value,':ro') || !$mod->object_sec && !$mod->secure('',':ro')) return $r;
  202. }
  203. $target_ds=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$target);
  204. if(!empty($options['target_options'])) $targetopts=$options['target_options'];
  205. else $targetopts=array();
  206. if(!empty($options['_charset'])) $targetopts['_charset']=$options['_charset'];
  207. else $targetopts['_charset'] = XLang::getCharset();
  208. // Liste des champs à recuperer
  209. if(@$options['display_format']){
  210. $olddisplayformat=$this->display_format;
  211. $this->display_format=$options['display_format'];
  212. }
  213. if(strpos($this->display_format,'%_')!==false){
  214. preg_match_all('/%_([a-z0-9_]+)/i',$this->display_format,$fmtfields);
  215. $fmtfields=$fmtfields[1];
  216. }else{
  217. $fmtfields=array();
  218. }
  219. if(isset($options['target_fields'])) $targetopts['selectedfields']=$options['target_fields'];
  220. else $targetopts['selectedfields']=$target_ds->getPublished(false);
  221. $targetopts['selectedfields']=array_merge($fmtfields,$targetopts['selectedfields']);
  222. // Recupere les champs de l'objet cible
  223. $values=&$target_ds->rDisplay($value, array(), false, $LANG_DATA, $lang, $targetopts);
  224. $cnt=count($values['fields_object']);
  225. if (XShell::admini_mode())
  226. $cnt = max($cnt, $this->getNbPublishedFields());
  227. // Si l'oid n'existe plus, on met à jour la table pour supprimer l'oid partout ou il est present et on retourne un objet sans valeur
  228. if(!is_array($values) && $values!='UNPUBLISHED' && XDbIni::get('disable_xlinkclean','val')!=1) {
  229. // Si la table est traduisible et qu'on est pas dans la langue par defaut, on verifie si l'oid existe dans au moins une langue
  230. if($target_ds->isTranslatable() && $LANG_DATA!=TZR_DEFAULT_LANG){
  231. $nb=countSelectQuery('SELECT count(*) FROM '.$target.' WHERE KOID="'.$value.'"');
  232. if($nb) return $r;
  233. }
  234. // Multivalué, traite tous les cas possibles (%||oid||%, oid||% et %||oid)
  235. $tolog=($target_ds->toLog() && $this->table!='LOGS');
  236. if($this->multivalued){
  237. $l=strlen($value);
  238. // %||oid||%
  239. if($tolog) {
  240. $rs=selectQuery('select KOID from '.$this->table.' where '.$this->field.' like "%||'.$value.'||%"');
  241. while($rs && ($ors=$rs->fetch())) XLogs::update('update',$ors['KOID'],'remove oid '.$value.' from '.$this->field);
  242. }
  243. if(!$tolog || $rs->rowCount()>0) {
  244. updateQuery('update '.$this->table.' set UPD=UPD,'.$this->field.'=REPLACE('.$this->field.',"||'.$value.'||","||") '.
  245. 'where '.$this->field.' like "%||'.$value.'||%"');
  246. }
  247. // oid||%
  248. if($tolog) {
  249. $rs=selectQuery('select KOID from '.$this->table.' where '.$this->field.' like "'.$value.'||%"');
  250. while($rs && ($ors=$rs->fetch())) XLogs::update('update',$ors['KOID'],'remove oid '.$value.' from '.$this->field);
  251. }
  252. if(!$tolog || $rs->rowCount()>0) {
  253. updateQuery('update '.$this->table.' set UPD=UPD,'.$this->field.'=SUBSTR('.$this->field.','.($l+3).') '.
  254. 'where '.$this->field.' like "'.$value.'||%"');
  255. }
  256. // %||oid
  257. if($tolog) {
  258. $rs=selectQuery('select KOID from '.$this->table.' where '.$this->field.' like "%||'.$value.'||%"');
  259. while($rs && ($ors=$rs->fetch())) XLogs::update('update',$ors['KOID'],'remove oid '.$value.' from '.$this->field);
  260. }
  261. if(!$tolog || $rs->rowCount()>0) {
  262. updateQuery('update '.$this->table.' set UPD=UPD,'.$this->field.'=SUBSTR('.$this->field.',1,LENGTH('.$this->field.')-'.($l+2).') '.
  263. 'where '.$this->field.' like "%||'.$value.'"');
  264. }
  265. }
  266. if($tolog) {
  267. $rs=selectQuery('select KOID from '.$this->table.' where '.$this->field.'="'.$value.'"');
  268. while($rs && ($ors=$rs->fetch())) XLogs::update('update',$ors['KOID'],'remove oid '.$value.' from '.$this->field);
  269. }
  270. if(!$tolog || $rs->rowCount()>0) updateQuery('update '.$this->table.' set UPD=UPD,'.$this->field.'="" where '.$this->field.'="'.$value.'"');
  271. $r->raw='';
  272. return $r;
  273. }elseif($values=='UNPUBLISHED'){
  274. $r->raw='';
  275. return $r;
  276. }
  277. // Prepare le html
  278. $display='';
  279. if(!empty($this->display_format)){
  280. if(strpos($this->display_format,'%_')!==false){
  281. $display=$this->display_format;
  282. foreach($fmtfields as $f) $display=str_replace('%_'.$f,$values['o'.$f]->html,$display);
  283. }else{
  284. $htmls=array();
  285. foreach($values['fields_object'] as $f) $htmls[]=$f->html;
  286. $display=@vsprintf($this->display_format,array_pad($htmls,substr_count($this->display_format,'%'),''));
  287. }
  288. }
  289. if(empty($this->display_format) || $display===false){
  290. for($i=0;$i<$this->getNbPublishedFields();$i++) {
  291. if(!isset($values['fields_object'][$i])) break;
  292. if($i==0) $display.=$values['fields_object'][$i]->html;
  293. else $display.=' '.$values['fields_object'][$i]->html;
  294. }
  295. }
  296. // Ajoute les liens vers l'objet dans le html si necessaire
  297. $r->html=$display;
  298. if(XShell::admini_mode() && $this->generate_link){
  299. if($this->modsUsingTable===NULL){
  300. if($this->sourcemodule) $this->modsUsingTable=array($mod->_moid=>$mod->modulename);
  301. else $this->modsUsingTable=XModule::modulesUsingTable($target,false,true,true,true);
  302. }
  303. if(!empty($this->modsUsingTable)) {
  304. $url=$GLOBALS['TZR_SESSION_MANAGER']::admin_url(false,true);
  305. if($_format!='application/prince' && $_format!='application/excel') {
  306. if(count($this->modsUsingTable)>1) {
  307. $mi=0;
  308. foreach($this->modsUsingTable as $mod=>&$label) {
  309. $mi++;
  310. if($mi<=XLINKDEF_MAXLINKS) {
  311. if($mi==1) $r->html.=' [';
  312. else $r->html.='|';
  313. $r->html.='<a class="cv8-ajaxlink" href="'.$url.'&moid='.$mod.'&function=goto1&oid='.$value.'" title="'.$label.'">'.$mi.'</a>';
  314. }
  315. }
  316. if($mi>0) $r->html.=']';
  317. } else {
  318. reset($this->modsUsingTable);
  319. $v1=each($this->modsUsingTable);
  320. $r->html='<a class="cv8-ajaxlink" href="'.$url.'&moid='.$v1['key'].'&function=goto1&oid='.$value.'" title="'.$v1['value'].'">'
  321. .preg_replace('@<a([^>]*)>([^<]*)</a>@i','$2',$r->html).'</a>';
  322. }
  323. }
  324. }
  325. }
  326. $r->title=$display;
  327. $r->link=$values;
  328. $r->raw=$value;
  329. $this->_cache[$value]=$r;
  330. if($olddisplayformat) $this->display_format=$olddisplayformat;
  331. return $r;
  332. }
  333. function my_browse(&$value, &$options) {
  334. $r= &$this->_newXFieldVal($options);
  335. if(!empty($options['nofollowlinks'])) {
  336. $r->raw=$value;
  337. $r->html='';
  338. return $r;
  339. }
  340. return $this->my_display($value, $options);
  341. }
  342. /// Un champ de type Lien n'est en edit que sur la langue par defaut.
  343. function my_edit(&$value,&$options) {
  344. $queryorder='';
  345. $queryfilter='';
  346. if($this->target==TZR_DEFAULT_TARGET){
  347. return $this->my_display($value,$options);
  348. }
  349. $p=new XParam($options,array());
  350. $lang_data=XShell::getLangData();
  351. $r=$this->_newXFieldVal($options);
  352. $r->raw=$value;
  353. if(!XDataSource::sourceExists($this->target)) {
  354. $r->html='';
  355. return $r;
  356. }
  357. $format=@$options['fmt'];
  358. if(isset($options['intable'])) {
  359. $o=$options['intable'];
  360. $fname=$this->field.'['.$o.']';
  361. $hiddenname=$this->field.'_HID['.$o.']';
  362. } elseif(!empty($options['fieldname'])) {
  363. $fname=$options['fieldname'];
  364. $hiddenname=$options['fieldname'].'_HID';
  365. } else {
  366. $fname=$this->field;
  367. $hiddenname=$this->field.'_HID';
  368. }
  369. // cas ou il y a une requete qui donne l'ensemble des valeurs
  370. if(!empty($this->query)) {
  371. preg_match('/^SELECT (.+) FROM .+( WHERE (.*))?( ORDER BY .*)?$/Ui', $this->query, $matches);
  372. if(!isset($options['target_fields']) && $matches[1]!='*') $options['target_fields'] = explode(',', $matches[1]);
  373. $queryfilter=$matches[3];
  374. $queryorder=$matches[4];
  375. }
  376. // Liste des champs de la cible
  377. if(!empty($options['display_format'])){
  378. $olddisplayformat=$this->display_format;
  379. $this->display_format=$options['display_format'];
  380. }
  381. list($myliste,$my_flist,$first)=$this->getFieldList($options);
  382. // Construction de la requete
  383. // est ce que l'on veux les objet publie
  384. $dstarget=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->target);
  385. $dspublishedMode = $dstarget->publishedMode($p);
  386. if(!empty($options['filter'])) $filter='('.$options['filter'].')';
  387. else $filter=$this->filter;
  388. if(!empty($queryfilter)) {
  389. if(!empty($filter)) $filter.=' AND ';
  390. $filter.=$queryfilter;
  391. }
  392. if($dspublishedMode == 'public'){
  393. if(!empty($filter)) $filter .= ' AND ';
  394. $filter .= ' PUBLISH = 1 ';
  395. }
  396. if(!empty($filter)) $filter.=' AND ';
  397. $maxrecords=max($this->checkbox_limit, $this->autocomplete_limit)+1;
  398. if($dstarget->isTranslatable())
  399. $rs2=selectQuery('SELECT DISTINCT '.$my_flist.' FROM '.$this->target.' WHERE '.$filter.' LANG="'.$lang_data.'"'.
  400. ($queryorder?$queryorder:($first?' ORDER BY '.$first:'')).' LIMIT '.$maxrecords);
  401. else
  402. $rs2=selectQuery('SELECT DISTINCT '.$my_flist.' FROM '.$this->target.' WHERE '.$filter.' 1 '.
  403. ($queryorder?$queryorder:($first?' ORDER BY '.$first:'')).' LIMIT '.$maxrecords);
  404. // Format de la saisie
  405. $nb=($rs2?$rs2->rowCount():0);
  406. $checkbox=($nb<=$this->checkbox_limit || $format=='checkbox') && $format!='listbox' && $this->checkbox && empty($options['simple']);
  407. $autocomplete=($nb>=$this->autocomplete_limit && $this->autocomplete);
  408. $doublebox=($this->multivalued && $this->doublebox && empty($options['simple']));
  409. if($checkbox) $this->getCheckboxes($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  410. elseif($autocomplete) $this->getAutocomplete($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  411. elseif($doublebox) $this->getDoubleSelect($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  412. else $this->getSelect($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  413. if(!empty($olddisplayformat)) $this->display_format=$olddisplayformat;
  414. return $r;
  415. }
  416. /// Recherche
  417. function my_query($value,$options=NULL) {
  418. $format=@$options['fmt'];
  419. if(empty($format)) $format=@$options['qfmt'];
  420. if(empty($format)) $format=$this->query_format;
  421. $searchmode=@$options['searchmode'];
  422. $fname=(isset($options['fieldname'])?$options['fieldname']:$this->field);
  423. $hiddenname=$fname.'_HID';
  424. $r=$this->_newXFieldVal($options,true);
  425. $r->raw=$value;
  426. if($this->target==TZR_DEFAULT_TARGET) {
  427. $r->html.='<input name="'.$fname.'" size="30" type="text" value="'.$value.'">';
  428. return $r;
  429. }
  430. // Liste des champs de la cible
  431. if(!empty($options['display_format'])){
  432. $olddisplayformat=$this->display_format;
  433. $this->display_format=$options['display_format'];
  434. }
  435. list($myliste,$my_flist,$first)=$this->getFieldList($options);
  436. if($format=='autocomplete'){
  437. $this->getAutocomplete($value,$options,$r,$rs,$fname,$hiddenname,$myliste);
  438. return $r;
  439. }
  440. // Construction de la requete
  441. $filter=array();
  442. if(!empty($options['filter'])) $filter[]='('.$options['filter'].')';
  443. elseif(!empty($this->filter)) $filter[]='('.$this->filter.')';
  444. if(!empty($this->query)) {
  445. $inclause=array();
  446. $rs=selectQuery($this->query);
  447. while($rs && ($ors=$rs->fetch())) $inclause[]="'".$ors['KOID']."'";
  448. $filter[]='(KOID IN ('.implode(',',$inclause).'))';
  449. }
  450. if($searchmode=='simple') {
  451. $allvalues=array();
  452. $selectquery=@$options['select'];
  453. if(!empty($selectquery)) $allvalues=$this->_getUsedValues(NULL,$selectquery);
  454. else $allvalues=$this->_getUsedValues("LANG='".TZR_DEFAULT_LANG."'");
  455. $filter[]='(KOID IN ("'.implode('","',array_keys($allvalues)).'"))';
  456. }
  457. if(!empty($filter)) $filter=implode(' AND ',$filter).' AND ';
  458. else $filter='';
  459. $rs2=cacheSelectQuery("select distinct $my_flist from ".$this->target." where $filter LANG='".TZR_DEFAULT_LANG."'".
  460. ' '.($first ? "order by $first":""));
  461. // Format de la saisie
  462. if($rs2) $nb=$rs2->rowCount();
  463. if ($nb >= $this->autocomplete_limit && $this->autocomplete && !$this->multivalued) {
  464. $this->getAutocomplete($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  465. return $r;
  466. }
  467. $checkbox=(($nb<=$this->checkbox_limit || $format=='checkbox') && $format!='listbox' && $format!='listbox-one' && $this->checkbox);
  468. $op='';
  469. if($this->get_multivalued() && $format!='listbox-one'){
  470. $varid=$r->varid;
  471. $textid = $fname.'_id';
  472. $op=$options['op'];
  473. $medit='<input class="radio" type="radio" name="'.$fname.'_op" value="AND" id="'.$textid.'-AND" checked>'.
  474. '<label for="'.$textid.'-AND">'.XLabels::getSysLabel('xfielddef.xlinkdef_allterms').'</label>&nbsp;&nbsp;'.
  475. '<input class="radio" type="radio" name="'.$fname.'_op" value="OR" id="'.$varid.'-OR"'.($op=='OR'?' checked':'').'>'.
  476. '<label for="'.$textid.'-OR">'.XLabels::getSysLabel('xfielddef.xlinkdef_leastaterm').'</label><br>';
  477. }else{
  478. $medit='';
  479. }
  480. if(@$options['genempty'] !== false && XShell::admini_mode()){
  481. $varid = $r->varid;
  482. $textid = $fname.'_id';
  483. if ($medit == '')
  484. $emptytype = 'checkbox';
  485. else
  486. $emptytype = 'radio';
  487. $medit .= '<input class="'.$emptytype.'" type="'.$emptytype.'" name="'.$fname.'_op" value="is empty" id="'.$textid.'-EMPTY"'.($op=='is empty'?' checked':'').'>'.'<label for="'.$textid.'-EMPTY">'.XLabels::getSysLabel('xfielddef.is_empty').'</label><br>';
  488. }
  489. if($checkbox) $this->getCheckboxes($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  490. else $this->getSelect($value,$options,$r,$rs2,$fname,$hiddenname,$myliste);
  491. $r->html=$medit.$r->html;
  492. if(!empty($olddisplayformat)) $this->display_format=$olddisplayformat;
  493. return $r;
  494. }
  495. function my_quickquery($value,$options=NULL) {
  496. $oldc=$this->checkbox;
  497. $oldd=$this->doublebox;
  498. $olda=$this->autocomplete;
  499. $this->checkbox=false;
  500. $this->doublebox=false;
  501. $this->autocomplete=true;
  502. $options['genempty'] = false;
  503. $ret=$this->query($value, $options);
  504. $ret->html.='<input type="hidden" value="'.$this->field.'" name="_FIELDS['.$this->field.']">';
  505. $this->checkbox=$oldc;
  506. $this->doublebox=$oldd;
  507. $this->autocomplete=$olda;
  508. return $ret;
  509. }
  510. function post_edit($value,$options,&$computed_fields=NULL){
  511. $r=$this->_newXFieldVal($options);
  512. $oid=$options['oid'];
  513. $ischeckbox=(@$options[$this->field.'_HID']=='checkbox')||(@$options[$this->field.'_FMT']=='checkbox');
  514. if($ischeckbox) {
  515. $nvalue=array();
  516. // Attention éviter les liens vers lui-même
  517. foreach($value as $soid => $set) {
  518. if($soid!='Foo' && $soid!=$oid) $nvalue[]=$soid;
  519. }
  520. $value=$nvalue;
  521. }else{
  522. if(is_array($value)){
  523. foreach($value as $i=>$foo){
  524. if(empty($foo)) unset($value[$i]);
  525. }
  526. }
  527. }
  528. if(!empty($this->exif_source) && empty($value)){
  529. $value=array();
  530. $meta=$this->getMetaValue($computed_fields,array('IPTC','EXIF','XMP'),true);
  531. if(!is_array($meta->raw)) $meta->raw=array($meta->raw);
  532. $opt=array('srcField'=>$this->flabel);
  533. if($this->isAutorizedToAdd($options)) $opt['create']=true;
  534. foreach($meta->raw as $i=>$v){
  535. if(!is_string($v)) continue;
  536. $ret=$this->my_import($v,$opt);
  537. $value[]=$ret['value'][0];
  538. }
  539. }
  540. if($value==$oid) $value=NULL;
  541. $r->raw=$value;
  542. // Edition par lot sur champ multivalué
  543. if(!empty($options['editbatch']) && $this->multivalued){
  544. $p=new XParam($options);
  545. $op=$p->get($this->field.'_op');
  546. $old=explode('||',$options['old']->raw);
  547. if($op=='+') $r->raw=array_unique(array_merge($r->raw,$old));
  548. elseif($op=='-') $r->raw=array_diff($old,$r->raw);
  549. }
  550. // Trace
  551. $old=@$options['old'];
  552. if(!empty($old)){
  553. if(is_array($r->raw)) $v=implode('||',$r->raw);
  554. else $v=$r->raw;
  555. $r1=&$this->display($v,$options);
  556. if($r1->html!=$old->html) $this->trace($options['old'],$r, '['.$old->html.'] -> ['.$r1->html.']');
  557. }
  558. return $r;
  559. }
  560. /// Autorise l'ajout d'une entrée à la volée
  561. public function isAutorizedToAdd(&$options){
  562. if($this->sourcemodule){
  563. if(empty($this->cache->modules[$this->sourcemodule])){
  564. $this->cache->modules[$this->sourcemodule]=XModule::objectFactory($this->sourcemodule);
  565. }
  566. return $this->cache->modules[$this->sourcemodule]->secure('',':rw');
  567. }elseif(!empty($options['fmoid'])){
  568. if(empty($this->cache->modules[$options['fmoid']])){
  569. $this->cache->modules[$options['fmoid']]=XModule::objectFactory($options['fmoid']);
  570. }
  571. return $this->cache->modules[$options['fmoid']]->secure($options['oid'],':rwv');
  572. }
  573. return false;
  574. }
  575. function post_query(&$o,$options=NULL) {
  576. $p=new XParam($options,array());
  577. if ($o->op == 'is empty'){
  578. $o->value = '';
  579. } else {
  580. $ischeckbox=($o->hid=='checkbox') || ($o->fmt=='checkbox');
  581. if($ischeckbox && is_array($o->value)) {
  582. $nvalue=array();
  583. foreach($o->value as $soid => $set) {
  584. $nvalue[]=$soid;
  585. }
  586. $o->value=$nvalue;
  587. }
  588. }
  589. return parent::post_query($o,$options);
  590. }
  591. function search($value,$options=NULL){
  592. if($this->target!='%'){
  593. if(!is_array($value)) $value=array($value);
  594. $cond=array();
  595. $x=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->target);
  596. if(!empty($options['target_fields'])) $pub=$options['target_fields'];
  597. else $pub=$x->getPublished(false);
  598. foreach($value as $v) $cond[]='concat('.implode('," ",',$pub).') like "%'.addslashes($v).'%"';
  599. if(!empty($cond)) return $this->field.' in (select KOID from '.$this->target.' where '.implode($cond,' or ').')';
  600. else return '';
  601. }
  602. }
  603. function getNbPublishedFields(){
  604. if(!XShell::admini_mode()) return 99;
  605. if($this->target=='%' || empty($this->target)) return 2;
  606. if(strpos($this->display_format,'%')!==false) return 99;
  607. if(empty($this->published_fields_in_admin)){
  608. $tablexset=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->target);
  609. $this->published_fields_in_admin=$tablexset->published_fields_in_admin;
  610. }
  611. return $this->published_fields_in_admin;
  612. }
  613. /// Formate l'affichage d'un lien
  614. function format_display(&$myliste,&$ors,&$opt,$nbpublishedfields=NULL,$prop='html'){
  615. reset($myliste);
  616. $display='';
  617. $htmls=array();
  618. $replace=false;
  619. if ($prop == 'text' && !empty($this->display_text_format) && strpos($this->display_text_format,'%_')!==false) {
  620. $replace=true;
  621. $display=$this->display_text_format;
  622. } elseif (!empty($this->display_format) && strpos($this->display_format,'%_')!==false) {
  623. $replace=true;
  624. $display=$this->display_format;
  625. } elseif ($prop == 'text') {
  626. $verify_ftypes = true;
  627. }
  628. foreach($myliste as $k=>$f) {
  629. // Types de champs à ne pas afficher dans les listes <select> et <input autocomplete>
  630. if ($verify_ftypes && in_array($f->ftype, $this->display_text_unwanted_ftypes)) continue;
  631. $o=$f->display($ors[$k],$opt);
  632. $t=$o->$prop;
  633. if($replace) $display=str_replace('%_'.$k,$t,$display);
  634. else $htmls[]=$t;
  635. }
  636. if(!$replace){
  637. if($prop == 'text' && !empty($this->display_text_format))
  638. $display=@vsprintf($this->display_text_format,array_pad($htmls,substr_count($this->display_text_format,'%'),''));
  639. elseif(!empty($this->display_format))
  640. $display=@vsprintf($this->display_format,array_pad($htmls,substr_count($this->display_format,'%'),''));
  641. else $display=implode(' ',$htmls);
  642. }
  643. return $display;
  644. }
  645. /// Ecriture dans un fichier excel
  646. function writeXLS(&$xl,$i,$j,&$value,$format=0,&$ss=NULL) {
  647. $t=str_replace('&nbsp;', ' ', $value->text);
  648. $t=preg_replace('/\[.*\]/', '', $t);
  649. convert_charset($t,TZR_INTERNAL_CHARSET,'UTF-8');
  650. $xl->setCellValueByColumnAndRow($j,$i,$t);
  651. if(is_array($format)) $xl->getStyleByColumnAndRow($j,$i)->applyFromArray($format);
  652. }
  653. /// Sous fonction pour l'import de données vers une table
  654. /// Options : srcField (string) => champ à utiliser dans la table cible pour creer le lien (si vide la valeur doit etre un oid)
  655. /// create (true/false) => creation automatique des fiches cible non existante (false par defaut)
  656. /// separator (string) => séparateur pour des valeurs multiples (| par defaut)
  657. /// forcekoid (true/false) => force la génération de l'oid à partir de la valeur (false par defaut)
  658. function my_import($value,&$options){
  659. $separator=(string)$options['separator'];
  660. if(empty($separator)) $separator='|';
  661. $create=(string)$options['create'];
  662. $forcekoid=(string)$options['forcekoid'];
  663. $srcField=(string)$options['srcField'];
  664. if(!empty($options['input']) && is_array($options['input'])){
  665. $inputar=$options['input'];
  666. }else{
  667. $inputar=array();
  668. }
  669. $message='';
  670. if($value!=''){
  671. if(empty($srcField) && !Kernel::isAMultipleKoid($value)){
  672. $srcField=array();
  673. $rs=selectQuery('select FIELD from DICT where DTAB="'.$this->target.'" and PUBLISHED=1 order by forder limit '.$this->getNbPublishedFields());
  674. while($rs && $ors=$rs->fetch()) $srcField[]=$ors['FIELD'];
  675. }else{
  676. $srcField=array($srcField);
  677. }
  678. if(!empty($srcField)){
  679. $ret=array();
  680. cp1252_replace($value);
  681. $valueslist=explode($separator,$value);
  682. $ret=array();
  683. $concatfields='CONCAT('.implode('," ",', $srcField).')';
  684. foreach($valueslist as $v){
  685. $v=trim($v);
  686. if($v!=''){
  687. $filter=$this->filter;
  688. if(!empty($options['filter'])) $filter='('.$options['filter'].')';
  689. if(!empty($filter)) $filter.=' AND ';
  690. $rs=preparedSelectQuery(array(strtoupper($v)),'SELECT KOID FROM '.$this->target.' WHERE '.$filter.' TRIM(UPPER('.$concatfields.'))=?');
  691. if($rs && $ors=$rs->fetch()){
  692. $ret[]=$ors['KOID'];
  693. }else{ // la target n'existe pas
  694. if(!empty($create) && $create!='false'){
  695. $toinsert=$inputar;
  696. if(!empty($forcekoid) && $forcekoid!='false'){
  697. $toinsert['newoid']=$this->target.':'.strtoupper(preg_replace('/([^a-z0-9]+)/','',rewriteToAscii($v)));
  698. }
  699. $xset=&XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$this->target);
  700. $toinsert['tplentry']=TZR_RETURN_DATA;
  701. $toinsert['PUBLISH']=1;
  702. $toinsert[$srcField[0]]=$v;
  703. $mess=$xset->procInput($toinsert);
  704. $message.=$this->field.' : "'.$v.'" created<br/>';
  705. $ret[]=$mess['oid'];
  706. }else{
  707. $message.='<u>Warning</u> : '.$this->field.' : "'.$v.'" doesn\'t exist<br/>';
  708. }
  709. }
  710. }
  711. }
  712. }else{
  713. $ret=$value;
  714. }
  715. }
  716. return array('message'=>$message,'value'=>$ret);
  717. }
  718. /// creation d'un index si c'est un champ mono value
  719. function chk(&$msg) {
  720. parent::chk($msg);
  721. if(!$this->get_multivalued()) {
  722. // ajout d'un index sur les champs non multivalues
  723. if (!countSelectQuery('SHOW INDEX FROM '.$this->table.' where Column_name="'.$this->field.'"')) {
  724. updateQuery('ALTER TABLE '.$this->table.' ADD INDEX '.$this->field.'('.$this->field.'(40))');
  725. }
  726. // verification que le champ n'inclue pas de ||
  727. $rs=selectQuery('SELECT KOID,LANG,'.$this->field.' FROM '.$this->table.' WHERE '.$this->field.' like "%||%"');
  728. while($rs && ($ors=$rs->fetch())) {
  729. $oid='';
  730. $value=$ors[$this->field];
  731. $values=explode('||',$value);
  732. foreach($values as $value){
  733. if(!empty($value) && Kernel::objectExists($value)){
  734. $oid=$value;
  735. break;
  736. }
  737. }
  738. updateQuery('UPDATE '.$this->table.' SET UPD=UPD,'.$this->field.'="'.$oid.'" WHERE KOID="'.$ors['KOID'].'" AND LANG="'.$ors['LANG'].'"');
  739. }
  740. $rs->closeCursor();
  741. }
  742. return true;
  743. }
  744. // Edition du champ sous la forme d'une double liste déroulante
  745. function getDoubleSelect(&$value,&$options,&$r,&$rs,$fname,$hiddenname,$myliste){
  746. if($this->sourcemodule){
  747. $mod=XModule::objectFactory($this->sourcemodule);
  748. if($mod->object_sec && !$mod->secure('',':list') || !$mod->object_sec && !$mod->secure('',':ro')) return;
  749. }
  750. $oidcollection=$collection=$opts=array();
  751. $varid=getUniqID('v');
  752. $unselectedname=preg_replace('/^([^\[]+)/','$1_unselected',$fname);
  753. $morder = $this->doubleboxorder ? 'false' : 'true';
  754. $edit1='<select name="'.$unselectedname.'" size="'.$this->boxsize.'" multiple ondblclick="TZR.doubleAdd('.
  755. 'this.form.elements[\''.$unselectedname.'\'],this.form.elements[\''.$fname.'[]\'],'.$morder.')" class="doublebox">';
  756. $edit2='<select name="'.$fname.'[]" size="'.$this->boxsize.'" multiple id="'.$varid.'" ondblclick="TZR.doubleAdd(this.form.elements[\''.$fname.'[]\'],'.
  757. 'this.form.elements[\''.$unselectedname.'\'],'.$morder.')" class="doublebox">';
  758. $order = 0;
  759. if ($this->grouplist) { // la liste est groupée sur le premier champ du lien
  760. if (count($myliste) <= 1)
  761. $this->groupliste == false;
  762. else {
  763. $fields = array_keys($myliste);
  764. $groupField = $fields[0];
  765. $groupListe[$groupField] = array_shift($myliste);
  766. $groupid = 0;
  767. }
  768. }
  769. $used_values=null;
  770. if($options['query_format']==XFieldDef::QUICKQUERY_FORMAT && !XShell::admini_mode()){
  771. $used_values=$this->_getUsedValues(null,null,$options);
  772. }
  773. while($ors=$rs->fetch()) {
  774. $koid=$ors['KOID'];
  775. if($used_values!==null && !$used_values[$koid]) continue;
  776. if($mod && $mod->object_sec && !$mod->secure($koid,':ro')) continue;
  777. $order++;
  778. $selected=isset($value[$koid]);
  779. if ($this->grouplist && $currentGroup != $ors[$groupField]) {
  780. $currentGroup = $ors[$groupField];
  781. $groupid++;
  782. $groupLabel = $this->format_display($groupListe,$ors,$opts,null,'text');
  783. $edit1 .= '<optgroup label="'.$groupLabel.'" id="unselected_'.$fname.'_'.$groupid.'">';
  784. $edit2 .= '<optgroup label="'.$groupLabel.'" id="'.$fname.'_'.$groupid.'">';
  785. }
  786. $display=$this->format_display($myliste,$ors,$opts,null,'text');
  787. if(!$selected) $edit1.='<option value="'.$koid.'" order="'.$order.'">'.$display.'</option>';
  788. else $edit2.='<option value="'.$koid.'" order="'.$order.'">'.$display.'</option>';
  789. if($selected) $r->text.=$display;
  790. $oidcollection[]=$koid;
  791. $collection[]=$display;
  792. }
  793. $edit1.='</select>';
  794. $edit2.='</select>';
  795. $buttons='<input type="button" value=">>" onclick="TZR.doubleAdd(this.form.elements[\''.$unselectedname.'\'],'.
  796. 'this.form.elements[\''.$fname.'[]\'],true)"><br/>'.
  797. '<input type="button" value="<<" onclick="TZR.doubleAdd(this.form.elements[\''.$fname.'[]\'],'.
  798. 'this.form.elements[\''.$unselectedname.'\'],'.$morder.')">';
  799. $hidd='<input type="hidden" name="'.$hiddenname.'" value="doublebox"/>';
  800. $color=XIni::get('error_color');
  801. if($this->compulsory) $t1="TZR.addValidator(['$varid',/(.+)/,'".addslashes($this->label)."','$color','XLinkDef']);";
  802. else $t1="TZR.addValidator(['$varid','','".addslashes($this->label)."','$color','XLinkDef']);";
  803. $js="<script type=\"text/javascript\">if(typeof(TZR)!='undefined') { $t1 }</script>";
  804. $edit='<table class="doublebox"><tr><td>'.$edit1.'</td><td class="button">'.$buttons.$hidd.'</td><td>'.$edit2.'</td></tr></table>'.$js;
  805. $r->oidcollection=$oidcollection;
  806. $r->collection=$collection;
  807. $r->html=$edit;
  808. }
  809. /// Edition du champ sous la forme de boite à cocher (checkbox/radio)
  810. function getCheckboxes(&$value,&$options,&$r,&$rs,$fname,$hiddenname,$myliste){
  811. $mod=null;
  812. if($this->sourcemodule){
  813. $mod=XModule::objectFactory($this->sourcemodule);
  814. if($mod->object_sec && !$mod->secure('',':list') || !$mod->object_sec && !$mod->secure('',':ro')) return;
  815. }
  816. $qf=@$options['query_format'];
  817. if($this->multivalued || $qf) $typebox='checkbox';
  818. else $typebox='radio';
  819. $my_compulsory=($this->compulsory || @$options['compulsory']) && !$qf;
  820. $cols=0;
  821. $edit='<input type="hidden" name="'.$hiddenname.'" value="'.$typebox.'"/>';
  822. $edit.='<table class="tzr-checkboxtable">';
  823. $edit.='<tr>';
  824. if($typebox!='radio') $edit.='<input type="hidden" name="'.$fname.'[0]" value="Foo"/>';
  825. if(!$my_compulsory && ($typebox=='radio')) {
  826. $varid=getUniqID('v');
  827. $edit.='<td><input type="'.$typebox.'" class="checkbox" name="'.$fname.'" value="" id="'.$varid.'"/>'.
  828. '<label for="'.$varid.'">'.XLabels::getSysLabel('general','empty_menu').'</label></td>';
  829. $cols++;
  830. }
  831. $listvarid=array();
  832. $opts=array('_published'=>'all');
  833. if ($this->grouplist) { // la liste est groupée sur le premier champ du lien
  834. if (count($myliste) <= 1)
  835. $this->groupliste == false;
  836. else {
  837. $fields = array_keys($myliste);
  838. $groupField = $fields[0];
  839. $groupListe[$groupField] = array_shift($myliste);
  840. }
  841. }
  842. if($cols>=$this->checkbox_cols) {
  843. $edit.='</tr><tr>';
  844. $cols=0;
  845. }
  846. $nb = 0;
  847. $r->text='';
  848. $used_values=null;
  849. if($qf==XFieldDef::QUICKQUERY_FORMAT && !XShell::admini_mode()){
  850. $used_values=$this->_getUsedValues(null,null,$options);
  851. }
  852. while($rs && $ors=$rs->fetch()) {
  853. $koid=$ors['KOID'];
  854. if($used_values!==null && !$used_values[$koid]) continue;
  855. $nb++;
  856. if($mod && $mod->object_sec && !$mod->secure($koid,':ro')) continue;
  857. if ($this->grouplist && $currentGroup != $ors[$groupField]) {
  858. $currentGroup = $ors[$groupField];
  859. $edit .= '</td></tr><tr><td colspan="'.$this->checkbox_cols.'">';
  860. $edit .= $this->format_display($groupListe,$ors,$opts,null,'html');
  861. $edit .= '</td></tr><tr>';
  862. $cols=0;
  863. }
  864. $edit.='<td>';
  865. $koid=$ors['KOID'];
  866. $varid=uniqid('v');
  867. if ($qf)
  868. $varid = $fname.$nb.'_id'.$nb;
  869. $listvarid[]=$varid;
  870. $display=$this->format_display($myliste,$ors,$opts);
  871. if($this->multivalued || $qf){
  872. $checked=isset($value[$koid]);
  873. }elseif($my_compulsory && empty($value) && $this->usedefault) {
  874. $checked=true;
  875. $value=$koid;
  876. }else{
  877. $checked=($koid==$value);
  878. }
  879. if($typebox=='checkbox')
  880. $edit.='<input type="checkbox" class="radio" id="'.$varid.'" name="'.$fname.'['.$koid.']" '.($checked?' checked ':'').
  881. '/> <label for="'.$varid.'">'.$display.'</label></td>';
  882. else
  883. $edit.='<input type="radio" class="radio" id="'.$varid.'" name="'.$fname.'" value="'.$koid.'" '.
  884. ($checked?' checked ':'').'/> <label for="'.$varid.'">'.$display.'</label></td>';
  885. $cols++;
  886. if($checked) $r->text.=$display;
  887. if($cols>=$this->checkbox_cols) {
  888. $edit.='</tr><tr>';
  889. $cols=0;
  890. }
  891. $oidcollection[]=$koid;
  892. $collection[]=$display;
  893. }
  894. $edit.='</tr></table>';
  895. if(!empty($my_compulsory) && !empty($listvarid)) {
  896. $color=XIni::get('error_color');
  897. $edit.="<script type=\"text/javascript\">if(typeof(TZR)!='undefined') { TZR.addValidator(['".$listvarid[0]."','','".
  898. addslashes($this->label)."','$color','XLinkDef','',['".implode("','",$listvarid)."']]); }</script>";
  899. }
  900. $r->oidcollection=$oidcollection;
  901. $r->collection=$collection;
  902. $r->varid=$listvarid[0];
  903. $r->html=$edit;
  904. }
  905. // Edition du champ sous la forme d'une zone d'autocomplétion
  906. function getAutocomplete(&$value,&$options,&$r,&$rs,$fname,$hiddenname,$myliste){
  907. if(is_array($value)){
  908. $v=array_keys($value);
  909. $v=@$v[0];
  910. }else $v=$value;
  911. $qf=@$options['query_format'];
  912. $lang=XShell::getLangUser();
  913. $lang_data=XShell::getLangData();
  914. if(isset($options['target_fields'])){
  915. $fieldslist=implode(',',$options['target_fields']);
  916. $pubonly=false;
  917. }else{
  918. $fieldslist='';
  919. $pubonly=true;
  920. }
  921. if($qf) $varid=$fname.'_id';
  922. else $varid=getUniqID('v');
  923. $textid='_INPUT'.$varid;
  924. $edit=$mborder=$callback=$js=$fmt='';
  925. if(!$qf && $this->compulsory) {
  926. $mborder='tzr-input-compulsory';
  927. if(!$this->multivalued) $fmt=' onblur="TZR.isIdValid(\''.$varid.'\')" ';
  928. $js='<script type="text/javascript">'.
  929. 'TZR.addValidator(["'.$varid.'",/.+:.+/,"'.addslashes($this->label).'","'.XIni::get('error_color').'","XLinkDef","'.$textid.'"]);</script>';
  930. }
  931. if(/*!$qf && */$this->multivalued){
  932. if(is_array($value)) $v=array_keys($value);
  933. else $v=$value;
  934. $delico=XLabels::getSysLabel('general','delete');
  935. $callback=',TZR.autoCompleteMultipleValue';
  936. $edit.='<input id="'.$varid.'" autocomplete="off" name="foo" value="" type="hidden">';
  937. $edit.='<input autocomplete="off" id="'.$textid.'" name="_INPUT'.$fname.'" size="30" type="text" '.$fmt.' class="tzr-link '.$mborder.'">';
  938. if (XShell::admini_mode() && !$qf && ($this->sourcemodule && $this->isAutorizedToAdd($options))){
  939. $urlnew = $GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,true).'&moid='.$this->sourcemodule.'&function=insert&template=xmodtable/popinsert.html&tplentry=br&tabsmode=1&varid='.$varid;
  940. $newico = XLabels::getSysLabel('general','new');
  941. $edit .= '<a href="#" onclick="TZR.openPopup(\''.$urlnew.'\'); return false;">'.$newico.'</a>';
  942. }
  943. if ($qf && XShell::admini_mode()){
  944. $op=$options['op'];
  945. $querypart='<input class="radio" type="radio" name="'.$fname.'_op" value="AND" id="'.$textid.'-AND" checked>'.
  946. '<label for="'.$varid.'-AND">'.XLabels::getSysLabel('xfielddef.xlinkdef_allterms').'</label>&nbsp;&nbsp;'.
  947. '<input class="radio" type="radio" name="'.$fname.'_op" value="OR" id="'.$textid.'-OR"'.($op=='OR'?' checked':'').'>'.
  948. '<label for="'.$varid.'-OR">'.XLabels::getSysLabel('xfielddef.xlinkdef_leastaterm').'</label>';
  949. if( $options['genempty'] !== false ){
  950. $querypart .= '&nbsp;<input class="radio" type="radio" name="'.$fname.'_op" value="is empty" id="'.$textid.'-EMPTY"'.($op=='is empty'?' checked':'').'>'.'<label for="'.$textid.'-EMPTY">'.XLabels::getSysLabel('xfielddef.is_empty').'</label>';
  951. }
  952. }else{
  953. $querypart='';
  954. }
  955. $edit.='<table id="table'.$varid.'"><tr style="display:none;"><td><a href="#" onclick="TZR.delLine(this);return false;">'.$delico.'</a><input type="hidden" name="'.$fname.'[]" value=""></td><td></td></tr>';
  956. $r->text='';
  957. if(!empty($v)){
  958. if(!is_array($v)) $v=array($v);
  959. $oidcollection = $v;
  960. foreach($v as $oid){
  961. $target=Kernel::getTable($oid);
  962. if(XSystem::tableExists($target)) {
  963. $t=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$target);
  964. if($t->isTranslatable())
  965. $rs2=selectQuery('select * from '.$target.' where KOID="'.$oid.'" AND LANG = \''.$lang_data.'\'');
  966. else
  967. $rs2=selectQuery('select * from '.$target.' where KOID="'.$oid.'"');
  968. $ors2=$rs2->fetch();
  969. if($ors2) {
  970. $myopts=array();
  971. if(!empty($options['_charset'])) $myopts['_charset']=$options['_charset'];
  972. $display=$this->format_display($myliste,$ors2,$myopts,NULL,'text');
  973. }
  974. }
  975. $display=trim($display);
  976. $r->text.=$display.' ';
  977. $edit.='<tr><td><a href="#" onclick="TZR.delLine(this);return false;">'.$delico.'</a><input type="hidden" name="'.$fname.'[]" value="'.$oid.'" '.
  978. '</td><td>'.$display.'</td></tr>';
  979. }
  980. $r->text=substr($r->text,0,-1);
  981. }
  982. $edit.='</table>';
  983. if ($querypart != '')
  984. $edit = $querypart.'<br>'.$edit;
  985. }else{
  986. $display='';
  987. if($v){
  988. $target=Kernel::getTable($v);
  989. if(XSystem::tableExists($target)) {
  990. $t=XDataSource::objectFactoryHelper8('BCLASS=XDSTable&SPECS='.$target);
  991. $rs2=selectQuery('select * from '.$target.' where KOID="'.$v.'"');
  992. $ors2=$rs2->fetch();
  993. if($ors2) {
  994. $myopts=array();
  995. if(!empty($options['_charset'])) $myopts['_charset']=$options['_charset'];
  996. $display=$this->format_display($myliste,$ors2,$myopts,NULL,'text');
  997. }
  998. }
  999. $display=trim($display);
  1000. }
  1001. $r->text=$display;
  1002. $edit.='<input id="'.$varid.'" autocomplete="off" name="'.$fname.'" value="'.$v.'" type="hidden">';
  1003. $edit.='<input autocomplete="off" id="'.$textid.'" name="_INPUT'.$fname.'" size="30" type="text" value="'.$display.'" '.$fmt.
  1004. ' class="tzr-link '.$mborder.'">';
  1005. if (XShell::admini_mode() && !$qf && ($this->sourcemodule && $this->isAutorizedToAdd($options))){
  1006. $urlnew = $GLOBALS['TZR_SESSION_MANAGER']::admin_url(true,true).'&moid='.$this->sourcemodule.'&function=insert&template=xmodtable/popinsert.html&tplentry=br&tabsmode=1&varid='.$varid;
  1007. $newico = XLabels::getSysLabel('general','new');
  1008. $edit .= '<a href="#" onclick="TZR.openPopup(\''.$urlnew.'\'); return false;">'.$newico.'</a>';
  1009. }
  1010. if( $qf && XShell::admini_mode() && $options['genempty'] !== false ){
  1011. $querypart .= '<input class="checkbox" type="checkbox" name="'.$fname.'_op" value="is empty" id="'.$textid.'-EMPTY"'.($op=='is empty'?' checked':'').'>'.'<label for="'.$textid.'-EMPTY">'.XLabels::getSysLabel('xfielddef.is_empty').'</label>';
  1012. } else {
  1013. $querypart = '';
  1014. }
  1015. if ($querypart != '')
  1016. $edit = $querypart.'<br>'.$edit;
  1017. }
  1018. $url=TZR_AJAX8.'?class=xlinkdef&function=xlinkdef_autocomplete&_silent=1&query_format='.$qf.($this->display_format?'&options[display_format]='.urlencode($this->display_format):'');
  1019. $edit.='<script type="text/javascript" language="javascript">TZR.addAutoComplete("'.$url.'","'.$varid.'","'.$options['fmoid'].'",'.
  1020. '"'.$this->table.'","'.$this->field.'","'.$fieldslist.'"'.$callback.');</script>'.$js;
  1021. $r->oidcollection=$r->collection=array();
  1022. $r->varid=$varid;
  1023. $r->html=$edit;
  1024. }
  1025. // Edition du champ sous la forme d'une liste déroulante
  1026. function getSelect(&$value,&$options,&$r,&$rs,$fname,$hiddenname,$myliste) {
  1027. $varid='';
  1028. if($this->sourcemodule){
  1029. $mod=XModule::objectFactory($this->sourcemodule);
  1030. if($mod->object_sec && !$mod->secure('',':list') || !$mod->object_sec && !$mod->secure('',':ro')) return;
  1031. }
  1032. $qf=@$options['query_format'];
  1033. $oidcollection=$collection=array();
  1034. $edit=$my_previousOid='';
  1035. $opts=array('_published'=>'all');
  1036. $i=0;
  1037. if ($this->grouplist) { // la liste est groupée sur le premier champ du lien
  1038. if (count($myliste) <= 1)
  1039. $this->groupliste == false;
  1040. else {
  1041. $fields = array_keys($myliste);
  1042. $groupField = $fields[0];
  1043. $groupListe[$groupField] = array_shift($myliste);
  1044. }
  1045. }
  1046. $used_values=null;
  1047. if($qf==XFieldDef::QUICKQUERY_FORMAT && !XShell::admini_mode()){
  1048. $used_values=$this->_getUsedValues(null,null,$options);
  1049. }
  1050. while($rs && $ors=$rs->fetch()) {
  1051. $i++;
  1052. $koid=$ors['KOID'];
  1053. if($used_values!==null && !$used_values[$koid]) continue;
  1054. if(!empty($mod) && $mod->object_sec && !$mod->secure($koid,':ro')) continue;
  1055. if((is_array($value) && isset($value[$koid])) || ($koid==$value)) $selected=' selected';
  1056. else $selected='';
  1057. if ($this->grouplist && $currentGroup != $ors[$groupField]) {
  1058. $currentGroup = $ors[$groupField];
  1059. $groupLabel = $this->format_display($groupListe,$ors,$opts,null,'text');
  1060. $edit .= '<optgroup label="'.$groupLabel.'">';
  1061. $i++;
  1062. }
  1063. $display=$this->format_display($myliste,$ors,$opts,null,'text');
  1064. $edit.='<option value="'.$koid.'"'.$selected.'>'.$display.'</option>';
  1065. if($selected) $r->text.=$display;
  1066. $oidcollection[]=$koid;
  1067. $collection[]=$display;
  1068. if(!empty($selected) && empty($first)) $first='<option value="'.$koid.'">'.$this->label.' : '.$display.'</option>';
  1069. }
  1070. if($qf){
  1071. $labelin=@$options['labelin'];
  1072. $format=@$options['fmt'];
  1073. if(empty($format)) $format=@$options['qfmt'];
  1074. if(empty($format)) $format=$this->query_format;
  1075. if(empty($labelin)) $first='<option value="">----</option>';
  1076. elseif(empty($first) || $format=='listbox') $first='<option value="">'.$this->label.'</option>';
  1077. else{
  1078. $first.='<option value="">'.XLabels::getSysLabel('xfielddef','n/a').'</option>';
  1079. $edit=str_replace('" selected>','">',$edit);
  1080. }
  1081. $i++;
  1082. if($i<2 || $format=='listbox-one') $edit='<select name="'.$fname.'" id="'.$fname.'">'.$first.$edit.'</select>';
  1083. else $edit='<select name="'.$fname.'[]" id="'.$fname.'" size="'.min($i,$this->boxsize).'" multiple>'.$first.$edit.'</select>';
  1084. }else{
  1085. if(!$this->compulsory || !$this->usedefault) {
  1086. $edit='<option value="">----</option>'.$edit;
  1087. $i++;

Large files files are truncated, but you can click here to view the full file