Пример #1
0
 /**
  * Plugin un-installer with best effort depending on what it finds.
  *
  * @param  int      $pluginId  Plugin id to uninstall
  * @param  string   $option    Option request of component
  * @return boolean             Success
  */
 function uninstall($pluginId, $option)
 {
     global $_CB_framework, $_CB_database;
     $db = false;
     $success = false;
     if (!$this->checkPluginGetXml($pluginId, $option)) {
         return false;
     }
     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 !== false) {
             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;
                     // needed for the require_once below !
                     /** @noinspection PhpIncludeInspection */
                     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();
             $installFileName = basename($this->i_installfilename);
             $this->deleteFiles($files_element, $adminFS, $installFileName);
             // Are there any CBLib libraries ?
             $libraries_element = $cbInstallXML->getElementByPath('libraries');
             if ($libraries_element !== false) {
                 foreach ($libraries_element->children() as $library) {
                     if ($library->getName() != 'library') {
                         continue;
                     }
                     // Delete files from library package:
                     $savePackage = $this->i_xmldocument;
                     $subFolder = $library->attributes('name');
                     $saveElement = $this->elementDir();
                     $this->elementDir($_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/libraries/' . ($subFolder ? $subFolder . '/' : null));
                     $this->i_xmldocument = $library;
                     $this->deleteFiles($library->getElementByPath('files'), $adminFS, null);
                     $this->i_xmldocument = $savePackage;
                     $this->elementDir($saveElement);
                 }
             }
             // 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->getErrorMsg());
                         return false;
                     }
                 }
             }
             // Are there any Database statements ??
             $db = $cbInstallXML->getElementByPath('database');
             if ($db !== false && count($db->children()) > 0) {
                 $sqlUpgrader = new DatabaseUpgrade(null, false);
                 //$sqlUpgrader->setDryRun( true );
                 $success = $sqlUpgrader->checkXmlDatabaseDescription($db, $cleanedMainFileName, 'drop', null, null);
                 /*
                 var_dump( $success );
                 echo "<br>\nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />\n\n", "<br />\n" );
                 echo "<br>\nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />\n\n", "<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($pluginId);
             // 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) {
                 self::renderInstallMessage('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) {
                 self::renderInstallMessage('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) $pluginId);
     if (!$_CB_database->query()) {
         $msg = $_CB_database->getErrorMsg();
         self::renderInstallMessage('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) {
         CBDatabaseChecker::renderDatabaseResults($sqlUpgrader, true, false, $success, array(), array(), $this->elementName(), 1, false);
     }
     return true;
 }
Пример #2
0
 /**
  * Check or fix field according to XML description if exsitant (or old method otherwise)
  *
  * @param  DatabaseUpgrade  $sqlUpgrader
  * @param  FieldTable       $field
  * @param  boolean          $change
  * @return boolean
  */
 public function checkFixSQL($sqlUpgrader, $field, $change = true)
 {
     $fieldXML =& $this->_loadFieldXML($field);
     if ($fieldXML) {
         $db = $fieldXML->getElementByPath('database');
         if ($db !== false) {
             // <database><table><columns>.... structure:
             $success = $sqlUpgrader->checkXmlDatabaseDescription($db, $field->name, $change, null);
         } else {
             $data = $fieldXML->getElementByPath('data');
             if ($data !== false) {
                 // <data ....> structure:
                 $xmlText = '<?xml version="1.0" encoding="UTF-8"?>' . '<database version="1">' . '<table name="' . $field->table . '" maintable="true" strict="false" drop="never" shared="true">' . '<columns>' . '</columns>' . '</table>' . '</database>';
                 $dbXml = new SimpleXMLElement($xmlText);
                 $columns = $dbXml->getElementByPath('table/columns');
                 $columns->addChildWithAttr('column', '', null, $data->attributes());
                 $success = $sqlUpgrader->checkXmlDatabaseDescription($dbXml, $field->name, $change, null);
             } else {
                 $success = true;
             }
         }
     } else {
         // no XML file or no <fieldtype> in xml, must be an old plugin or one which is uninstalled or missing files:
         $cols = $field->getTableColumns();
         if (count($cols) == 0) {
             // the comprofiler_files database is upgraded, but this (status) field does not require comprofiler entries:
             $success = true;
         } else {
             // database has been upgraded, take a guess and take first column name as name of the comprofiler table:
             // or database has not been upgraded: take name:
             $colNamePrefix = $cols[0];
             $xmlText = '<?xml version="1.0" encoding="UTF-8"?>' . '<database version="1">' . '<table name="#__comprofiler" class="\\CB\\Database\\Table\\ComprofilerTable" maintable="true" strict="false" drop="never" shared="true">' . '<columns>' . '<column name="" nametype="namesuffix" type="sql:text||sql:varchar(255)" null="true" default="NULL" />' . '</columns>' . '</table>' . '</database>';
             $dbXml = new SimpleXMLElement($xmlText);
             $success = $sqlUpgrader->checkXmlDatabaseDescription($dbXml, $colNamePrefix, $change, null);
         }
     }
     if (!$success) {
         // Temporary way to workaround _error protected, as this whole function should probably go to to new FieldModel:
         $field->set('_error', $sqlUpgrader->getErrors());
     }
     /*
     var_dump( $success );
     echo "<br>\nERRORS: " . $sqlUpgrader->getErrors( "<br /><br />\n\n", "<br />\n" );
     echo "<br>\nLOGS: " . $sqlUpgrader->getLogs( "<br /><br />\n\n", "<br />\n" );
     //exit;
     */
     return $success;
 }
Пример #3
0
 /**
  * Shows result of database check or fix (with or without dryrun)
  *
  * @param  DatabaseUpgrade|CBDatabaseChecker|cbInstallerPlugin  $dbChecker
  * @param  boolean                                              $upgrade
  * @param  boolean                                              $dryRun
  * @param  boolean                                              $result
  * @param  array                                                $messagesBefore
  * @param  array                                                $messagesAfter
  * @param  string                                               $dbName
  * @param  int                                                  $dbId
  * @param  boolean                                              $showConclusion
  */
 public static function renderDatabaseResults(&$dbChecker, $upgrade, $dryRun, $result, $messagesBefore, $messagesAfter, $dbName, $dbId, $showConclusion = true)
 {
     global $_CB_framework;
     static $JS_LOADED = 0;
     if (!$JS_LOADED++) {
         $js = "\$( '.cbDbResultsLogShow' ).on( 'click', function() {" . "\$( this ).addClass( 'hidden' );" . "\$( this ).siblings( '.cbDbResultsLogHide' ).removeClass( 'hidden' );" . "\$( this ).siblings( '.cbDbResultsLogMsgs' ).slideDown();" . "});" . "\$( '.cbDbResultsLogHide' ).on( 'click', function() {" . "\$( this ).addClass( 'hidden' );" . "\$( this ).siblings( '.cbDbResultsLogShow' ).removeClass( 'hidden' );" . "\$( this ).siblings( '.cbDbResultsLogMsgs' ).slideUp();" . "});" . "\$( '.cbDbResultsLogMsgs' ).hide();";
         $_CB_framework->outputCbJQuery($js);
     }
     $cbSpoofField = cbSpoofField();
     $cbSpoofString = cbSpoofString(null, 'plugin');
     $return = '<div class="cbDbResults">';
     if ($messagesBefore) {
         $return .= '<div class="form-group cb_form_line clearfix cbDbResultsMsgs">';
         foreach ($messagesBefore as $msg) {
             if ($msg) {
                 $return .= '<div class="cbDbResultsMsg">' . $msg . '</div>';
             }
         }
         $return .= '</div>';
     }
     if ($dbChecker !== null) {
         $return .= '<div class="form-group cb_form_line clearfix cbDbResultsCheck">';
         if ($result == true) {
             $return .= '<div class="text-success cbDbResultsSuccess">';
             if ($upgrade) {
                 if ($dryRun) {
                     $return .= CBTxt::T('NAME_DATABASE_ADJS_DRY_SUCCESS', '[name] database adjustments dryrun is successful. See results below.', array('[name]' => $dbName));
                 } else {
                     $return .= CBTxt::T('NAME_DATABASE_ADJS_SUCCESS', '[name] database adjustments have been performed successfully.', array('[name]' => $dbName));
                 }
             } else {
                 $return .= CBTxt::T('ALL_NAME_DATABASE_UPTODATE', 'All [name] database is up to date.', array('[name]' => $dbName));
             }
             $return .= '</div>';
         } elseif (is_string($result)) {
             $return .= '<div class="text-danger">' . $result . '</div>';
         } else {
             $return .= '<div class="text-danger cbDbResultsErrors">';
             if ($upgrade) {
                 $return .= CBTxt::T('NAME_DATABASE_ADJS_ERRORS', '[name] database adjustments errors:', array('[name]' => $dbName));
             } else {
                 $return .= CBTxt::T('NAME_DATABASE_STRUCT_DIFF', '[name] database structure differences:', array('[name]' => $dbName));
             }
             foreach ($dbChecker->getErrors(false) as $error) {
                 $return .= '<div class="text-large cbDbResultsError">' . htmlspecialchars($error[0]) . ($error[1] ? '<div class="text-small">' . htmlspecialchars($error[1]) . '</div>' : null) . '</div>';
             }
             $return .= '</div>';
             if (!$upgrade) {
                 $return .= '<div class="text-danger cbDbResultsErrorsFix">' . CBTxt::T('NAME_DATABASE_STRUCT_FIX', 'The [name] database structure differences can be fixed (adjusted) by clicking here:', array('[name]' => $dbName)) . ' <span class="alert alert-sm alert-danger text-large">' . '<a href="' . $_CB_framework->backendUrl("index.php?option=com_comprofiler&view=fixcbdb&dryrun=0&databaseid={$dbId}&{$cbSpoofField}={$cbSpoofString}") . '">' . CBTxt::T('NAME_DATABASE_DIFF_FIX_CLICK_HERE', 'Click here to fix (adjust) all [name] database differences listed above', array('[name]' => $dbName)) . '</a>' . '</span> ' . CBTxt::T('DATABASE_STRUCT_DRY_CLICK_HERE', '(you can also <a href="[url]">Click here to preview fixing (adjusting) queries in a dry-run</a>), but <strong class="text-large text-underline">in all cases you need to backup database first</strong> as this adjustment is changing the database structure to match the needed structure for the installed version.', array('[url]' => $_CB_framework->backendUrl("index.php?option=com_comprofiler&view=fixcbdb&dryrun=1&databaseid={$dbId}&{$cbSpoofField}={$cbSpoofString}"))) . '</div>';
             }
         }
         $logs = $dbChecker->getLogs(false);
         if (count($logs) > 0) {
             $return .= '<div class="cbDbResultsLog">' . '<a href="javascript:void(0);" class="cbDbResultsLogShow">' . CBTxt::T('Click here to show details') . ' <span class="fa fa-caret-down"></span></a>' . '<a href="javascript:void(0);" class="cbDbResultsLogHide hidden">' . CBTxt::T('Click here to hide details') . ' <span class="fa fa-caret-up"></span></a>' . '<div class="text-success cbDbResultsLogMsgs" style="display: none;">';
             foreach ($logs as $log) {
                 $return .= '<div class="text-large cbDbResultsLogMsg">' . htmlspecialchars($log[0]) . ($log[1] ? '<div class="text-small">' . htmlspecialchars($log[1]) . '</div>' : null) . '</div>';
             }
             $return .= '</div>' . '</div>';
         }
         $return .= '</div>';
     }
     if ($showConclusion) {
         if ($upgrade) {
             if ($dryRun) {
                 $return .= '<div class="form-group cb_form_line clearfix cbDbResultsConclusion">' . CBTxt::T('NAME_DATABASE_ADJS_DRY', 'Dry-run of [name] database adjustments done. None of the queries listed in details have been performed.', array('[name]' => $dbName)) . '<br />' . CBTxt::T('NAME_DATABASE_ADJS_FIX', 'The [name] database adjustments listed above can be applied by clicking here:', array('[name]' => $dbName)) . ' <span class="alert alert-sm alert-danger text-large">' . '<a href="' . $_CB_framework->backendUrl("index.php?option=com_comprofiler&view=fixcbdb&dryrun=0&databaseid={$dbId}&{$cbSpoofField}={$cbSpoofString}") . '">' . CBTxt::T('NAME_DATABASE_DIFF_FIX_CLICK_HERE', 'Click here to fix (adjust) all [name] database differences listed above', array('[name]' => $dbName)) . '</a>' . '</span> ' . CBTxt::T('DATABASE_FIX_BACKUP_FIRST', '<strong class="text-danger text-large text-underline">You need to backup database first</strong> as this fixing/adjusting is changing the database structure to match the needed structure for the installed version.') . '</div>';
             } else {
                 $return .= '<div class="form-group cb_form_line clearfix cbDbResultsConclusion">' . CBTxt::T('NAME_DATABASE_ADJS_DONE', 'The [name] database adjustments have been done. If all lines above are in green, database adjustments completed successfully. Otherwise, if some lines are red, please report exact errors and queries to authors forum, and try checking database again.', array('[name]' => $dbName)) . '<br />' . CBTxt::T('NAME_DATABASE_STRUCT_CHECK', 'The [name] database structure can be checked again by clicking here:', array('[name]' => $dbName)) . ' <span class="alert alert-sm alert-warning text-large">' . '<a href="' . $_CB_framework->backendUrl("index.php?option=com_comprofiler&view=checkcbdb&databaseid={$dbId}&{$cbSpoofField}={$cbSpoofString}") . '">' . CBTxt::T('NAME_DATABASE_DIFF_CHECK_CLICK_HERE', 'Click here to check [name] database', array('[name]' => $dbName)) . '</a>' . '</span> ' . '</div>';
             }
         } else {
             $return .= '<div class="form-group cb_form_line clearfix cbDbResultsConclusion">' . CBTxt::T('NAME_DATABASE_CHECKS_DONE', '[name] database checks done. If all lines above are in green, test completed successfully. Otherwise, please take corrective measures proposed in red.', array('[name]' => $dbName)) . '</div>';
         }
     }
     if ($messagesAfter) {
         $return .= '<div class="form-group cb_form_line clearfix cbDbResultsMsgs">';
         foreach ($messagesAfter as $msg) {
             if ($msg) {
                 $return .= '<div class="cbDbResultsMsg">' . $msg . '</div>';
             }
         }
         $return .= '</div>';
     }
     $return .= '</div>';
     echo $return;
 }