cb.installer.php
上传用户:stephen_wu
上传日期:2008-07-05
资源大小:1757k
文件大小:46k
源码类别:

网络

开发平台:

Unix_Linux

  1. <?php
  2. /**
  3. * Joomla Community Builder : Plugin Handler
  4. * @version $Id: library/cb/cb.params.php 610 2006-12-13 17:33:44Z beat $
  5. * @package Community Builder
  6. * @subpackage cb.params.php
  7. * @author various, JoomlaJoe and Beat
  8. * @copyright (C) Beat and JoomlaJoe, www.joomlapolis.com and various
  9. * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU/GPL version 2
  10. */
  11. // ensure this file is being included by a parent file
  12. if ( ! ( defined( '_VALID_CB' ) || defined( '_JEXEC' ) || defined( '_VALID_MOS' ) ) ) { die( 'Direct Access to this location is not allowed.' ); }
  13. /**
  14. * Installer class
  15. * @package Community Builder
  16. * @subpackage Installer
  17. * @abstract
  18. */
  19. class cbInstaller {
  20. // name of the XML file with installation information
  21. var $i_installfilename = "";
  22. var $i_installarchive = "";
  23. var $i_installdir = "";
  24. var $i_iswin = false;
  25. var $i_errno = 0;
  26. var $i_error = "";
  27. var $i_installtype = "";
  28. var $i_unpackdir = "";
  29. var $i_docleanup = true;
  30. /** @var string The directory where the element is to be installed */
  31. var $i_elementdir = '';
  32. /** @var string The name of the Mambo element */
  33. var $i_elementname = '';
  34. /** @var string The name of a special atttibute in a tag */
  35. var $i_elementspecial = '';
  36. /** @var object A DOMIT XML document */
  37. var $i_xmldocument = null;
  38. var $i_hasinstallfile = null;
  39. var $i_installfile = null;
  40. /**
  41. * Constructor
  42. */
  43. function cbInstaller() {
  44. cbimport( 'cb.adminfilesystem' );
  45. $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
  46. }
  47. /**
  48. * Uploads and unpacks a file
  49. * @param string The uploaded package filename or install directory
  50. * @param boolean True if the file is an archive file
  51. * @return boolean True on success, False on error
  52. */
  53. function upload($p_filename = null, $p_unpack = true, $p_findinstallfile = true ) {
  54. $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
  55. $this->installArchive( $p_filename );
  56. if ($p_unpack) {
  57. if ($this->extractArchive()) {
  58. if ( $p_findinstallfile ) {
  59. return $this->findInstallFile();
  60. } else {
  61. return true;
  62. }
  63. } else {
  64. return false;
  65. }
  66. } else {
  67. return false;
  68. }
  69. }
  70. /**
  71. * Extracts the package archive file
  72. * @return boolean True on success, False on error
  73. */
  74. function extractArchive() {
  75. global $_CB_framework;
  76. $base_Dir = _cbPathName( $_CB_framework->getCfg('tmp_path') );
  77. $archivename = $this->installArchive();
  78. $tmpdir = uniqid( 'install_' );
  79. $extractdir = _cbPathName( $base_Dir . $tmpdir );
  80. $archivename = _cbPathName( $archivename, false );
  81. $this->unpackDir( $extractdir );
  82. if ( preg_match( "/\.zip$/i", $archivename ) ) {
  83. // Extract functions
  84. cbimport( 'pcl.pclziplib' );
  85. $zipfile = new PclZip( $archivename );
  86. if($this->isWindows()) {
  87. define('OS_WINDOWS',1);
  88. } else {
  89. define('OS_WINDOWS',0);
  90. }
  91. $ret = $zipfile->extract( PCLZIP_OPT_PATH, $extractdir );
  92. if($ret == 0) {
  93. $this->setError( 1, 'Unrecoverable error "'.$zipfile->errorName(true).'"' );
  94. return false;
  95. }
  96. } else {
  97. cbimport( 'pcl.tar' ); // includes/Archive/Tar.php' );
  98. $archive =& new Archive_Tar( $archivename );
  99. $archive->setErrorHandling( PEAR_ERROR_PRINT );
  100. if ( ! $archive->extractModify( $extractdir, '' ) ) {
  101. $this->setError( 1, 'Extract Error' );
  102. return false;
  103. }
  104. }
  105. $this->installDir( $extractdir );
  106. // Try to find the correct install dir. in case that the package have subdirs
  107. // Save the install dir for later cleanup
  108. $filesindir = cbReadDirectory( $this->installDir(), '' );
  109. if ( count( $filesindir ) == 1 ) {
  110. if ( is_dir( $extractdir . $filesindir[0] ) ) {
  111. $this->installDir( _cbPathName( $extractdir . $filesindir[0] ) );
  112. }
  113. }
  114. return true;
  115. }
  116. /**
  117. * Tries to find the package XML file
  118. * @return boolean True on success, False on error
  119. */
  120. function findInstallFile() {
  121. $found = false;
  122. // Search the install dir for an xml file
  123. $files = cbReadDirectory( $this->installDir(), '.xml$', true, false );
  124. if (count( $files ) > 0) {
  125. foreach ($files as $file) {
  126. $packagefile =& $this->isPackageFile( $this->installDir() . $file );
  127. if (!is_null( $packagefile ) && !$found ) {
  128. $this->i_xmldocument =& $packagefile;
  129. return true;
  130. }
  131. }
  132. $this->setError( 1, 'ERROR: Could not find a CB XML setup file in the package.' );
  133. return false;
  134. } else {
  135. $this->setError( 1, 'ERROR: Could not find an XML setup file in the package.' );
  136. return false;
  137. }
  138. }
  139. /**
  140. * @param string A file path
  141. * @return object A DOMIT XML document, or null if the file failed to parse
  142. */
  143. function & isPackageFile( $p_file ) {
  144. $null = null;
  145. if ( ! file_exists( $p_file ) ) {
  146. return $null;
  147. }
  148. cbimport('cb.xml.simplexml');
  149. $xmlString = trim( file_get_contents( $p_file ) );
  150. $element =& new CBSimpleXMLElement( $xmlString );
  151. if ( count( $element->children() ) == 0 ) {
  152. return $null;
  153. }
  154. if ( $element->name() != 'cbinstall' ) {
  155. //echo "didn't find cbinstall";
  156. return $null;
  157. }
  158. // Set the type
  159. //echo "<br />element->attributes( 'type' )=".$element->attributes( 'type' );
  160. $this->installType( $element->attributes( 'type' ) );
  161. $this->installFilename( $p_file );
  162. return $element;
  163. }
  164. /**
  165. * Loads and parses the XML setup file
  166. * @return boolean True on success, False on error
  167. */
  168. function readInstallFile() {
  169. if ($this->installFilename() == "") {
  170. $this->setError( 1, 'No filename specified' );
  171. return false;
  172. }
  173. cbimport('cb.xml.simplexml');
  174. if ( file_exists( $this->installFilename() ) ) {
  175. $xmlString = trim( file_get_contents( $this->installFilename() ) );
  176. $this->i_xmldocument =& new CBSimpleXMLElement( $xmlString );
  177. if ( count( $this->i_xmldocument->children() ) == 0 ) {
  178. return false;
  179. }
  180. }
  181. $main_element =& $this->i_xmldocument;
  182. // Check that it's am installation file
  183. if ($main_element->name() != 'cbinstall') {
  184. $this->setError( 1, 'File :"' . $this->installFilename() . '" is not a valid Joomla installation file' );
  185. return false;
  186. }
  187. //echo "<br />main_element->attributes( 'type' )=".$main_element->attributes( 'type' );
  188. $this->installType( $main_element->attributes( 'type' ) );
  189. return true;
  190. }
  191. /**
  192. * Abstract install method
  193. */
  194. function install() {
  195. die( 'Method "install" cannot be called by class ' . strtolower(get_class( $this )) );
  196. }
  197. /**
  198. * Abstract uninstall method
  199. */
  200. function uninstall() {
  201. die( 'Method "uninstall" cannot be called by class ' . strtolower(get_class( $this )) );
  202. }
  203. /**
  204. * return to method
  205. */
  206. function returnTo( $option, $task ) {
  207. return "index2.php?option=$option&task=$task";
  208. }
  209. /**
  210. * @param string Install from directory
  211. * @param string The install type
  212. * @return boolean
  213. */
  214. function preInstallCheck( $p_fromdir, $type='plugin' ) {
  215. if (!is_null($p_fromdir)) {
  216. $this->installDir($p_fromdir);
  217. }
  218. if (!$this->installfile()) {
  219. $this->findInstallFile();
  220. }
  221. if (!$this->readInstallFile()) {
  222. $this->setError( 1, 'Installation file not found:<br />' . $this->installDir() );
  223. return false;
  224. }
  225. //echo "<br />type=".$type." this->installType()=".$this->installType();
  226. if (trim($this->installType()) != trim($type)) {
  227. //echo "<br />failing here<br />";
  228. $this->setError( 1, 'XML setup file is not for a "'.$type.'".' );
  229. return false;
  230. }
  231. // In case there where an error doring reading or extracting the archive
  232. if ($this->errno()) {
  233. return false;
  234. }
  235. return true;
  236. }
  237. /**
  238. * @param string The tag name to parse
  239. * @param string An attribute to search for in a filename element
  240. * @param string The value of the 'special' element if found
  241. * @param boolean True for Administrator components
  242. * @return mixed Number of file or False on error
  243. */
  244. function parseFiles( $tagName='files', $special='', $specialError='', $adminFiles=0 ) {
  245. global $_CB_framework;
  246. // Find files to copy
  247. $cbInstallXML =& $this->i_xmldocument;
  248. $files_element =& $cbInstallXML->getElementByPath( $tagName );
  249. if ( ! ( $files_element )) {
  250. return 0;
  251. }
  252. if ( count( $files_element->children() ) == 0 ) {
  253. // no files
  254. return 0;
  255. }
  256. $copyfiles = array();
  257. $folder = $files_element->attributes( 'folder' );
  258. if ( $folder ) {
  259. $temp  = _cbPathName( $this->unpackDir() . $folder );
  260. if ($temp == $this->installDir()) {
  261. // this must be only an admin component
  262. $installFrom = $this->installDir();
  263. } else {
  264. $installFrom = _cbPathName( $this->installDir() . $folder );
  265. }
  266. } else {
  267. $installFrom = $this->installDir();
  268. }
  269. foreach ( $files_element->children() as $file ) {
  270. if ( basename( $file->data() ) != $file->data() ) {
  271. $newdir = dirname( $file->data() );
  272. if ( $adminFiles ) {
  273. if ( ! $this->mosMakePath( $this->componentAdminDir(), $newdir ) ) {
  274. $this->setError( 1, 'Failed to create directory "' . ($this->componentAdminDir()) . $newdir . '"' );
  275. return false;
  276. }
  277. } else {
  278. if ( ! $this->mosMakePath( $this->elementDir(), $newdir ) ) {
  279. $this->setError( 1, 'Failed to create directory "' . ($this->elementDir()) . $newdir . '"' );
  280. return false;
  281. }
  282. }
  283. }
  284. $copyfiles[] = $file->data();
  285. // check special for attribute
  286. if ( $file->attributes( $special ) ) {
  287. $this->elementSpecial( $file->attributes( $special ) );
  288. }
  289. }
  290. if ( $specialError ) {
  291. if ( $this->elementSpecial() == '' ) {
  292. $this->setError( 1, $specialError );
  293. return false;
  294. }
  295. }
  296. if ( $tagName == 'media' ) {
  297. // media is a special tag
  298. $installTo = _cbPathName( $_CB_framework->getCfg('absolute_path') . '/images/stories' );
  299. } else if ($adminFiles) {
  300. $installTo = $this->componentAdminDir();
  301. } else {
  302. $installTo = $this->elementDir();
  303. }
  304. $result = $this->copyFiles( $installFrom, $installTo, $copyfiles );
  305. return $result;
  306. }
  307. /**
  308. * @param string Source directory
  309. * @param string Destination directory
  310. * @param array array with filenames
  311. * @param boolean True is existing files can be replaced
  312. * @return boolean True on success, False on error
  313. */
  314. function copyFiles( $p_sourcedir, $p_destdir, $p_files, $overwrite=false ) {
  315. global $_CB_framework;
  316. if (is_array( $p_files ) && count( $p_files ) > 0) {
  317. $adminFS =& cbAdminFileSystem::getInstance();
  318. $filePerms = $_CB_framework->getCfg( 'fileperms' );
  319. $dirPerms = $_CB_framework->getCfg( 'dirperms' );
  320. if ( $filePerms ) {
  321. $filePerms = octdec( $filePerms );
  322. } else {
  323. $filePerms = null;
  324. }
  325. if ( $dirPerms ) {
  326. $dirPerms = octdec( $dirPerms );
  327. } else {
  328. $dirPerms = null;
  329. }
  330. foreach($p_files as $_file) {
  331. $filesource = _cbPathName( _cbPathName( $p_sourcedir ) . $_file, false );
  332. $filedest = _cbPathName( _cbPathName( $p_destdir ) . $_file, false );
  333. if ( ! file_exists( $filesource ) ) {
  334. $this->setError( 1, "File $filesource does not exist!" );
  335. return false;
  336. } else if ( file_exists( $filedest ) && ! $overwrite ) {
  337. $this->setError( 1, "There is already a file called $filedest - Are you trying to install the same Plugin twice?" );
  338. return false;
  339. } else if ( ! $adminFS->copy( $filesource, $filedest ) ) {
  340. $this->setError( 1, "Failed to copy file: $filesource to $filedest" );
  341. return false;
  342. } else {
  343. if ( is_dir( $filesource ) && $dirPerms ) {
  344. $perms = $dirPerms;
  345. } elseif ( is_file( $filesource ) && $filePerms ) {
  346. $perms = $filePerms;
  347. } else {
  348. $perms = null;
  349. }
  350. if ( $perms && ! $adminFS->chmod( $filedest, $perms ) ) {
  351. $this->setError( 1, "Failed to chmod file: $filedest" );
  352. return false;
  353. }
  354. }
  355. }
  356. } else {
  357. return false;
  358. }
  359. return count( $p_files );
  360. }
  361. /**
  362. * Copies the XML setup file to the element Admin directory
  363. * Used by Plugin Installer
  364. * @return boolean True on success, False on error
  365. */
  366. function copySetupFile( $where='admin' ) {
  367. if ($where == 'admin') {
  368. return $this->copyFiles( $this->installDir(), $this->componentAdminDir(), array( basename( $this->installFilename() ) ), true );
  369. } else if ($where == 'front') {
  370. return $this->copyFiles( $this->installDir(), $this->elementDir(), array( basename( $this->installFilename() ) ), true );
  371. }
  372. return false;
  373. }
  374. /**
  375. * @param int The error number
  376. * @param string The error message
  377. */
  378. function setError( $p_errno, $p_error ) {
  379. $this->errno( $p_errno );
  380. $this->error( $p_error );
  381. }
  382. /**
  383. * @param boolean True to display both number and message
  384. * @param string The error message
  385. * @return string
  386. */
  387. function getError($p_full = false) {
  388. if ($p_full) {
  389. return $this->errno() . " " . $this->error();
  390. } else {
  391. return $this->error();
  392. }
  393. }
  394. /**
  395. * @param string The name of the property to set/get
  396. * @param mixed The value of the property to set
  397. * @return The value of the property
  398. */
  399. function setVar( $name, $value=null ) {
  400. if (!is_null( $value )) {
  401. $this->$name = $value;
  402. }
  403. return $this->$name;
  404. }
  405. function installFilename( $p_filename = null ) {
  406. if(!is_null($p_filename)) {
  407. if($this->isWindows()) {
  408. $this->i_installfilename = str_replace('/','\',$p_filename);
  409. } else {
  410. $this->i_installfilename = str_replace('\','/',$p_filename);
  411. }
  412. }
  413. return $this->i_installfilename;
  414. }
  415. function installType( $p_installtype = null ) {
  416. return $this->setVar( 'i_installtype', $p_installtype );
  417. }
  418. function error( $p_error = null ) {
  419. return $this->setVar( 'i_error', $p_error );
  420. }
  421. function installArchive( $p_filename = null ) {
  422. return $this->setVar( 'i_installarchive', $p_filename );
  423. }
  424. function installDir( $p_dirname = null ) {
  425. return $this->setVar( 'i_installdir', $p_dirname );
  426. }
  427. function unpackDir( $p_dirname = null ) {
  428. return $this->setVar( 'i_unpackdir', $p_dirname );
  429. }
  430. function isWindows() {
  431. return $this->i_iswin;
  432. }
  433. function errno( $p_errno = null ) {
  434. return $this->setVar( 'i_errno', $p_errno );
  435. }
  436. function hasInstallfile( $p_hasinstallfile = null ) {
  437. return $this->setVar( 'i_hasinstallfile', $p_hasinstallfile );
  438. }
  439. function installfile( $p_installfile = null ) {
  440. return $this->setVar( 'i_installfile', $p_installfile );
  441. }
  442. function elementDir( $p_dirname = null ) {
  443. return $this->setVar( 'i_elementdir', $p_dirname );
  444. }
  445. function elementName( $p_name = null ) {
  446. return $this->setVar( 'i_elementname', $p_name );
  447. }
  448. function elementSpecial( $p_name = null ) {
  449. return $this->setVar( 'i_elementspecial', $p_name );
  450. }
  451. /**
  452. * Warning: needs cbAdminFileSystem  File-system loaded to use
  453. * @param  string  $base  An existing base path
  454. * @param  string  $path  A path to create from the base path
  455. * @param  int     $mode  Directory permissions
  456. * @return boolean         True if successful
  457. */
  458. function mosMakePath( $base, $path='', $mode = null ) {
  459. global $_CB_framework;
  460. // convert windows paths
  461. $path = preg_replace( "/(\/){2,}|(\\){1,}/",'/', $path );
  462. // check if dir exists
  463. if ( file_exists( $base . $path ) ) {
  464. return true;
  465. }
  466. // set mode
  467. $origmask = null;
  468. if ( isset( $mode ) ) {
  469. $origmask = @umask(0);
  470. } else {
  471. if ( $_CB_framework->getCfg( 'dirperms' ) == '' ) {
  472. // rely on umask
  473. $mode = 0755; // 0777;
  474. } else {
  475. $origmask = @umask( 0 );
  476. $mode = octdec( $_CB_framework->getCfg( 'dirperms' ) );
  477. }
  478. }
  479. $ret = true;
  480. if ( $path == '' ) {
  481. while ( substr( $base, -1, 1 ) == '/' ) {
  482. $base = substr( $base, 0, -1 );
  483. }
  484. $adminFS =& cbAdminFileSystem::getInstance();
  485. $ret = $adminFS->mkdir( $base, $mode );
  486. } else {
  487. $parts = explode( '/', $path );
  488. $n = count( $parts );
  489. $path = $base;
  490. for ( $i = 0 ; $i < $n ; $i++ ) {
  491. $path .= $parts[$i];
  492. if ( ! file_exists( $path ) ) {
  493. $adminFS =& cbAdminFileSystem::getInstance();
  494. if ( ! $adminFS->mkdir( $path, $mode ) ) {
  495. $ret = false;
  496. break;
  497. }
  498. }
  499. $path .= '/';
  500. }
  501. }
  502. if ( isset( $origmask ) ) {
  503. @umask( $origmask );
  504. }
  505. return $ret;
  506. }
  507. } // end class cbInstaller
  508. function cleanupInstall( $userfile_name, $resultdir) {
  509. if ( file_exists( $resultdir ) ) {
  510. $adminFS =& cbAdminFileSystem::getInstance();
  511. $adminFS->deldir( $resultdir );
  512. if ( $userfile_name ) {
  513. $adminFS->unlink( _cbPathName( $userfile_name, false ) );
  514. }
  515. }
  516. }
  517. class cbInstallerPlugin extends cbInstaller {
  518. /** @var string The element type */
  519. var $elementType = 'plugin';
  520. var $checkdbErrors = null;
  521. var $checkdbLogs = null;
  522. /**
  523. * Constructor
  524. */
  525. function cbInstallerPlugin() {
  526. $this->cbInstaller();
  527. }
  528. /**
  529. * Custom install method
  530. * @param boolean True if installing from directory
  531. */
  532. function install( $p_fromdir = null ) {
  533. global $_CB_framework, $_CB_database, $ueConfig, $_PLUGINS;
  534.         
  535. if (!$this->preInstallCheck( $p_fromdir,$this->elementType )) {
  536. return false;
  537. }
  538. $cbInstallXML =& $this->i_xmldocument;
  539. // Get name
  540. $e = &$cbInstallXML->getElementByPath( 'name' );
  541. $this->elementName( $e->data() );
  542. $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
  543. // Get plugin filename
  544. $files_element = &$cbInstallXML->getElementByPath( 'files' );
  545. foreach ( $files_element->children() as $file ) {
  546. if ($file->attributes( "plugin" )) {
  547. $this->elementSpecial( $file->attributes( "plugin" ) );
  548. }
  549. }
  550. $fileNopathNoext = null;
  551. $matches = array();
  552. if ( preg_match("/^.*[\/\\](.*)\..*$/", $this->installFilename(), $matches ) ) {
  553. $fileNopathNoext = $matches[1];
  554. }
  555. if ( ! ( $fileNopathNoext && ( $this->elementSpecial() == $fileNopathNoext ) ) ) {
  556. $this->setError( 1, 'Installation filename `' . $fileNopathNoext . '` (with .xml) does not match main php file plugin attribute `'  . $this->elementSpecial() . '` in the plugin xml file<br />' );
  557. return false;
  558. }
  559. $cleanedMainFileName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementSpecial()));
  560. // check version
  561. $v = &$cbInstallXML->getElementByPath( 'version' );
  562. $version = $v->data();
  563. if (($version == $ueConfig['version']) || ($version=="1.2 RC" || $version=="1.0 RC 2" || $version=="1.0" || $version=="1.0.1" || $version=="1.0.2" || $version=="1.1")) {
  564. ;
  565. } else {
  566.        $this->setError( 1, 'Plugin version ('.$version.') different from Community Builder version ('.$ueConfig['version'].')' );
  567. return false;
  568.      }
  569.      $backendMenu = "";
  570.      $adminmenusnode =& $cbInstallXML->getElementByPath( 'adminmenus' );
  571. if ( $adminmenusnode ) {
  572. $menusArr = array();
  573. //cycle through each menu
  574. foreach( $adminmenusnode->children() AS $menu ) {
  575. if ( $menu->name() == "menu" ) {
  576. $action = $menu->attributes('action');
  577. $text = getLangDefinition($menu->data());
  578. $menusArr[] = $text . ":" . $action;
  579. }
  580. }
  581. $backendMenu = implode( ",", $menusArr );
  582. }
  583. $folder = strtolower($cbInstallXML->attributes( 'group' ));
  584. $subFolderPrefix = ( ( $folder == "user" ) ? "plug_" : "" );
  585. $subFolder = $subFolderPrefix . $cleanedElementName;
  586. $this->elementDir( $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $folder . "/" . $subFolder . "/" );
  587. if (file_exists($this->elementDir())) {
  588.        $this->setError( 1, 'Another plugin is already using directory: "' . $this->elementDir() . '"' );
  589. return false;
  590.      }
  591. if(!file_exists($this->elementDir()) && !$this->mosMakePath($this->elementDir())) {
  592. $this->setError( 1, 'Failed to create directory' .' "' . $this->elementDir() . '"' );
  593. return false;
  594. }
  595. // Copy files from package:
  596. if ($this->parseFiles( 'files', 'plugin', 'No file is marked as plugin file' ) === false) {
  597. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  598. return false;
  599. }
  600. // Check to see if plugin already exists in db
  601. $_CB_database->setQuery( "SELECT id FROM #__comprofiler_plugin WHERE element = '" . $this->elementSpecial() . "' AND folder = '" . $subFolder . "'" );
  602. if (!$_CB_database->query()) {
  603. $this->setError( 1, 'SQL error' .': ' . $_CB_database->stderr( true ) );
  604. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  605. return false;
  606. }
  607. $pluginid  = $_CB_database->loadResult();
  608. $pluginRowWasNotExisting = ( ! $pluginid );
  609. $row = new moscomprofilerPlugin( $_CB_database );
  610. $row->id = $pluginid;
  611. if ( ! $pluginid ) {
  612. $row->name = $this->elementName();
  613. $row->ordering = 99;
  614. }
  615. $row->type = $folder;
  616. if ( $row->type == 'language' ) {
  617. $row->published = 1;
  618. }
  619. $row->folder = $subFolder;
  620. $row->backend_menu = $backendMenu;
  621. $row->iscore = 0;
  622. $row->access = 0;
  623. $row->client_id = 0;
  624. $row->element = $this->elementSpecial();
  625. if (!$row->store()) {
  626. $this->setError( 1, 'SQL error' .': ' . $row->getError() );
  627. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  628. return false;
  629. }
  630. if ( ! $pluginid ) {
  631. $pluginid = $_CB_database->insertid();
  632. }
  633. $_PLUGINS->_setLoading( $row, true );
  634. // Are there any Database statements ??
  635. $db =& $cbInstallXML->getElementByPath( 'database' );
  636. if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
  637. cbimport( 'cb.sql.upgrader' );
  638. $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
  639. //$sqlUpgrader->setDryRun( true );
  640. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, true, null );
  641. /*
  642. var_dump( $success );
  643. echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
  644. echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
  645. exit;
  646. */
  647. if ( ! $success ) {
  648. $this->setError( 1, "Plugin database XML SQL Error " .  $sqlUpgrader->getErrors() );
  649. if ( $pluginRowWasNotExisting ) {
  650. $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
  651. $row->delete();
  652. }
  653. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  654. return false;
  655. }
  656. }
  657. $e =& $cbInstallXML->getElementByPath( 'description' );
  658. if ( $e !== false ) {
  659. $desc = $this->elementName() . '<div>' . $e->data() . '</div>';
  660. $this->setError( 0, $desc );
  661. }
  662. //If type equals user then check for tabs and fields
  663. if ( $folder == 'user' ) {
  664. $tabsnode =& $cbInstallXML->getElementByPath( 'tabs' );
  665. if( $tabsnode ) {
  666. //cycle through each tab
  667. foreach( $tabsnode->children() AS $tab ) {
  668. if ( $tab->name() == 'tab' ) {
  669. //install each tab
  670. $tabid = $this->installTab($pluginid,$tab);
  671. if ( $tabid ) {
  672. //get all fields in the tab
  673. $fieldsnode = $tab->getElementByPath( 'fields' );
  674. if ( $fieldsnode ) {
  675. //cycle through each field
  676. foreach( $fieldsnode->children() AS $field ) {
  677. if ($field->name() == "field") {
  678. //install each field
  679. //echo "installing field...";
  680. $fieldid = $this->installField($pluginid,$tabid,$field);
  681. //get all fieldvalues for the field
  682. //cycle through each fieldValue
  683. foreach( $field->children() AS $fieldValue) {
  684. if ( $fieldValue->name() == "fieldvalue" ) {
  685. $this->installFieldValue($fieldid,$fieldValue);
  686. }
  687. }
  688. }
  689. }
  690. }
  691. } else {
  692. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  693. return false;
  694. }
  695. }
  696. }
  697. }
  698. // (re)install field types of plugin:
  699. $fieldtypes =& $cbInstallXML->getElementByPath( 'fieldtypes' );
  700. if( $fieldtypes ) {
  701. foreach ( $fieldtypes->children() as $typ ) {
  702. if ( $typ->name() == 'field' ) {
  703. $this->installFieldType( $pluginid, $typ->attributes( 'type' ) );
  704. }
  705. }
  706. }
  707. }
  708. // Are there any SQL queries??
  709. $query_element =& $cbInstallXML->getElementByPath( 'install/queries' );
  710. if ( $query_element ) {
  711. foreach( $query_element->children() as $query ) {
  712. $_CB_database->setQuery( trim( $query->data() ) );
  713. if ( ! $_CB_database->query() )
  714. {
  715. $this->setError( 1, "SQL Error " . $_CB_database->stderr( true ) );
  716. if ( $pluginRowWasNotExisting ) {
  717. if ( $db ) {
  718. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
  719. }
  720. $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
  721. $row->delete();
  722. }
  723. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  724. return false;
  725. }
  726. }
  727. }
  728. // Is there an installfile
  729. $installfile_elemet =& $cbInstallXML->getElementByPath( 'installfile' );
  730. if ( $installfile_elemet ) {
  731. // check if parse files has already copied the install.component.php file (error in 3rd party xml's!)
  732. if ( ! file_exists( $this->elementDir() . $installfile_elemet->data() ) ) {
  733. if( ! $this->copyFiles( $this->installDir(), $this->elementDir(), array( $installfile_elemet->data() ) ) ) {
  734. $this->setError( 1, 'Could not copy PHP install file.' );
  735. if ( $pluginRowWasNotExisting ) {
  736. if ( $db ) {
  737. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
  738. }
  739. $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
  740. $row->delete();
  741. }
  742. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  743. return false;
  744. }
  745. }
  746. $this->hasInstallfile( true );
  747. $this->installFile( $installfile_elemet->data() );
  748. }
  749. // Is there an uninstallfile
  750. $uninstallfile_elemet =& $cbInstallXML->getElementByPath( 'uninstallfile' );
  751. if( $uninstallfile_elemet ) {
  752. if ( ! file_exists( $this->elementDir() . $uninstallfile_elemet->data() ) ) {
  753. if( ! $this->copyFiles( $this->installDir(), $this->elementDir(), array( $uninstallfile_elemet->data() ) ) ) {
  754. $this->setError( 1, 'Could not copy PHP uninstall file' );
  755. if ( $pluginRowWasNotExisting ) {
  756. if ( $db ) {
  757. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
  758. }
  759. $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
  760. $row->delete();
  761. }
  762. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  763. return false;
  764. }
  765. }
  766. }
  767. if ( $this->hasInstallfile() ) {
  768. if ( is_file( $this->elementDir() . '/' . $this->installFile() ) ) {
  769. require_once( $this->elementDir() . "/" . $this->installFile() );
  770. $ret = call_user_func_array( 'plug_' . $cleanedMainFileName . '_install', array() );
  771. if ( $ret != '' ) {
  772. $this->setError( 0, $desc . $ret );
  773. }
  774. }
  775. }
  776. $res = $this->copySetupFile('front');
  777. if ( $res === false ) {
  778. if ( $pluginRowWasNotExisting ) {
  779. if ( $db ) {
  780. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
  781. }
  782. $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
  783. $row->delete();
  784. }
  785. cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
  786. return false;
  787. }
  788. if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
  789. HTML_comprofiler::fixcbdbShowResults( $sqlUpgrader, true, false, $success, array(), array(), $this->elementName(), 1, false );
  790. }
  791. return true;
  792. }
  793. /**
  794.  * Installs a tab into database, finding already existing one if needed.
  795.  *
  796.  * @param  int                 $pluginid
  797.  * @param  CBSimpleXMLElement  $tab
  798.  * @return int|boolean         id of tab or FALSE in case of error (error saved with $this->setError() ).
  799.  */
  800. function installTab( $pluginid, &$tab ) {
  801. global $_CB_database, $_CB_framework;
  802. // Check to see if plugin tab already exists in db
  803. if ( $tab->attributes( 'class' ) ) {
  804. $query = "SELECT tabid FROM #__comprofiler_tabs WHERE " /* . "pluginid = " . (int) $pluginid . " AND " */ . "pluginclass = " . $_CB_database->Quote( $tab->attributes('class') );
  805. } else {
  806. $query = "SELECT tabid FROM #__comprofiler_tabs WHERE pluginid = " . (int) $pluginid . " AND pluginclass = ''";
  807. }
  808. $_CB_database->setQuery( $query );
  809. $tabid = $_CB_database->loadResult();
  810. if ( $tab->attributes( 'type' ) == 'existingSytemTab' ) {
  811. if ( $tabid == null ) {
  812. $this->setError( 1, 'installTab error: existingSystemTab' . ': ' . $tab->attributes( 'class' ) . ' ' . 'not found' . '.' );
  813. return false;
  814. }
  815. } else {
  816. $row = new moscomprofilerTabs( $_CB_database );
  817. if ( ! $tabid ) {
  818. $row->title = $tab->attributes('name');
  819. $row->description = $tab->attributes('description');
  820. $row->ordering = 99;
  821. $row->position = $tab->attributes('position');
  822. $row->displaytype = $tab->attributes('displaytype');
  823. }
  824. $row->width = $tab->attributes('width');
  825. $row->pluginclass = $tab->attributes('class');
  826. $row->pluginid = $pluginid;
  827. $row->fields = $tab->attributes('fields');
  828. $row->sys = $tab->attributes('sys');
  829. $userGroupName = $tab->attributes( 'useraccessgroup' );
  830. switch ( $userGroupName ) {
  831. case 'All Registered Users':
  832. $row->useraccessgroupid = -1;
  833. break;
  834. case 'Everybody':
  835. default:
  836. if ( $userGroupName && ( $userGroupName != 'Everybody' ) ) {
  837. $groupId = $_CB_framework->acl->get_group_id( $userGroupName, 'ARO' );
  838. if ( $groupId ) {
  839. $row->useraccessgroupid = $groupId;
  840. } else {
  841. $row->useraccessgroupid = -2;
  842. }
  843. break;
  844. }
  845. }
  846. if ( ! $row->store( $tabid ) ) {
  847. $this->setError( 1, 'SQL error' .': ' . $row->getError() );
  848. return false;
  849. }
  850. if ( ! $tabid ) {
  851. $tabid = $_CB_database->insertid();
  852. }
  853. }
  854. return $tabid;
  855. }
  856. /**
  857. * installs a field for plugin
  858. *
  859. * @param  int                 $pluginid    id of the plugin creating the field
  860. * @param  CBSimpleXMLElement  $field
  861. * @return int|false     fieldid or False on error
  862. */
  863. function installField( $pluginid,$tabid,$field) {
  864. global $_CB_database, $_PLUGINS;
  865. // Check to see if plugin tab already exists in db
  866. $_CB_database->setQuery( "SELECT fieldid FROM #__comprofiler_fields WHERE name = '".$field->attributes('name')."'" );
  867. $fieldid = $_CB_database->loadResult();
  868. $row = new moscomprofilerFields( $_CB_database );
  869. $row->name = $field->attributes('name');
  870. $row->pluginid = $pluginid;
  871. $row->tabid = $tabid;
  872. $row->type = $field->attributes('type');
  873. if (!$fieldid) {
  874. $row->title = $field->attributes('title');
  875. $row->description = $field->attributes('description');
  876. $row->ordering = 99;
  877. $row->registration = $field->attributes('registration');
  878. $row->profile = $field->attributes('profile');
  879. $row->readonly = $field->attributes('readonly');
  880. $row->params = $field->attributes('params');
  881. }
  882. $dbTable =& $field->getElementByPath( 'database/table' );
  883. if ( $dbTable ) {
  884. $table = $dbTable->attributes( 'name' );
  885. } else {
  886. $table = $field->attributes('table');
  887. }
  888. if ( $table ) {
  889. $row->table = $table;
  890. } else {
  891. $row->table = '#__comprofiler';
  892. }
  893. // if the field type is unknown, suppose it's a field type of the plugin:
  894. $fieldTypePluginId = $_PLUGINS->getUserFieldPluginId( $row->type );
  895. if ( ! $fieldTypePluginId ) {
  896. // and register it so that the XML file for custom type can be found for store:
  897. $_PLUGINS->registerUserFieldTypes( array( $row->type => 'CBfield_' . $row->type ), $pluginid );
  898. }
  899. if (!$row->store($fieldid)) {
  900. $this->setError( 1, 'SQL error on field store2' .': ' . $row->getError() );
  901. return false;
  902. }
  903. if (!$fieldid) {
  904. $fieldid = $_CB_database->insertid();
  905. }
  906. return $fieldid;
  907. }
  908. function installFieldValue($fieldid,$fieldvalue) {
  909. global $_CB_database;
  910. $row = new moscomprofilerFieldValues($_CB_database);
  911. $row->fieldid = $fieldid;
  912. $row->fieldtitle = $fieldvalue->attributes('title');
  913. $row->ordering = $fieldvalue->attributes('ordering');
  914. $row->sys = $fieldvalue->attributes('sys');
  915. $_CB_database->setQuery("SELECT fieldvalueid FROM #__comprofiler_field_values WHERE fieldid = ". (int) $fieldid . " AND fieldtitle = '".$row->fieldtitle."'");
  916. $fieldvalueid = $_CB_database->loadResult();
  917. if (!$row->store($fieldvalueid)) {
  918. $this->setError( 1, 'SQL error on field store' .': ' . $row->getError() );
  919. return false;
  920. }
  921. return true;
  922. }
  923. /**
  924.  * Installs field type (for now just updates pluginid of existing entries)
  925.  *
  926.  * @param int     $pluginid
  927.  * @param string  $fieldType
  928.  */
  929. function installFieldType( $pluginid, $fieldType ) {
  930. global $_CB_database;
  931. // Update already existing fields of this type in db
  932. $_CB_database->setQuery( "UPDATE #__comprofiler_fields SET pluginid = " . ( $pluginid === null ? "NULL" : (int) $pluginid ) . " WHERE type = '" . $_CB_database->getEscaped( $fieldType ) . "'" );
  933. $_CB_database->query();
  934. }
  935. /**
  936. * Gets XML of plugin
  937. * @param  int  $pluginId
  938. * @return CBSimpleXMLElement  or string if error
  939. */
  940. function getXml( $id ) {
  941. global $_CB_database, $_CB_framework;
  942. $_CB_database->setQuery( "SELECT `name`, `folder`, `element`, `type`, `iscore` FROM #__comprofiler_plugin WHERE `id` = " . (int) $id );
  943. $row = null;
  944. $_CB_database->loadObject( $row );
  945. if ( $_CB_database->getErrorNum() ) {
  946. return $_CB_database->stderr();
  947. }
  948. if ( $row == null ) {
  949. return 'Invalid object id';
  950. }
  951. if ( trim( $row->folder ) == '' ) {
  952. return 'Folder field empty';
  953. }
  954. $this->i_elementdir = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/'.$row->folder.'/';
  955. $this->i_installfilename = $this->i_elementdir . $row->element . '.xml';
  956. if ( ! ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) ) {
  957. return $row->name .' '. "has no readable xml file " . $this->i_installfilename;
  958. }
  959. cbimport('cb.xml.simplexml');
  960. return new CBSimpleXMLElement( trim( file_get_contents( $this->i_installfilename ) ) );
  961. }
  962. /**
  963.  * Checks the plugin's database tables and upgrades if needed
  964.  * Backend-use only.
  965.  *
  966.  * Sets for $this->getErrors() $this->checkdbErrors and for $this->getLogs() $this->checkdbLogs
  967.  *
  968.  * @param  int             $pluginId
  969.  * @param  boolean         $upgrade    False: only check table, True: upgrades table (depending on $dryRun)
  970.  * @param  boolean         $dryRun     True: doesn't do the modifying queries, but lists them, False: does the job
  971.  * @return boolean|string              True: success: see logs, False: error, see errors, string: error
  972.  */
  973. function checkDatabase( $pluginId, $upgrade = false, $dryRun = false ) {
  974. global $_CB_database;
  975. $success = null;
  976. $cbInstallXML = $this->getXml( $pluginId );
  977. if ( is_object( $cbInstallXML ) ) {
  978. $db =& $cbInstallXML->getElementByPath( 'database' );
  979. if ( $db ) {
  980. // get the element name:
  981. $e =& $cbInstallXML->getElementByPath( 'name' );
  982. $this->elementName( $e->data() );
  983. $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
  984. cbimport( 'cb.sql.upgrader' );
  985. $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
  986. $sqlUpgrader->setDryRun( $dryRun );
  987. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, $upgrade, null );
  988. /*
  989. var_dump( $success );
  990. echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
  991. echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
  992. exit;
  993. */
  994. $this->checkdbErrors = $sqlUpgrader->getErrors( false );
  995. $this->checkdbLogs = $sqlUpgrader->getLogs( false );
  996. }
  997. } else {
  998. $success = $cbInstallXML;
  999. }
  1000. return $success;
  1001. }
  1002. function getErrors( ) {
  1003. return $this->checkdbErrors;
  1004. }
  1005. function getLogs( ) {
  1006. return $this->checkdbLogs;
  1007. }
  1008. /**
  1009.  * Checks that plugin is properly installed and sets, if returned true:
  1010.  * $this->i_elementdir   To the directory of the plugin (with final / )
  1011.  * $this->i_xmldocument  To a CBSimpleXMLElement of the XML file
  1012.  *
  1013.  * @param  int     $id
  1014.  * @param  string  $option
  1015.  * @param  int     $client
  1016.  * @param  string  $action
  1017.  * @return boolean
  1018.  */
  1019. function checkPluginGetXml( $id, $option, $client = 0, $action = 'Uninstall' ) {
  1020. global $_CB_database, $_CB_framework;
  1021. $_CB_database->setQuery( "SELECT `name`, `folder`, `element`, `type`, `iscore` FROM #__comprofiler_plugin WHERE `id` = " . (int) $id );
  1022. $row = null;
  1023. $_CB_database->loadObject( $row );
  1024. if ( $_CB_database->getErrorNum() ) {
  1025. HTML_comprofiler::showInstallMessage( $_CB_database->stderr(), $action . ' -  error' ,
  1026. $this->returnTo( $option, 'showPlugins') );
  1027. return false;
  1028. }
  1029. if ($row == null) {
  1030. HTML_comprofiler::showInstallMessage( 'Invalid object id', $action . ' -  error' ,
  1031. $this->returnTo( $option, 'showPlugins') );
  1032. return false;
  1033. }
  1034. if (trim( $row->folder ) == '') {
  1035. HTML_comprofiler::showInstallMessage( 'Folder field empty, cannot remove files', $action . ' -  error',
  1036. $this->returnTo( $option, 'showPlugins') );
  1037. return false;
  1038. }
  1039. if ($row->iscore) {
  1040. HTML_comprofiler::showInstallMessage( $row->name .' '. "is a core element, and cannot be uninstalled.<br />You need to unpublish it if you don't want to use it" ,
  1041. 'Uninstall -  error', $this->returnTo( $option, 'showPlugins') );
  1042. return false;
  1043. }
  1044. $this->i_elementdir = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/'.$row->folder.'/';
  1045. $this->i_installfilename = $this->i_elementdir . $row->element . '.xml';
  1046. if ( ! ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) ) {
  1047. HTML_comprofiler::showInstallMessage( $row->name .' '. "has no readable xml file " . $this->i_installfilename . ", and might not be uninstalled completely." ,
  1048. $action . ' -  warning', $this->returnTo( $option, 'showPlugins') );
  1049. }
  1050. // see if there is an xml install file, must be same name as element
  1051. if ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) {
  1052. cbimport('cb.xml.simplexml');
  1053. $this->i_xmldocument =& new CBSimpleXMLElement( trim( file_get_contents( $this->i_installfilename ) ) );
  1054. } else {
  1055. $this->i_xmldocument = null;
  1056. }
  1057. return true;
  1058. }
  1059. /**
  1060.  * plugin uninstaller with best effort depending on what it finds.
  1061.  *
  1062.  * @param  int     $id
  1063.  * @param  string  $option
  1064.  * @param  int     $client
  1065.  * @param  string  $action
  1066.  * @return boolean
  1067.  */
  1068. function uninstall( $id, $option, $client = 0 ) {
  1069. global $_CB_database;
  1070. $db = false;
  1071. if ( $this->checkPluginGetXml( $id, $option, $client ) ) {
  1072. if ( ( $this->i_xmldocument !== null ) && count( $this->i_xmldocument->children() ) > 0 ) {
  1073. $cbInstallXML =& $this->i_xmldocument;
  1074. // get the element name:
  1075. $e =& $cbInstallXML->getElementByPath( 'name' );
  1076. $this->elementName( $e->data() );
  1077. $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
  1078. // get the files element
  1079. $files_element =& $cbInstallXML->getElementByPath( 'files' );
  1080. if ( $files_element ) {
  1081. if ( count( $files_element->children() ) ) {
  1082. foreach ( $files_element->children() as $file) {
  1083. if ($file->attributes( "plugin" )) {
  1084. $this->elementSpecial( $file->attributes( "plugin" ) );
  1085. break;
  1086. }
  1087. }
  1088. $cleanedMainFileName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementSpecial()));
  1089. }
  1090. // Is there an uninstallfile
  1091. $uninstallfile_elemet = &$cbInstallXML->getElementByPath( 'uninstallfile' );
  1092. if ( $uninstallfile_elemet !== false ) {
  1093. if (is_file( $this->i_elementdir . $uninstallfile_elemet->data())) {
  1094. global $_PLUGINS;
  1095. require_once( $this->i_elementdir . $uninstallfile_elemet->data());
  1096. $ret = call_user_func_array("plug_".$cleanedMainFileName."_uninstall", array());
  1097. if ($ret != '') {
  1098. $this->setError( 0, $ret );
  1099. }
  1100. }
  1101. }
  1102. $adminFS =& cbAdminFileSystem::getInstance();
  1103. foreach ( $files_element->children() as $file ) {
  1104. // delete the files
  1105. $filename = $file->data();
  1106. if ( file_exists( $this->i_elementdir . $filename ) ) {
  1107. $parts = pathinfo( $filename );
  1108. $subpath = $parts['dirname'];
  1109. if ( $subpath <> '' && $subpath <> '.' && $subpath <> '..' ) {
  1110. //echo '<br />'. 'Deleting'  .': '. $this->i_elementdir . $subpath;
  1111. $result = $adminFS->deldir( _cbPathName( $this->i_elementdir . $subpath . '/' ) );
  1112. } else {
  1113. //echo '<br />'. 'Deleting'  .': '. $this->i_elementdir . $filename;
  1114. $result = $adminFS->unlink( _cbPathName( $this->i_elementdir . $filename, false ) );
  1115. }
  1116. //echo intval( $result );
  1117. }
  1118. }
  1119. // Are there any SQL queries??
  1120. $query_element = &$cbInstallXML->getElementByPath( 'uninstall/queries' );
  1121. if ( $query_element !== false ) {
  1122. foreach ( $query_element->children() as $query )
  1123. {
  1124. $_CB_database->setQuery( trim( $query->data() ) );
  1125. if ( ! $_CB_database->query() )
  1126. {
  1127. $this->setError( 1, "SQL Error " . $_CB_database->stderr( true ) );
  1128. return false;
  1129. }
  1130. }
  1131. }
  1132. // Are there any Database statements ??
  1133. $db =& $cbInstallXML->getElementByPath( 'database' );
  1134. if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
  1135. cbimport( 'cb.sql.upgrader' );
  1136. $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
  1137. //$sqlUpgrader->setDryRun( true );
  1138. $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedMainFileName, 'drop', null );
  1139. /*
  1140. var_dump( $success );
  1141. echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
  1142. echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
  1143. exit;
  1144. */
  1145. if ( ! $success ) {
  1146. $this->setError( 1, "Plugin database XML SQL Error " .  $sqlUpgrader->getErrors() );
  1147. return false;
  1148. }
  1149. }
  1150. // Delete tabs and private fields of plugin:
  1151. $this->deleteTabAndFieldsOfPlugin( $id );
  1152. // remove XML file from front
  1153. $xmlRemoveResult = $adminFS->unlink(  _cbPathName( $this->i_installfilename, false ) );
  1154. $filesRemoveResult = true;
  1155. /* // define folders that should not be removed
  1156. $sysFolders = array(
  1157. 'content',
  1158. 'search'
  1159. );
  1160. if ( ! in_array( $row->folder, $sysFolders ) ) {
  1161. */ // delete the non-system folders if empty
  1162. if ( count( cbReadDirectory( $this->i_elementdir ) ) < 1 ) {
  1163. $filesRemoveResult = $adminFS->deldir( $this->i_elementdir );
  1164. }
  1165. /* }
  1166. */
  1167. if ( ! $xmlRemoveResult ) {
  1168. HTML_comprofiler::showInstallMessage( 'Could not delete XML file: ' . _cbPathName( $this->i_installfilename, false ) . ' due to permission error. Please remove manually.', 'Uninstall -  warning',
  1169. $this->returnTo( $option, 'showPlugins') );
  1170. }
  1171. if ( ! $filesRemoveResult ) {
  1172. HTML_comprofiler::showInstallMessage( 'Could not delete directory: ' . $this->i_elementdir . ' due to permission error. Please remove manually.', 'Uninstall -  warning',
  1173. $this->returnTo( $option, 'showPlugins') );
  1174. }
  1175. }
  1176. }
  1177. $_CB_database->setQuery( "DELETE FROM #__comprofiler_plugin WHERE id = " . (int) $id );
  1178. if (!$_CB_database->query()) {
  1179. $msg = $_CB_database->stderr;
  1180. HTML_comprofiler::showInstallMessage( 'Cannot delete plugin database entry due to error: ' . $msg, 'Uninstall -  error',
  1181. $this->returnTo( $option, 'showPlugins') );
  1182. return false;
  1183. }
  1184. if ( ( $this->i_xmldocument !== null ) && ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
  1185. HTML_comprofiler::fixcbdbShowResults( $sqlUpgrader, true, false, $success, array(), array(), $this->elementName(), 1, false );
  1186. }
  1187. return true;
  1188. }
  1189. return false;
  1190. }
  1191. /**
  1192.  * Deletes tabs and private fields of plugin id
  1193.  *
  1194.  * @param int $id   id of plugin
  1195.  */
  1196. function deleteTabAndFieldsOfPlugin( $id ) {
  1197. global $_CB_database;
  1198. //Find all tabs related to this plugin
  1199. $_CB_database->setQuery( "SELECT `tabid`, `fields` FROM #__comprofiler_tabs WHERE pluginid=" . (int) $id );
  1200. $tabs = $_CB_database->loadObjectList();
  1201. if ( count( $tabs ) > 0 ) {
  1202. $rowTab = new moscomprofilerTabs( $_CB_database );
  1203. foreach( $tabs AS $tab ) {
  1204. //Find all fields related to the tab
  1205. $_CB_database->setQuery( "SELECT `fieldid`, `name` FROM #__comprofiler_fields WHERE `tabid`=" . (int) $tab->tabid . " AND `pluginid`=" . (int) $id );
  1206. $fields = $_CB_database->loadObjectList();
  1207. $rowField = new moscomprofilerFields( $_CB_database );
  1208. //Delete fields and fieldValues, but not data content itself in the comprofilier table so they stay on reinstall
  1209. if ( count( $fields ) > 0 ) {
  1210. //delete each field related to a tab and all field value related to a field, but not the content
  1211. foreach( $fields AS $field ) {
  1212. //Now delete the field itself without deleting the user data, preserving it for reinstall
  1213. //$rowField->deleteColumn('#__comprofiler',$field->name); // this would delete the user data
  1214. $rowField->delete( $field->fieldid );
  1215. }
  1216. }
  1217. $fcount = 0;
  1218. if( $tab->fields ) {
  1219. $_CB_database->setQuery( "SELECT COUNT(*) FROM #__comprofiler_fields WHERE tabid=" . (int) $tab->tabid );
  1220. $fcount = $_CB_database->loadResult();
  1221. if( $fcount > 0 ) {
  1222. $_CB_database->setQuery( "UPDATE #__comprofiler_tabs SET `pluginclass`=null, `pluginid`=null WHERE `tabid`=" . (int) $tab->tabid );
  1223. $_CB_database->query();
  1224. } else {
  1225. //delete each tab
  1226. $rowTab->delete( $tab->tabid );
  1227. }
  1228. } else {
  1229. //delete each tab
  1230. $rowTab->delete( $tab->tabid );
  1231. }
  1232. }
  1233. }
  1234. //Find all fields related to this plugin and set to NULL the now uninstalled plugin.
  1235. $_CB_database->setQuery( "SELECT COUNT(*) FROM #__comprofiler_fields WHERE pluginid=" . (int) $id );
  1236. $fieldsNumber = $_CB_database->loadResult();
  1237. if ( $fieldsNumber > 0 ) {
  1238. $_CB_database->setQuery( "UPDATE #__comprofiler_fields SET pluginid = NULL WHERE pluginid=" . (int) $id );
  1239. $_CB_database->query();
  1240. }
  1241. }
  1242. }
  1243. ?>