PageRenderTime 44ms CodeModel.GetById 10ms RepoModel.GetById 0ms app.codeStats 1ms

/htdocs/core/modules/DolibarrModules.class.php

https://github.com/asterix14/dolibarr
PHP | 1469 lines | 976 code | 214 blank | 279 comment | 159 complexity | 8064a78548165ffb5c59fb4088d2194f MD5 | raw file
Possible License(s): LGPL-2.0
  1. <?php
  2. /* Copyright (C) 2003-2007 Rodolphe Quiedeville <rodolphe@quiedeville.org>
  3. * Copyright (C) 2004 Sebastien Di Cintio <sdicintio@ressource-toi.org>
  4. * Copyright (C) 2004 Benoit Mortier <benoit.mortier@opensides.be>
  5. * Copyright (C) 2004 Eric Seigne <eric.seigne@ryxeo.com>
  6. * Copyright (C) 2005-2011 Laurent Destailleur <eldy@users.sourceforge.net>
  7. * Copyright (C) 2005-2011 Regis Houssin <regis@dolibarr.fr>
  8. *
  9. * This program is free software; you can redistribute it and/or modify
  10. * it under the terms of the GNU General Public License as published by
  11. * the Free Software Foundation; either version 2 of the License, or
  12. * (at your option) any later version.
  13. *
  14. * This program is distributed in the hope that it will be useful,
  15. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  16. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  17. * GNU General Public License for more details.
  18. *
  19. * You should have received a copy of the GNU General Public License
  20. * along with this program. If not, see <http://www.gnu.org/licenses/>.
  21. */
  22. /**
  23. * \file htdocs/core/modules/DolibarrModules.class.php
  24. * \brief Fichier de description et activation des modules Dolibarr
  25. */
  26. /**
  27. * \class DolibarrModules
  28. * \brief Classe mere des classes de description et activation des modules Dolibarr
  29. */
  30. abstract class DolibarrModules
  31. {
  32. //! Database handler
  33. var $db;
  34. //! Relative path to module style sheet
  35. var $style_sheet = '';
  36. //! Path to create when module activated
  37. var $dirs = array();
  38. //! Tableau des boites
  39. var $boxes;
  40. //! Tableau des constantes
  41. var $const;
  42. //! Tableau des droits
  43. var $rights;
  44. //! Tableau des menus
  45. var $menu=array();
  46. //! Tableau des documents ???
  47. var $docs;
  48. var $dbversion = "-";
  49. /**
  50. * Fonction d'activation. Insere en base les constantes et boites du module
  51. *
  52. * @param array $array_sql Array of SQL requests to execute when enabling module
  53. * @param string $options Options when enabling module ('', 'noboxes')
  54. * @return int 1 if OK, 0 if KO
  55. */
  56. function _init($array_sql, $options='')
  57. {
  58. global $langs;
  59. $err=0;
  60. $this->db->begin();
  61. // Insert line in module table
  62. if (! $err) $err+=$this->_dbactive();
  63. // Insert activation module constant
  64. if (! $err) $err+=$this->_active();
  65. // Insere le nom de la feuille de style
  66. if (! $err) $err+=$this->insert_style_sheet();
  67. // Insert new pages for tabs into llx_const
  68. if (! $err) $err+=$this->insert_tabs();
  69. // Insert activation triggers
  70. if (! $err) $err+=$this->insert_triggers();
  71. // Insert activation login method
  72. if (! $err) $err+=$this->insert_login_method();
  73. // Insert constant defined by modules, into llx_const
  74. if (! $err) $err+=$this->insert_const();
  75. // Insere les boites dans llx_boxes_def
  76. if (! $err && $options != 'noboxes') $err+=$this->insert_boxes();
  77. // Insert permission definitions of module into llx_rights_def. If user is admin, grant this permission to user.
  78. if (! $err) $err+=$this->insert_permissions(1);
  79. // Insere les constantes associees au module dans llx_const
  80. if (! $err) $err+=$this->insert_menus();
  81. // Create module's directories
  82. if (! $err) $err+=$this->create_dirs();
  83. // Execute les requetes sql complementaires
  84. if (! $err)
  85. {
  86. $num=count($array_sql);
  87. for ($i = 0; $i < $num; $i++)
  88. {
  89. if (! $err)
  90. {
  91. $val=$array_sql[$i];
  92. $sql='';
  93. $ignoreerror=0;
  94. if (is_array($val))
  95. {
  96. $sql=$val['sql'];
  97. $ignoreerror=$val['ignoreerror'];
  98. }
  99. else
  100. {
  101. $sql=$val;
  102. }
  103. dol_syslog(get_class($this)."::_init ignoreerror=".$ignoreerror." sql=".$sql, LOG_DEBUG);
  104. $result=$this->db->query($sql);
  105. if (! $result)
  106. {
  107. if (! $ignoreerror)
  108. {
  109. $this->error=$this->db->lasterror();
  110. dol_syslog(get_class($this)."::_init Error ".$this->error, LOG_ERR);
  111. $err++;
  112. }
  113. else
  114. {
  115. dol_syslog(get_class($this)."::_init Warning ".$this->db->lasterror(), LOG_WARNING);
  116. }
  117. }
  118. }
  119. }
  120. }
  121. // Return code
  122. if (! $err)
  123. {
  124. $this->db->commit();
  125. return 1;
  126. }
  127. else
  128. {
  129. $this->db->rollback();
  130. return 0;
  131. }
  132. }
  133. /**
  134. * Fonction de desactivation. Supprime de la base les constantes et boites du module
  135. *
  136. * @param array $array_sql Array of SQL requests to execute when disable module
  137. * @param string $options Options when disabling module ('', 'noboxes')
  138. * @return int 1 if OK, 0 if KO
  139. */
  140. function _remove($array_sql, $options='')
  141. {
  142. global $langs;
  143. $err=0;
  144. $this->db->begin();
  145. // Remove line in activation module (entry in table llx_dolibarr_modules)
  146. if (! $err) $err+=$this->_dbunactive();
  147. // Remove activation module line (constant MAIN_MODULE_MYMODULE in llx_const)
  148. if (! $err) $err+=$this->_unactive();
  149. // Remove activation of module's style sheet (constant MAIN_MODULE_MYMODULE_CSS in llx_const)
  150. if (! $err) $err+=$this->delete_style_sheet();
  151. // Remove activation of module's new tabs (MAIN_MODULE_MYMODULE_TABS_XXX in llx_const)
  152. if (! $err) $err+=$this->delete_tabs();
  153. // Remove activation of module's triggers (MAIN_MODULE_MYMODULE_TRIGGERS in llx_const)
  154. if (! $err) $err+=$this->delete_triggers();
  155. // Remove activation of module's authentification method (MAIN_MODULE_MYMODULE_LOGIN_METHOD in llx_const)
  156. if (! $err) $err+=$this->delete_login_method();
  157. // Remove constants defined by modules
  158. if (! $err) $err+=$this->delete_const();
  159. // Remove list of module's available boxes (entry in llx_boxes)
  160. if (! $err && $options != 'noboxes') $err+=$this->delete_boxes();
  161. // Remove module's permissions from list of available permissions (entries in llx_rights_def)
  162. if (! $err) $err+=$this->delete_permissions();
  163. // Remove module's menus (entries in llx_menu)
  164. if (! $err) $err+=$this->delete_menus();
  165. // Remove module's directories
  166. if (! $err) $err+=$this->delete_dirs();
  167. // Run complementary sql requests
  168. $num=count($array_sql);
  169. for ($i = 0; $i < $num; $i++)
  170. {
  171. if (! $err)
  172. {
  173. dol_syslog(get_class($this)."::_remove sql=".$array_sql[$i], LOG_DEBUG);
  174. $result=$this->db->query($array_sql[$i]);
  175. if (! $result)
  176. {
  177. $this->error=$this->db->error();
  178. dol_syslog(get_class($this)."::_remove Error ".$this->error, LOG_ERR);
  179. $err++;
  180. }
  181. }
  182. }
  183. // Return code
  184. if (! $err)
  185. {
  186. $this->db->commit();
  187. return 1;
  188. }
  189. else
  190. {
  191. $this->db->rollback();
  192. return 0;
  193. }
  194. }
  195. /**
  196. * Retourne le nom traduit du module si la traduction existe dans admin.lang,
  197. * sinon le nom defini par defaut dans le module.
  198. * @return string Nom du module traduit
  199. */
  200. function getName()
  201. {
  202. global $langs;
  203. $langs->load("admin");
  204. if ($langs->trans("Module".$this->numero."Name") != ("Module".$this->numero."Name"))
  205. {
  206. // Si traduction du nom du module existe
  207. return $langs->trans("Module".$this->numero."Name");
  208. }
  209. else
  210. {
  211. // If translation of module with its numero does not exists, we take its name
  212. return $this->name;
  213. }
  214. }
  215. /**
  216. * Retourne la description traduite du module si la traduction existe dans admin.lang,
  217. * sinon la description definie par defaut dans le module
  218. *
  219. * @return string Nom du module traduit
  220. */
  221. function getDesc()
  222. {
  223. global $langs;
  224. $langs->load("admin");
  225. if ($langs->trans("Module".$this->numero."Desc") != ("Module".$this->numero."Desc"))
  226. {
  227. // Si traduction de la description du module existe
  228. return $langs->trans("Module".$this->numero."Desc");
  229. }
  230. else
  231. {
  232. // Si traduction de la description du module n'existe pas, on prend definition en dur dans module
  233. return $this->description;
  234. }
  235. }
  236. /**
  237. * Retourne la version du module.
  238. * Pour les modules a l'etat 'experimental', retourne la traduction de 'experimental'
  239. * Pour les modules 'dolibarr', retourne la version de Dolibarr
  240. * Pour les autres modules, retourne la version du module
  241. *
  242. * @return string Version du module
  243. */
  244. function getVersion()
  245. {
  246. global $langs;
  247. $langs->load("admin");
  248. if ($this->version == 'experimental') return $langs->trans("VersionExperimental");
  249. elseif ($this->version == 'development') return $langs->trans("VersionDevelopment");
  250. elseif ($this->version == 'dolibarr') return DOL_VERSION;
  251. elseif ($this->version) return $this->version;
  252. else return $langs->trans("VersionUnknown");
  253. }
  254. /**
  255. * Return list of lang files related to module
  256. *
  257. * @return array Array of lang files
  258. */
  259. function getLangFilesArray()
  260. {
  261. return $this->langfiles;
  262. }
  263. /**
  264. * Return translated label of a export dataset
  265. *
  266. * @return string Label of databaset
  267. */
  268. function getExportDatasetLabel($r)
  269. {
  270. global $langs;
  271. $langstring="ExportDataset_".$this->export_code[$r];
  272. if ($langs->trans($langstring) == $langstring)
  273. {
  274. // Traduction non trouvee
  275. return $langs->trans($this->export_label[$r]);
  276. }
  277. else
  278. {
  279. // Traduction trouvee
  280. return $langs->trans($langstring);
  281. }
  282. }
  283. /**
  284. * Return translated label of an import dataset
  285. *
  286. * @return string Label of databaset
  287. */
  288. function getImportDatasetLabel($r)
  289. {
  290. global $langs;
  291. $langstring="ImportDataset_".$this->import_code[$r];
  292. //print "x".$langstring;
  293. if ($langs->trans($langstring) == $langstring)
  294. {
  295. // Traduction non trouvee
  296. return $langs->trans($this->import_label[$r]);
  297. }
  298. else
  299. {
  300. // Traduction trouvee
  301. return $langs->trans($langstring);
  302. }
  303. }
  304. /**
  305. * Insert line in dolibarr_modules table.
  306. * Storage is made for information only, table is not required for Dolibarr usage
  307. *
  308. * @return int Nb of errors (0 if OK)
  309. */
  310. function _dbactive()
  311. {
  312. global $conf;
  313. $err = 0;
  314. $sql = "DELETE FROM ".MAIN_DB_PREFIX."dolibarr_modules";
  315. $sql.= " WHERE numero = ".$this->numero;
  316. $sql.= " AND entity = ".$conf->entity;
  317. dol_syslog(get_class($this)."::_dbactive sql=".$sql, LOG_DEBUG);
  318. $this->db->query($sql);
  319. $sql = "INSERT INTO ".MAIN_DB_PREFIX."dolibarr_modules (";
  320. $sql.= "numero";
  321. $sql.= ", entity";
  322. $sql.= ", active";
  323. $sql.= ", active_date";
  324. $sql.= ", active_version";
  325. $sql.= ")";
  326. $sql.= " VALUES (";
  327. $sql.= $this->numero;
  328. $sql.= ", ".$conf->entity;
  329. $sql.= ", 1";
  330. $sql.= ", '".$this->db->idate(gmmktime())."'";
  331. $sql.= ", '".$this->version."'";
  332. $sql.= ")";
  333. dol_syslog(get_class($this)."::_dbactive sql=".$sql, LOG_DEBUG);
  334. $this->db->query($sql);
  335. return $err;
  336. }
  337. /**
  338. * Remove line in dolibarr_modules table
  339. * Storage is made for information only, table is not required for Dolibarr usage
  340. *
  341. * @return int Nb of errors (0 if OK)
  342. */
  343. function _dbunactive()
  344. {
  345. global $conf;
  346. $err = 0;
  347. $sql = "DELETE FROM ".MAIN_DB_PREFIX."dolibarr_modules";
  348. $sql.= " WHERE numero = ".$this->numero;
  349. $sql.= " AND entity in (0, ".$conf->entity.")";
  350. dol_syslog(get_class($this)."::_dbunactive sql=".$sql, LOG_DEBUG);
  351. $this->db->query($sql);
  352. return $err;
  353. }
  354. /**
  355. * Insert constant to activate module
  356. *
  357. * @return int Nb of errors (0 if OK)
  358. */
  359. function _active()
  360. {
  361. global $conf;
  362. $err = 0;
  363. // Common module
  364. $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity);
  365. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  366. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->const_name."'";
  367. $sql.= " AND entity in (0, ".$entity.")";
  368. dol_syslog(get_class($this)."::_active sql=".$sql, LOG_DEBUG);
  369. $this->db->query($sql);
  370. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,value,visible,entity) VALUES";
  371. $sql.= " (".$this->db->encrypt($this->const_name,1);
  372. $sql.= ",".$this->db->encrypt('1',1);
  373. $sql.= ",0,".$entity.")";
  374. dol_syslog(get_class($this)."::_active sql=".$sql, LOG_DEBUG);
  375. if (!$this->db->query($sql))
  376. {
  377. $err++;
  378. }
  379. return $err;
  380. }
  381. /**
  382. * Remove activation line
  383. *
  384. * @return int Nb of errors (0 if OK)
  385. **/
  386. function _unactive()
  387. {
  388. global $conf;
  389. $err = 0;
  390. // Common module
  391. $entity = ((! empty($this->always_enabled) || ! empty($this->core_enabled)) ? 0 : $conf->entity);
  392. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  393. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->const_name."'";
  394. $sql.= " AND entity in (0, ".$entity.")";
  395. dol_syslog(get_class($this)."::_unactive sql=".$sql);
  396. $this->db->query($sql);
  397. return $err;
  398. }
  399. /**
  400. * Create tables and keys required by module.
  401. * Files module.sql and module.key.sql with create table and create keys
  402. * commands must be stored in directory reldir='/module/sql/'
  403. * This function is called by this->init
  404. *
  405. * @return int <=0 if KO, >0 if OK
  406. */
  407. function _load_tables($reldir)
  408. {
  409. global $db,$conf;
  410. $error=0;
  411. include_once(DOL_DOCUMENT_ROOT ."/core/lib/admin.lib.php");
  412. $ok = 1;
  413. foreach($conf->file->dol_document_root as $dirroot)
  414. {
  415. if ($ok)
  416. {
  417. $dir = $dirroot.$reldir;
  418. $ok = 0;
  419. // Run llx_mytable.sql files
  420. $handle=@opendir($dir); // Dir may not exists
  421. if (is_resource($handle))
  422. {
  423. while (($file = readdir($handle))!==false)
  424. {
  425. if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
  426. {
  427. $result=run_sql($dir.$file,1,'',1);
  428. if ($result <= 0) $error++;
  429. }
  430. }
  431. closedir($handle);
  432. }
  433. // Run llx_mytable.key.sql files (Must be done after llx_mytable.sql)
  434. $handle=@opendir($dir); // Dir may not exist
  435. if (is_resource($handle))
  436. {
  437. while (($file = readdir($handle))!==false)
  438. {
  439. if (preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'llx_' && substr($file,0,4) != 'data')
  440. {
  441. $result=run_sql($dir.$file,1,'',1);
  442. if ($result <= 0) $error++;
  443. }
  444. }
  445. closedir($handle);
  446. }
  447. // Run data_xxx.sql files (Must be done after llx_mytable.key.sql)
  448. $handle=@opendir($dir); // Dir may not exist
  449. if (is_resource($handle))
  450. {
  451. while (($file = readdir($handle))!==false)
  452. {
  453. if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,4) == 'data')
  454. {
  455. $result=run_sql($dir.$file,1,'',1);
  456. if ($result <= 0) $error++;
  457. }
  458. }
  459. closedir($handle);
  460. }
  461. // Run update_xxx.sql files
  462. $handle=@opendir($dir); // Dir may not exist
  463. if (is_resource($handle))
  464. {
  465. while (($file = readdir($handle))!==false)
  466. {
  467. if (preg_match('/\.sql$/i',$file) && ! preg_match('/\.key\.sql$/i',$file) && substr($file,0,6) == 'update')
  468. {
  469. $result=run_sql($dir.$file,1,'',1);
  470. if ($result <= 0) $error++;
  471. }
  472. }
  473. closedir($handle);
  474. }
  475. if ($error == 0)
  476. {
  477. $ok = 1;
  478. }
  479. }
  480. }
  481. return $ok;
  482. }
  483. /**
  484. * Insert boxes into llx_boxes_def
  485. *
  486. * @return int Nb of errors (0 if OK)
  487. */
  488. function insert_boxes()
  489. {
  490. global $conf;
  491. $err=0;
  492. if (is_array($this->boxes))
  493. {
  494. foreach ($this->boxes as $key => $value)
  495. {
  496. //$titre = $this->boxes[$key][0];
  497. $file = isset($this->boxes[$key][1])?$this->boxes[$key][1]:'';
  498. $note = isset($this->boxes[$key][2])?$this->boxes[$key][2]:'';
  499. $sql = "SELECT count(*) FROM ".MAIN_DB_PREFIX."boxes_def";
  500. $sql.= " WHERE file = '".$file."'";
  501. $sql.= " AND entity = ".$conf->entity;
  502. if ($note) $sql.=" AND note ='".$this->db->escape($note)."'";
  503. $result=$this->db->query($sql);
  504. if ($result)
  505. {
  506. $row = $this->db->fetch_row($result);
  507. if ($row[0] == 0)
  508. {
  509. $sql = "INSERT INTO ".MAIN_DB_PREFIX."boxes_def (file,entity,note)";
  510. $sql.= " VALUES ('".$this->db->escape($file)."',";
  511. $sql.= $conf->entity.",";
  512. $sql.= $note?"'".$this->db->escape($note)."'":"null";
  513. $sql.= ")";
  514. dol_syslog(get_class($this)."::insert_boxes sql=".$sql);
  515. if (! $this->db->query($sql))
  516. {
  517. $err++;
  518. }
  519. }
  520. }
  521. else
  522. {
  523. $this->error=$this->db->lasterror();
  524. dol_syslog(get_class($this)."::insert_boxes ".$this->error, LOG_ERR);
  525. $err++;
  526. }
  527. }
  528. }
  529. return $err;
  530. }
  531. /**
  532. * Delete boxes
  533. *
  534. * @return int Nb of errors (0 if OK)
  535. */
  536. function delete_boxes()
  537. {
  538. global $conf;
  539. $err=0;
  540. if (is_array($this->boxes))
  541. {
  542. foreach ($this->boxes as $key => $value)
  543. {
  544. //$titre = $this->boxes[$key][0];
  545. $file = $this->boxes[$key][1];
  546. //$note = $this->boxes[$key][2];
  547. $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes";
  548. $sql.= " USING ".MAIN_DB_PREFIX."boxes, ".MAIN_DB_PREFIX."boxes_def";
  549. $sql.= " WHERE ".MAIN_DB_PREFIX."boxes.box_id = ".MAIN_DB_PREFIX."boxes_def.rowid";
  550. $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.file = '".$this->db->escape($file)."'";
  551. $sql.= " AND ".MAIN_DB_PREFIX."boxes_def.entity = ".$conf->entity;
  552. dol_syslog(get_class($this)."::delete_boxes sql=".$sql);
  553. $resql=$this->db->query($sql);
  554. if (! $resql)
  555. {
  556. $this->error=$this->db->lasterror();
  557. dol_syslog(get_class($this)."::delete_boxes ".$this->error, LOG_ERR);
  558. $err++;
  559. }
  560. $sql = "DELETE FROM ".MAIN_DB_PREFIX."boxes_def";
  561. $sql.= " WHERE file = '".$this->db->escape($file)."'";
  562. $sql.= " AND entity = ".$conf->entity;
  563. dol_syslog(get_class($this)."::delete_boxes sql=".$sql);
  564. $resql=$this->db->query($sql);
  565. if (! $resql)
  566. {
  567. $this->error=$this->db->lasterror();
  568. dol_syslog(get_class($this)."::delete_boxes ".$this->error, LOG_ERR);
  569. $err++;
  570. }
  571. }
  572. }
  573. return $err;
  574. }
  575. /**
  576. * Desactive feuille de style du module par suppression ligne dans llx_const
  577. *
  578. * @return int Nb of errors (0 if OK)
  579. */
  580. function delete_style_sheet()
  581. {
  582. global $conf;
  583. $err=0;
  584. if ($this->style_sheet)
  585. {
  586. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  587. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$this->const_name."_CSS'";
  588. $sql.= " AND entity = ".$conf->entity;
  589. dol_syslog(get_class($this)."::delete_style_sheet sql=".$sql);
  590. if (! $this->db->query($sql))
  591. {
  592. $this->error=$this->db->lasterror();
  593. dol_syslog(get_class($this)."::delete_style_sheet ".$this->error, LOG_ERR);
  594. $err++;
  595. }
  596. }
  597. return $err;
  598. }
  599. /**
  600. * Remove links to new module page present in llx_const
  601. *
  602. * @return int Nb of errors (0 if OK)
  603. */
  604. function delete_tabs()
  605. {
  606. global $conf;
  607. $err=0;
  608. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  609. $sql.= " WHERE ".$this->db->decrypt('name')." like '".$this->const_name."_TABS_%'";
  610. $sql.= " AND entity = ".$conf->entity;
  611. dol_syslog(get_class($this)."::delete_tabs sql=".$sql);
  612. if (! $this->db->query($sql))
  613. {
  614. $this->error=$this->db->lasterror();
  615. dol_syslog(get_class($this)."::delete_tabs ".$this->error, LOG_ERR);
  616. $err++;
  617. }
  618. return $err;
  619. }
  620. /**
  621. * Activate stylesheet provided by module by adding a line into llx_const
  622. *
  623. * @return int Nb of errors (0 if OK)
  624. */
  625. function insert_style_sheet()
  626. {
  627. global $conf;
  628. $err=0;
  629. if ($this->style_sheet)
  630. {
  631. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
  632. $sql.= "name";
  633. $sql.= ", type";
  634. $sql.= ", value";
  635. $sql.= ", note";
  636. $sql.= ", visible";
  637. $sql.= ", entity";
  638. $sql.= ")";
  639. $sql.= " VALUES (";
  640. $sql.= $this->db->encrypt($this->const_name."_CSS",1);
  641. $sql.= ", 'chaine'";
  642. $sql.= ", ".$this->db->encrypt($this->style_sheet,1);
  643. $sql.= ", 'Style sheet for module ".$this->name."'";
  644. $sql.= ", '0'";
  645. $sql.= ", ".$conf->entity;
  646. $sql.= ")";
  647. dol_syslog(get_class($this)."::insert_style_sheet sql=".$sql);
  648. $resql=$this->db->query($sql);
  649. /* Allow duplicate key
  650. if (! $resql)
  651. {
  652. $err++;
  653. }
  654. */
  655. }
  656. return $err;
  657. }
  658. /**
  659. * Add links of new pages from modules in llx_const
  660. *
  661. * @return int Number of errors (0 if ok)
  662. */
  663. function insert_tabs()
  664. {
  665. global $conf;
  666. $err=0;
  667. if (! empty($this->tabs))
  668. {
  669. $i=0;
  670. foreach ($this->tabs as $key => $value)
  671. {
  672. if ($value)
  673. {
  674. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
  675. $sql.= "name";
  676. $sql.= ", type";
  677. $sql.= ", value";
  678. $sql.= ", note";
  679. $sql.= ", visible";
  680. $sql.= ", entity";
  681. $sql.= ")";
  682. $sql.= " VALUES (";
  683. $sql.= $this->db->encrypt($this->const_name."_TABS_".$i,1);
  684. $sql.= ", 'chaine'";
  685. $sql.= ", ".$this->db->encrypt($value,1);
  686. $sql.= ", null";
  687. $sql.= ", '0'";
  688. $sql.= ", ".$conf->entity;
  689. $sql.= ")";
  690. dol_syslog(get_class($this)."::insert_tabs sql=".$sql);
  691. $resql=$this->db->query($sql);
  692. /* Allow duplicate key
  693. if (! $resql)
  694. {
  695. $err++;
  696. }
  697. */
  698. }
  699. $i++;
  700. }
  701. }
  702. return $err;
  703. }
  704. /**
  705. * Insert constants defined into $this->const array into table llx_const
  706. *
  707. * @return int Number of errors (0 if OK)
  708. */
  709. function insert_const()
  710. {
  711. global $conf;
  712. $err=0;
  713. foreach ($this->const as $key => $value)
  714. {
  715. $name = $this->const[$key][0];
  716. $type = $this->const[$key][1];
  717. $val = $this->const[$key][2];
  718. $note = isset($this->const[$key][3])?$this->const[$key][3]:'';
  719. $visible = isset($this->const[$key][4])?$this->const[$key][4]:0;
  720. $entity = (! empty($this->const[$key][5]) && $this->const[$key][5]!='current')?0:$conf->entity;
  721. // Clean
  722. if (empty($visible)) $visible='0';
  723. if (empty($val)) $val='';
  724. $sql = "SELECT count(*)";
  725. $sql.= " FROM ".MAIN_DB_PREFIX."const";
  726. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'";
  727. $sql.= " AND entity = ".$entity;
  728. $result=$this->db->query($sql);
  729. if ($result)
  730. {
  731. $row = $this->db->fetch_row($result);
  732. if ($row[0] == 0) // If not found
  733. {
  734. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)";
  735. $sql.= " VALUES (";
  736. $sql.= $this->db->encrypt($name,1);
  737. $sql.= ",'".$type."'";
  738. $sql.= ",".($val?$this->db->encrypt($val,1):"''");
  739. $sql.= ",".($note?"'".$this->db->escape($note)."'":"null");
  740. $sql.= ",'".$visible."'";
  741. $sql.= ",".$entity;
  742. $sql.= ")";
  743. dol_syslog(get_class($this)."::insert_const sql=".$sql);
  744. if (! $this->db->query($sql) )
  745. {
  746. dol_syslog(get_class($this)."::insert_const ".$this->db->lasterror(), LOG_ERR);
  747. $err++;
  748. }
  749. }
  750. else
  751. {
  752. dol_syslog(get_class($this)."::insert_const constant '".$name."' already exists", LOG_WARNING);
  753. }
  754. }
  755. else
  756. {
  757. $err++;
  758. }
  759. }
  760. return $err;
  761. }
  762. /**
  763. * Remove constants with tags deleteonunactive
  764. *
  765. * @return int <0 if KO, 0 if OK
  766. */
  767. function delete_const()
  768. {
  769. global $conf;
  770. $err=0;
  771. foreach ($this->const as $key => $value)
  772. {
  773. $name = $this->const[$key][0];
  774. $deleteonunactive = (! empty($this->const[$key][6]))?1:0;
  775. if ($deleteonunactive)
  776. {
  777. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  778. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'";
  779. $sql.= " AND entity in (0, ".$conf->entity.")";
  780. dol_syslog(get_class($this)."::delete_const sql=".$sql);
  781. if (! $this->db->query($sql))
  782. {
  783. $this->error=$this->db->lasterror();
  784. dol_syslog(get_class($this)."::delete_const ".$this->error, LOG_ERR);
  785. $err++;
  786. }
  787. }
  788. }
  789. return $err;
  790. }
  791. /**
  792. * Insert permissions definitions related to the module into llx_rights_def
  793. *
  794. * @param $reinitadminperms If 1, we also grant them to all admin users
  795. * @return int Number of error (0 if OK)
  796. */
  797. function insert_permissions($reinitadminperms=0)
  798. {
  799. global $conf,$user;
  800. $err=0;
  801. //print $this->rights_class." ".count($this->rights)."<br>";
  802. // Test if module is activated
  803. $sql_del = "SELECT ".$this->db->decrypt('value')." as value";
  804. $sql_del.= " FROM ".MAIN_DB_PREFIX."const";
  805. $sql_del.= " WHERE ".$this->db->decrypt('name')." = '".$this->const_name."'";
  806. $sql_del.= " AND entity IN (0,".$conf->entity.")";
  807. dol_syslog(get_class($this)."::insert_permissions sql=".$sql_del);
  808. $resql=$this->db->query($sql_del);
  809. if ($resql)
  810. {
  811. $obj=$this->db->fetch_object($resql);
  812. if ($obj->value)
  813. {
  814. // Si module actif
  815. foreach ($this->rights as $key => $value)
  816. {
  817. $r_id = $this->rights[$key][0];
  818. $r_desc = $this->rights[$key][1];
  819. $r_type = isset($this->rights[$key][2])?$this->rights[$key][2]:'';
  820. $r_def = $this->rights[$key][3];
  821. $r_perms = $this->rights[$key][4];
  822. $r_subperms = isset($this->rights[$key][5])?$this->rights[$key][5]:'';
  823. $r_modul = $this->rights_class;
  824. if (empty($r_type)) $r_type='w';
  825. if (dol_strlen($r_perms) )
  826. {
  827. if (dol_strlen($r_subperms) )
  828. {
  829. $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def";
  830. $sql.= " (id, entity, libelle, module, type, bydefault, perms, subperms)";
  831. $sql.= " VALUES ";
  832. $sql.= "(".$r_id.",".$conf->entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."','".$r_subperms."')";
  833. }
  834. else
  835. {
  836. $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def";
  837. $sql.= " (id, entity, libelle, module, type, bydefault, perms)";
  838. $sql.= " VALUES ";
  839. $sql.= "(".$r_id.",".$conf->entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.",'".$r_perms."')";
  840. }
  841. }
  842. else
  843. {
  844. $sql = "INSERT INTO ".MAIN_DB_PREFIX."rights_def ";
  845. $sql .= " (id, entity, libelle, module, type, bydefault)";
  846. $sql .= " VALUES ";
  847. $sql .= "(".$r_id.",".$conf->entity.",'".$this->db->escape($r_desc)."','".$r_modul."','".$r_type."',".$r_def.")";
  848. }
  849. dol_syslog(get_class($this)."::insert_permissions sql=".$sql, LOG_DEBUG);
  850. $resqlinsert=$this->db->query($sql,1);
  851. if (! $resqlinsert)
  852. {
  853. if ($this->db->errno() != "DB_ERROR_RECORD_ALREADY_EXISTS")
  854. {
  855. $this->error=$this->db->lasterror();
  856. dol_syslog(get_class($this)."::insert_permissions error ".$this->error, LOG_ERR);
  857. $err++;
  858. break;
  859. }
  860. else dol_syslog(get_class($this)."::insert_permissions record already exists", LOG_INFO);
  861. }
  862. $this->db->free($resqlinsert);
  863. // If we want to init permissions on admin users
  864. if ($reinitadminperms)
  865. {
  866. include_once(DOL_DOCUMENT_ROOT.'/user/class/user.class.php');
  867. $sql="SELECT rowid from ".MAIN_DB_PREFIX."user where admin = 1";
  868. dol_syslog(get_class($this)."::insert_permissions Search all admin users sql=".$sql);
  869. $resqlseladmin=$this->db->query($sql,1);
  870. if ($resqlseladmin)
  871. {
  872. $num=$this->db->num_rows($resqlseladmin);
  873. $i=0;
  874. while ($i < $num)
  875. {
  876. $obj2=$this->db->fetch_object($resqlseladmin);
  877. dol_syslog(get_class($this)."::insert_permissions Add permission to user id=".$obj2->rowid);
  878. $tmpuser=new User($this->db);
  879. $tmpuser->fetch($obj2->rowid);
  880. $tmpuser->addrights($r_id);
  881. $i++;
  882. }
  883. if (! empty($user->admin)) // Reload permission for current user if defined
  884. {
  885. // We reload permissions
  886. $user->clearrights();
  887. $user->getrights();
  888. }
  889. }
  890. else dol_print_error($this->db);
  891. }
  892. }
  893. }
  894. $this->db->free($resql);
  895. }
  896. else
  897. {
  898. $this->error=$this->db->lasterror();
  899. dol_syslog(get_class($this)."::insert_permissions ".$this->error, LOG_ERR);
  900. $err++;
  901. }
  902. return $err;
  903. }
  904. /**
  905. * Delete permissions
  906. *
  907. * @return int Nb of errors (0 if OK)
  908. */
  909. function delete_permissions()
  910. {
  911. global $conf;
  912. $err=0;
  913. $sql = "DELETE FROM ".MAIN_DB_PREFIX."rights_def";
  914. $sql.= " WHERE module = '".$this->rights_class."'";
  915. $sql.= " AND entity = ".$conf->entity;
  916. dol_syslog(get_class($this)."::delete_permissions sql=".$sql);
  917. if (! $this->db->query($sql))
  918. {
  919. $this->error=$this->db->lasterror();
  920. dol_syslog(get_class($this)."::delete_permissions ".$this->error, LOG_ERR);
  921. $err++;
  922. }
  923. return $err;
  924. }
  925. /**
  926. * Insert menus entries found into $this->menu into llx_menu*
  927. *
  928. * @return int Nb of errors (0 if OK)
  929. */
  930. function insert_menus()
  931. {
  932. require_once(DOL_DOCUMENT_ROOT."/core/class/menubase.class.php");
  933. $err=0;
  934. $this->db->begin();
  935. //var_dump($this->menu); exit;
  936. foreach ($this->menu as $key => $value)
  937. {
  938. $menu = new Menubase($this->db);
  939. $menu->menu_handler='all';
  940. $menu->module=$this->rights_class;
  941. if (! $this->menu[$key]['fk_menu'])
  942. {
  943. $menu->fk_menu=0;
  944. //print 'aaa'.$this->menu[$key]['fk_menu'];
  945. }
  946. else
  947. {
  948. //print 'xxx'.$this->menu[$key]['fk_menu'];exit;
  949. $foundparent=0;
  950. $fk_parent=$this->menu[$key]['fk_menu'];
  951. if (preg_match('/r=/',$fk_parent))
  952. {
  953. $fk_parent=str_replace('r=','',$fk_parent);
  954. if (isset($this->menu[$fk_parent]['rowid']))
  955. {
  956. $menu->fk_menu=$this->menu[$fk_parent]['rowid'];
  957. $foundparent=1;
  958. }
  959. }
  960. elseif (preg_match('/mainmenu=(.*),leftmenu=(.*)/',$fk_parent,$reg))
  961. {
  962. $menu->fk_menu=-1;
  963. $menu->fk_mainmenu=$reg[1];
  964. $menu->fk_leftmenu=$reg[2];
  965. $foundparent=1;
  966. }
  967. if (! $foundparent)
  968. {
  969. $this->error="ErrorBadDefinitionOfMenuArrayInModuleDescriptor (bad value for key fk_menu)";
  970. dol_syslog(get_class($this)."::insert_menus ".$this->error." ".$this->menu[$key]['fk_menu'], LOG_ERR);
  971. $err++;
  972. }
  973. }
  974. $menu->type=$this->menu[$key]['type'];
  975. $menu->mainmenu=$this->menu[$key]['mainmenu'];
  976. $menu->titre=$this->menu[$key]['titre'];
  977. $menu->leftmenu=isset($this->menu[$key]['leftmenu'])?$this->menu[$key]['leftmenu']:0;
  978. $menu->url=$this->menu[$key]['url'];
  979. $menu->langs=$this->menu[$key]['langs'];
  980. $menu->position=$this->menu[$key]['position'];
  981. $menu->perms=$this->menu[$key]['perms'];
  982. $menu->target=$this->menu[$key]['target'];
  983. $menu->user=$this->menu[$key]['user'];
  984. //$menu->constraint=$this->menu[$key]['constraint'];
  985. $menu->enabled=isset($this->menu[$key]['enabled'])?$this->menu[$key]['enabled']:0;
  986. if (! $err)
  987. {
  988. $result=$menu->create();
  989. if ($result > 0)
  990. {
  991. $this->menu[$key]['rowid']=$result;
  992. }
  993. else
  994. {
  995. $this->error=$menu->error;
  996. dol_syslog('DolibarrModules::insert_menus result='.$result." ".$this->error, LOG_ERR);
  997. $err++;
  998. break;
  999. }
  1000. }
  1001. }
  1002. if (! $err)
  1003. {
  1004. $this->db->commit();
  1005. }
  1006. else
  1007. {
  1008. dol_syslog(get_class($this)."::insert_menus ".$this->error, LOG_ERR);
  1009. $this->db->rollback();
  1010. }
  1011. return $err;
  1012. }
  1013. /**
  1014. * Remove menus entries
  1015. *
  1016. * @return int Nb of errors (0 if OK)
  1017. */
  1018. function delete_menus()
  1019. {
  1020. global $conf;
  1021. $err=0;
  1022. $sql = "DELETE FROM ".MAIN_DB_PREFIX."menu";
  1023. $sql.= " WHERE module = '".$this->db->escape($this->rights_class)."'";
  1024. $sql.= " AND entity = ".$conf->entity;
  1025. dol_syslog(get_class($this)."::delete_menus sql=".$sql);
  1026. $resql=$this->db->query($sql);
  1027. if (! $resql)
  1028. {
  1029. $this->error=$this->db->lasterror();
  1030. dol_syslog(get_class($this)."::delete_menus ".$this->error, LOG_ERR);
  1031. $err++;
  1032. }
  1033. return $err;
  1034. }
  1035. /**
  1036. * Create directories required by module
  1037. *
  1038. * @return int Nb of errors (0 if OK)
  1039. */
  1040. function create_dirs()
  1041. {
  1042. global $langs, $conf;
  1043. $err=0;
  1044. if (is_array($this->dirs))
  1045. {
  1046. foreach ($this->dirs as $key => $value)
  1047. {
  1048. $addtodatabase=0;
  1049. if (! is_array($value)) $dir=$value; // Default simple mode
  1050. else {
  1051. $constname = $this->const_name."_DIR_";
  1052. $dir = $this->dirs[$key][1];
  1053. $addtodatabase = empty($this->dirs[$key][2])?'':$this->dirs[$key][2]; // Create constante in llx_const
  1054. $subname = empty($this->dirs[$key][3])?'':strtoupper($this->dirs[$key][3]); // Add submodule name (ex: $conf->module->submodule->dir_output)
  1055. $forcename = empty($this->dirs[$key][4])?'':strtoupper($this->dirs[$key][4]); // Change the module name if different
  1056. if ($forcename) $constname = 'MAIN_MODULE_'.$forcename."_DIR_";
  1057. if ($subname) $constname = $constname.$subname."_";
  1058. $name = $constname.strtoupper($this->dirs[$key][0]);
  1059. }
  1060. // Define directory full path ($dir must start with "/")
  1061. if (empty($conf->global->MAIN_MODULE_MULTICOMPANY) || $conf->entity == 1) $fulldir = DOL_DATA_ROOT.$dir;
  1062. else $fulldir = DOL_DATA_ROOT."/".$conf->entity.$dir;
  1063. // Create dir if it does not exists
  1064. if ($fulldir && ! file_exists($fulldir))
  1065. {
  1066. if (create_exdir($fulldir) < 0)
  1067. {
  1068. $this->error = $langs->trans("ErrorCanNotCreateDir",$fulldir);
  1069. dol_syslog(get_class($this)."::_init ".$this->error, LOG_ERR);
  1070. $err++;
  1071. }
  1072. }
  1073. // Define the constant in database if requested (not the default mode)
  1074. if ($addtodatabase)
  1075. {
  1076. $result = $this->insert_dirs($name,$dir);
  1077. if ($result) $err++;
  1078. }
  1079. }
  1080. }
  1081. return $err;
  1082. }
  1083. /**
  1084. * Insert directories in llx_const
  1085. *
  1086. * @return int Nb of errors (0 if OK)
  1087. */
  1088. function insert_dirs($name,$dir)
  1089. {
  1090. global $conf;
  1091. $err=0;
  1092. $sql = "SELECT count(*)";
  1093. $sql.= " FROM ".MAIN_DB_PREFIX."const";
  1094. $sql.= " WHERE ".$this->db->decrypt('name')." = '".$name."'";
  1095. $sql.= " AND entity = ".$conf->entity;
  1096. dol_syslog(get_class($this)."::insert_dirs sql=".$sql);
  1097. $result=$this->db->query($sql);
  1098. if ($result)
  1099. {
  1100. $row = $this->db->fetch_row($result);
  1101. if ($row[0] == 0)
  1102. {
  1103. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (name,type,value,note,visible,entity)";
  1104. $sql.= " VALUES (".$this->db->encrypt($name,1).",'chaine',".$this->db->encrypt($dir,1).",'Directory for module ".$this->name."','0',".$conf->entity.")";
  1105. dol_syslog(get_class($this)."::insert_dirs sql=".$sql);
  1106. $resql=$this->db->query($sql);
  1107. }
  1108. }
  1109. else
  1110. {
  1111. $this->error=$this->db->lasterror();
  1112. dol_syslog(get_class($this)."::insert_dirs ".$this->error, LOG_ERR);
  1113. $err++;
  1114. }
  1115. return $err;
  1116. }
  1117. /**
  1118. * Remove directory entries
  1119. *
  1120. * @return int Nb of errors (0 if OK)
  1121. */
  1122. function delete_dirs()
  1123. {
  1124. global $conf;
  1125. $err=0;
  1126. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  1127. $sql.= " WHERE ".$this->db->decrypt('name')." like '".$this->const_name."_DIR_%'";
  1128. $sql.= " AND entity = ".$conf->entity;
  1129. dol_syslog(get_class($this)."::delete_dirs sql=".$sql);
  1130. if (! $this->db->query($sql))
  1131. {
  1132. $this->error=$this->db->lasterror();
  1133. dol_syslog(get_class($this)."::delete_dirs ".$this->error, LOG_ERR);
  1134. $err++;
  1135. }
  1136. return $err;
  1137. }
  1138. /**
  1139. * Insert activation triggers from modules in llx_const
  1140. *
  1141. * @return int Nb of errors (0 if OK)
  1142. */
  1143. function insert_triggers()
  1144. {
  1145. global $conf;
  1146. $err=0;
  1147. if (! empty($this->triggers))
  1148. {
  1149. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
  1150. $sql.= "name";
  1151. $sql.= ", type";
  1152. $sql.= ", value";
  1153. $sql.= ", note";
  1154. $sql.= ", visible";
  1155. $sql.= ", entity";
  1156. $sql.= ")";
  1157. $sql.= " VALUES (";
  1158. $sql.= $this->db->encrypt($this->const_name."_TRIGGERS",1);
  1159. $sql.= ", 'chaine'";
  1160. $sql.= ", ".$this->db->encrypt($this->triggers,1);
  1161. $sql.= ", null";
  1162. $sql.= ", '0'";
  1163. $sql.= ", ".$conf->entity;
  1164. $sql.= ")";
  1165. dol_syslog(get_class($this)."::insert_triggers sql=".$sql);
  1166. $resql=$this->db->query($sql);
  1167. if (! $resql)
  1168. {
  1169. $this->error=$this->db->lasterror();
  1170. dol_syslog(get_class($this)."::insert_triggers ".$this->error);
  1171. }
  1172. }
  1173. return $err;
  1174. }
  1175. /**
  1176. * Remove activation triggers from modules in llx_const
  1177. *
  1178. * @return int Nb of errors (0 if OK)
  1179. */
  1180. function delete_triggers()
  1181. {
  1182. global $conf;
  1183. $err=0;
  1184. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  1185. $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_TRIGGERS'";
  1186. $sql.= " AND entity = ".$conf->entity;
  1187. dol_syslog(get_class($this)."::delete_triggers sql=".$sql);
  1188. if (! $this->db->query($sql))
  1189. {
  1190. $this->error=$this->db->lasterror();
  1191. dol_syslog(get_class($this)."::delete_triggers ".$this->error, LOG_ERR);
  1192. $err++;
  1193. }
  1194. return $err;
  1195. }
  1196. /**
  1197. * Insert activation login method from modules in llx_const
  1198. *
  1199. * @return int Number of errors (0 if ok)
  1200. */
  1201. function insert_login_method()
  1202. {
  1203. global $conf;
  1204. $err=0;
  1205. if (! empty($this->login_method))
  1206. {
  1207. $sql = "INSERT INTO ".MAIN_DB_PREFIX."const (";
  1208. $sql.= "name";
  1209. $sql.= ", type";
  1210. $sql.= ", value";
  1211. $sql.= ", note";
  1212. $sql.= ", visible";
  1213. $sql.= ", entity";
  1214. $sql.= ")";
  1215. $sql.= " VALUES (";
  1216. $sql.= $this->db->encrypt($this->const_name."_LOGIN_METHOD",1);
  1217. $sql.= ", 'chaine'";
  1218. $sql.= ", ".$this->db->encrypt($this->login_method,1);
  1219. $sql.= ", null";
  1220. $sql.= ", '0'";
  1221. $sql.= ", ".$conf->entity;
  1222. $sql.= ")";
  1223. dol_syslog(get_class($this)."::insert_login_method sql=".$sql);
  1224. $resql=$this->db->query($sql);
  1225. if (! $resql)
  1226. {
  1227. $this->error=$this->db->lasterror();
  1228. dol_syslog(get_class($this)."::insert_login_method ".$this->error);
  1229. }
  1230. }
  1231. return $err;
  1232. }
  1233. /**
  1234. * Remove activation login method from modules in llx_const
  1235. *
  1236. * @return int Nombre d'erreurs (0 si ok)
  1237. */
  1238. function delete_login_method()
  1239. {
  1240. global $conf;
  1241. $err=0;
  1242. $sql = "DELETE FROM ".MAIN_DB_PREFIX."const";
  1243. $sql.= " WHERE ".$this->db->decrypt('name')." LIKE '".$this->const_name."_LOGIN_METHOD'";
  1244. $sql.= " AND entity = ".$conf->entity;
  1245. dol_syslog(get_class($this)."::delete_login_method sql=".$sql);
  1246. if (! $this->db->query($sql))
  1247. {
  1248. $this->error=$this->db->lasterror();
  1249. dol_syslog(get_class($this)."::delete_login_method ".$this->error, LOG_ERR);
  1250. $err++;
  1251. }
  1252. return $err;
  1253. }
  1254. }
  1255. ?>