PageRenderTime 72ms CodeModel.GetById 24ms RepoModel.GetById 0ms app.codeStats 1ms

/class.xdatasource.inc

https://github.com/jcplat/console-seolan
PHP | 3190 lines | 2684 code | 219 blank | 287 comment | 733 complexity | 3681a96257cee3e37f34c19afd9aa61d 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. /// Classe de base pour la gestion des sources de donnees
  3. class XDataSource implements XModuleContainerInterface {
  4. static $_sources;
  5. protected $base = NULL;
  6. protected $boid = NULL;
  7. protected $title=NULL;
  8. protected $translatable=false;
  9. protected $log=1;
  10. public $desc = array();
  11. public $orddesc = array();
  12. private static $_factory=array();
  13. private static $_factory_by_sourcepath=array();
  14. protected static $_basebase=NULL;
  15. protected static $_boid=array();
  16. public $published_fields_in_admin=2;
  17. public $sendacopytofields=array();
  18. /// construction d'une source de donnee avec un nom de table (legacy) ou un boid
  19. function __construct($boid=0) {
  20. XDataSource::preLoadBaseBase();
  21. if(!empty($boid)) {
  22. $this->boid=$boid;
  23. $this->base=XDataSource::$_boid[$boid]->BTAB;
  24. $this->initOptions();
  25. $param=XOptions::rawFromXML(XDataSource::$_boid[$this->boid]->BPARAM);
  26. $this->_options->setValues($this,$param);
  27. } else {
  28. XLogs::critical('XDataSource::construct', '<'.$boid.'> is empty');
  29. return NULL;
  30. }
  31. }
  32. /// Initialise les options de la source
  33. public function initOptions() {
  34. if(empty($this->_options)) $this->_options=new XOptions();
  35. $this->_options->setId($this->boid);
  36. }
  37. /// Supprime le cache des datasources
  38. static public function clearCache(){
  39. XDataSource::preLoadBaseBase(true);
  40. XDataSource::$_factory=array();
  41. XDataSource::$_factory_by_sourcepath=array();
  42. }
  43. /// chargement en mémoire de la liste des tables et les libellés associés
  44. static function preLoadBaseBase($refresh=false) {
  45. if(empty(XDataSource::$_basebase) || $refresh) {
  46. XLogs::debug('XShell::loadBaseBase: start');
  47. $lang = XShell::getLangUser();
  48. $rs=selectQueryGetAll('select BASEBASE.*,AMSG.* from BASEBASE,AMSG where BASEBASE.BOID=AMSG.MOID and MLANG="'.$lang.'" AND MTXT != ""');
  49. XDataSource::$_basebase=array();
  50. XDataSource::$_boid=array();
  51. foreach($rs as $idx => $o1) {
  52. XDataSource::$_basebase[$o1['BTAB']]=(object)$o1;
  53. XDataSource::$_boid[$o1['BOID']]=&XDataSource::$_basebase[$o1['BTAB']];
  54. }
  55. // Chargement des tables qui ne sont pas traduites
  56. if($lang!=TZR_DEFAULT_LANG) {
  57. $rs=selectQuery('select BASEBASE.*,AMSG.* from BASEBASE,AMSG where BASEBASE.BOID=AMSG.MOID and MLANG="'.TZR_DEFAULT_LANG.'"');
  58. $ors=array();
  59. while($ors=$rs->fetch() ) {
  60. if(empty(XDataSource::$_basebase[$ors['BTAB']])) {
  61. XDataSource::$_basebase[$ors['BTAB']]=(object)$ors;
  62. XDataSource::$_boid[$ors['BOID']]=&XDataSource::$_basebase[$ors['BTAB']];
  63. }
  64. }
  65. $rs->closeCursor();
  66. }
  67. XLogs::debug('XShell::loadBaseBase: end');
  68. }
  69. }
  70. /// Creation d'un objet de type xdatasource via le boid
  71. public static function objectFactory8($boid) {
  72. XLogs::debug('XDataSource::objectfactory8 boid='.$boid);
  73. if(!preg_match('/^[0-9a-f]+$/',$boid)) securityWarning('XDataSource::objectFactory8: Trying to get unauthorized <'.$boid.'>');
  74. XDataSource::preLoadBaseBase();
  75. if(empty(XDataSource::$_boid[$boid])) XDataSource::preLoadBaseBase(true);
  76. $c=XDataSource::$_boid[$boid]->BCLASS;
  77. if(!class_exists($c)) {
  78. XLogs::notice('XDataSource::objectfactory8','class '.$c.' doesn\'t exist');
  79. $c='XDSTable';
  80. }
  81. if(empty(XDataSource::$_factory[$boid])) {
  82. XLogs::debug($c.'::objectFactory8 creating '.$boid);
  83. XDataSource::$_factory[$boid]=new $c($boid);
  84. }
  85. return XDataSource::$_factory[$boid];
  86. }
  87. /// Creation d'un objet de type xdatasource via ses caratéristiques
  88. /// Ex de sourcepath : BCLASS=XDSTable&SPECS=_MLOGS pour recuperer la source de type XDSTable sur la table _MLOGS
  89. public static function objectFactoryHelper8($sourcepath) {
  90. XLogs::debug('XDataSource::objectfactoryHelper8 source='.$sourcepath);
  91. if(isset(XDataSource::$_factory_by_sourcepath[$sourcepath]))
  92. return XDataSource::$_factory_by_sourcepath[$sourcepath];
  93. XDataSource::preLoadBaseBase();
  94. parse_str($sourcepath,$output);
  95. $c=@$output['BCLASS'];
  96. $specs=@$output['SPECS'];
  97. if(Kernel::isAKoid($specs)) $specs=Kernel::getTable($specs);
  98. $boid=XDataSource::getBoidFromSpecs($c, $specs);
  99. if(empty($boid)) return NULL;
  100. return XDataSource::$_factory_by_sourcepath[$sourcepath] = XDataSource::objectFactory8($boid);
  101. }
  102. static function getBoidFromSpecs($class, $spec) {
  103. if(empty(XDataSource::$_basebase[$spec])) XDataSource::preLoadBaseBase(true);
  104. if(empty(XDataSource::$_basebase[$spec])) return NULL;
  105. return XDataSource::$_basebase[$spec]->BOID;
  106. }
  107. static function sysTable($table) {
  108. return in_array($table,array('USERS','GRP','TEMPLATES','LOGS','TASKS','LETTERS','REPLI','JOURNAL','OPTS','_MLOGS','_MLOGSD'));
  109. }
  110. static function notToReplicate($table) {
  111. return in_array($table,array('TASKS','REPLI','JOURNAL'));
  112. }
  113. static function tablesLogStatus() {
  114. XDataSource::preLoadBaseBase(true);
  115. $tablesLogStatus = array();
  116. foreach (XDataSource::$_basebase as $tableName => $tableObject)
  117. $tablesLogStatus[$tableName] = ($tableObject->LOG == 1 && $tableName != 'LOGS');
  118. return $tablesLogStatus;
  119. }
  120. public function &actionlist1() {
  121. $actions = array();
  122. $this->_actionlist($actions);
  123. return $actions;
  124. }
  125. // rend la liste des champs browsables
  126. //
  127. function browsableFields($selectedfields=NULL) {
  128. $fields=array();
  129. foreach($this->desc as $k => &$v) {
  130. if($v->get_browsable() || ($selectedfields=='all')) {
  131. $fields[]=$k;
  132. }
  133. }
  134. return $fields;
  135. }
  136. /// Transforme le résultat d'un formulaire en object requête
  137. function captureQuery($ar=NULL) {
  138. $p=new XParam($ar, array());
  139. $options=$p->get('options');
  140. $_FIELDS=$p->get('_FIELDS');
  141. $st=array();
  142. $st['_date']=mktime();
  143. $st['_table']=$this->base;
  144. $st['options']=$p->get('options');
  145. $st['oids']=$p->get('oids');
  146. $st['operator']=$p->get('operator');
  147. $st['_select']=$p->get('_select');
  148. $st['pagesize']=$p->get('pagesize');
  149. $st['order']=array();
  150. if(!empty($_FIELDS)) {
  151. $st['_querymode']='query2';
  152. $st['_FIELDS']=$_FIELDS;
  153. }else{
  154. $st['_FIELDS']=array();
  155. foreach($this->desc as $k=>&$v) $_FIELDS[$k]=$k;
  156. }
  157. foreach($_FIELDS as $field=>$k) {
  158. $v=&$this->desc[$k];
  159. if(is_object($v)) {
  160. if(!$v->get_queryable()) continue;
  161. $v1=$p->get($field);
  162. $st[$field]=$v1;
  163. $st[$field.'_op']=$p->get($field.'_op');
  164. $st[$field.'_HID']=$p->get($field.'_HID');
  165. $st[$field.'_FMT']=$p->get($field.'_FMT');
  166. $st[$field.'_PAR']=$p->get($field.'_PAR');
  167. $st[$field.'_empty']=$p->get($field.'_empty');
  168. }
  169. }
  170. $order=$p->get('order');
  171. $_order=$p->get('_order');
  172. if(is_array($order)) {
  173. foreach($order as $i=>$f) {
  174. if(!empty($f)) $st['order'][]=trim($order[$i].' '.$_order[$i]);
  175. }
  176. }
  177. return $st;
  178. }
  179. /// prend en entrée une requête stockée ($qinit) et génére les paramètres d'entrée
  180. public function prepareQuery(&$qinit, $storedname=NULL) {
  181. // table dans laquelle se trouvenet les donnees
  182. if(!empty($storedname)) {
  183. $rs=& selectQuery("select * from QUERIES where KOID = '$storedname' and LANG='".TZR_DEFAULT_LANG."'");
  184. $ors=array();
  185. if($ors=$rs->fetch()) {
  186. // fusion du contenu de la recherche sauevardee et de la recherche en cours.
  187. // on prend en priorite le contenu de la requete sauvegardee, qinit sinon
  188. $q1 = unserialize(stripslashes($ors['query']));
  189. $q2=$q1;
  190. foreach($qinit as $k=>$v) {
  191. if(!empty($qinit[$k])) $q2[$k]=$v;
  192. }
  193. $qinit=$q2;
  194. }
  195. }
  196. $selectedfields=array();
  197. $r=NULL;
  198. $r['operator']=@$qinit['operator'];
  199. if(empty($r['operator'])) $r['operator']='and';
  200. $parametrized=false;
  201. $labelin=@$qinit['labelin'];
  202. if(is_array($qinit)) {
  203. foreach($this->desc as $k => &$v) {
  204. if(!empty($qinit[$k.'_PAR'])) {
  205. $parametrized=true;
  206. $selectedfields[]=$k;
  207. unset($qinit[$k]);
  208. unset($qinit[$k.'_op']);
  209. unset($qinit[$k.'_HID']);
  210. unset($qinit[$k.'_PAR']);
  211. unset($qinit[$k.'_FMT']);
  212. if(!empty($labelin)) $qinit['options'][$k]['labelin']=true;
  213. }
  214. }
  215. if(!empty($selectedfields)) {
  216. $r=$this->query(array('tplentry'=>TZR_RETURN_DATA,'selectedfields'=>$selectedfields,
  217. 'searchmode'=>'simple','_preparedquery'=>$qinit, 'fmoid' => $qinit['fmoid']));
  218. }
  219. }
  220. $r['parametrized']=$parametrized;
  221. return $r;
  222. }
  223. /// rend vrai si la base existe
  224. public static function sourceExists($t) {
  225. XDataSource::preLoadBaseBase();
  226. return isset( XDataSource::$_basebase[$t] );
  227. }
  228. /// rend le libelle de la table
  229. public function getLabel() {
  230. return $this->title;
  231. }
  232. /// Rend la table de la source
  233. public function getTable() {
  234. return $this->base;
  235. }
  236. /// Rend le boid de la source
  237. function getBoid(){
  238. return $this->boid;
  239. }
  240. /// Rend le nom de la source
  241. function getSourceName(){
  242. return XDataSource::$_boid[$this->boid]->MTXT;
  243. }
  244. /// Rend un propriété d'une source via la BOID
  245. static function getBoidProp($boid,$prop){
  246. return XDataSource::$_boid[$boid]->$prop;
  247. }
  248. /// Rend un propriété d'une source via le nom de la table
  249. static function getTableProp($table,$prop) {
  250. return XDataSource::$_basebase[$table]->$prop;
  251. }
  252. public function &getPublished($field=true) {
  253. $links=array();
  254. foreach($this->desc as $i => &$v) {
  255. if(is_object($v)) {
  256. $f=$v->get_field();
  257. if($v->get_published()){
  258. if($field) $links[]=$f;
  259. else $links[]=$i;
  260. }
  261. }
  262. }
  263. return $links;
  264. }
  265. public function isTranslatable() {
  266. return ($this->translatable>0);
  267. }
  268. public function getTranslatable() {
  269. return $this->translatable;
  270. }
  271. public function toLog() {
  272. return ($this->base!='LOGS' && $this->log==1);
  273. }
  274. public function getAutoTranslate() {
  275. return $this->autotranslate;
  276. }
  277. /// genere les traductions dans toutes les langues
  278. function autoTranslate() {
  279. if($this->isTranslatable()) {
  280. $xk=new Kernel;
  281. $requete='select distinct KOID from '.$this->base.' where LANG="'.TZR_DEFAULT_LANG.'"';
  282. $rs=selectQuery($requete);
  283. while($rs && ($ors=$rs->fetch())) {
  284. $koid=$ors['KOID'];
  285. $xk->data_autoTranslate($koid);
  286. }
  287. $rs->closeCursor();
  288. }else{
  289. updateQuery('delete from '.$this->base.' where LANG!="'.TZR_DEFAULT_LANG.'"');
  290. }
  291. }
  292. public static function &getBaseList($myselfIncluded=true,$refresh=false) {
  293. XDataSource::preLoadBaseBase($refresh);
  294. $liste = array();
  295. foreach(XDataSource::$_basebase as $b=>&$o) {
  296. $liste[$b]=$o->MTXT;
  297. }
  298. asort($liste);
  299. return $liste;
  300. }
  301. public static function &getBaseList8($myself=true){
  302. XDataSource::preLoadBaseBase();
  303. $liste=array();
  304. foreach(XDataSource::$_boid as $b=>&$o){
  305. if($myself || (!$myself && (empty($this) || $this->boid!=$b)))
  306. $liste[$b]=$o->MTXT;
  307. }
  308. asort($liste);
  309. return $liste;
  310. }
  311. /// Créer une boite de selection de champ
  312. function fieldSelector($ar=NULL) {
  313. $p=new XParam($ar, array('tplentry'=>'','compulsory'=>true,'filter'=>array()));
  314. $tplentry=$p->get('tplentry');
  315. $fieldname=$p->get('fieldname');
  316. $value=$p->get('value');
  317. $type=$p->get('type');
  318. if(!is_array($type) && !empty($type)) $type=array($type);
  319. $compulsory=$p->get('compulsory');
  320. $multivalued=$p->get('multivalued');
  321. $filter=$p->get('filter','local');
  322. if($multivalued) $retval='<select name="'.$fieldname.'[]" size="6" multiple>';
  323. else $retval='<select name="'.$fieldname.'">';
  324. if(!$compulsory) $retval.='<option value="">----</option>';
  325. foreach($this->desc as $k => &$v) {
  326. if(empty($type) || in_array($v->get_ftype(),$type)){
  327. $ok=true;
  328. foreach($filter as $prop=>$val){
  329. if(is_array($val)){
  330. if(!eval('return (\''.$val[1].'\''.$val[0].'\''.$v->$prop.'\');' ) ){
  331. $ok=false;
  332. break;
  333. }
  334. }else{
  335. if($v->$prop!=$val){
  336. $ok=false;
  337. break;
  338. }
  339. }
  340. }
  341. if($ok) $retval.='<option value="'.$k.'" '.(isset($value) && ($value==$k || is_array($value) && in_array($k,$value))?'selected':'')." >". $v->get_label().'</option>';
  342. }
  343. }
  344. $retval.='</select>';
  345. return $retval;
  346. }
  347. function order_selector($ar=NULL) {
  348. $p = new XParam($ar, array('tplentry'=>'','compulsory'=>true,'random'=>true,'multiple'=>false));
  349. $tplentry = $p->get('tplentry');
  350. $LANG_USER = XShell::getLangUser();
  351. $LANG_DATA = XShell::getLangData();
  352. $fieldname=$p->get('fieldname');
  353. $value=$p->get('value');
  354. if(isset($value) && !is_array($value)) $value=array($value);
  355. $random=$p->get('random');
  356. $compulsory=$p->get('compulsory');
  357. $multiple=$p->get('multiple');
  358. $retval='<select name="'.$fieldname.'"'.($multiple?' multiple size="6"':'').'>';
  359. if(!$compulsory) $retval.='<option value="">---</option>';
  360. if($random) $retval.='<option value="RAND()">'.XLabels::getSysLabel('xdatasource.random').'</option>';
  361. foreach($this->desc as $k => $v) {
  362. $retval.='<option value="'.$k.'" '.(isset($value) && in_array($k,$value)?'selected':'').
  363. ' >'. $v->get_label().'</option>';
  364. }
  365. $retval.='</select>';
  366. return $retval;
  367. }
  368. /// rend le descriptif d'un champ
  369. public function getField($f) {
  370. return $this->desc[$f];
  371. }
  372. /// Rend la liste des champs de la table filtres par type et par propriétés
  373. public function &getFieldsList($type=NULL,$browsable=false,$published=false,$queryable=false,$compulsory=false,$translatable=false,
  374. $multivalued=false,$fields=null,$op='AND') {
  375. if(!is_array($fields) || empty($fields)) $fields=$this->orddesc;
  376. $list=array();
  377. $checktype=is_array($type) && !empty($type);
  378. foreach($fields as $i=>$f) {
  379. if(empty($this->desc[$f])) continue;
  380. $v=&$this->desc[$f];
  381. if($op=='AND' && (!$checktype || in_array($v->get_ftype(),$type)) && (!$browsable || $v->get_browsable()) && (!$published || $v->get_published()) && (!$queryable || $v->get_queryable()) && (!$compulsory || $v->get_compulsory()) && (!$translatable || $v->get_translatable()) && (!$multivalued || $v->get_multivalued()))
  382. $list[]=$f;
  383. elseif($op=='OR' && (($checktype && in_array($v->get_ftype(),$type)) || ($browsable && $v->get_browsable()) || ($published && $v->get_published()) || ($queryable && $v->get_queryable()) || ($compulsory && $v->get_compulsory()) || ($translatable && $v->get_translatable()) || ($multivalued && $v->get_multivalued())))
  384. $list[]=$f;
  385. }
  386. return $list;
  387. }
  388. /// Rend les champs indexables
  389. function getIndexablesFields($fields=NULL){
  390. if(!is_array($fields) || empty($fields)) $fields=$this->orddesc;
  391. $list=array();
  392. foreach($fields as $i=>$f) {
  393. if(!isset($this->desc[$f])) continue;
  394. if (isset($this->desc[$f]->indexable) && $this->desc[$f]->indexable == 1)
  395. $list[] = $f;
  396. }
  397. return $list;
  398. }
  399. /// Rend le nombre de champ non traduisible
  400. function getNonTranslatableFieldCount() {
  401. if (!isset($this->_NonTranslatableFieldCount))
  402. $this->_NonTranslatableFieldCount = countSelectQuery("select count(*) from DICT where DTAB='$this->base' and TRANSLATABLE!=1");
  403. return $this->_NonTranslatableFieldCount;
  404. }
  405. /// Fabrique une condition pour une recherche
  406. function make_cond($def, $v){
  407. return '';
  408. }
  409. function make_simple_cond($k, $v) {
  410. return '';
  411. }
  412. /// generation d'une condition utilisable sur le container
  413. function select_query($args=NULL) {
  414. return '';
  415. }
  416. /// Retourne une requete pour retourner des objets aléatoires
  417. function random_select_query($args=NULL) {
  418. return '';
  419. }
  420. /// Retourne une requete pour compter des objects
  421. function count_query($args=NULL) {
  422. return '';
  423. }
  424. // Fonction reservee a la creation d'une data pour la langue par defaut.
  425. // La creation d'une data dans tout autre code langue se fait par Kernel::data_edit() et Kernel::proc_data_edit()
  426. // apres avoir cree une data en l'initialisant avec la data correspondante dans le code langue par defaut.
  427. //
  428. public function input($ar=NULL) {
  429. $p = new XParam($ar, array( 'tplentry'=>$this->base,'hiddenfields'=>array(),'options'=>array(),'fieldssec'=>array()));
  430. $tplentry = $p->get('tplentry');
  431. $options = $p->get('options');
  432. $translatable= $this->getTranslatable();
  433. $fieldssec=$p->get('fieldssec','local');
  434. $module_filter=$p->get('module_filter','local');
  435. $moid=$p->get('fmoid','local');
  436. $selectedfields=$p->get('selectedfields');
  437. $editbatch=$p->get('editbatch');
  438. if(empty($selectedfields) || (is_string($selectedfields) && ($selectedfields=='all'))) $all=true;
  439. else $all=false;
  440. if(empty($selectedfields)) $selectedfields=array();
  441. $lang=XShell::getLangData($p->get('LANG_DATA'));
  442. if(($translatable!=3) && $this->isTranslatable() && ($lang!=TZR_DEFAULT_LANG)) {
  443. if($tplentry!=TZR_RETURN_DATA)
  444. XShell::redirect2error(array('message'=>'Security violation'));
  445. return;
  446. }
  447. $LANG_USER = XShell::getLangUser();
  448. $myi=0;
  449. $ofieldvalue=array();
  450. $osysvalue=array();
  451. foreach($this->orddesc as $i => $k) {
  452. if(!empty($fieldssec[$k]) && $fieldssec[$k]!='rw') continue;
  453. if(!($all || in_array($k,$selectedfields))) continue;
  454. $v=&$this->desc[$k];
  455. $options[$k]['fmoid']=$moid;
  456. $options[$k]['editbatch']=$editbatch;
  457. $options[$k]['module_filter']=$module_filter;
  458. if(!$v->sys) {
  459. $ofieldvalue[$myi]=$v->edit($v->default_value(),$options[$k]);
  460. $result['o'.$k]=$ofieldvalue[$myi];
  461. $myi++;
  462. } else {
  463. $value=$v->edit($v->default_value(),$options[$k]);
  464. $osysvalue[]=$value;
  465. if($k=='PUBLISH' || $k=='PRP') $result['o'.$k]=$value;
  466. }
  467. }
  468. $result['fields_object']= $ofieldvalue;
  469. $result['sysfields_object']= $osysvalue;
  470. $result['newoid']=$this->getNewOID($ar);
  471. $result['tablelabel']=$this->getLabel();
  472. // recherche des groupes de champs
  473. $groups=array();
  474. foreach($this->orddesc as $foo => $k) {
  475. if(!empty($fieldssec[$k]) && $fieldssec[$k]!='rw') continue;
  476. if(!($all || in_array($k,$selectedfields))) continue;
  477. $v=&$this->desc[$k];
  478. if(!$v->sysField()) {
  479. if(empty($v->fgroup)) $v->fgroup='General';
  480. if(!empty($v->fgroup)) {
  481. $groups[$v->fgroup][]=&$result['o'.$k];
  482. }
  483. }
  484. }
  485. ksort($groups);
  486. if(count($groups)>1) $result['_groups']=$groups;
  487. // Information sur le caractere 'translatable' ou non de toute la table
  488. $result['translatable'] = $this->isTranslatable();
  489. return XShell::toScreen1($tplentry, $result);
  490. }
  491. /// génération de l'écran de recherche
  492. public function query($ar=NULL) {
  493. $p = new XParam($ar, array( 'tplentry'=>$this->base,'selectedfields'=>'','searchmode'=>'advanced','querymode'=>'query',
  494. 'operator'=>'AND','genoptions'=>array(),'fieldssec'=>array()));
  495. $LANG_USER = XShell::getLangUser();
  496. $LANG_DATA = XShell::getLangData();
  497. $tplentry = $p->get('tplentry');
  498. $fieldssec=$p->get('fieldssec','local');
  499. $module_filter=$p->get('module_filter','local');
  500. $fmoid = $p->get('fmoid','local');
  501. $persistent=$p->get('_persistent');
  502. $selectedfields=$p->get('selectedfields');
  503. if(empty($selectedfields) || (is_string($selectedfields) && ($selectedfields=='all'))) $all=true;
  504. else $all=false;
  505. if(empty($selectedfields)) $selectedfields=array();
  506. $genoptions=array();
  507. $selectquery='';
  508. // on a une requete preparee qui contraint le formulaire
  509. $preparedquery=$p->get('_preparedquery');
  510. if(!empty($preparedquery)) {
  511. $preparedquery['getselectonly']=true;
  512. $preparedquery['_options']=array('local'=>1);
  513. // on construit la requete sql contraignante
  514. $selectquery=self::procQuery($preparedquery);
  515. if (isset($preparedquery['options']))
  516. $genoptions=$preparedquery['options'];
  517. elseif (isset($preparedquery['genoptions']))
  518. $genoptions=$preparedquery['genoptions'];
  519. }
  520. if ($p->is_set('options'))
  521. $genoptions=array_merge($genoptions,$p->get('options'));
  522. elseif ($p->is_set('genoptions'))
  523. $genoptions=array_merge($genoptions,$p->get('genoptions'));
  524. $searchmode=$p->get('searchmode');
  525. $mode=$p->get('querymode');
  526. $myi=0;
  527. $result=array();
  528. foreach($this->orddesc as $field){
  529. if(!empty($fieldssec[$field]) && $fieldssec[$field]=='none') continue;
  530. $v=&$this->desc[$field];
  531. if(!($v->get_queryable() && ($all || in_array($field,$selectedfields)))) continue;
  532. if(!$persistent){
  533. if(!empty($genoptions[$field]['value'])) {
  534. $initval=$genoptions[$field]['value'];
  535. if(!is_array($initval)) $initval=array($initval);
  536. } else {
  537. $initval=$p->get($field);
  538. if(!is_array($initval)){
  539. $initval=trim($initval);
  540. if(!empty($initval)) $initval=array($initval);
  541. }
  542. }
  543. }else{
  544. $initval=null;
  545. }
  546. if(!empty($genoptions[$field])) $opts1=$genoptions[$field];
  547. else $opts1=array();
  548. $opts1['searchmode']=$searchmode;
  549. // requete contrainte
  550. $opts1['select']=$selectquery;
  551. $opts1['fmoid']=$fmoid;
  552. $opts1['module_filter']=$module_filter;
  553. if(empty($opts1['op'])) $opts1['op']=$p->get($field.'_op');
  554. if($mode=='query2') $opts1['fieldname']='fieldxidxid';
  555. if($mode=='pquery') $ofieldvalue[$myi]=$v->pquery($initval, $opts1);
  556. else $ofieldvalue[$myi]=$v->query($initval, $opts1);
  557. if($mode=='query2') $ofieldvalue[$myi]->html.='<input type="hidden" name="_FIELDS[fieldxidxid]" value="'.$field.'">';
  558. $result['o'.$field]=&$ofieldvalue[$myi];
  559. $fieldpar[$myi]=@$genoptions[$field]['par'];
  560. $fieldname[$myi]=$v->get_label();
  561. $myi++;
  562. }
  563. if($mode=='query2') array_multisort($fieldname,SORT_STRING,$fieldpar,$ofieldvalue);
  564. $result['operator']=$p->get('operator');
  565. $result['fields_object']=&$ofieldvalue;
  566. $result['fields_par']=$fieldpar;
  567. return XShell::toScreen1($tplentry, $result);
  568. }
  569. /// Génération de l'écran de recherche rapide
  570. public function quickquery($ar=NULL) {
  571. $p=new XParam($ar,array('tplentry'=>$this->base,'selectedfields'=>'','genoptions'=>array()));
  572. $tplentry=$p->get('tplentry');
  573. $fields=$p->get('selectedfields');
  574. $fmoid=$p->get('fmoid','local');
  575. $persistent=$p->get('_persistent');
  576. if(!empty($fields) && is_array($fields)) $selectedfields=$fields;
  577. else $selectedfields=self::browsableFields($fields);
  578. $genoptions=$p->get('genoptions');
  579. if($p->is_set('options')) $genoptions=$p->get('options');
  580. $myi=0;
  581. $result=array();
  582. $ofieldvalue=array();
  583. $fieldpar=array();
  584. foreach($this->orddesc as $i => $field){
  585. $v=$this->desc[$field];
  586. if($v->get_queryable() && in_array($field,$selectedfields)) {
  587. $fieldname[$myi]=$v->get_label();
  588. if(!$persistent){
  589. if(!empty($genoptions[$field]['value'])) {
  590. $initval=$genoptions[$field]['value'];
  591. if(!is_array($initval)) $initval=array($initval);
  592. } else {
  593. $initval=$p->get($field);
  594. if(!is_array($initval)){
  595. $initval=trim($initval);
  596. if(!empty($initval)) $initval=array($initval);
  597. }
  598. }
  599. }else{
  600. $initval=NULL;
  601. }
  602. if(empty($genoptions[$field])) $genoptions[$field]=array();
  603. $genoptions[$field]['fmoid']=$fmoid;
  604. $genoptions[$field]['op']=$p->get($field.'_op');
  605. $genoptions[$field]['fields_complement'] = $ar;
  606. $ofieldvalue[$myi]=$v->quickquery($initval, $genoptions[$field]);
  607. $result['o'.$field]=$ofieldvalue[$myi];
  608. $ftable['o'.$field]=$ofieldvalue[$myi];
  609. $fieldpar[$myi]=@$genoptions[$field]['par'];
  610. $myi++;
  611. }
  612. }
  613. $result['operator']=$p->get('operator');
  614. $result['fields_object']=$ofieldvalue;
  615. $result['fields_par']=$fieldpar;
  616. if(!empty($ftable)) $result['fields_ftable']=$ftable;
  617. return XShell::toScreen1($tplentry,$result);
  618. }
  619. /// Verifie si l'oid peut etre traité par la source
  620. function checkOID($oid,&$ar,$f,$return=false){
  621. if(Kernel::getTable($oid)!=$this->base){
  622. if($return) return false;
  623. else securityWarning('XDataSource::'.$f.': Trying to use '.$oid.' with wrong XDataSource <'.$this->base.'>');
  624. }
  625. return true;
  626. }
  627. /// Génère un oid pour la source
  628. function getNewOID($ar=NULL){
  629. return self::getNewBasicOID($this->base);
  630. }
  631. /// Génère un oid au format par defaut pour une table donnée (généré à partir du timestamp avec les µs et d'un nombre aléatoire, chacun converti en base 36)
  632. static function getNewBasicOID($t){
  633. $addr=str_replace('.','', base_convert(microtime(true),10,36));
  634. $addr.=base_convert(rand(1,32000),10,36);
  635. $newoid=substr($t.':'.$addr,0,40);
  636. /* on verifie si le koid n'existe pas deja */
  637. $cnt=countSelectQuery('select COUNT(KOID) from '.$t.' where KOID="'.$newoid.'"');
  638. if(!$cnt) return $newoid;
  639. else return self::getNewBasicOID($t);
  640. }
  641. /// Génère un oid au format spécifique pour une table donnée (simple raccourci pour ne pas instancier soit meme la source pour générer un oid)
  642. static function getNewSpecificOID($t,$ar=NULL){
  643. $xset=XDataSource::objectFactoryHelper8('SPECS='.$t);
  644. return $xset->getNewOID($ar);
  645. }
  646. /// Generation d'un ecran d'edition
  647. function edit($ar=NULL) {
  648. $p=new XParam($ar,array('tplentry'=>$this->base,'options'=>array(),'selectedfields'=>array(),'fieldssec'=>array(),'accesslog'=>0));
  649. $accesslog=$p->get('accesslog');
  650. $tplentry = $p->get('tplentry');
  651. $fieldssec = $p->get('fieldssec','local');
  652. $moid=$p->get('fmoid','local');
  653. $oid=$p->get('oid');
  654. XLogs::debug('XDataSource::edit('.$oid.')');
  655. $this->checkOID($oid,$ar,'edit');
  656. $options=$p->get('options');
  657. if(!empty($GLOBALS['XLOCK'])) {
  658. $mode=$p->get('_mode');
  659. if($mode=='lock') {
  660. $GLOBALS['XLOCK']->lock($oid, TZR_DEFAULT_LANG, XUser::get_current_user_uid());
  661. $GLOBALS['XLOCK']->initLocks();
  662. }
  663. }
  664. $selectedfields=$p->get('selectedfields');
  665. if(!is_array($selectedfields)) {
  666. unset($selectedfields);
  667. $selectedfields=array();
  668. }
  669. $translatable=$this->getTranslatable();
  670. $LANG_DATA=$p->get('LANG_DATA');
  671. if(!$translatable) $LANG_DATA=TZR_DEFAULT_LANG;
  672. else $LANG_DATA=XShell::getLangData($LANG_DATA,true);
  673. $LANG_TRAD = XShell::getLangTrad($p->get('LANG_TRAD'));
  674. $LANG_USER = XShell::getLangUser();
  675. if(($translatable!=TZR_LANG_FREELANG) && !empty($LANG_TRAD) && ($LANG_TRAD!=$LANG_DATA)) {
  676. $ar1=$ar;
  677. $ar1['LANG_DATA']=$LANG_TRAD;
  678. $ar1['tplentry']=TZR_RETURN_DATA;
  679. $result=array();
  680. $result['d']=self::display($ar1);
  681. }
  682. $rs=selectQuery('select * from '.$this->base.
  683. " where KOID='$oid' and LANG='$LANG_DATA'");
  684. // si on ne trouve pas dans la langue en cours on regarde dans la langue de base
  685. if(!$ors=$rs->fetch()) {
  686. $rs->closeCursor();
  687. $rs=selectQuery('select * from '.$this->base.
  688. " where KOID='$oid' and LANG='".TZR_DEFAULT_LANG."'");
  689. $ors=$rs->fetch();
  690. }
  691. $rs->closeCursor();
  692. $myi=0;
  693. foreach($this->desc as $k=>$v) {
  694. if(!empty($selectedfields) && !in_array($k, $selectedfields)) continue;
  695. $options[$k]['oid']=$oid;
  696. $options[$k]['fmoid']=$moid;
  697. if(empty($fieldssec[$k]) || $fieldssec[$k]=='rw') $f='edit';
  698. elseif($fieldssec[$k]=='ro') $f='display';
  699. else continue;
  700. if($LANG_DATA!=TZR_DEFAULT_LANG && $translatable!=TZR_LANG_FREELANG && !$v->get_translatable() && $this->isTranslatable()) $f='display';
  701. $ofieldvalue[$myi]=&$v->$f($ors[$k],$options[$k],$ors);
  702. $fieldequiv[$myi] = $k;
  703. $result['o'.$k]=&$ofieldvalue[$myi];
  704. $myi++;
  705. }
  706. $rs->closeCursor();
  707. $result['oid']= $oid;
  708. $result['fields_object']=&$ofieldvalue;
  709. $result['tablelabel']=$this->getLabel();
  710. if(!empty($GLOBALS['XLOCK'])) {
  711. $result['_lock']=$GLOBALS['XLOCK']->locked($oid, TZR_DEFAULT_LANG);
  712. if(!empty($result['_lock'])) {
  713. $result['_lock_editable']=(empty($result['_lock'])||
  714. (XUser::get_current_user_uid()==$result['_lock']['OWN']));
  715. }
  716. }
  717. // recherche des groupes de champs
  718. $groups=array();
  719. foreach($fieldequiv as $foo => $k) {
  720. $v=&$this->desc[$k];
  721. if(!$v->sysField()) {
  722. if(empty($v->fgroup)) $v->fgroup='General';
  723. if(!empty($v->fgroup)) {
  724. $groups[$v->fgroup][]=&$result['o'.$k];
  725. }
  726. }
  727. }
  728. ksort($groups);
  729. if(count($groups)>1) $result['_groups']=$groups;
  730. // Log
  731. if($accesslog) XLogs::uniqueUpdate('access',$oid);
  732. // Information sur le caractere 'translatable' ou non de toute la table
  733. $result['translatable'] = $this->isTranslatable();
  734. return XShell::toScreen1($tplentry,$result);
  735. }
  736. /// publication d'une donnée (oid) ou d'un ensemble de données (_selected)
  737. public function publish($ar) {
  738. $p=new XParam($ar, array('value'=>1, '_selected'=>NULL,'key'=>true));
  739. $oid=$p->get('oid');
  740. $value=$p->get('value');
  741. $lang=$p->get('LANG_DATA');
  742. $sel = $p->get('_selected');
  743. $key=$p->get('key');
  744. if(is_array($sel) && !$key) $sel=array_flip($sel);
  745. if(empty($sel) && !empty($oid)) $sel=array($oid=>$value);
  746. // traitement de la valeur pour se ramener à 1 (oui) ou 2 (non)
  747. if(empty($value)) $value=2;
  748. if(empty($sel)) return;
  749. foreach($sel as $oid => $val) {
  750. if(Kernel::objectExists($oid)) {
  751. $this->procEdit(array('oid'=>$oid, 'LANG_DATA'=>$lang, 'PUBLISH'=>$value, '_options'=>array('local'=>true)));
  752. }
  753. }
  754. }
  755. /// Affichage d'un objet
  756. public function &display($ar) {
  757. $p=new XParam($ar,array('tplentry'=>$this->base,'_lastupdate'=>XShell::admini_mode(),'genempty'=>1,'selectedfields'=>array(),
  758. 'fieldssec'=>array(),'accesslog'=>0,'tlink'=>false));
  759. $tplentry = $p->get('tplentry');
  760. $fallback = $p->get('fallback');
  761. $publishedonly = $p->get('_publishedonly');
  762. $selectedfields=$p->get('selectedfields');
  763. if(!is_array($selectedfields)) {
  764. unset($selectedfields);
  765. $selectedfields=array();
  766. }
  767. $genempty = $p->get('genempty');
  768. $moid = $p->get('fmoid','local');
  769. $fieldssec = $p->get('fieldssec','local');
  770. $archive = $p->get('_archive');
  771. $accesslog=$p->get('accesslog');
  772. $tlink=$p->get('tlink');
  773. // dans le cas ou la data d'archive est codee en 9999-99-99 99:99:99
  774. // on enleve tous les caracteres non chiffres
  775. if(!empty($archive) && !preg_match('/^([0-9]+)$/',$archive)) $archive=preg_replace('/([^0-9])/','',$archive);
  776. $charset = $p->get('_charset');
  777. $table = $this->base;
  778. $filter='';
  779. $_filter = $p->get('_filter', 'local');
  780. if (!empty($_filter))
  781. $filter = ' AND '.$_filter;
  782. if(!empty($archive)) {
  783. $table='A_'.$this->base;
  784. $filter=" AND UPD='$archive'";
  785. }
  786. $LANG_USER = XShell::getLangUser();
  787. $LANG_DATA = XShell::getLangData($p->get('LANG_DATA','local'));
  788. if(!$this->isTranslatable()) $LANG_DATA=TZR_DEFAULT_LANG;
  789. $LANG_TRAD = XShell::getLangTrad($p->get('LANG_TRAD'));
  790. $oid = $p->get('oid');
  791. if(empty($oid)) {
  792. $r= 'XDataSource::display: no oid';
  793. return $r;
  794. }
  795. $this->checkOID($oid,$ar,'display');
  796. XLogs::debug('XDataSource::display('.$oid.')');
  797. $options = $p->get('options');
  798. $_format=$p->get('_format');
  799. $_options = $p->get('_options');
  800. $lastupdate = $p->get('_lastupdate');
  801. $genpublishtag= @$_options['genpublishtag'];
  802. $error = @$_options['error'];
  803. $published=$this->publishedMode($p);
  804. if(!isset($genpublishtag)) $genpublishtag=true;
  805. XAudit::plusplus('display('.$table.')');
  806. // Recherche de l'objet en base et génération d'une erreur si introuvable
  807. $rs=selectQuery('SELECT * FROM '.$table.' WHERE KOID="'.$oid.'" AND LANG="'.$LANG_DATA.'" '.$filter);
  808. if(!$ors=$rs->fetch()) {
  809. if($this->isTranslatable() || $fallback) {
  810. $rs->closeCursor();
  811. $rs=selectQuery('SELECT * FROM '.$table.' WHERE KOID="'.$oid.'" AND LANG="'.$LANG_TRAD.'" '.$filter);
  812. if(!$ors=$rs->fetch()) {
  813. if($error=='return') return $r='XDataSource('.$table.')->display: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>';
  814. else XShell::quit('XDataSource('.$table.')->display: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>');
  815. }
  816. } else {
  817. if($error=='return') return $r='XDataSource('.$table.')->display: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>';
  818. else XShell::quit('XDataSource('.$table.')->display: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>');
  819. }
  820. }
  821. $rs->closeCursor();
  822. // Fiche non publié
  823. if($published=='public' && $ors['PUBLISH']!=1) {
  824. if($error=='return') return $r='XDataSource('.$table.')->display: data '.$oid.' has not been published has public<br/>';
  825. else XShell::quit('XDataSource('.$table.')->display: data '.$oid.' has not been published has public<br/>');
  826. }
  827. $result=array();
  828. // Si on est dans l'admin, vérification de la génération du champ publié ou non
  829. if($genpublishtag && XShell::admini_mode() && ($published=='marked')) {
  830. $mark=$ors['PUBLISH'];
  831. if($mark=='1') $pubval='checked';
  832. else $pubval='';
  833. $result['_PUBLISH_tag']='<input type="checkbox" class="checkbox" name="_PUBLISH['.$oid.']" '.$pubval.'/>';
  834. $result['_PUBLISH_tag'].='<input type="hidden" name="_PUBLISH_H['.$oid.']" value="'.$mark.'"/>';
  835. }
  836. // Display sur chaque champ
  837. $result['fields_object']=array();
  838. $result['link']='';
  839. if($tlink) $result['tlink']='';
  840. foreach($this->desc as $k => &$v) {
  841. if((!empty($selectedfields) && !in_array($k, $selectedfields)) || (!empty($fieldssec[$k]) && $fieldssec[$k]=='none')) continue;
  842. if(($v->get_published() && $publishedonly) || !isset($publishedonly)) {
  843. $val=$ors[$k];
  844. // Calcul des options d'affichage
  845. $opt=@$options[$k];
  846. if(!empty($moid)) $opt['fmoid']=$moid;
  847. if($published=='marked' && $ors['PUBLISH']=='2') $opt['_published']=false;
  848. else $opt['_published']=true;
  849. if(!empty($archive)) $opt['_archive']=$archive;
  850. if(!empty($charset)) $opt['_charset']=$charset;
  851. $opt['_format']=$_format;
  852. // Nouvel objet d'affichage
  853. $o=&$v->display($val,$opt);
  854. $result['o'.$k]=$o;
  855. // Construction de fields_object et du lien avec les champs publié
  856. if($genempty || $o->html!='') {
  857. $result['fields_object'][]=$o;
  858. if($v->get_published()) {
  859. if(!empty($result['link'])) $result['link'].=' ';
  860. $result['link'].=$o->html;
  861. if($tlink){
  862. if(!empty($result['tlink'])) $result['tlink'].=' ';
  863. $result['tlink'].=$o->text;
  864. }
  865. }
  866. }
  867. }
  868. }
  869. $result['oid']= $oid;
  870. // Information sur le caractere 'translatable' ou non de toute la table
  871. $result['translatable']=$this->isTranslatable();
  872. if($result['translatable'] && isset($LANG_TRAD)) {
  873. $cnt=countSelectQuery("select COUNT(KOID) from $table where KOID='$oid' and LANG='$LANG_TRAD' $filter");
  874. if($cnt<=0) $result['_translation_ok']='0';
  875. else $result['_translation_ok']='1';
  876. }
  877. // information sur la langue générée
  878. $result['_lang_data']=$LANG_DATA;
  879. if(!empty($LANG_TRAD) && ($LANG_TRAD!=$LANG_DATA)) {
  880. $ar['tplentry']=TZR_RETURN_DATA;
  881. $ar['LANG_DATA']=$LANG_TRAD;
  882. $r2=self::display($ar);
  883. $result['d']=$r2;
  884. }
  885. // Etat du verouillage de la fiche
  886. if(!empty($GLOBALS['XLOCK'])) {
  887. $result['_lock']=$GLOBALS['XLOCK']->locked($oid,$LANG_DATA);
  888. $result['_lock_user'] = $GLOBALS['XLOCK']->getUser($oid,$LANG_DATA);
  889. $result['_lock_editable']=(empty($result['_lock']) || (XUser::get_current_user_uid()==$result['_lock']['OWN']));
  890. }
  891. // Derniere mise à jour
  892. if(!empty($lastupdate)) $result['lst_upd']=XLogs::getLastUpdate($oid,(!empty($result['oUPD'])?$result['oUPD']->raw:NULL));
  893. // Recherche des groupes de champs
  894. $groups=array();
  895. foreach($this->orddesc as $foo => $k) {
  896. $v=&$this->desc[$k];
  897. if(!$v->sysField()) {
  898. if(empty($v->fgroup)) $v->fgroup='General';
  899. if(!empty($v->fgroup) && !empty($result['o'.$k])) $groups[$v->fgroup][]=&$result['o'.$k];
  900. }
  901. }
  902. ksort($groups);
  903. if(count($groups)>1) $result['_groups']=$groups;
  904. // Log
  905. if($accesslog) XLogs::uniqueUpdate('access',$oid);
  906. return XShell::toScreen1($tplentry,$result);
  907. }
  908. /// affichage d'une objet
  909. public function &display2($ar) {
  910. $p = new XParam($ar, array('_lastupdate'=>XShell::admini_mode(),
  911. 'genempty'=>1));
  912. $publishedonly = $p->get('_publishedonly');
  913. $genempty = $p->get('genempty');
  914. $archive = $p->get('_archive');
  915. // dans le cas ou la data d'archive est codee en 9999-99-99 99:99:99
  916. // on enleve tous les caracteres non chiffres
  917. if(!empty($archive) && !preg_match('/^([0-9]+)$/',$archive)) $archive=preg_replace('/([^0-9]+)/','',$archive);
  918. $charset = $p->get('_charset');
  919. $table = $this->base;
  920. $filter='';
  921. if(!empty($archive)) {
  922. $table='A_'.$this->base;
  923. $filter=" AND UPD='$archive' ";
  924. }
  925. $LANG_USER = XShell::getLangUser();
  926. $LANG_DATA = XShell::getLangData($p->get('LANG_DATA','local'));
  927. if(!$this->isTranslatable()) $LANG_DATA=TZR_DEFAULT_LANG;
  928. $oid = $p->get('oid');
  929. XLogs::debug('XDataSource::display2('.$oid.')');
  930. $r=array();
  931. if(empty($oid)) return $r;
  932. $this->checkOID($oid,$ar,'display2');
  933. $options = $p->get('options');
  934. $_format=$p->get('_format');
  935. $_options = $p->get('_options');
  936. $lastupdate = $p->get('_lastupdate');
  937. $genpublishtag=@$_options['genpublishtag'];
  938. $published=$this->publishedMode($p);
  939. if(!isset($genpublishtag)) $genpublishtag=true;
  940. $verb='display2('.$table.')';
  941. XAudit::plusplus($verb);
  942. $rs=selectQuery("SELECT * FROM $table WHERE KOID='$oid' AND LANG='$LANG_DATA' $filter");
  943. if(!$ors=$rs->fetch()) {
  944. return $r;
  945. }
  946. $rs->closeCursor();
  947. if(($published=='public') && ($ors['PUBLISH']!=1)) {
  948. return $r;
  949. }
  950. $result=array();
  951. // si on est dans l'admin, vérification de la génération du champ publié ou non
  952. if($genpublishtag && XShell::admini_mode() && ($published=='marked')) {
  953. $mark=$ors['PUBLISH'];
  954. if($mark=='1') $pubval='checked';
  955. else $pubval='';
  956. $result['_PUBLISH_tag']='<input type="checkbox" class="checkbox" name="_PUBLISH['.$oid.']" '.$pubval.'/>';
  957. $result['_PUBLISH_tag'].='<input type="hidden" name="_PUBLISH_H['.$oid.']" value="'.$mark.'"/>';
  958. }
  959. $myi=0;
  960. $link='';
  961. $tlink='';
  962. foreach($this->desc as $k => &$v) {
  963. if(($v->get_published() && $publishedonly)||!isset($publishedonly)) {
  964. $val = $ors[$k];
  965. // calcul des options d'affichage
  966. $opt = $options[$k];
  967. if(($published=='marked') && ($ors['PUBLISH']=='2'))
  968. $opt['_published']=false;
  969. else
  970. $opt['_published']=true;
  971. if(!empty($archive))
  972. $opt['_archive']=$archive;
  973. $opt['_format']=$_format;
  974. if(!empty($charset)) {
  975. $opt['_charset']=$charset;
  976. }
  977. // nouvel objet d'affichage
  978. $o=&$v->display($val,$opt);
  979. $result['o'.$k]=$o;
  980. if($genempty || ($o->html!='')) {
  981. $result['fields_object'][$myi]=$o;
  982. $result[$k]=$o->html;
  983. $result['fields_field'][$myi]=$k;
  984. $myi++;
  985. if($v->get_published()) {
  986. if(!empty($link)) {
  987. $link.=' ';
  988. $tlink.=' ';
  989. }
  990. $link.=$o->html;
  991. $tlink.=$o->text;
  992. }
  993. }
  994. }
  995. }
  996. $result['link']=$link;
  997. $result['tlink']=$tlink;
  998. $result['oid']= $oid;
  999. if(!empty($lastupdate)) {
  1000. $result['lst_upd']=XLogs::getLastUpdate($oid);
  1001. }
  1002. XLogs::debug('XDataSource::display2: end '.$oid);
  1003. return $result;
  1004. }
  1005. public function &rDisplayText($oid, $LANG_DATA='', $LANG_USER='', $opts=array()) {
  1006. if(empty($LANG_USER)) $LANG_USER=XShell::getLangUser();
  1007. if(empty($LANG_DATA)) $LANG_DATA=XShell::getLangData();
  1008. $fallback = true;
  1009. $table = $this->base;
  1010. $charset=@$opts['_charset'];
  1011. $_format=@$opts['_format'];
  1012. $fmoid=@$opts['fmoid'];
  1013. $selectedfields=@$opts['selectedfields'];
  1014. if(!$this->isTranslatable()) $LANG_DATA=TZR_DEFAULT_LANG;
  1015. $verb='rDisplayText('.$table.')';
  1016. XAudit::plusplus($verb);
  1017. if(is_array($oid)) {
  1018. $ors=$oid;
  1019. $oid=$ors['KOID'];
  1020. } else {
  1021. $p=new XParam(array(),NULL);
  1022. $rs=&selectQuery('SELECT * FROM '.$table.' WHERE KOID="'.$oid.'" AND LANG="'.$LANG_DATA.'"');
  1023. if(!$ors=$rs->fetch()) {
  1024. $ret='XDataSource('.$table.')::rDisplayText: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>';
  1025. XLogs::critical('rDisplayText',$ret);
  1026. return $ret;
  1027. }elseif($this->publishedMode($p)=='public' && array_key_exists('PUBLISH',$ors) && $ors['PUBLISH']!=1){
  1028. XLogs::critical('rDisplayText', 'XDataSource('.$table.')::rDisplayText: Unpublished object with oid='.$oid.' and lang='.$LANG_DATA);
  1029. return $ret='UNPUBLISHED';
  1030. }
  1031. $rs->closeCursor();
  1032. }
  1033. $result=array();
  1034. $myi=0;
  1035. $tlink='';
  1036. foreach($this->desc as $k => &$v) {
  1037. if($selectedfields == 'all' || $v->get_published() || (!empty($selectedfields) && in_array($k,$selectedfields))) {
  1038. $val = $ors[$k];
  1039. // calcul des options d'affichage
  1040. if(isset($options[$k])) $opt = $options[$k];
  1041. else $opt=array();
  1042. if(!empty($fmoid)) $opt['fmoid']=$fmoid;
  1043. $opt['_published']=true;
  1044. $opt['_format']=$_format;
  1045. if(!empty($charset)) {
  1046. $opt['_charset']=$charset;
  1047. }
  1048. // nouvel objet d'affichage
  1049. $o=&$v->display($val,$opt);
  1050. if(!empty($tlink)) $tlink.=" ";
  1051. $tlink.=$o->toText();
  1052. }
  1053. }
  1054. $result['link']=$tlink;
  1055. $result['oid']= $oid;
  1056. return $result;
  1057. }
  1058. /**
  1059. * generation d'infos d'affichage simplifiees a partir d'un oid
  1060. * utilisé en particulier pour le display des champs liens
  1061. * @param KOID $oid
  1062. * @param PDO_STATEMENT $ors si renseigné écrase l'oid par $ors['KOID'], (utilisé ?)
  1063. * @param bool $publishedonly retourner uniquement les champs publiés
  1064. * @param string $LANG_DATA
  1065. * @param string $LANG_USER
  1066. * @param $opts [ tableau d'options indirectes
  1067. * selectedfields : tableau des champs sql à calculer (ou 'all')
  1068. * ...
  1069. * ]
  1070. * @return array [
  1071. * array fields_object : array of XFieldVal Object, integer key
  1072. * XFieldVal Object ofield : pour chaque champ retourné
  1073. * string link : représentation html
  1074. * KOID oid
  1075. * bool translatable
  1076. * ]
  1077. */
  1078. public function &rDisplay($oid,$ors=array(),$publishedonly=false,$LANG_DATA='',$LANG_USER='',$opts=array()) {
  1079. if(empty($LANG_USER)) $LANG_USER=XShell::getLangUser();
  1080. if(empty($LANG_DATA)) $LANG_DATA=XShell::getLangData();
  1081. $table=$this->base;
  1082. $charset=@$opts['_charset'];
  1083. $_format=@$opts['_format'];
  1084. $fmoid=@$opts['fmoid'];
  1085. $lastupdate=@$opts['_lastupdate'];
  1086. $selectedfields=@$opts['selectedfields'];
  1087. if(!$this->isTranslatable()) $LANG_DATA=TZR_DEFAULT_LANG;
  1088. XLogs::debug('XDataSource::rDisplay('.$oid.')');
  1089. XAudit::plusplus('rDisplay('.$table.')');
  1090. if(!empty($ors)) {
  1091. $oid=$ors['KOID'];
  1092. } else {
  1093. $ar=array();
  1094. $p=new XParam($ar,NULL);
  1095. $rs=selectQuery('SELECT * FROM '.$table.' WHERE KOID="'.$oid.'" AND LANG="'.$LANG_DATA.'"');
  1096. if(!$rs || !$ors=$rs->fetch()){
  1097. $ret='XDataSource('.$table.')::rDisplay: could not find object with oid='.$oid.' and lang='.$LANG_DATA.'<br/>';
  1098. XLogs::critical('rDisplay',$ret);
  1099. return $ret;
  1100. }elseif($this->publishedMode($p)=='public' && array_key_exists('PUBLISH',$ors) && $ors['PUBLISH']!=1){
  1101. XLogs::critical('rDisplay', 'XDataSource('.$table.')::rDisplay: Unpublished object with oid='.$oid.' and lang='.$LANG_DATA);
  1102. return $ret='UNPUBLISHED';
  1103. }
  1104. $rs->closeCursor();
  1105. }
  1106. $link='';
  1107. $result=array('fields_object'=>array());
  1108. foreach($this->desc as $k => &$v) {
  1109. if($selectedfields == 'all' || (($v->get_published() && $publishedonly) || !$publishedonly) && (empty($selectedfields) || in_array($k,$selectedfields))) {
  1110. $val = $ors[$k];
  1111. // calcul des options d'affichage
  1112. if(isset($opts[$k])) $opt = $opts[$k];
  1113. else $opt=array();
  1114. if(!empty($fmoid)) $opt['fmoid']=$fmoid;
  1115. if (empty($opt['selectedfields']))
  1116. $opt['_published']=true;
  1117. $opt['_format']=$_format;
  1118. if(!empty($charset)) $opt['_charset']=$charset;
  1119. // Nouvel objet d'affichage
  1120. $o=&$v->display($val,$opt);
  1121. $result['o'.$k]=$o;
  1122. $result['fields_object'][]=$o;
  1123. if($v->get_published()) {
  1124. if(!empty($link)) $link.=' ';
  1125. $link.=$o->html;
  1126. }
  1127. }
  1128. }
  1129. $result['link']=$link;
  1130. $result['oid']=$oid;
  1131. // Derniere mise à jour
  1132. if(!empty($lastupdate)) $result['lst_upd']=XLogs::getLastUpdate($oid,$result['oUPD']->raw);
  1133. // Information sur le caractere 'translatable' ou non de toute la table
  1134. $result['translatable']=$this->isTranslatable();
  1135. return $result;
  1136. }
  1137. /// Affichage d'une donnee dont l'oid est $oid, via la methode rdisplay
  1138. public static function objectDisplayHelper($oid) {
  1139. $x=XDataSource::objectFactoryHelper8('SPECS='.$oid);
  1140. if(!empty($x) && Kernel::objectExists($oid)) return $x->display(array('oid'=>$oid));
  1141. else return NULL;
  1142. }
  1143. /****m* XDataSource/fdisplay
  1144. * NAME
  1145. * XDataSource::fdisplay - affichage detaille d'un champ
  1146. * DESCRIPTION
  1147. * Permet d'afficher le contenu detaille d'un champ, fonction utilisée
  1148. * principalement pour l'affichage detaille.
  1149. ****/
  1150. public function fdisplay($ar) {
  1151. $p = new XParam($ar, array('tplentry'=>$this->base,
  1152. // liste des champs qui seront affichés sur des liens
  1153. // si on ne veut pas prendre les published par defaut
  1154. 'genempty'=>1));
  1155. $tplentry = $p->get('tplentry');
  1156. $field = $p->get('field');
  1157. $LANG_USER = XShell::getLangUser();
  1158. $LANG_DATA = XShell::getLangData($p->get('LANG_DATA'));
  1159. if(!$this->isTranslatable()) $LANG_DATA=TZR_DEFAULT_LANG;
  1160. $verb='fdisplay('.$this->base.')';
  1161. XAudit::plusplus($verb);
  1162. $ar['tplentry']=TZR_RETURN_DATA;
  1163. $r=self::display($ar);
  1164. XShell::toScreen2($tplentry, 'field', $r['o'.$field]);
  1165. }
  1166. /*****
  1167. Fonction : XDataSource::gen_random_display_mask()
  1168. Description : Display d'1 tuple pris aléatoirement.
  1169. *****/
  1170. function gen_random_display_mask($ar=NULL) {
  1171. $query = $this->random_select_query($ar);
  1172. $rs=selectQuery($query);
  1173. $ors=array();
  1174. if ( $ors=$rs->fetch()) $oid = $ors['KOID'];
  1175. $ar['oid'] = $oid;
  1176. $this->display($ar);
  1177. $rs->closeCursor();
  1178. }
  1179. // Fonction reservee a la creation d'une data pour la langue par defaut.
  1180. // La creation d'une data dans tout autre code langue se fait par Kernel::data_edit() et Kernel::proc_data_edit()
  1181. // apres avoir cree une data en l'initialisant avec la data correspondante dans le code langue par defaut.
  1182. //
  1183. public function procInput($ar=NULL) {
  1184. $this->preUpdateTasks($ar);
  1185. $p=new XParam($ar, array('tplentry'=>$this->base,'_inputs'=>array(),'options'=>array()));
  1186. $tplentry = $p->get('tplentry');
  1187. $j=$p->get('_nojournal');
  1188. $journal=empty($j);
  1189. $moid=$p->get('fmoid','local');
  1190. $nolog=$p->get('_nolog','local');
  1191. $all=$p->get('_allfields');
  1192. $fieldssec=$p->get('fieldssec','local');
  1193. $delayed=$p->get('_delayed');
  1194. if(!empty($delayed)) $delayed='LOW_PRIORITY ';
  1195. else $delayed='';
  1196. $options=$p->get('options');
  1197. // Si option est un champ
  1198. if(is_string($options)) $options=array();
  1199. $unique=$p->get('_unique');
  1200. $updateifexists = $p->get('_updateifexists');
  1201. $unique_val = array();
  1202. $insert = true;
  1203. $jn='';
  1204. // Nouvel oid puisqu'on cree une nouvelle data en langue par defaut
  1205. $oid=$p->get('newoid'); // permet d'imposer le KOID
  1206. if(!empty($oid) && empty($updateifexists)) {
  1207. $cnt=countSelectQuery("select COUNT(KOID) from {$this->base} where KOID='$oid' limit 1");
  1208. if($cnt) {
  1209. XLogs::notice('XDataSource::procInput', $oid.' already exist');
  1210. return array('error'=>true,'message'=>$oid.' already exist');
  1211. }
  1212. }
  1213. if(empty($oid)) $oid=$this->getNewOID($ar);
  1214. else $this->checkOID($oid,$ar,'procInput');
  1215. // traitement des langues
  1216. $translatable = $this->getTranslatable();
  1217. if(!$this->isTranslatable()) $lang=TZR_DEFAULT_LANG;
  1218. elseif($translatable==3)
  1219. $lang=XShell::getLangData($p->get('LANG_DATA'));
  1220. else {
  1221. $lang=XShell::getLangData($p->get('LANG_DATA'));
  1222. if($lang!=TZR_DEFAULT_LANG) return array('error'=>true,'message'=>'Lang error');
  1223. }
  1224. $query = $jn."INSERT {$delayed}INTO ".$this->base.'(';
  1225. $fields='KOID,LANG';
  1226. $values="'$oid','".$lang."'";
  1227. $nottorepeat=array('UPD');
  1228. if($this->fieldExists('OWN') && !$p->get('OWN')) {
  1229. $fields.=',OWN';
  1230. $values.=",'".XUser::get_current_user_uid()."'";
  1231. $nottorepeat[]='OWN';
  1232. }
  1233. if($this->fieldExists('CREAD')) {
  1234. $fields.=',CREAD';
  1235. $values.=",'".date('Y-m-d H:i:s')."'";
  1236. $nottorepeat[]='CREAD';
  1237. }
  1238. if($this->fieldExists('PUBLISH') && !$p->is_set('PUBLISH')) {
  1239. $fields.=',PUBLISH';
  1240. $values.=",'2'";
  1241. $nottorepeat[]='PUBLISH';
  1242. }
  1243. $inputs=$p->get('_inputs','local');
  1244. $inputvalues=array();
  1245. foreach($this->desc as $k => &$v) {
  1246. if(!empty($fieldssec[$k]) && $fieldssec[$k]!='rw') continue;
  1247. if(($p->is_set($k) || $p->is_set($k.'_HID') || !empty($all)) && !in_array($k, $nottorepeat)) {
  1248. $value = $p->get($k);
  1249. $value_hid = $p->get($k.'_HID');
  1250. // traitement en post edit dans les cas simples
  1251. if(!is_object($v)) XShell::quit(array('message'=>'XDataSource::procInput: '.$this->base.':'.$k.' is not a valid field'));
  1252. $options[$k]['oid']=$oid;
  1253. $options[$k][$k.'_HID']=$value_hid;
  1254. $options[$k][$k.'_title']=$p->get($k.'_title');
  1255. $options[$k]['fmoid']=$moid;
  1256. $r1=$v->post_edit($value,$options[$k],$inputs);
  1257. $inputs[$k]=$r1;
  1258. $nvalue=$r1->raw;
  1259. $fields .= ','.$k;
  1260. if(!empty($unique) && in_array($k, $unique)) $unique_val[]="$k like '$nvalue'";
  1261. // cas ou on garde la valeur
  1262. $value=$nvalue;
  1263. if(is_array($value) && (count($value)>1)) {
  1264. $finalval='||';
  1265. foreach($value as $o1=>$o2)
  1266. $finalval.=$o2.'||';
  1267. $values.=",'".$finalval."'";
  1268. } elseif(is_array($value)) {
  1269. list($o1,$o2)=each($value);
  1270. $values.=',?';
  1271. $inputvalues[]=$o2;
  1272. }

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