/** * Helper task for installing CB plugin later * * @throws Exception - if CB not found * * @return void */ public function installPlugin() { JLoader::import("joomla.filesystem.file"); JLoader::import("joomla.filesystem.folder"); if (JFile::exists(JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php')) { global $_CB_framework; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/comprofiler.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php'; $plugin = "plug_cmc"; $cbInstaller = new cbInstallerPlugin(); if ($cbInstaller->install(JPATH_ROOT . '/components/com_comprofiler/plugin/user/' . $plugin . '/')) { $langPath = JPATH_ROOT . '/components/com_comprofiler/plugin/user/' . $plugin . '/administrator/language'; $cbNames = explode('_', $plugin); if (JFolder::exists($langPath)) { $languages = JFolder::folders($langPath); foreach ($languages as $language) { if (JFolder::exists(JPATH_ROOT . '/administrator/language/' . $language)) { JFile::copy($langPath . '/' . $language . '/' . $language . '.plg_' . $cbNames[1] . '.ini', JPATH_ROOT . '/administrator/language/' . $language . '/' . $language . '.plg_' . $cbNames[1] . '.ini'); } } } } else { throw new Exception("CB plugin installation failed"); } } else { throw new Exception("CB Framework not found", 404); } $msg = JText::_('COM_CMC_CB_PLUGIN_INSTALLED_SUCCESSFULLY'); $this->setRedirect('index.php?option=com_cmc&view=lists', $msg); }
/** * Function to install an AUP rule * * @param object $parent - the parent installer object * @param string $pluginName - the plugin name * * @return boolean */ public static function install($parent, $pluginName) { $status = false; if (JFile::exists(JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php')) { global $_CB_framework; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/comprofiler.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php'; $cbInstaller = new cbInstallerPlugin(); if ($cbInstaller->install($parent->getParent()->getPath('source') . '/components/com_comprofiler/plugin/user/' . $pluginName . '/')) { $path = $parent->getParent()->getPath('source') . '/components/com_comprofiler/plugin/user/' . $pluginName . '/administrator/language'; if (JFolder::exists($path)) { $languages = JFolder::folders($path); foreach ($languages as $language) { if (JFolder::exists(JPATH_ROOT . '/administrator/language/' . $language)) { if (file_exists($path . '/' . $language . '/' . $language . '.plg_' . $pluginName . '.ini')) { JFile::copy($path . '/' . $language . '/' . $language . '.plg_' . $pluginName . '.ini', JPATH_ROOT . '/administrator/language/' . $language . '/' . $language . '.plg_' . $pluginName . '.ini'); } elseif (file_exists($path . '/' . $language . '/' . $language . '.plg_' . str_replace('plug_', '', $pluginName) . '.ini')) { JFile::copy($path . '/' . $language . '/' . $language . '.plg_' . str_replace('plug_', '', $pluginName) . '.ini', JPATH_ROOT . '/administrator/language/' . $language . '/' . $language . '.plg_' . str_replace('plug_', '', $pluginName) . '.ini'); } } } } $status = true; } } return $status; }
/** * Installs the plugin By in-place Discovery * * @param string $plgFile Directory discovered * @return boolean Success */ private function installPluginDisc($plgFile) { global $_CB_framework; // Try extending time, as unziping/ftping took already quite some... : @set_time_limit(240); _CBsecureAboveForm('showPlugins'); outputCbTemplate(2); outputCbJs(2); initToolTip(2); $installer = new cbInstallerPlugin(); // Check if file xml exists if (!$plgFile) { cbInstaller::showInstallMessage(CBTxt::T('No file selected'), CBTxt::T('Install new plugin from discovery - error'), false); return false; } $path = _cbPathName($_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin/' . $plgFile); if (!is_dir($path)) { $path = dirname($path); } if (!is_dir($path)) { cbInstaller::showInstallMessage(CBTxt::T('FILE_DOES_NOT_EXIST_FILE', 'File does not exist - [file]', array('[file]' => $path)), CBTxt::T('INSTALL_NEW_PLUGIN_FROM_DISCOVERY_ERROR', 'Install new plugin from discovery - error'), false); return false; } $ret = $installer->install($path, true); cbInstaller::showInstallMessage($installer->getError(), CBTxt::T('INSTALL_NEW_PLUGIN_FROM_DISCOVERY_ERROR_FILE_STATUS', 'Install new plugin from discovery - [file] - [status]', array('[file]' => $path, '[status]' => $ret ? CBTxt::T('Success') : CBTxt::T('Failed'))), $ret); return $ret; }
/** * Deletes this record (no checks) * * @param int $oid Key id of row to delete (otherwise it's the one of $this) (only int supported here) * @return boolean TRUE if OK, FALSE if error */ public function delete($oid = null) { $k = $this->_tbl_key; if ($oid) { $this->{$k} = (int) $oid; } cbimport('cb.installer'); ob_start(); $plgInstaller = new \cbInstallerPlugin(); //TODO: Move $installed = $plgInstaller->uninstall($this->{$k}, 'com_comprofiler'); ob_end_clean(); if (!$installed) { $this->_error = $plgInstaller->getError(); return false; } return true; }
/** * Installs subextensions (modules, plugins) bundled with the main extension * * @param JInstaller $parent * @return JObject The subextension installation status */ private function _installSubextensions($parent) { if (version_compare(JVERSION, '1.6.0', 'ge')) { $src = $parent->getParent()->getPath('source'); } else { $src = $parent->getPath('source'); } $db = JFactory::getDbo(); $status = new JObject(); $status->modules = array(); $status->plugins = array(); $status->adsmanagerfields = array(); $src = str_replace('backend', '', $src); // Modules installation if (count($this->installation_queue['modules'])) { foreach ($this->installation_queue['modules'] as $folder => $modules) { if (count($modules)) { foreach ($modules as $module => $modulePreferences) { // Install the module if (empty($folder)) { $folder = 'site'; } $path = "{$src}/modules/{$folder}/{$module}"; if (!is_dir($path)) { $path = "{$src}/modules/{$folder}/mod_{$module}"; } if (!is_dir($path)) { $path = "{$src}/modules/{$module}"; } if (!is_dir($path)) { $path = "{$src}/modules/mod_{$module}"; } if (!is_dir($path)) { continue; } // Was the module already installed? if (version_compare(JVERSION, '1.6.0', 'ge')) { $sql = $db->getQuery(true)->select('COUNT(*)')->from('#__modules')->where($db->qn('module') . ' = ' . $db->q('mod_' . $module)); $db->setQuery($sql); $count = $db->loadResult(); } else { $count = 1; } $installer = new JInstaller(); $result = $installer->install($path); $status->modules[] = array('name' => 'mod_' . $module, 'client' => $folder, 'result' => $result); // Modify where it's published and its published state if (!$count) { // A. Position and state list($modulePosition, $modulePublished) = $modulePreferences; if ($modulePosition == 'cpanel') { $modulePosition = 'icon'; } if (version_compare(JVERSION, '3.0.2', 'ge')) { if ($modulePosition == "left") { $modulePosition = 'position-7'; } } $sql = $db->getQuery(true)->update($db->qn('#__modules'))->set($db->qn('position') . ' = ' . $db->q($modulePosition))->where($db->qn('module') . ' = ' . $db->q('mod_' . $module)); if ($modulePublished) { $sql->set($db->qn('published') . ' = ' . $db->q('1')); } $db->setQuery($sql); $db->query(); // B. Change the ordering of back-end modules to 1 + max ordering if ($folder == 'admin') { $query = $db->getQuery(true); $query->select('MAX(' . $db->qn('ordering') . ')')->from($db->qn('#__modules'))->where($db->qn('position') . '=' . $db->q($modulePosition)); $db->setQuery($query); $position = $db->loadResult(); $position++; $query = $db->getQuery(true); $query->update($db->qn('#__modules'))->set($db->qn('ordering') . ' = ' . $db->q($position))->where($db->qn('module') . ' = ' . $db->q('mod_' . $module)); $db->setQuery($query); $db->query(); } // C. Link to all pages $query = $db->getQuery(true); $query->select('id')->from($db->qn('#__modules'))->where($db->qn('module') . ' = ' . $db->q('mod_' . $module)); $db->setQuery($query); $moduleid = $db->loadResult(); $query = $db->getQuery(true); $query->select('*')->from($db->qn('#__modules_menu'))->where($db->qn('moduleid') . ' = ' . $db->q($moduleid)); $db->setQuery($query); $assignments = $db->loadObjectList(); $isAssigned = !empty($assignments); if (!$isAssigned) { $o = (object) array('moduleid' => $moduleid, 'menuid' => 0); $db->insertObject('#__modules_menu', $o); } } } } } } if (version_compare(JVERSION, '1.6.0', 'ge')) { $this->installation_queue['plugins']['sh404sefextplugins'] = array('sh404sefextplugincom_adsmanager' => 1); } else { $this->installation_queue['plugins']['sh404sefextplugins'] = array('com_adsmanager' => 1); unset($this->installation_queue['plugins']['xmap']); } // Plugins installation if (count($this->installation_queue['plugins'])) { foreach ($this->installation_queue['plugins'] as $folder => $plugins) { if (count($plugins)) { foreach ($plugins as $plugin => $published) { $path = "{$src}/plugins/{$folder}/{$plugin}"; if (!is_dir($path)) { $path = "{$src}/plugins/{$folder}/plg_{$plugin}"; } if (!is_dir($path)) { $path = "{$src}/plugins/{$plugin}"; } if (!is_dir($path)) { $path = "{$src}/plugins/plg_{$plugin}"; } if (!is_dir($path)) { continue; } // Was the plugin already installed? if (version_compare(JVERSION, '1.6.0', 'ge')) { $query = $db->getQuery(true)->select('COUNT(*)')->from($db->qn('#__extensions'))->where($db->qn('element') . ' = ' . $db->q($plugin))->where($db->qn('folder') . ' = ' . $db->q($folder)); $db->setQuery($query); $count = $db->loadResult(); } else { $count = 1; } $installer = new JInstaller(); $result = $installer->install($path); $status->plugins[] = array('name' => 'plg_' . $plugin, 'group' => $folder, 'result' => $result); if ($published && !$count) { $query = $db->getQuery(true)->update($db->qn('#__extensions'))->set($db->qn('enabled') . ' = ' . $db->q('1'))->where($db->qn('element') . ' = ' . $db->q($plugin))->where($db->qn('folder') . ' = ' . $db->q($folder)); $db->setQuery($query); $db->query(); } } } } } // External Plugins installation if (count($this->installation_queue['adsmanagerfields'])) { $path = JPATH_SITE . "/images/com_adsmanager/plugins"; if (file_exists($path)) { foreach ($this->installation_queue['adsmanagerfields'] as $folder => $plugins) { if (count($plugins)) { foreach ($plugins as $plugin) { $destPath = $path . "/" . $folder; $sourcePath = $src . "/adsmanagerfields/" . $folder; if (is_dir($destPath)) { //echo "ok"; $this->rmdir_recurse($destPath); //if (is_dir($destPath)) //echo "ok"; } @mkdir($path); $this->recurse_copy($sourcePath, $destPath); if (file_exists($destPath . '/plug.php')) { include_once $destPath . '/plug.php'; if (isset($plugins[$folder])) { $plugins[$folder]->install(); } } } } $status->adsmanagerfields[] = array('name' => $folder, 'group' => '', 'result' => 'Installed'); } } } // External Plugins installation if (file_exists(JPATH_ROOT . '/components/com_comprofiler/comprofiler.php')) { global $_CB_framework, $mainframe; if (defined('JPATH_ADMINISTRATOR')) { if (!file_exists(JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php')) { echo 'CB not installed!'; return; } include_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php'; } else { if (!file_exists($mainframe->getCfg('absolute_path') . '/administrator/components/com_comprofiler/plugin.foundation.php')) { echo 'CB not installed!'; return; } include_once $mainframe->getCfg('absolute_path') . '/administrator/components/com_comprofiler/plugin.foundation.php'; } cbimport('cb.html'); cbimport('cb.installer'); $installer = new cbInstallerPlugin(); $sourcePath = $src . "/cbplugins/"; if (count($this->installation_queue['cbplugins'])) { foreach ($this->installation_queue['cbplugins'] as $plugin) { if ($installer->install($sourcePath . $plugin . "/")) { $installed = true; } else { $installed = false; } $installer->cleanupInstall(null, $installer->unpackDir()); $status->plugins[] = array('name' => 'CB Plugin ' . ucfirst($plugin), 'group' => '', 'result' => $installed); } } } $app = JFactory::getApplication(); $source = $src . "/langplugins/joomfish"; if (file_exists(JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/")) { JFile::copy($source . "/adsmanager_ads.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_ads.xml"); JFile::copy($source . "/adsmanager_categories.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_categories.xml"); JFile::copy($source . "/adsmanager_columns.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_columns.xml"); JFile::copy($source . "/adsmanager_config.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_config.xml"); JFile::copy($source . "/adsmanager_fields.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_fields.xml"); JFile::copy($source . "/adsmanager_field_values.xml", JPATH_ROOT . "/administrator/components/com_joomfish/contentelements/adsmanager_field_values.xml"); $status->plugins[] = array('name' => 'Joomfish XML files', 'group' => '', 'result' => true); } $source = $src . "/langplugins/falang"; if (file_exists(JPATH_ROOT . "/administrator/components/com_falang/contentelements/")) { JFile::copy($source . "/adsmanager_ads.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_ads.xml"); JFile::copy($source . "/adsmanager_categories.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_categories.xml"); JFile::copy($source . "/adsmanager_columns.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_columns.xml"); JFile::copy($source . "/adsmanager_config.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_config.xml"); JFile::copy($source . "/adsmanager_fields.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_fields.xml"); JFile::copy($source . "/adsmanager_field_values.xml", JPATH_ROOT . "/administrator/components/com_falang/contentelements/adsmanager_field_values.xml"); $status->plugins[] = array('name' => 'Falang XML files', 'group' => '', 'result' => true); } return $status; }
function finishInstallation($option) { global $_CB_framework, $ueConfig, $task; // Try extending time, as unziping/ftping took already quite some... : @set_time_limit(240); _CBsecureAboveForm('finishInstallation'); $tgzFile = $_CB_framework->getCfg('absolute_path') . '/administrator/components/com_comprofiler/pluginsfiles.tgz'; $installerFile = $_CB_framework->getCfg('absolute_path') . '/administrator/components/com_comprofiler/'; if (file_exists($installerFile . 'comprofiler.xml')) { $installerFile .= 'comprofiler.xml'; } elseif (file_exists($installerFile . 'comprofilej.xml')) { $installerFile .= 'comprofilej.xml'; } elseif (file_exists($installerFile . 'comprofileg.xml')) { $installerFile .= 'comprofileg.xml'; } if (!file_exists($tgzFile)) { echo CBTxt::T('UE_NOT_AUTHORIZED', 'You are not authorized to view this page!'); return; } $installer = new cbInstallerPlugin(); $client = 2; // Check that the zlib is available if (!extension_loaded('zlib')) { cbInstaller::renderInstallMessage(CBTxt::T('The installer cannot continue before zlib is installed'), CBTxt::T('Installer - Error'), $installer->returnTo($option, $task, $client)); return; } if (!$installer->upload($tgzFile, true, false)) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Uncompressing %s failed.'), $tgzFile), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } $adminFS = cbAdminFileSystem::getInstance(); $installFrom = $installer->installDir(); $filesList = cbReadDirectory($installFrom, '.', true); // check if core directories exist as are needed to install plugins: $baseDir = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler'; if (!$adminFS->is_dir($baseDir . '/plugin')) { if (!$adminFS->mkdir($baseDir . '/plugin')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $baseDir . '/plugin'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } if (!$adminFS->copy($baseDir . '/index.html', $baseDir . '/plugin/index.html')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create index "%s"'), $baseDir . '/plugin/index.html'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } } if (!$adminFS->is_dir($baseDir . '/plugin/language')) { if (!$adminFS->mkdir($baseDir . '/plugin/language')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $baseDir . '/plugin/language'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } if (!$adminFS->copy($baseDir . '/index.html', $baseDir . '/plugin/language/index.html')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create index "%s"'), $baseDir . '/plugin/language/index.html'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } } if (!$adminFS->is_dir($baseDir . '/plugin/templates')) { if (!$adminFS->mkdir($baseDir . '/plugin/templates')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $baseDir . '/plugin/templates'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } if (!$adminFS->copy($baseDir . '/index.html', $baseDir . '/plugin/templates/index.html')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create index "%s"'), $baseDir . '/plugin/templates/index.html'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } } if (!$adminFS->is_dir($baseDir . '/plugin/user')) { if (!$adminFS->mkdir($baseDir . '/plugin/user')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $baseDir . '/plugin/user'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } if (!$adminFS->copy($baseDir . '/index.html', $baseDir . '/plugin/user/index.html')) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Failed to create index "%s"'), $baseDir . '/plugin/user/index.html'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } } // install core plugins: foreach ($filesList as $file) { if (preg_match('/^.+\\.xml$/i', $file)) { $plgPath = $installFrom . (substr($installFrom, -1, 1) == '/' ? '' : '/') . $file; $plgXml = new \CBLib\Xml\SimpleXMLElement(trim(file_get_contents($plgPath))); if ($plgXml->getName() == 'cbinstall') { $plgDir = dirname($plgPath) . '/'; $plgInstaller = new cbInstallerPlugin(); if (!$plgInstaller->install($plgDir)) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Installing plugin failed with error: %s : %s'), $plgInstaller->i_elementname ? $plgInstaller->i_elementname : $file, $plgInstaller->getError()), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); return; } } } } $result = $adminFS->deldir(_cbPathName($installFrom . '/')); if ($result === false) { cbInstaller::renderInstallMessage(CBTxt::T('Deleting expanded tgz file directory failed with an error.'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); } $tgzFileOS = _cbPathName($tgzFile, false); $result = $adminFS->unlink($tgzFileOS); if ($result === false) { cbInstaller::renderInstallMessage(sprintf(CBTxt::T('Deleting file %s failed with an error.'), $tgzFileOS), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); } // adapt published fields to global CB config (regarding name type) _cbAdaptNameFieldsPublished($ueConfig); $htmlToDisplay = $_CB_framework->getUserState('com_comprofiler_install'); // clears the session buffer memory after installaion done: $_CB_framework->setUserState('com_comprofiler_install', ''); $installerXml = new SimpleXMLElement(file_get_contents($installerFile)); if (is_object($installerXml)) { $description = $installerXml->getElementByPath('description'); if ($description !== false) { echo '<h2>' . $description->data() . '</h2>'; } } echo $htmlToDisplay; echo '<div style="color:green;font-size:18px;font-weight:bold;margin-top:15px;margin-bottom:15px;">' . CBTxt::Th('Installation done.') . '</div>' . '<div style="color:green;font-size:18px;font-weight:bold;margin-top:15px;margin-bottom:15px;">' . CBTxt::Th('Now is a great time to checkout the <a href="[help_url]" target="_blank">Getting Started</a> resources.', null, array('[help_url]' => 'http://www.joomlapolis.com/documentation/community-builder/getting-started?pk_campaign=in-cb&pk_kwd=installedwelcomescreen')) . '</div>' . '<div style="margin-bottom:10px;">' . '<div style="font-size:12px;"><a href="http://www.joomlapolis.com/cb-solutions?pk_campaign=in-cb&pk_kwd=installedwelcomescreen" target="_blank">' . CBTxt::Th('Click here to see more CB Plugins (Languages, Fields, Tabs, Signup-Connect, Paid Memberships and over 30 more) by CB Team at joomlapolis.com') . '</a></div>' . '<div style="font-size:12px;"><a href="http://extensions.joomla.org/extensions/clients-a-communities/communities/210" target="_blank">' . CBTxt::Th('Click here to see our CB listing on the Joomla! Extensions Directory (JED) and find third-party add-ons for your website.') . '</a></div>' . '<div style="font-size:12px;margin:10px 0 25px;">or <a href="index.php?option=com_comprofiler&view=showconfig" class="btn btn-primary">' . CBTxt::Th('Start to Configure Community Builder') . '</a></div>' . '</div>'; $_CB_framework->setUserState("com_comprofiler_install", ''); }
/** * method to run after an install/update/discover method * * @param string $type - the type * @param object $parent - the parent object * * @return void */ public function postflight($type, $parent) { $path = $parent->getParent()->getPath('source'); $this->status = new stdClass(); $dbInstaller = new CompojoomDatabaseInstaller(array('dbinstaller_directory' => $path . '/administrator/components/com_cmc/sql/xml')); $dbInstaller->updateSchema(); // Let us install the modules $this->status->plugins = $this->installer->installPlugins($this->installationQueue['plugins']); $this->status->modules = $this->installer->installModules($this->installationQueue['modules']); $this->status->libraries = $this->installer->installLibraries($this->installationQueue['libraries']); $this->status->cb = false; if (JFile::exists(JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php')) { global $_CB_framework; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.foundation.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/comprofiler.class.php'; require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/library/cb/cb.installer.php'; foreach ($this->installationQueue['cbplugins'] as $plugin) { $cbInstaller = new cbInstallerPlugin(); if ($cbInstaller->install($path . '/components/com_comprofiler/plugin/user/' . $plugin . '/')) { $langPath = $parent->getParent()->getPath('source') . '/components/com_comprofiler/plugin/user/' . $plugin . '/administrator/language'; $cbNames = explode('_', $plugin); if (JFolder::exists($langPath)) { $languages = JFolder::folders($langPath); foreach ($languages as $language) { if (JFolder::exists(JPATH_ROOT . '/administrator/language/' . $language)) { JFile::copy($langPath . '/' . $language . '/' . $language . '.plg_' . $cbNames[1] . '.ini', JPATH_ROOT . '/administrator/language/' . $language . '/' . $language . '.plg_' . $cbNames[1] . '.ini'); } } } $this->status->cb = true; } } } echo $this->displayInfoInstallation(); }
function installExtensions($mainmsg) { jimport('joomla.installer.helper'); jimport('joomla.installer.installer'); jimport('joomla.filesystem.file'); jimport('joomla.filesystem.folder'); $db =& JFactory::getDBO(); $installer = new JInstaller(); // $installer->_overwrite = true; $pkg_path = JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_joomailermailchimpintegration' . DS . 'extensions' . DS; $pkgs = array('com_joomailermailchimpsignup.zip' => 'Joomlamailer Signup component', 'plg_joomailermailchimpsignup.zip' => 'Joomlamailer Signup plugin', 'mod_mailchimpsignup.zip' => 'MailChimp Signup', 'mod_mailchimpstats.zip' => 'MailChimp Admin Stats', 'plg_fmsts.zip' => 'MailChimp STS plugin', 'plg_joomlamailer_JomSocial.zip' => 'JomSocial plugin', 'plg_joomlamailer_CommunityBuilder.zip' => 'CommunityBuilder plugin'); $mainframe =& JFactory::getApplication(); foreach ($pkgs as $pkg => $pkgname) { if ($pkg == 'plg_joomlamailer_CommunityBuilder.zip') { $cbinstaller = JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_comprofiler' . DS . 'library' . DS . 'cb' . DS . 'cb.installer.php'; if (JFile::exists($cbinstaller)) { require_once $cbinstaller; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_comprofiler' . DS . 'plugin.class.php'; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_comprofiler' . DS . 'plugin.foundation.php'; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_comprofiler' . DS . 'library' . DS . 'cb' . DS . 'cb.database.php'; require_once JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_comprofiler' . DS . 'comprofiler.class.php'; $installer = new cbInstallerPlugin(); $installer->installArchive($pkg_path . $pkg); $installer->extractArchive(); if ($installer->install()) { $query = "UPDATE #__comprofiler_plugin SET `published` = '1' WHERE `folder` = 'plug_joomlamailercbsignup'"; $db->setQuery($query); $db->query(); } } } else { $package = JInstallerHelper::unpack($pkg_path . $pkg); if ($installer->install($package['dir'])) { $msg = 1; $msgtext = "{$pkgname} successfully installed."; } else { $msg = 0; $msgtext = "ERROR: Could not install the {$pkgname}. Please install manually."; } if (!$msg) { $mainframe->redirect('index.php', $msgtext . "\n" . $mainmsg); } else { if ($pkg == 'com_joomailermailchimpsignup.zip') { // remove signup component from backend menu if (version_compare(JVERSION, '1.6.0', 'ge')) { $query = "DELETE FROM #__menu WHERE `title` = 'com_joomailermailchimpsignup';"; $db->setQuery($query); $db->query(); } } else { if ($pkg == 'mod_mailchimpstats.zip') { $query = "UPDATE #__modules SET published = '1', position = 'cpanel', ordering = '-1' WHERE `module` = 'mod_mailchimpstats'"; $db->setQuery($query); $db->query(); if (version_compare(JVERSION, '1.6.0', 'ge')) { $query = "SELECT id FROM #__modules WHERE `module` = 'mod_mailchimpstats'"; $db->setQuery($query); $moduleID = $db->loadResult(); $query = "INSERT INTO #__modules_menu (moduleid, menuid) VALUES ('" . $moduleID . "', '0')"; $db->setQuery($query); $db->query(); } } else { if ($pkg == 'plg_joomlamailer_JomSocial.zip') { if (version_compare(JVERSION, '1.6.0', 'ge')) { $query = "UPDATE #__extensions SET `enabled` = '1' WHERE `element` = 'joomlamailer' AND `folder` = 'community'"; } else { $query = "UPDATE #__plugins SET `published` = '1' WHERE `element` = 'joomlamailer' AND `folder` = 'community'"; } $db->setQuery($query); $db->query(); } } } } } } $path = JPATH_ADMINISTRATOR . DS . 'components' . DS . 'com_joomailermailchimpintegration' . DS . 'extensions'; if (JFolder::exists($path)) { JFolder::delete($path); } }
function plug_cbgallery_install() { global $_CB_framework, $_CB_database; $plugin = new PluginTable(); if ( $plugin->load( array( 'element' => 'cb.profilegallery' ) ) ) { $path = $_CB_framework->getCfg( 'absolute_path' ); $indexPath = $path . '/components/com_comprofiler/plugin/user/plug_cbgallery/index.html'; $oldFilesPath = $path . '/images/comprofiler/plug_profilegallery'; $newFilesPath = $path . '/images/comprofiler/plug_cbgallery'; $query = 'SELECT *' . "\n FROM " . $_CB_database->NameQuote( '#__comprofiler_plug_profilegallery' ); $_CB_database->setQuery( $query ); $rows = $_CB_database->loadObjectList( null, '\CBLib\Database\Table\Table', array( $_CB_database, '#__comprofiler_plug_profilegallery', 'id' ) ); /** @var $rows Table[] */ foreach ( $rows as $row ) { $oldFilePath = $oldFilesPath . '/' . (int) $row->get( 'userid' ); if ( in_array( $row->get( 'pgitemtype' ), array( 'jpg', 'jpeg', 'gif', 'png' ) ) ) { $type = 'photos'; } else { $type = 'files'; } $newFilePath = $newFilesPath . '/' . (int) $row->get( 'userid' ) . '/' . $type; if ( ( ! file_exists( $oldFilePath . '/' . $row->get( 'pgitemfilename' ) ) ) || ( ( $type == 'photos' ) && ( ! file_exists( $oldFilePath . '/tn' . $row->get( 'pgitemfilename' ) ) ) ) ) { continue; } $cleanFileName = str_replace( 'pg_', '', pathinfo( $row->get( 'pgitemfilename' ), PATHINFO_FILENAME ) ); $newFileName = uniqid( $cleanFileName . '_' ) . '.' . strtolower( pathinfo( $row->get( 'pgitemfilename' ), PATHINFO_EXTENSION ) ); if ( cbReadDirectory( $newFilePath, '^' . preg_quote( $cleanFileName ) ) ) { $query = 'SELECT COUNT(*)' . "\n FROM " . $_CB_database->NameQuote( '#__comprofiler_plugin_gallery_items' ) . "\n WHERE " . $_CB_database->NameQuote( 'user_id' ) . " = " . (int) $row->get( 'userid' ) . "\n AND " . $_CB_database->NameQuote( 'value' ) . " LIKE " . $_CB_database->Quote( '%' . $_CB_database->getEscaped( $cleanFileName, true ) . '%', false ); $_CB_database->setQuery( $query ); if ( $_CB_database->loadResult() ) { continue; } } if ( ! is_dir( $newFilesPath ) ) { $oldMask = @umask( 0 ); if ( @mkdir( $newFilesPath, 0755, true ) ) { @umask( $oldMask ); @chmod( $newFilesPath, 0755 ); if ( ! file_exists( $newFilesPath . '/index.html' ) ) { @copy( $indexPath, $newFilesPath . '/index.html' ); @chmod( $newFilesPath . '/index.html', 0755 ); } } else { @umask( $oldMask ); } } if ( ! file_exists( $newFilesPath . '/.htaccess' ) ) { file_put_contents( $newFilesPath . '/.htaccess', 'deny from all' ); } if ( ! is_dir( $newFilePath ) ) { $oldMask = @umask( 0 ); if ( @mkdir( $newFilePath, 0755, true ) ) { @umask( $oldMask ); @chmod( $newFilePath, 0755 ); if ( ! file_exists( $newFilePath . '/index.html' ) ) { @copy( $indexPath, $newFilePath . '/index.html' ); @chmod( $newFilePath . '/index.html', 0755 ); } } else { @umask( $oldMask ); } } if ( ! @copy( $oldFilePath . '/' . $row->get( 'pgitemfilename' ), $newFilePath . '/' . $newFileName ) ) { continue; } else { @chmod( $newFilePath . '/' . $newFileName, 0755 ); } if ( $type == 'photos' ) { if ( ! @copy( $oldFilePath . '/tn' . $row->get( 'pgitemfilename' ), $newFilePath . '/tn' . $newFileName ) ) { continue; } else { @chmod( $newFilePath . '/tn' . $newFileName, 0755 ); } } $item = new Table( null, '#__comprofiler_plugin_gallery_items', 'id' ); $item->set( 'user_id', (int) $row->get( 'userid' ) ); $item->set( 'type', $type ); $item->set( 'value', $newFileName ); $item->set( 'folder', 0 ); $item->set( 'title', $row->get( 'pgitemtitle' ) ); $item->set( 'description', $row->get( 'pgitemdescription' ) ); $item->set( 'date', $row->get( 'pgitemdate' ) ); $item->set( 'published', ( $row->get( 'pgitemapproved', 0 ) ? (int) $row->get( 'pgitempublished', 0 ) : -1 ) ); if ( ! $item->store() ) { @unlink( $newFilePath . '/' . $newFileName ); if ( $type == 'photos' ) { @unlink( $newFilePath . '/tn' . $newFileName ); } } } $field = new FieldTable(); if ( $field->load( array( 'name' => 'cb_pgtotalquotaitems' ) ) ) { $field->set( 'type', 'integer' ); $field->set( 'tabid', 11 ); $field->set( 'pluginid', 1 ); $field->set( 'readonly', 1 ); $field->set( 'calculated', 0 ); $field->set( 'sys', 0 ); $field->store(); } $gallery = new PluginTable(); if ( $gallery->load( array( 'element' => 'cbgallery' ) ) ) { $galleryParams = new Registry( $gallery->params ); $galleryParams->set( 'photos_item_limit', 'cb_pgtotalquotaitems' ); $galleryParams->set( 'files_item_limit', 'cb_pgtotalquotaitems' ); $gallery->set( 'params', $galleryParams->asJson() ); $gallery->store(); } ob_start(); $plgInstaller = new cbInstallerPlugin(); $plgInstaller->uninstall( $plugin->id, 'com_comprofiler' ); ob_end_clean(); } }
function finishInstallation($option) { global $_CB_framework, $ueConfig, $task; // Try extending time, as unziping/ftping took already quite some... : @set_time_limit(240); HTML_comprofiler::secureAboveForm('finishInstallation'); $tgzFile = $_CB_framework->getCfg('absolute_path') . '/administrator/components/com_comprofiler/pluginsfiles.tgz'; $installerFile = $_CB_framework->getCfg('absolute_path') . '/administrator/components/com_comprofiler/'; if (file_exists($installerFile . 'comprofiler.xml')) { $installerFile .= 'comprofiler.xml'; } elseif (file_exists($installerFile . 'comprofilej.xml')) { $installerFile .= 'comprofilej.xml'; } elseif (file_exists($installerFile . 'comprofileg.xml')) { $installerFile .= 'comprofileg.xml'; } if (!file_exists($tgzFile)) { echo _UE_NOT_AUTHORIZED; return; } $installer = new cbInstallerPlugin(); $client = 2; // Check that the zlib is available if (!extension_loaded('zlib')) { HTML_comprofiler::showInstallMessage(CBTxt::T('The installer cannot continue before zlib is installed'), CBTxt::T('Installer - Error'), $installer->returnTo($option, $task, $client)); exit; } if (!$installer->upload($tgzFile, true, false)) { HTML_comprofiler::showInstallMessage(sprintf(CBTxt::T("Uncompressing %s failed."), $tgzFile), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); exit; } $installFrom = $installer->installDir(); $installTo = $_CB_framework->getCfg('absolute_path') . '/components/com_comprofiler/plugin'; $filesList = cbReadDirectory($installFrom, '.', true); // create directories and remove them from file list: if (!$installer->mosMakePath(dirname($installTo) . '/', 'plugin')) { HTML_comprofiler::showInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $installTo . '/plugin'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); exit; } foreach ($filesList as $k => $file) { if (basename($file) != $file) { $newdir = dirname($file); if (!$installer->mosMakePath($installTo . '/', $newdir)) { HTML_comprofiler::showInstallMessage(sprintf(CBTxt::T('Failed to create directory "%s"'), $installTo . '/' . $newdir), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); exit; } } if (!is_file($installFrom . '/' . $file)) { unset($filesList[$k]); } } $result = $installer->copyFiles($installFrom, $installTo, $filesList, true); if ($result === false) { HTML_comprofiler::showInstallMessage(sprintf(CBTxt::T("Copying plugin files failed with error: %s"), $installer->getError()), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); exit; } $adminFS =& cbAdminFileSystem::getInstance(); $result = $adminFS->deldir(_cbPathName($installFrom . '/')); if ($result === false) { HTML_comprofiler::showInstallMessage(CBTxt::T('Deleting expanded tgz file directory failed with an error.'), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); } $tgzFileOS = _cbPathName($tgzFile, false); $result = $adminFS->unlink($tgzFileOS); if ($result === false) { HTML_comprofiler::showInstallMessage(sprintf(CBTxt::T("Deleting file %s failed with an error."), $tgzFileOS), CBTxt::T('Installer - Error'), $installer->returnTo($option, '', 2)); } // adapt published fields to global CB config (regarding name type) _cbAdaptNameFieldsPublished($ueConfig); $htmlToDisplay = $_CB_framework->getUserState('com_comprofiler_install'); // clears the session buffer memory after installaion done: $_CB_framework->setUserState('com_comprofiler_install', ''); cbimport('cb.xml.simplexml'); $installerXml = new CBSimpleXMLElement(file_get_contents($installerFile)); if (is_object($installerXml)) { $description = $installerXml->getElementByPath('description'); if ($description !== false) { echo '<h2>' . $description->data() . '</h2>'; } } echo $htmlToDisplay; ?> <div style="font-weight:bold;font-size:110%;background:#ffffe4;border:2px green solid;padding:5px;margin-bottom:20px;"><font color="green"><?php echo CBTxt::T('Second and last installation step of Community Builder Component (comprofiler) done successfully.'); ?> </font></div><br /> <div style="font-weight:bold;font-size:125%;background:#ffffe4;border:2px green solid;padding:5px;"> <font color="green"><b><?php echo CBTxt::T('Installation finished. Important: Please read README.TXT and installation manual for further settings.'); ?> <br /><br /><?php echo CBTxt::T('We also have a PDF installation guide as well as a complete documentation available on'); ?> <a href="http://www.joomlapolis.com">www.joomlapolis.com</a> <?php echo CBTxt::T('which will help you making the most out of your Community Builder installation, while supporting this project, as well as plugins and templates.'); ?> </b></font> </div> <?php $_CB_framework->setUserState("com_comprofiler_install", ''); }
public function migrate() { $step = JRequest::getInt('step'); if (!$step) { echo json_encode(array('error' => "Invalid request (step = {$step})")); exit; } $db = JFactory::getDBO(); $res = array('success' => true); switch ($step) { // migrate plugin configuration case 1: $query = $db->getQuery(true)->select($db->qn(array('params', 'enabled')))->from($db->qn('#__extensions'))->where($db->qn('type') . ' = ' . $db->q('plugin'))->where($db->qn('folder') . ' = ' . $db->q('system'))->where($db->qn('element') . ' = ' . $db->q('joomailermailchimpsignup')); $db->setQuery($query); try { $pluginData = $db->loadObject(); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } if (!$pluginData) { $res = array('notRequired' => true); break; } $query = $db->getQuery(true)->update($db->qn('#__extensions'))->set($db->qn('enabled') . ' = ' . $db->q($pluginData->enabled))->set($db->qn('params') . ' = ' . $db->q($pluginData->params))->where($db->qn('type') . ' = ' . $db->q('plugin'))->where($db->qn('folder') . ' = ' . $db->q('user'))->where($db->qn('element') . ' = ' . $db->q('joomlamailer')); $db->setQuery($query); try { $db->execute(); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } break; // uninstall system plugin // uninstall system plugin case 2: $query = $db->getQuery(true)->select($db->qn('extension_id'))->from($db->qn('#__extensions'))->where($db->qn('type') . ' = ' . $db->q('plugin'))->where($db->qn('folder') . ' = ' . $db->q('system'))->where($db->qn('element') . ' = ' . $db->q('joomailermailchimpsignup')); $db->setQuery($query); try { $extension_id = $db->loadResult(); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } if ($extension_id) { jimport('joomla.installer.installer'); $installer = new JInstaller(); $installer->uninstall('plugin', $extension_id, 0); } else { $res = array('notRequired' => true); } break; // uninstall signup component // uninstall signup component case 3: $query = $db->getQuery(true)->select($db->qn('extension_id'))->from($db->qn('#__extensions'))->where($db->qn('type') . ' = ' . $db->q('component'))->where($db->qn('element') . ' = ' . $db->q('com_joomailermailchimpsignup')); $db->setQuery($query); try { $extension_id = $db->loadResult(); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } if ($extension_id) { jimport('joomla.installer.installer'); $installer = new JInstaller(); $installer->uninstall('component', $extension_id, 0); try { $db->dropTable('#__joomailermailchimpsignup'); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } } else { $res = array('notRequired' => true); } break; // uninstall community builder plugin // uninstall community builder plugin case 4: if (!JFile::exists(JPATH_ROOT . '/libraries/CBLib/CB/Application/CBApplication.php') || !JFile::exists(JPATH_ROOT . '/libraries/CBLib/CB/Legacy/LegacyComprofilerFunctions.php') || !JFile::exists(JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.class.php')) { $res = array('notRequired' => true); echo json_encode($res); exit; } $query = $db->getQuery(true)->select($db->qn('id'))->from($db->qn('#__comprofiler_plugin'))->where($db->qn('element') . ' = ' . $db->q('cb.joomlamailer'))->where($db->qn('folder') . ' = ' . $db->q('plug_joomlamailercbsignup')); $db->setQuery($query); try { $extension_id = $db->loadResult(); } catch (Exception $e) { $res = array('error' => $e->getMessage(), 'query' => $query); echo json_encode($res); exit; } if ($extension_id) { require_once JPATH_ROOT . '/libraries/CBLib/CB/Application/CBApplication.php'; require_once JPATH_ROOT . '/libraries/CBLib/CB/Legacy/LegacyComprofilerFunctions.php'; CB\Application\CBApplication::init()->getDI()->get('\\CB\\Legacy\\LegacyFoundationFunctions'); require_once JPATH_ADMINISTRATOR . '/components/com_comprofiler/plugin.class.php'; $cbInstallerPlugin = new cbInstallerPlugin(); $cbInstallerPlugin->uninstall($extension_id, 'com_joomailermailchimpintegration'); } else { $res = array('notRequired' => true); } break; default: echo json_encode(array('error' => "Invalid request (step = {$step})")); exit; } echo json_encode($res); }
function cbInstaller_uninstall_plugin($plugin, &$return) { if ($plugin->id) { ob_start(); $plgInstaller = new cbInstallerPlugin(); $installed = $plgInstaller->uninstall($plugin->id, 'com_comprofiler'); ob_end_clean(); if (!$installed) { $return .= '<div style="font-size:14px;color:red;margin-bottom:10px;">' . CBTxt::P('Conflicting plugin [element] failed to uninstall. Error: [error]', array('[element]' => $plugin->element, '[error]' => $plgInstaller->getError())) . '</div>'; return false; } } return true; }
public function install($adapter) { $app = JFactory::getApplication(); $installer = JInstaller::getInstance(); $source = $installer->getPath('source'); $out = ''; $extInstaller = new JInstaller(); // intsall RaidPlanner Today Module if ($extInstaller->install($source . '/mod_raidplanner_today')) { // module installed $out .= 'RaidPlanner Today module installed!<br />'; } else { $out .= 'RaidPlanner Today module installation failed!<br />'; } // intsall RaidPlanner Today Module if ($extInstaller->install($source . '/mod_raidplanner_events')) { // module installed $out .= 'RaidPlanner Events module installed!<br />'; } else { $out .= 'RaidPlanner Events module installation failed!<br />'; } // install RaidPlanner User Plugin (just for J 1.6!) if ($extInstaller->install($source . '/plg_raidplanner')) { // module installed $out .= 'RaidPlanner User plugin installed!<br />'; } else { $out .= 'RaidPlanner User plugin installation failed!<br />'; } /* Detect Community Builder */ jimport('joomla.application.component.helper'); $_CB_adminpath = JPATH_ADMINISTRATOR . '/components/com_comprofiler'; if (file_exists($_CB_adminpath . '/plugin.foundation.php')) { $cbComp = JComponentHelper::getComponent('com_comprofiler'); if ($cbComp && $cbComp->enabled) { try { global $_CB_framework; include_once $_CB_adminpath . '/plugin.foundation.php'; $_CB_framework->cbset('_ui', 2); cbimport('cb.tabs'); cbimport('cb.adminfilesystem'); cbimport('cb.installer'); $CB_installer = new cbInstallerPlugin(); $install_dir = $source . '/3rd_party_plugins/community_builder/plug_raidplanner/'; $ret = $CB_installer->install($install_dir); } catch (Exception $e) { $ret = 0; } $out .= "\nCommunity Builder installed in Joomla. RaidPlanner Community builder installation:" . ($ret ? "[OK]" : "[Failed]") . "<br />"; } } /* Detect JomSocial */ if (file_exists(JPATH_SITE . '/components/com_community/libraries/core.php')) { $ret = $extInstaller->install($source . '/3rd_party_plugins/jomsocial/'); $out .= "\nJomSocial is installed in Joomla. RaidPlanner JomSocial plugin installation:" . ($ret ? "[OK]" : "[Failed]") . "<br />"; /* patching customfields.xml file */ $xml = simplexml_load_file(JPATH_SITE . '/components/com_community/libraries/fields/customfields.xml'); $result = $xml->xpath('/jomsocial/fields/field/type[text()="rp_characters"]'); if (empty($result)) { /* add rp_characters to customfields */ $newfield = $xml->fields->addChild('field'); $newfield->addChild('type', 'rp_characters'); $newfield->addChild('name', 'RaidPlanner Characters'); $xml->saveXML(JPATH_SITE . '/components/com_community/libraries/fields/customfields.xml'); $out .= "<small>- RaidPlanner Characters fieldtype added to JomSocial</small><br>\n"; } } $out .= "<br />IMPORTANT!<br />Read the <a href=\"http://taracque.hu/wiki/raidplanner-docs/whats-new/\" target=\"_blank\">What's new section of RaidPlanner documentation</a> for latest changes!<br />"; $app->enqueueMessage($out); }