cb.installer.php
上传用户:stephen_wu
上传日期:2008-07-05
资源大小:1757k
文件大小:46k
- <?php
- /**
- * Joomla Community Builder : Plugin Handler
- * @version $Id: library/cb/cb.params.php 610 2006-12-13 17:33:44Z beat $
- * @package Community Builder
- * @subpackage cb.params.php
- * @author various, JoomlaJoe and Beat
- * @copyright (C) Beat and JoomlaJoe, www.joomlapolis.com and various
- * @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html GNU/GPL version 2
- */
- // ensure this file is being included by a parent file
- if ( ! ( defined( '_VALID_CB' ) || defined( '_JEXEC' ) || defined( '_VALID_MOS' ) ) ) { die( 'Direct Access to this location is not allowed.' ); }
- /**
- * Installer class
- * @package Community Builder
- * @subpackage Installer
- * @abstract
- */
- class cbInstaller {
- // name of the XML file with installation information
- var $i_installfilename = "";
- var $i_installarchive = "";
- var $i_installdir = "";
- var $i_iswin = false;
- var $i_errno = 0;
- var $i_error = "";
- var $i_installtype = "";
- var $i_unpackdir = "";
- var $i_docleanup = true;
- /** @var string The directory where the element is to be installed */
- var $i_elementdir = '';
- /** @var string The name of the Mambo element */
- var $i_elementname = '';
- /** @var string The name of a special atttibute in a tag */
- var $i_elementspecial = '';
- /** @var object A DOMIT XML document */
- var $i_xmldocument = null;
- var $i_hasinstallfile = null;
- var $i_installfile = null;
- /**
- * Constructor
- */
- function cbInstaller() {
- cbimport( 'cb.adminfilesystem' );
- $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
- }
- /**
- * Uploads and unpacks a file
- * @param string The uploaded package filename or install directory
- * @param boolean True if the file is an archive file
- * @return boolean True on success, False on error
- */
- function upload($p_filename = null, $p_unpack = true, $p_findinstallfile = true ) {
- $this->i_iswin = (substr(PHP_OS, 0, 3) == 'WIN');
- $this->installArchive( $p_filename );
- if ($p_unpack) {
- if ($this->extractArchive()) {
- if ( $p_findinstallfile ) {
- return $this->findInstallFile();
- } else {
- return true;
- }
- } else {
- return false;
- }
- } else {
- return false;
- }
- }
- /**
- * Extracts the package archive file
- * @return boolean True on success, False on error
- */
- function extractArchive() {
- global $_CB_framework;
- $base_Dir = _cbPathName( $_CB_framework->getCfg('tmp_path') );
- $archivename = $this->installArchive();
- $tmpdir = uniqid( 'install_' );
- $extractdir = _cbPathName( $base_Dir . $tmpdir );
- $archivename = _cbPathName( $archivename, false );
- $this->unpackDir( $extractdir );
- if ( preg_match( "/\.zip$/i", $archivename ) ) {
- // Extract functions
- cbimport( 'pcl.pclziplib' );
- $zipfile = new PclZip( $archivename );
- if($this->isWindows()) {
- define('OS_WINDOWS',1);
- } else {
- define('OS_WINDOWS',0);
- }
- $ret = $zipfile->extract( PCLZIP_OPT_PATH, $extractdir );
- if($ret == 0) {
- $this->setError( 1, 'Unrecoverable error "'.$zipfile->errorName(true).'"' );
- return false;
- }
- } else {
- cbimport( 'pcl.tar' ); // includes/Archive/Tar.php' );
- $archive =& new Archive_Tar( $archivename );
- $archive->setErrorHandling( PEAR_ERROR_PRINT );
- if ( ! $archive->extractModify( $extractdir, '' ) ) {
- $this->setError( 1, 'Extract Error' );
- return false;
- }
- }
- $this->installDir( $extractdir );
- // Try to find the correct install dir. in case that the package have subdirs
- // Save the install dir for later cleanup
- $filesindir = cbReadDirectory( $this->installDir(), '' );
- if ( count( $filesindir ) == 1 ) {
- if ( is_dir( $extractdir . $filesindir[0] ) ) {
- $this->installDir( _cbPathName( $extractdir . $filesindir[0] ) );
- }
- }
- return true;
- }
- /**
- * Tries to find the package XML file
- * @return boolean True on success, False on error
- */
- function findInstallFile() {
- $found = false;
- // Search the install dir for an xml file
- $files = cbReadDirectory( $this->installDir(), '.xml$', true, false );
- if (count( $files ) > 0) {
- foreach ($files as $file) {
- $packagefile =& $this->isPackageFile( $this->installDir() . $file );
- if (!is_null( $packagefile ) && !$found ) {
- $this->i_xmldocument =& $packagefile;
- return true;
- }
- }
- $this->setError( 1, 'ERROR: Could not find a CB XML setup file in the package.' );
- return false;
- } else {
- $this->setError( 1, 'ERROR: Could not find an XML setup file in the package.' );
- return false;
- }
- }
- /**
- * @param string A file path
- * @return object A DOMIT XML document, or null if the file failed to parse
- */
- function & isPackageFile( $p_file ) {
- $null = null;
- if ( ! file_exists( $p_file ) ) {
- return $null;
- }
- cbimport('cb.xml.simplexml');
- $xmlString = trim( file_get_contents( $p_file ) );
- $element =& new CBSimpleXMLElement( $xmlString );
- if ( count( $element->children() ) == 0 ) {
- return $null;
- }
- if ( $element->name() != 'cbinstall' ) {
- //echo "didn't find cbinstall";
- return $null;
- }
- // Set the type
- //echo "<br />element->attributes( 'type' )=".$element->attributes( 'type' );
- $this->installType( $element->attributes( 'type' ) );
- $this->installFilename( $p_file );
- return $element;
- }
- /**
- * Loads and parses the XML setup file
- * @return boolean True on success, False on error
- */
- function readInstallFile() {
- if ($this->installFilename() == "") {
- $this->setError( 1, 'No filename specified' );
- return false;
- }
- cbimport('cb.xml.simplexml');
- if ( file_exists( $this->installFilename() ) ) {
- $xmlString = trim( file_get_contents( $this->installFilename() ) );
- $this->i_xmldocument =& new CBSimpleXMLElement( $xmlString );
- if ( count( $this->i_xmldocument->children() ) == 0 ) {
- return false;
- }
- }
- $main_element =& $this->i_xmldocument;
- // Check that it's am installation file
- if ($main_element->name() != 'cbinstall') {
- $this->setError( 1, 'File :"' . $this->installFilename() . '" is not a valid Joomla installation file' );
- return false;
- }
- //echo "<br />main_element->attributes( 'type' )=".$main_element->attributes( 'type' );
- $this->installType( $main_element->attributes( 'type' ) );
- return true;
- }
- /**
- * Abstract install method
- */
- function install() {
- die( 'Method "install" cannot be called by class ' . strtolower(get_class( $this )) );
- }
- /**
- * Abstract uninstall method
- */
- function uninstall() {
- die( 'Method "uninstall" cannot be called by class ' . strtolower(get_class( $this )) );
- }
- /**
- * return to method
- */
- function returnTo( $option, $task ) {
- return "index2.php?option=$option&task=$task";
- }
- /**
- * @param string Install from directory
- * @param string The install type
- * @return boolean
- */
- function preInstallCheck( $p_fromdir, $type='plugin' ) {
- if (!is_null($p_fromdir)) {
- $this->installDir($p_fromdir);
- }
- if (!$this->installfile()) {
- $this->findInstallFile();
- }
- if (!$this->readInstallFile()) {
- $this->setError( 1, 'Installation file not found:<br />' . $this->installDir() );
- return false;
- }
-
- //echo "<br />type=".$type." this->installType()=".$this->installType();
- if (trim($this->installType()) != trim($type)) {
- //echo "<br />failing here<br />";
- $this->setError( 1, 'XML setup file is not for a "'.$type.'".' );
- return false;
- }
-
- // In case there where an error doring reading or extracting the archive
- if ($this->errno()) {
- return false;
- }
- return true;
- }
- /**
- * @param string The tag name to parse
- * @param string An attribute to search for in a filename element
- * @param string The value of the 'special' element if found
- * @param boolean True for Administrator components
- * @return mixed Number of file or False on error
- */
- function parseFiles( $tagName='files', $special='', $specialError='', $adminFiles=0 ) {
- global $_CB_framework;
- // Find files to copy
- $cbInstallXML =& $this->i_xmldocument;
- $files_element =& $cbInstallXML->getElementByPath( $tagName );
- if ( ! ( $files_element )) {
- return 0;
- }
- if ( count( $files_element->children() ) == 0 ) {
- // no files
- return 0;
- }
- $copyfiles = array();
- $folder = $files_element->attributes( 'folder' );
- if ( $folder ) {
- $temp = _cbPathName( $this->unpackDir() . $folder );
- if ($temp == $this->installDir()) {
- // this must be only an admin component
- $installFrom = $this->installDir();
- } else {
- $installFrom = _cbPathName( $this->installDir() . $folder );
- }
- } else {
- $installFrom = $this->installDir();
- }
- foreach ( $files_element->children() as $file ) {
- if ( basename( $file->data() ) != $file->data() ) {
- $newdir = dirname( $file->data() );
- if ( $adminFiles ) {
- if ( ! $this->mosMakePath( $this->componentAdminDir(), $newdir ) ) {
- $this->setError( 1, 'Failed to create directory "' . ($this->componentAdminDir()) . $newdir . '"' );
- return false;
- }
- } else {
- if ( ! $this->mosMakePath( $this->elementDir(), $newdir ) ) {
- $this->setError( 1, 'Failed to create directory "' . ($this->elementDir()) . $newdir . '"' );
- return false;
- }
- }
- }
- $copyfiles[] = $file->data();
- // check special for attribute
- if ( $file->attributes( $special ) ) {
- $this->elementSpecial( $file->attributes( $special ) );
- }
- }
- if ( $specialError ) {
- if ( $this->elementSpecial() == '' ) {
- $this->setError( 1, $specialError );
- return false;
- }
- }
- if ( $tagName == 'media' ) {
- // media is a special tag
- $installTo = _cbPathName( $_CB_framework->getCfg('absolute_path') . '/images/stories' );
- } else if ($adminFiles) {
- $installTo = $this->componentAdminDir();
- } else {
- $installTo = $this->elementDir();
- }
- $result = $this->copyFiles( $installFrom, $installTo, $copyfiles );
- return $result;
- }
- /**
- * @param string Source directory
- * @param string Destination directory
- * @param array array with filenames
- * @param boolean True is existing files can be replaced
- * @return boolean True on success, False on error
- */
- function copyFiles( $p_sourcedir, $p_destdir, $p_files, $overwrite=false ) {
- global $_CB_framework;
- if (is_array( $p_files ) && count( $p_files ) > 0) {
- $adminFS =& cbAdminFileSystem::getInstance();
- $filePerms = $_CB_framework->getCfg( 'fileperms' );
- $dirPerms = $_CB_framework->getCfg( 'dirperms' );
- if ( $filePerms ) {
- $filePerms = octdec( $filePerms );
- } else {
- $filePerms = null;
- }
- if ( $dirPerms ) {
- $dirPerms = octdec( $dirPerms );
- } else {
- $dirPerms = null;
- }
- foreach($p_files as $_file) {
- $filesource = _cbPathName( _cbPathName( $p_sourcedir ) . $_file, false );
- $filedest = _cbPathName( _cbPathName( $p_destdir ) . $_file, false );
- if ( ! file_exists( $filesource ) ) {
- $this->setError( 1, "File $filesource does not exist!" );
- return false;
- } else if ( file_exists( $filedest ) && ! $overwrite ) {
- $this->setError( 1, "There is already a file called $filedest - Are you trying to install the same Plugin twice?" );
- return false;
- } else if ( ! $adminFS->copy( $filesource, $filedest ) ) {
- $this->setError( 1, "Failed to copy file: $filesource to $filedest" );
- return false;
- } else {
- if ( is_dir( $filesource ) && $dirPerms ) {
- $perms = $dirPerms;
- } elseif ( is_file( $filesource ) && $filePerms ) {
- $perms = $filePerms;
- } else {
- $perms = null;
- }
- if ( $perms && ! $adminFS->chmod( $filedest, $perms ) ) {
- $this->setError( 1, "Failed to chmod file: $filedest" );
- return false;
- }
- }
- }
- } else {
- return false;
- }
- return count( $p_files );
- }
- /**
- * Copies the XML setup file to the element Admin directory
- * Used by Plugin Installer
- * @return boolean True on success, False on error
- */
- function copySetupFile( $where='admin' ) {
- if ($where == 'admin') {
- return $this->copyFiles( $this->installDir(), $this->componentAdminDir(), array( basename( $this->installFilename() ) ), true );
- } else if ($where == 'front') {
- return $this->copyFiles( $this->installDir(), $this->elementDir(), array( basename( $this->installFilename() ) ), true );
- }
- return false;
- }
- /**
- * @param int The error number
- * @param string The error message
- */
- function setError( $p_errno, $p_error ) {
- $this->errno( $p_errno );
- $this->error( $p_error );
- }
- /**
- * @param boolean True to display both number and message
- * @param string The error message
- * @return string
- */
- function getError($p_full = false) {
- if ($p_full) {
- return $this->errno() . " " . $this->error();
- } else {
- return $this->error();
- }
- }
- /**
- * @param string The name of the property to set/get
- * @param mixed The value of the property to set
- * @return The value of the property
- */
- function setVar( $name, $value=null ) {
- if (!is_null( $value )) {
- $this->$name = $value;
- }
- return $this->$name;
- }
- function installFilename( $p_filename = null ) {
- if(!is_null($p_filename)) {
- if($this->isWindows()) {
- $this->i_installfilename = str_replace('/','\',$p_filename);
- } else {
- $this->i_installfilename = str_replace('\','/',$p_filename);
- }
- }
- return $this->i_installfilename;
- }
- function installType( $p_installtype = null ) {
- return $this->setVar( 'i_installtype', $p_installtype );
- }
- function error( $p_error = null ) {
- return $this->setVar( 'i_error', $p_error );
- }
- function installArchive( $p_filename = null ) {
- return $this->setVar( 'i_installarchive', $p_filename );
- }
- function installDir( $p_dirname = null ) {
- return $this->setVar( 'i_installdir', $p_dirname );
- }
- function unpackDir( $p_dirname = null ) {
- return $this->setVar( 'i_unpackdir', $p_dirname );
- }
- function isWindows() {
- return $this->i_iswin;
- }
- function errno( $p_errno = null ) {
- return $this->setVar( 'i_errno', $p_errno );
- }
- function hasInstallfile( $p_hasinstallfile = null ) {
- return $this->setVar( 'i_hasinstallfile', $p_hasinstallfile );
- }
- function installfile( $p_installfile = null ) {
- return $this->setVar( 'i_installfile', $p_installfile );
- }
- function elementDir( $p_dirname = null ) {
- return $this->setVar( 'i_elementdir', $p_dirname );
- }
- function elementName( $p_name = null ) {
- return $this->setVar( 'i_elementname', $p_name );
- }
- function elementSpecial( $p_name = null ) {
- return $this->setVar( 'i_elementspecial', $p_name );
- }
- /**
- * Warning: needs cbAdminFileSystem File-system loaded to use
- *
- * @param string $base An existing base path
- * @param string $path A path to create from the base path
- * @param int $mode Directory permissions
- * @return boolean True if successful
- */
- function mosMakePath( $base, $path='', $mode = null ) {
- global $_CB_framework;
- // convert windows paths
- $path = preg_replace( "/(\/){2,}|(\\){1,}/",'/', $path );
- // check if dir exists
- if ( file_exists( $base . $path ) ) {
- return true;
- }
- // set mode
- $origmask = null;
- if ( isset( $mode ) ) {
- $origmask = @umask(0);
- } else {
- if ( $_CB_framework->getCfg( 'dirperms' ) == '' ) {
- // rely on umask
- $mode = 0755; // 0777;
- } else {
- $origmask = @umask( 0 );
- $mode = octdec( $_CB_framework->getCfg( 'dirperms' ) );
- }
- }
- $ret = true;
- if ( $path == '' ) {
- while ( substr( $base, -1, 1 ) == '/' ) {
- $base = substr( $base, 0, -1 );
- }
- $adminFS =& cbAdminFileSystem::getInstance();
- $ret = $adminFS->mkdir( $base, $mode );
- } else {
- $parts = explode( '/', $path );
- $n = count( $parts );
- $path = $base;
- for ( $i = 0 ; $i < $n ; $i++ ) {
- $path .= $parts[$i];
- if ( ! file_exists( $path ) ) {
- $adminFS =& cbAdminFileSystem::getInstance();
- if ( ! $adminFS->mkdir( $path, $mode ) ) {
- $ret = false;
- break;
- }
- }
- $path .= '/';
- }
- }
- if ( isset( $origmask ) ) {
- @umask( $origmask );
- }
- return $ret;
- }
- } // end class cbInstaller
- function cleanupInstall( $userfile_name, $resultdir) {
- if ( file_exists( $resultdir ) ) {
- $adminFS =& cbAdminFileSystem::getInstance();
- $adminFS->deldir( $resultdir );
- if ( $userfile_name ) {
- $adminFS->unlink( _cbPathName( $userfile_name, false ) );
- }
- }
- }
- class cbInstallerPlugin extends cbInstaller {
- /** @var string The element type */
- var $elementType = 'plugin';
- var $checkdbErrors = null;
- var $checkdbLogs = null;
- /**
- * Constructor
- */
- function cbInstallerPlugin() {
- $this->cbInstaller();
- }
- /**
- * Custom install method
- * @param boolean True if installing from directory
- */
- function install( $p_fromdir = null ) {
- global $_CB_framework, $_CB_database, $ueConfig, $_PLUGINS;
-
- if (!$this->preInstallCheck( $p_fromdir,$this->elementType )) {
- return false;
- }
- $cbInstallXML =& $this->i_xmldocument;
- // Get name
- $e = &$cbInstallXML->getElementByPath( 'name' );
- $this->elementName( $e->data() );
- $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
- // Get plugin filename
- $files_element = &$cbInstallXML->getElementByPath( 'files' );
- foreach ( $files_element->children() as $file ) {
- if ($file->attributes( "plugin" )) {
- $this->elementSpecial( $file->attributes( "plugin" ) );
- }
- }
- $fileNopathNoext = null;
- $matches = array();
- if ( preg_match("/^.*[\/\\](.*)\..*$/", $this->installFilename(), $matches ) ) {
- $fileNopathNoext = $matches[1];
- }
- if ( ! ( $fileNopathNoext && ( $this->elementSpecial() == $fileNopathNoext ) ) ) {
- $this->setError( 1, 'Installation filename `' . $fileNopathNoext . '` (with .xml) does not match main php file plugin attribute `' . $this->elementSpecial() . '` in the plugin xml file<br />' );
- return false;
- }
- $cleanedMainFileName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementSpecial()));
- // check version
- $v = &$cbInstallXML->getElementByPath( 'version' );
- $version = $v->data();
- 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")) {
- ;
- } else {
- $this->setError( 1, 'Plugin version ('.$version.') different from Community Builder version ('.$ueConfig['version'].')' );
- return false;
- }
- $backendMenu = "";
- $adminmenusnode =& $cbInstallXML->getElementByPath( 'adminmenus' );
- if ( $adminmenusnode ) {
- $menusArr = array();
- //cycle through each menu
- foreach( $adminmenusnode->children() AS $menu ) {
- if ( $menu->name() == "menu" ) {
- $action = $menu->attributes('action');
- $text = getLangDefinition($menu->data());
- $menusArr[] = $text . ":" . $action;
- }
- }
- $backendMenu = implode( ",", $menusArr );
- }
- $folder = strtolower($cbInstallXML->attributes( 'group' ));
- $subFolderPrefix = ( ( $folder == "user" ) ? "plug_" : "" );
- $subFolder = $subFolderPrefix . $cleanedElementName;
- $this->elementDir( $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $folder . "/" . $subFolder . "/" );
-
- if (file_exists($this->elementDir())) {
- $this->setError( 1, 'Another plugin is already using directory: "' . $this->elementDir() . '"' );
- return false;
- }
- if(!file_exists($this->elementDir()) && !$this->mosMakePath($this->elementDir())) {
- $this->setError( 1, 'Failed to create directory' .' "' . $this->elementDir() . '"' );
- return false;
- }
- // Copy files from package:
- if ($this->parseFiles( 'files', 'plugin', 'No file is marked as plugin file' ) === false) {
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- // Check to see if plugin already exists in db
- $_CB_database->setQuery( "SELECT id FROM #__comprofiler_plugin WHERE element = '" . $this->elementSpecial() . "' AND folder = '" . $subFolder . "'" );
- if (!$_CB_database->query()) {
- $this->setError( 1, 'SQL error' .': ' . $_CB_database->stderr( true ) );
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- $pluginid = $_CB_database->loadResult();
- $pluginRowWasNotExisting = ( ! $pluginid );
- $row = new moscomprofilerPlugin( $_CB_database );
- $row->id = $pluginid;
- if ( ! $pluginid ) {
- $row->name = $this->elementName();
- $row->ordering = 99;
- }
- $row->type = $folder;
- if ( $row->type == 'language' ) {
- $row->published = 1;
- }
- $row->folder = $subFolder;
- $row->backend_menu = $backendMenu;
- $row->iscore = 0;
- $row->access = 0;
- $row->client_id = 0;
- $row->element = $this->elementSpecial();
- if (!$row->store()) {
- $this->setError( 1, 'SQL error' .': ' . $row->getError() );
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- if ( ! $pluginid ) {
- $pluginid = $_CB_database->insertid();
- }
- $_PLUGINS->_setLoading( $row, true );
- // Are there any Database statements ??
- $db =& $cbInstallXML->getElementByPath( 'database' );
- if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
- cbimport( 'cb.sql.upgrader' );
- $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
- //$sqlUpgrader->setDryRun( true );
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, true, null );
- /*
- var_dump( $success );
- echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
- echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
- exit;
- */
- if ( ! $success ) {
- $this->setError( 1, "Plugin database XML SQL Error " . $sqlUpgrader->getErrors() );
- if ( $pluginRowWasNotExisting ) {
- $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
- $row->delete();
- }
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- }
- $e =& $cbInstallXML->getElementByPath( 'description' );
- if ( $e !== false ) {
- $desc = $this->elementName() . '<div>' . $e->data() . '</div>';
- $this->setError( 0, $desc );
- }
- //If type equals user then check for tabs and fields
- if ( $folder == 'user' ) {
- $tabsnode =& $cbInstallXML->getElementByPath( 'tabs' );
- if( $tabsnode ) {
- //cycle through each tab
- foreach( $tabsnode->children() AS $tab ) {
- if ( $tab->name() == 'tab' ) {
- //install each tab
- $tabid = $this->installTab($pluginid,$tab);
- if ( $tabid ) {
- //get all fields in the tab
- $fieldsnode = $tab->getElementByPath( 'fields' );
- if ( $fieldsnode ) {
- //cycle through each field
- foreach( $fieldsnode->children() AS $field ) {
- if ($field->name() == "field") {
- //install each field
- //echo "installing field...";
- $fieldid = $this->installField($pluginid,$tabid,$field);
- //get all fieldvalues for the field
- //cycle through each fieldValue
- foreach( $field->children() AS $fieldValue) {
- if ( $fieldValue->name() == "fieldvalue" ) {
- $this->installFieldValue($fieldid,$fieldValue);
- }
- }
- }
- }
- }
- } else {
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- }
- }
- }
- // (re)install field types of plugin:
- $fieldtypes =& $cbInstallXML->getElementByPath( 'fieldtypes' );
- if( $fieldtypes ) {
- foreach ( $fieldtypes->children() as $typ ) {
- if ( $typ->name() == 'field' ) {
- $this->installFieldType( $pluginid, $typ->attributes( 'type' ) );
- }
- }
- }
- }
- // Are there any SQL queries??
- $query_element =& $cbInstallXML->getElementByPath( 'install/queries' );
- if ( $query_element ) {
- foreach( $query_element->children() as $query ) {
- $_CB_database->setQuery( trim( $query->data() ) );
- if ( ! $_CB_database->query() )
- {
- $this->setError( 1, "SQL Error " . $_CB_database->stderr( true ) );
- if ( $pluginRowWasNotExisting ) {
- if ( $db ) {
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
- }
- $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
- $row->delete();
- }
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- }
- }
-
- // Is there an installfile
- $installfile_elemet =& $cbInstallXML->getElementByPath( 'installfile' );
- if ( $installfile_elemet ) {
- // check if parse files has already copied the install.component.php file (error in 3rd party xml's!)
- if ( ! file_exists( $this->elementDir() . $installfile_elemet->data() ) ) {
- if( ! $this->copyFiles( $this->installDir(), $this->elementDir(), array( $installfile_elemet->data() ) ) ) {
- $this->setError( 1, 'Could not copy PHP install file.' );
- if ( $pluginRowWasNotExisting ) {
- if ( $db ) {
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
- }
- $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
- $row->delete();
- }
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- }
- $this->hasInstallfile( true );
- $this->installFile( $installfile_elemet->data() );
- }
- // Is there an uninstallfile
- $uninstallfile_elemet =& $cbInstallXML->getElementByPath( 'uninstallfile' );
- if( $uninstallfile_elemet ) {
- if ( ! file_exists( $this->elementDir() . $uninstallfile_elemet->data() ) ) {
- if( ! $this->copyFiles( $this->installDir(), $this->elementDir(), array( $uninstallfile_elemet->data() ) ) ) {
- $this->setError( 1, 'Could not copy PHP uninstall file' );
- if ( $pluginRowWasNotExisting ) {
- if ( $db ) {
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
- }
- $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
- $row->delete();
- }
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- }
- }
-
- if ( $this->hasInstallfile() ) {
- if ( is_file( $this->elementDir() . '/' . $this->installFile() ) ) {
- require_once( $this->elementDir() . "/" . $this->installFile() );
- $ret = call_user_func_array( 'plug_' . $cleanedMainFileName . '_install', array() );
- if ( $ret != '' ) {
- $this->setError( 0, $desc . $ret );
- }
- }
- }
-
- $res = $this->copySetupFile('front');
- if ( $res === false ) {
- if ( $pluginRowWasNotExisting ) {
- if ( $db ) {
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, 'drop', null );
- }
- $this->deleteTabAndFieldsOfPlugin( $row->id ); // delete tabs and private fields of plugin
- $row->delete();
- }
- cleanupInstall( null, $this->elementDir() ); // try removing directory and content just created successfully
- return false;
- }
- if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
- HTML_comprofiler::fixcbdbShowResults( $sqlUpgrader, true, false, $success, array(), array(), $this->elementName(), 1, false );
- }
- return true;
- }
-
- /**
- * Installs a tab into database, finding already existing one if needed.
- *
- * @param int $pluginid
- * @param CBSimpleXMLElement $tab
- * @return int|boolean id of tab or FALSE in case of error (error saved with $this->setError() ).
- */
- function installTab( $pluginid, &$tab ) {
- global $_CB_database, $_CB_framework;
- // Check to see if plugin tab already exists in db
- if ( $tab->attributes( 'class' ) ) {
- $query = "SELECT tabid FROM #__comprofiler_tabs WHERE " /* . "pluginid = " . (int) $pluginid . " AND " */ . "pluginclass = " . $_CB_database->Quote( $tab->attributes('class') );
- } else {
- $query = "SELECT tabid FROM #__comprofiler_tabs WHERE pluginid = " . (int) $pluginid . " AND pluginclass = ''";
- }
- $_CB_database->setQuery( $query );
- $tabid = $_CB_database->loadResult();
- if ( $tab->attributes( 'type' ) == 'existingSytemTab' ) {
- if ( $tabid == null ) {
- $this->setError( 1, 'installTab error: existingSystemTab' . ': ' . $tab->attributes( 'class' ) . ' ' . 'not found' . '.' );
- return false;
- }
- } else {
- $row = new moscomprofilerTabs( $_CB_database );
- if ( ! $tabid ) {
- $row->title = $tab->attributes('name');
- $row->description = $tab->attributes('description');
- $row->ordering = 99;
- $row->position = $tab->attributes('position');
- $row->displaytype = $tab->attributes('displaytype');
- }
- $row->width = $tab->attributes('width');
- $row->pluginclass = $tab->attributes('class');
- $row->pluginid = $pluginid;
- $row->fields = $tab->attributes('fields');
- $row->sys = $tab->attributes('sys');
-
- $userGroupName = $tab->attributes( 'useraccessgroup' );
- switch ( $userGroupName ) {
- case 'All Registered Users':
- $row->useraccessgroupid = -1;
- break;
- case 'Everybody':
- default:
- if ( $userGroupName && ( $userGroupName != 'Everybody' ) ) {
- $groupId = $_CB_framework->acl->get_group_id( $userGroupName, 'ARO' );
- if ( $groupId ) {
- $row->useraccessgroupid = $groupId;
- } else {
- $row->useraccessgroupid = -2;
- }
- break;
- }
- }
-
- if ( ! $row->store( $tabid ) ) {
- $this->setError( 1, 'SQL error' .': ' . $row->getError() );
- return false;
- }
-
- if ( ! $tabid ) {
- $tabid = $_CB_database->insertid();
- }
- }
- return $tabid;
- }
-
- /**
- * installs a field for plugin
- *
- * @param int $pluginid id of the plugin creating the field
- * @param CBSimpleXMLElement $field
- * @return int|false fieldid or False on error
- */
- function installField( $pluginid,$tabid,$field) {
- global $_CB_database, $_PLUGINS;
- // Check to see if plugin tab already exists in db
- $_CB_database->setQuery( "SELECT fieldid FROM #__comprofiler_fields WHERE name = '".$field->attributes('name')."'" );
- $fieldid = $_CB_database->loadResult();
- $row = new moscomprofilerFields( $_CB_database );
- $row->name = $field->attributes('name');
- $row->pluginid = $pluginid;
- $row->tabid = $tabid;
- $row->type = $field->attributes('type');
- if (!$fieldid) {
- $row->title = $field->attributes('title');
- $row->description = $field->attributes('description');
- $row->ordering = 99;
- $row->registration = $field->attributes('registration');
- $row->profile = $field->attributes('profile');
- $row->readonly = $field->attributes('readonly');
- $row->params = $field->attributes('params');
- }
- $dbTable =& $field->getElementByPath( 'database/table' );
- if ( $dbTable ) {
- $table = $dbTable->attributes( 'name' );
- } else {
- $table = $field->attributes('table');
- }
- if ( $table ) {
- $row->table = $table;
- } else {
- $row->table = '#__comprofiler';
- }
- // if the field type is unknown, suppose it's a field type of the plugin:
- $fieldTypePluginId = $_PLUGINS->getUserFieldPluginId( $row->type );
- if ( ! $fieldTypePluginId ) {
- // and register it so that the XML file for custom type can be found for store:
- $_PLUGINS->registerUserFieldTypes( array( $row->type => 'CBfield_' . $row->type ), $pluginid );
- }
- if (!$row->store($fieldid)) {
- $this->setError( 1, 'SQL error on field store2' .': ' . $row->getError() );
- return false;
- }
-
- if (!$fieldid) {
- $fieldid = $_CB_database->insertid();
- }
- return $fieldid;
- }
- function installFieldValue($fieldid,$fieldvalue) {
- global $_CB_database;
- $row = new moscomprofilerFieldValues($_CB_database);
- $row->fieldid = $fieldid;
- $row->fieldtitle = $fieldvalue->attributes('title');
- $row->ordering = $fieldvalue->attributes('ordering');
- $row->sys = $fieldvalue->attributes('sys');
-
- $_CB_database->setQuery("SELECT fieldvalueid FROM #__comprofiler_field_values WHERE fieldid = ". (int) $fieldid . " AND fieldtitle = '".$row->fieldtitle."'");
- $fieldvalueid = $_CB_database->loadResult();
-
- if (!$row->store($fieldvalueid)) {
- $this->setError( 1, 'SQL error on field store' .': ' . $row->getError() );
- return false;
- }
-
- return true;
- }
- /**
- * Installs field type (for now just updates pluginid of existing entries)
- *
- * @param int $pluginid
- * @param string $fieldType
- */
- function installFieldType( $pluginid, $fieldType ) {
- global $_CB_database;
- // Update already existing fields of this type in db
- $_CB_database->setQuery( "UPDATE #__comprofiler_fields SET pluginid = " . ( $pluginid === null ? "NULL" : (int) $pluginid ) . " WHERE type = '" . $_CB_database->getEscaped( $fieldType ) . "'" );
- $_CB_database->query();
- }
- /**
- * Gets XML of plugin
- * @param int $pluginId
- * @return CBSimpleXMLElement or string if error
- */
- function getXml( $id ) {
- global $_CB_database, $_CB_framework;
- $_CB_database->setQuery( "SELECT `name`, `folder`, `element`, `type`, `iscore` FROM #__comprofiler_plugin WHERE `id` = " . (int) $id );
- $row = null;
- $_CB_database->loadObject( $row );
- if ( $_CB_database->getErrorNum() ) {
- return $_CB_database->stderr();
- }
- if ( $row == null ) {
- return 'Invalid object id';
- }
- if ( trim( $row->folder ) == '' ) {
- return 'Folder field empty';
- }
-
- $this->i_elementdir = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/'.$row->folder.'/';
- $this->i_installfilename = $this->i_elementdir . $row->element . '.xml';
- if ( ! ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) ) {
- return $row->name .' '. "has no readable xml file " . $this->i_installfilename;
- }
- cbimport('cb.xml.simplexml');
- return new CBSimpleXMLElement( trim( file_get_contents( $this->i_installfilename ) ) );
- }
- /**
- * Checks the plugin's database tables and upgrades if needed
- * Backend-use only.
- *
- * Sets for $this->getErrors() $this->checkdbErrors and for $this->getLogs() $this->checkdbLogs
- *
- * @param int $pluginId
- * @param boolean $upgrade False: only check table, True: upgrades table (depending on $dryRun)
- * @param boolean $dryRun True: doesn't do the modifying queries, but lists them, False: does the job
- * @return boolean|string True: success: see logs, False: error, see errors, string: error
- */
- function checkDatabase( $pluginId, $upgrade = false, $dryRun = false ) {
- global $_CB_database;
- $success = null;
- $cbInstallXML = $this->getXml( $pluginId );
- if ( is_object( $cbInstallXML ) ) {
- $db =& $cbInstallXML->getElementByPath( 'database' );
- if ( $db ) {
- // get the element name:
- $e =& $cbInstallXML->getElementByPath( 'name' );
- $this->elementName( $e->data() );
- $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
-
- cbimport( 'cb.sql.upgrader' );
- $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
- $sqlUpgrader->setDryRun( $dryRun );
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedElementName, $upgrade, null );
- /*
- var_dump( $success );
- echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
- echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
- exit;
- */
- $this->checkdbErrors = $sqlUpgrader->getErrors( false );
- $this->checkdbLogs = $sqlUpgrader->getLogs( false );
- }
- } else {
- $success = $cbInstallXML;
- }
- return $success;
- }
- function getErrors( ) {
- return $this->checkdbErrors;
- }
- function getLogs( ) {
- return $this->checkdbLogs;
- }
- /**
- * Checks that plugin is properly installed and sets, if returned true:
- * $this->i_elementdir To the directory of the plugin (with final / )
- * $this->i_xmldocument To a CBSimpleXMLElement of the XML file
- *
- * @param int $id
- * @param string $option
- * @param int $client
- * @param string $action
- * @return boolean
- */
- function checkPluginGetXml( $id, $option, $client = 0, $action = 'Uninstall' ) {
- global $_CB_database, $_CB_framework;
- $_CB_database->setQuery( "SELECT `name`, `folder`, `element`, `type`, `iscore` FROM #__comprofiler_plugin WHERE `id` = " . (int) $id );
- $row = null;
- $_CB_database->loadObject( $row );
- if ( $_CB_database->getErrorNum() ) {
- HTML_comprofiler::showInstallMessage( $_CB_database->stderr(), $action . ' - error' ,
- $this->returnTo( $option, 'showPlugins') );
- return false;
- }
- if ($row == null) {
- HTML_comprofiler::showInstallMessage( 'Invalid object id', $action . ' - error' ,
- $this->returnTo( $option, 'showPlugins') );
- return false;
- }
- if (trim( $row->folder ) == '') {
- HTML_comprofiler::showInstallMessage( 'Folder field empty, cannot remove files', $action . ' - error',
- $this->returnTo( $option, 'showPlugins') );
- return false;
- }
-
- if ($row->iscore) {
- 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" ,
- 'Uninstall - error', $this->returnTo( $option, 'showPlugins') );
- return false;
- }
- $this->i_elementdir = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $row->type . '/'.$row->folder.'/';
- $this->i_installfilename = $this->i_elementdir . $row->element . '.xml';
- if ( ! ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) ) {
- HTML_comprofiler::showInstallMessage( $row->name .' '. "has no readable xml file " . $this->i_installfilename . ", and might not be uninstalled completely." ,
- $action . ' - warning', $this->returnTo( $option, 'showPlugins') );
- }
- // see if there is an xml install file, must be same name as element
- if ( file_exists( $this->i_installfilename ) && is_readable( $this->i_installfilename ) ) {
- cbimport('cb.xml.simplexml');
- $this->i_xmldocument =& new CBSimpleXMLElement( trim( file_get_contents( $this->i_installfilename ) ) );
- } else {
- $this->i_xmldocument = null;
- }
- return true;
- }
- /**
- * plugin uninstaller with best effort depending on what it finds.
- *
- * @param int $id
- * @param string $option
- * @param int $client
- * @param string $action
- * @return boolean
- */
- function uninstall( $id, $option, $client = 0 ) {
- global $_CB_database;
- $db = false;
- if ( $this->checkPluginGetXml( $id, $option, $client ) ) {
- if ( ( $this->i_xmldocument !== null ) && count( $this->i_xmldocument->children() ) > 0 ) {
- $cbInstallXML =& $this->i_xmldocument;
-
- // get the element name:
- $e =& $cbInstallXML->getElementByPath( 'name' );
- $this->elementName( $e->data() );
- $cleanedElementName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementName()));
-
- // get the files element
- $files_element =& $cbInstallXML->getElementByPath( 'files' );
- if ( $files_element ) {
- if ( count( $files_element->children() ) ) {
- foreach ( $files_element->children() as $file) {
- if ($file->attributes( "plugin" )) {
- $this->elementSpecial( $file->attributes( "plugin" ) );
- break;
- }
- }
- $cleanedMainFileName = strtolower(str_replace(array(" ","."),array("","_"),$this->elementSpecial()));
- }
- // Is there an uninstallfile
- $uninstallfile_elemet = &$cbInstallXML->getElementByPath( 'uninstallfile' );
- if ( $uninstallfile_elemet !== false ) {
- if (is_file( $this->i_elementdir . $uninstallfile_elemet->data())) {
- global $_PLUGINS;
- require_once( $this->i_elementdir . $uninstallfile_elemet->data());
- $ret = call_user_func_array("plug_".$cleanedMainFileName."_uninstall", array());
- if ($ret != '') {
- $this->setError( 0, $ret );
- }
- }
- }
- $adminFS =& cbAdminFileSystem::getInstance();
- foreach ( $files_element->children() as $file ) {
- // delete the files
- $filename = $file->data();
- if ( file_exists( $this->i_elementdir . $filename ) ) {
- $parts = pathinfo( $filename );
- $subpath = $parts['dirname'];
- if ( $subpath <> '' && $subpath <> '.' && $subpath <> '..' ) {
- //echo '<br />'. 'Deleting' .': '. $this->i_elementdir . $subpath;
- $result = $adminFS->deldir( _cbPathName( $this->i_elementdir . $subpath . '/' ) );
- } else {
- //echo '<br />'. 'Deleting' .': '. $this->i_elementdir . $filename;
- $result = $adminFS->unlink( _cbPathName( $this->i_elementdir . $filename, false ) );
- }
- //echo intval( $result );
- }
- }
-
- // Are there any SQL queries??
- $query_element = &$cbInstallXML->getElementByPath( 'uninstall/queries' );
- if ( $query_element !== false ) {
- foreach ( $query_element->children() as $query )
- {
- $_CB_database->setQuery( trim( $query->data() ) );
- if ( ! $_CB_database->query() )
- {
- $this->setError( 1, "SQL Error " . $_CB_database->stderr( true ) );
- return false;
- }
- }
- }
- // Are there any Database statements ??
- $db =& $cbInstallXML->getElementByPath( 'database' );
- if ( ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
- cbimport( 'cb.sql.upgrader' );
- $sqlUpgrader = new CBSQLupgrader( $_CB_database, false );
- //$sqlUpgrader->setDryRun( true );
- $success = $sqlUpgrader->checkXmlDatabaseDescription( $db, $cleanedMainFileName, 'drop', null );
- /*
- var_dump( $success );
- echo "<br>nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />nn", "<br />n" );
- echo "<br>nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />nn", "<br />n" );
- exit;
- */
- if ( ! $success ) {
- $this->setError( 1, "Plugin database XML SQL Error " . $sqlUpgrader->getErrors() );
- return false;
- }
- }
- // Delete tabs and private fields of plugin:
- $this->deleteTabAndFieldsOfPlugin( $id );
- // remove XML file from front
- $xmlRemoveResult = $adminFS->unlink( _cbPathName( $this->i_installfilename, false ) );
- $filesRemoveResult = true;
- /* // define folders that should not be removed
- $sysFolders = array(
- 'content',
- 'search'
- );
- if ( ! in_array( $row->folder, $sysFolders ) ) {
- */ // delete the non-system folders if empty
- if ( count( cbReadDirectory( $this->i_elementdir ) ) < 1 ) {
- $filesRemoveResult = $adminFS->deldir( $this->i_elementdir );
- }
- /* }
- */
- if ( ! $xmlRemoveResult ) {
- HTML_comprofiler::showInstallMessage( 'Could not delete XML file: ' . _cbPathName( $this->i_installfilename, false ) . ' due to permission error. Please remove manually.', 'Uninstall - warning',
- $this->returnTo( $option, 'showPlugins') );
- }
- if ( ! $filesRemoveResult ) {
- HTML_comprofiler::showInstallMessage( 'Could not delete directory: ' . $this->i_elementdir . ' due to permission error. Please remove manually.', 'Uninstall - warning',
- $this->returnTo( $option, 'showPlugins') );
- }
- }
- }
- $_CB_database->setQuery( "DELETE FROM #__comprofiler_plugin WHERE id = " . (int) $id );
- if (!$_CB_database->query()) {
- $msg = $_CB_database->stderr;
- HTML_comprofiler::showInstallMessage( 'Cannot delete plugin database entry due to error: ' . $msg, 'Uninstall - error',
- $this->returnTo( $option, 'showPlugins') );
- return false;
- }
- if ( ( $this->i_xmldocument !== null ) && ( $db !== false ) && ( count( $db->children() ) > 0 ) ) {
- HTML_comprofiler::fixcbdbShowResults( $sqlUpgrader, true, false, $success, array(), array(), $this->elementName(), 1, false );
- }
- return true;
- }
- return false;
- }
- /**
- * Deletes tabs and private fields of plugin id
- *
- * @param int $id id of plugin
- */
- function deleteTabAndFieldsOfPlugin( $id ) {
- global $_CB_database;
- //Find all tabs related to this plugin
- $_CB_database->setQuery( "SELECT `tabid`, `fields` FROM #__comprofiler_tabs WHERE pluginid=" . (int) $id );
- $tabs = $_CB_database->loadObjectList();
- if ( count( $tabs ) > 0 ) {
- $rowTab = new moscomprofilerTabs( $_CB_database );
- foreach( $tabs AS $tab ) {
- //Find all fields related to the tab
- $_CB_database->setQuery( "SELECT `fieldid`, `name` FROM #__comprofiler_fields WHERE `tabid`=" . (int) $tab->tabid . " AND `pluginid`=" . (int) $id );
- $fields = $_CB_database->loadObjectList();
- $rowField = new moscomprofilerFields( $_CB_database );
-
- //Delete fields and fieldValues, but not data content itself in the comprofilier table so they stay on reinstall
- if ( count( $fields ) > 0 ) {
- //delete each field related to a tab and all field value related to a field, but not the content
- foreach( $fields AS $field ) {
- //Now delete the field itself without deleting the user data, preserving it for reinstall
- //$rowField->deleteColumn('#__comprofiler',$field->name); // this would delete the user data
- $rowField->delete( $field->fieldid );
- }
- }
- $fcount = 0;
- if( $tab->fields ) {
- $_CB_database->setQuery( "SELECT COUNT(*) FROM #__comprofiler_fields WHERE tabid=" . (int) $tab->tabid );
- $fcount = $_CB_database->loadResult();
- if( $fcount > 0 ) {
- $_CB_database->setQuery( "UPDATE #__comprofiler_tabs SET `pluginclass`=null, `pluginid`=null WHERE `tabid`=" . (int) $tab->tabid );
- $_CB_database->query();
- } else {
- //delete each tab
- $rowTab->delete( $tab->tabid );
- }
- } else {
- //delete each tab
- $rowTab->delete( $tab->tabid );
- }
- }
- }
- //Find all fields related to this plugin and set to NULL the now uninstalled plugin.
- $_CB_database->setQuery( "SELECT COUNT(*) FROM #__comprofiler_fields WHERE pluginid=" . (int) $id );
- $fieldsNumber = $_CB_database->loadResult();
- if ( $fieldsNumber > 0 ) {
- $_CB_database->setQuery( "UPDATE #__comprofiler_fields SET pluginid = NULL WHERE pluginid=" . (int) $id );
- $_CB_database->query();
- }
- }
- }
- ?>