public function do_execute() { $mailing = TBGContext::getModule('mailing'); if (!$mailing->isOutgoingNotificationsEnabled()) { $this->cliEcho("Outgoing email notifications are disabled.\n", 'red', 'bold'); $this->cliEcho("\n"); return; } if (!$mailing->getMailingUrl()) { $this->cliEcho("You must configure the mailing url via the web interface before you can use this feature.\n", 'red', 'bold'); $this->cliEcho("\n"); return; } $this->cliEcho("Processing mail queue ... \n", 'white', 'bold'); $limit = $this->getProvidedArgument('limit', null); $messages = TBGMailQueueTable::getTable()->getQueuedMessages($limit); $this->cliEcho("Email(s) to process: "); $this->cliEcho(count($messages) . "\n", 'white', 'bold'); if ($this->getProvidedArgument('test', 'no') == 'no') { if (count($messages) > 0) { // $mailer = $mailing->getMailer(); $processed_messages = array(); $failed_messages = 0; try { foreach ($messages as $message_id => $message) { $retval = $mailing->send($message); $processed_messages[] = $message_id; if (!$retval) { $failed_messages++; } } } catch (Exception $e) { throw $e; } if (count($processed_messages)) { TBGMailQueueTable::getTable()->deleteProcessedMessages($processed_messages); $this->cliEcho("Emails successfully processed: "); $this->cliEcho(count($messages) . "\n", 'green', 'bold'); if ($failed_messages > 0) { $this->cliEcho("Emails processed with error(s): "); $this->cliEcho($failed_messages . "\n", 'red', 'bold'); } } } } else { $this->cliEcho("Not processing queue...\n"); } }
protected function _uninstallModule($module_name) { $this->cliEcho("Uninstall module\n", 'green', 'bold'); try { if (!$module_name || !file_exists(THEBUGGENIE_MODULES_PATH . $module_name . DS . 'module')) { throw new Exception("Please provide a valid module name"); } elseif (!TBGContext::isModuleLoaded($module_name)) { throw new Exception("This module is not installed"); } else { $this->cliEcho("Removing {$module_name} ..."); TBGContext::getModule($module_name)->uninstall(); $this->cliEcho(' ok!', 'green', 'bold'); $this->cliEcho("\n"); } } catch (Exception $e) { $this->cliEcho($e->getMessage() . "\n", 'red'); } }
public function do_execute() { /* Prepare variables */ $project = $this->getProvidedArgument('projectid'); $author = $this->getProvidedArgument('author'); $new_rev = $this->getProvidedArgument('revno'); $commit_msg = $this->getProvidedArgument('log'); $changed = $this->getProvidedArgument('changed'); $old_rev = $this->getProvidedArgument('oldrev', $new_rev - 1); $date = $this->getProvidedArgument('date', null); if (TBGContext::getModule('vcs_integration')->isUsingHTTPMethod()) { $this->cliEcho("This access method has been disallowed\n", 'red', 'bold'); exit; } if (!is_numeric($new_rev) && is_numeric($old_rev) || is_numeric($new_rev) && !is_numeric($old_rev)) { $this->cliEcho("If the old revision is specified, it must be the same format as the new revision (number or hash)\n", 'red', 'bold'); exit; } $output = TBGContext::getModule('vcs_integration')->addNewCommit($project, $commit_msg, $old_rev, $new_rev, $date, $changed, $author); $this->cliEcho($output); }
/** * Delete an article * * @param TBGRequest $request */ public function runDeleteArticle(TBGRequest $request) { try { if (!$this->article instanceof TBGWikiArticle) { throw new Exception($this->getI18n()->__('This article does not exist')); } if (!TBGContext::getModule('publish')->canUserDeleteArticle($this->article->getName())) { throw new Exception($this->getI18n()->__('You do not have permission to delete this article')); } if (!$request['article_name']) { throw new Exception($this->getI18n()->__('Please specify an article name')); } else { TBGWikiArticle::deleteByName($request['article_name']); } } catch (Exception $e) { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('title' => $this->getI18n()->__('An error occured'), 'error' => $e->getMessage())); } return $this->renderJSON(array('message' => $this->getI18n()->__('The article was deleted'))); }
public function canEdit() { return TBGContext::getModule('publish')->canUserEditArticle($this->getName()); }
public function runAddCommitGitorious(TBGRequest $request) { if (!TBGContext::getModule('vcs_integration')->isUsingHTTPMethod()) { echo 'Error: This access method has been disallowed'; exit; } $passkey = TBGContext::getRequest()->getParameter('passkey'); if ($passkey != TBGContext::getModule('vcs_integration')->getSetting('vcs_passkey')) { echo 'Error: Invalid passkey'; exit; } $project = TBGContext::getRequest()->getParameter('project'); $data = TBGContext::getRequest()->getParameter('payload', null, false); if (empty($data) || $data == null) { die('Error: Invalid data'); } if (!function_exists('json_decode')) { die('Error: Gitorious support requires either PHP 5.2.0 or later, or the json PECL module version 1.2.0 or later for prior versions of PHP'); } $entries = json_decode($data); echo $project; $previous = $entries->before; // Parse each commit individually foreach (array_reverse($entries->commits) as $commit) { $email = $commit->author->email; $author = $commit->author->name; $new_rev = $commit->id; $old_rev = $previous; $commit_msg = $commit->message; $time = strtotime($commit->timestamp); //$f_issues = array_unique($f_issues[3]); //$file_lines = preg_split('/[\n\r]+/', $changed); //$files = array(); echo TBGContext::getModule('vcs_integration')->addNewCommit($project, $commit_msg, $old_rev, $previous, $time, "", $author); $previous = $new_rev; exit; } }
<?php } else { ?> <h4> <div class="button button-green" style="float: right;" onclick="TBG.Main.Helpers.Backdrop.show('<?php echo make_url('get_partial_for_backdrop', array('key' => 'mailing_editincomingemailaccount', 'project_id' => $project->getId())); ?> ');"><?php echo __('Add new account'); ?> </div> <?php echo __('Incoming email accounts'); ?> </h4> <div id="mailing_incoming_accounts"> <?php foreach (TBGContext::getModule('mailing')->getIncomingEmailAccountsForProject(TBGContext::getCurrentProject()) as $account) { ?> <?php include_template('mailing/incomingemailaccount', array('account' => $account)); ?> <?php } ?> </div> <?php } ?> </div>
/** * Whether this user can access the specified module * * @param string $module The module key * * @return boolean */ public function hasModuleAccess($module) { return TBGContext::getModule($module)->hasAccess($this->getID()); }
<?php /* * Generate link for browser */ $link_repo = TBGContext::getModule('vcs_integration')->getSetting('browser_url_' . TBGContext::getCurrentProject()->getID()); if (TBGContext::getModule('vcs_integration')->getSetting('vcs_mode_' . TBGContext::getCurrentProject()->getID()) != TBGVCSIntegration::MODE_DISABLED) { echo link_tag(make_url('vcs_commitspage', array('project_key' => TBGContext::getCurrentProject()->getKey())), __('Commits'), $tbg_response->getPage() == 'vcs_commitspage' ? array('class' => 'selected') : array()); if (!$submenu && $tbg_response->getPage() == 'vcs_commitspage') { ?> <ul class="simple_list"> <li><a href="<?php echo $link_repo; ?> " target="_blank"><?php echo __('Browse source code'); ?> </a></li> </ul> <?php } }
/** * Show an article * * @param TBGRequest $request */ public function runEditArticle(TBGRequest $request) { $article_name = $this->article instanceof TBGWikiArticle ? $this->article->getName() : $request->getParameter('article_name'); if (!TBGContext::getModule('publish')->canUserEditArticle($article_name)) { TBGContext::setMessage('publish_article_error', TBGContext::getI18n()->__('You do not have permission to edit this article')); $this->forward(TBGContext::getRouting()->generate('publish_article', array('article_name' => $article_name))); } if ($request->isMethod(TBGRequest::POST)) { if ($request->hasParameter('new_article_name') && $request->getParameter('new_article_name') != '') { if ($request->hasParameter('change_reason') && trim($request->getParameter('change_reason')) != '') { try { if ($request->getParameter('article_id')) { if (($article = PublishFactory::article($request->getParameter('article_id'))) && $article instanceof TBGWikiArticle) { if ($article->getLastUpdatedDate() != $request->getParameter('last_modified')) { $this->error = TBGContext::getI18n()->__('The file has been modified since you last opened it'); } else { try { $article->setName($request->getParameter('new_article_name')); $article->setContent($request->getRawParameter('new_article_content')); if ($request->getParameter('preview')) { $this->article = $article; } else { $article->doSave(array(), $request->getParameter('change_reason')); TBGContext::setMessage('publish_article_message', TBGContext::getI18n()->__('The article was saved')); $this->forward(TBGContext::getRouting()->generate('publish_article', array('article_name' => $article->getName()))); } } catch (Exception $e) { $this->error = $e->getMessage(); } } } } } catch (Exception $e) { } if (($article = TBGWikiArticle::getByName($request->getParameter('new_article_name'))) && $article instanceof TBGWikiArticle && $article->getID() != $request->getParameter('article_id')) { $this->error = TBGContext::getI18n()->__('An article with that name already exists. Please choose a different article name'); } elseif (!$article instanceof TBGWikiArticle) { if ($request->getParameter('preview')) { $article = new TBGWikiArticle(); $article->setContent($request->getRawParameter('new_article_content')); $article->setName($request->getParameter('new_article_name')); $this->article = $article; } else { $article_id = TBGWikiArticle::createNew($request->getParameter('new_article_name'), $request->getRawParameter('new_article_content', ''), true); $this->forward(TBGContext::getRouting()->generate('publish_article', array('article_name' => $request->getParameter('new_article_name')))); } } } else { $this->error = TBGContext::getI18n()->__('You have to provide a reason for the changes'); } } else { $this->error = TBGContext::getI18n()->__('You need to specify the article name'); } } $this->preview = (bool) $request->getParameter('preview'); $this->article_title = null; $this->article_content = null; $this->article_intro = null; $this->change_reason = null; if ($this->article instanceof TBGWikiArticle) { $this->article_title = $this->article->getTitle(); $this->article_content = $this->article->getContent(); if ($request->isMethod(TBGRequest::POST)) { if ($request->hasParameter('new_article_name')) { $this->article_title = $request->getParameter('new_article_name'); } if ($request->hasParameter('new_article_content')) { $this->article_content = $request->getRawParameter('new_article_content'); } if ($request->hasParameter('change_reason')) { $this->change_reason = $request->getParameter('change_reason'); } } } else { if ($request->hasParameter('new_article_content')) { $this->article_content = $request->getRawParameter('new_article_content'); } TBGContext::loadLibrary('publish'); $this->article_title = str_replace(array(':', '_'), array(' ', ' '), get_spaced_name($this->article_name)); } }
/** * Log out the current user (does not work when auth method is set to http) */ public static function logout() { if (TBGSettings::isUsingExternalAuthenticationBackend()) { $mod = TBGContext::getModule(TBGSettings::getAuthenticationBackend()); $mod->logout(); } TBGEvent::createNew('core', 'pre_logout')->trigger(); self::getResponse()->deleteCookie('tbg3_username'); self::getResponse()->deleteCookie('tbg3_password'); self::getResponse()->deleteCookie('tbg3_elevated_password'); self::getResponse()->deleteCookie('tbg3_persona_session'); self::getResponse()->deleteCookie('THEBUGGENIE'); session_regenerate_id(true); TBGEvent::createNew('core', 'post_logout')->trigger(); }
public function doLogin($username, $password, $mode = 1) { $validgroups = $this->getSetting('groups'); $base_dn = $this->getSetting('b_dn'); $dn_attr = $this->escape($this->getSetting('dn_attr')); $username_attr = $this->escape($this->getSetting('u_attr')); $fullname_attr = $this->escape($this->getSetting('f_attr')); $buddyname_attr = $this->escape($this->getSetting('b_attr')); $email_attr = $this->escape($this->getSetting('e_attr')); $groups_members_attr = $this->escape($this->getSetting('g_attr')); $user_class = TBGContext::getModule('auth_ldap')->getSetting('u_type'); $group_class = TBGContext::getModule('auth_ldap')->getSetting('g_type'); $email = null; $integrated_auth = $this->getSetting('integrated_auth'); /* * Do the LDAP check here. * * If a connection error or something, throw an exception and log * * If we can, set $mail and $realname to correct values from LDAP * otherwise don't touch those variables. * * To log do: * TBGLogging::log('error goes here', 'ldap', TBGLogging::LEVEL_FATAL); */ try { /* * First job is to connect to our control user (may be an anonymous bind) * so we can find the user we want to log in as/validate. */ $connection = $this->connect(); $control_user = $this->getSetting('control_user'); $control_password = $this->getSetting('control_pass'); $this->bind($connection, $control_user, $control_password); // Assume bind successful, otherwise we would have had an exception /* * Search for a user with the username specified. We search in the base_dn, so we can * find users in multiple parts of the directory, and only return users of a specific * class (default person). * * We want exactly 1 user to be returned. We get the user's full name, email, cn * and dn. */ $fields = array($fullname_attr, $buddyname_attr, $email_attr, 'cn', $dn_attr); $filter = '(&(objectClass=' . TBGLDAPAuthentication::getModule()->escape($user_class) . ')(' . $username_attr . '=' . $this->escape($username) . '))'; $results = ldap_search($connection, $base_dn, $filter, $fields); if (!$results) { TBGLogging::log('failed to search for user: '******'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data = ldap_get_entries($connection, $results); // User does not exist if ($data['count'] == 0) { TBGLogging::log('could not find user ' . $username . ', class ' . $user_class . ', attribute ' . $username_attr, 'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('User does not exist in the directory')); } // If we have more than 1 user, something is seriously messed up... if ($data['count'] > 1) { TBGLogging::log('too many users for ' . $username . ', class ' . $user_class . ', attribute ' . $username_attr, 'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('This user was found multiple times in the directory, please contact your admimistrator')); } /* * If groups are specified, perform group restriction tests */ if ($validgroups != '') { /* * We will repeat this for every group, but groups are supplied as a comma-separated list */ if (strstr($validgroups, ',')) { $groups = explode(',', $validgroups); } else { $groups = array(); $groups[] = $validgroups; } // Assumed we are initially banned $allowed = false; foreach ($groups as $group) { // No need to carry on looking if we have access if ($allowed == true) { continue; } /* * Find the group we are looking for, we search the entire directory as per users (See that stuff) * We want to find 1 group, if we don't get 1, silently ignore this group. */ $fields2 = array($groups_members_attr); $filter2 = '(&(objectClass=' . TBGLDAPAuthentication::getModule()->escape($group_class) . ')(cn=' . $this->escape($group) . '))'; $results2 = ldap_search($connection, $base_dn, $filter2, $fields2); if (!$results2) { TBGLogging::log('failed to search for user after binding: ' . ldap_error($connection), 'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('Search failed ') . ldap_error($connection)); } $data2 = ldap_get_entries($connection, $results2); if ($data2['count'] != 1) { continue; } /* * Look through the group's member list. If we are found, grant access. */ foreach ($data2[0][strtolower($groups_members_attr)] as $member) { $member = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $member); $user_dn = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $data[0][strtolower($dn_attr)][0]); if (!is_numeric($member) && strtolower($member) == strtolower($user_dn)) { $allowed = true; } } } if ($allowed == false) { throw new Exception(TBGContext::getI18n()->__('You are not a member of a group allowed to log in')); } } /* * Set user's properties. * Realname is obtained from directory, if not found we set it to the username * Email is obtained from directory, if not found we set it to blank */ if (!array_key_exists(strtolower($fullname_attr), $data[0])) { $realname = $username; } else { $realname = $data[0][strtolower($fullname_attr)][0]; } if (!array_key_exists(strtolower($buddyname_attr), $data[0])) { $buddyname = $username; } else { $buddyname = $data[0][strtolower($buddyname_attr)][0]; } if (!array_key_exists(strtolower($email_attr), $data[0])) { $email = ''; } else { $email = $data[0][strtolower($email_attr)][0]; } /* * If we are performing a non integrated authentication login, * now bind to the user and see if the credentials * are valid. We bind using the full DN of the user, so no need for DOMAIN\ stuff * on Windows, and more importantly it fixes other servers. * * If the bind fails (exception), we throw a nicer exception and don't continue. */ if ($mode == 1 && !$integrated_auth) { try { if (!is_array($data[0][strtolower($dn_attr)])) { $dn = $data[0][strtolower($dn_attr)]; } else { $dn = $data[0][strtolower($dn_attr)][0]; } $bind = $this->bind($connection, $this->escape($dn), $password); } catch (Exception $e) { throw new Exception(TBGContext::geti18n()->__('Your password was not accepted by the server')); } } elseif ($mode == 1) { if (!isset($_SERVER[$this->getSetting('integrated_auth_header')]) || $_SERVER[$this->getSetting('integrated_auth_header')] != $username) { throw new Exception(TBGContext::geti18n()->__('HTTP authentication internal error.')); } } } catch (Exception $e) { ldap_unbind($connection); throw $e; } try { /* * Get the user object. If the user exists, update the user's * data from the directory. */ $user = TBGUser::getByUsername($username); if ($user instanceof TBGUser) { $user->setBuddyname($buddyname); $user->setRealname($realname); $user->setPassword($user->getJoinedDate() . $username); // update password $user->setEmail($email); // update email address $user->save(); } else { /* * If not, and we are performing an initial login, create the user object * if we are validating a log in, kick the user out as the session is invalid. */ if ($mode == 1) { // create user $user = new TBGUser(); $user->setUsername($username); $user->setRealname('temporary'); $user->setBuddyname($username); $user->setEmail('temporary'); $user->setEnabled(); $user->setActivated(); $user->setJoined(); $user->setPassword($user->getJoinedDate() . $username); $user->save(); } else { throw new Exception('User does not exist in TBG'); } } } catch (Exception $e) { ldap_unbind($connection); throw $e; } ldap_unbind($connection); /* * Set cookies and return user row for general operations. */ TBGContext::getResponse()->setCookie('tbg3_username', $username); TBGContext::getResponse()->setCookie('tbg3_password', TBGUser::hashPassword($user->getJoinedDate() . $username, $user->getSalt())); return TBGUsersTable::getTable()->getByUsername($username); }
" <?php if ($revision == $revision_count - 1) { ?> checked <?php } ?> name="from_revision" id="to_revision_<?php echo $revision; ?> "> <?php } ?> </td> <?php if ($revision < $revision_count && TBGContext::getModule('publish')->canUserEditArticle($article_name)) { ?> <td style="position: relative;"> <?php echo javascript_link_tag(__('Restore this version'), array('onclick' => "\$('restore_article_revision_{$revision}').toggle();")); ?> <div class="rounded_box white shadowed" style="width: 400px; position: absolute; right: 15px; display: none; z-index: 100;" id="restore_article_revision_<?php echo $revision; ?> "> <div class="header_div"><?php echo __('Are you sure you want to restore this revision?'); ?> </div> <div class="content" style="padding: 5px;"> <?php
/** * Return an instance of this module * * @return TBGVCSIntegration */ public static function getModule() { return TBGContext::getModule('vcs_integration'); }
protected function __construct($subject, $template, $parameters = array(), $language = null, $message_plain = null, $message_html = null, $recipients = array(), $charset = 'utf-8') { /* Prepare two separators. $sep1 for the html/text message part. $sep2 for the attachment part. */ for ($len = 10, $sep1 = ""; mb_strlen($sep1) < $len; $sep1 .= chr(!mt_rand(0, 2) ? mt_rand(48, 57) : (!mt_rand(0, 1) ? mt_rand(65, 90) : mt_rand(97, 122)))) { } for ($len = 10, $sep2 = ""; mb_strlen($sep2) < $len; $sep2 .= chr(!mt_rand(0, 2) ? mt_rand(48, 57) : (!mt_rand(0, 1) ? mt_rand(65, 90) : mt_rand(97, 122)))) { } $this->sep1 = "_1_" . bin2hex($sep1); $this->sep2 = "_2_" . bin2hex($sep2); $this->subject = $subject; if ($template !== null) { $this->template = $template; $this->template_parameters = $parameters; if ($language !== null) { $this->language = $language; } } elseif ($message_plain !== null) { $this->message_plain = $message_plain; $this->message_plain_replaced = $message_plain; if ($this->message_html !== null) { $this->message_html = $message_plain; $this->message_html_replaced = $message_plain; } } $recipients = (array) $recipients; foreach ($recipients as $recipient) { if (is_array($recipient)) { if (array_key_exists('name', $recipient)) { $this->addTo($recipient['address'], $recipient['name']); } elseif (count($recipient) == 2) { $this->addTo($recipient[1], $recipient[0]); } else { $this->addTo($recipient[0]); } } else { $this->addTo($recipient); } } $this->charset = $charset; $this->headers['X-Mailer'] = "TBG"; $this->headers['Subject'] = $subject; $this->headers['Date'] = date('r'); $this->headers['MIME-Version'] = "1.0"; $server_name = TBGContext::getModule('mailing')->getMailingUrl(true); $this->headers['Message-ID'] = "<{$this->sep1}@{$server_name}>"; }
public function runConfigureProjectSettings(TBGRequest $request) { $this->forward403unless($request->isPost()); if ($this->access_level != TBGSettings::ACCESS_FULL) { $project_id = $request['project_id']; if ($request['mailing_from_address'] != '') { if (filter_var(trim($request['mailing_from_address']), FILTER_VALIDATE_EMAIL) !== false) { TBGContext::getModule('mailing')->saveSetting(TBGMailing::SETTING_PROJECT_FROM_ADDRESS . $project_id, trim(mb_strtolower($request->getParameter('mailing_from_address')))); if (trim($request['mailing_from_name']) !== '') { TBGContext::getModule('mailing')->saveSetting(TBGMailing::SETTING_PROJECT_FROM_NAME . $project_id, trim($request->getParameter('mailing_from_name'))); } else { TBGContext::getModule('mailing')->deleteSetting(TBGMailing::SETTING_PROJECT_FROM_NAME . $project_id); } } else { $this->getResponse()->setHttpStatus(400); return $this->renderJSON(array('message' => TBGContext::getI18n()->__('Please enter a valid email address'))); } } elseif ($request->getParameter('mailing_reply_address') == '') { TBGContext::getModule('mailing')->deleteSetting(TBGMailing::SETTING_PROJECT_FROM_ADDRESS . $project_id); TBGContext::getModule('mailing')->deleteSetting(TBGMailing::SETTING_PROJECT_FROM_NAME . $project_id); } return $this->renderJSON(array('failed' => false, 'message' => TBGContext::getI18n()->__('Settings saved'))); } else { $this->forward403(); } }
<?php if ($commits == false) { ?> <br><br> <p class="faded_out">No commits for this time range were found for this project.</p> <?php } else { ?> <div class="project_commits_box"> <?php $web_path = TBGContext::getModule('vcs_integration')->getSetting('web_path_' . $selected_project->getID()); $web_repo = TBGContext::getModule('vcs_integration')->getSetting('web_repo_' . $selected_project->getID()); foreach ($commits as $revno => $entry) { $revision = $revno; /* Build correct URLs */ switch (TBGContext::getModule('vcs_integration')->getSetting('web_type_' . $selected_project->getID())) { case 'viewvc': $link_rev = $web_path . '/' . '?root=' . $web_repo . '&view=rev&revision=' . $revision; break; case 'viewvc_repo': $link_rev = $web_path . '/' . '?view=rev&revision=' . $revision; break; case 'websvn': $link_rev = $web_path . '/revision.php?repname=' . $web_repo . '&isdir=1&rev=' . $revision; break; case 'websvn_mv': $link_rev = $web_path . '/' . '?repname=' . $web_repo . '&op=log&isdir=1&rev=' . $revision; break; case 'loggerhead': $link_rev = $web_path . '/' . $web_repo . '/revision/' . $revision; break;
public function listen_viewissue_panel(TBGEvent $event) { if (TBGContext::getModule('vcs_integration')->getSetting('vcs_mode_' . TBGContext::getCurrentProject()->getID()) == TBGVCSIntegration::MODE_DISABLED) { return; } $links = TBGVCSIntegrationIssueLink::getCommitsByIssue($event->getSubject()); TBGActionComponent::includeTemplate('vcs_integration/viewissue_commits', array('links' => $links, 'projectId' => $event->getSubject()->getProject()->getID())); }
/** * Import all valid users * * @param TBGRequest $request */ public function runImportUsers(TBGRequest $request) { $validgroups = TBGContext::getModule('auth_ldap')->getSetting('groups'); $base_dn = TBGContext::getModule('auth_ldap')->getSetting('b_dn'); $dn_attr = TBGContext::getModule('auth_ldap')->getSetting('dn_attr'); $username_attr = TBGContext::getModule('auth_ldap')->getSetting('u_attr'); $fullname_attr = TBGContext::getModule('auth_ldap')->getSetting('f_attr'); $buddyname_attr = TBGContext::getModule('auth_ldap')->getSetting('b_attr'); $email_attr = TBGContext::getModule('auth_ldap')->getSetting('e_attr'); $groups_members_attr = TBGContext::getModule('auth_ldap')->getSetting('g_attr'); $user_class = TBGContext::getModule('auth_ldap')->getSetting('u_type'); $group_class = TBGContext::getModule('auth_ldap')->getSetting('g_type'); $users = array(); $importcount = 0; $updatecount = 0; try { /* * Connect and bind to the control user */ $connection = TBGContext::getModule('auth_ldap')->connect(); TBGContext::getModule('auth_ldap')->bind($connection, TBGContext::getModule('auth_ldap')->getSetting('control_user'), TBGContext::getModule('auth_ldap')->getSetting('control_pass')); /* * Get a list of all users of a certain objectClass */ $fields = array($fullname_attr, $buddyname_attr, $username_attr, $email_attr, 'cn', $dn_attr); $filter = '(objectClass=' . TBGLDAPAuthentication::getModule()->escape($user_class) . ')'; $results = ldap_search($connection, $base_dn, $filter, $fields); if (!$results) { TBGLogging::log('failed to search for users: ' . ldap_error($connection), 'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data = ldap_get_entries($connection, $results); /* * For every user that exists, process it. */ for ($i = 0; $i != $data['count']; $i++) { $user_dn = $data[$i][strtolower($dn_attr)][0]; /* * If groups are specified, perform group restriction tests */ if ($validgroups != '') { /* * We will repeat this for every group, but groups are supplied as a comma-separated list */ if (strstr($validgroups, ',')) { $groups = explode(',', $validgroups); } else { $groups = array(); $groups[] = $validgroups; } // Assumed we are initially banned $allowed = false; foreach ($groups as $group) { // No need to carry on looking if we have access if ($allowed == true) { continue; } /* * Find the group we are looking for, we search the entire directory * We want to find 1 group, if we don't get 1, silently ignore this group. */ $fields2 = array($groups_members_attr); $filter2 = '(&(cn=' . TBGLDAPAuthentication::getModule()->escape($group) . ')(objectClass=' . TBGLDAPAuthentication::getModule()->escape($group_class) . '))'; $results2 = ldap_search($connection, $base_dn, $filter2, $fields2); if (!$results2) { TBGLogging::log('failed to search for user: '******'ldap', TBGLogging::LEVEL_FATAL); throw new Exception(TBGContext::geti18n()->__('Search failed: ') . ldap_error($connection)); } $data2 = ldap_get_entries($connection, $results2); if ($data2['count'] != 1) { continue; } /* * Look through the group's member list. If we are found, grant access. */ foreach ($data2[0][strtolower($groups_members_attr)] as $member) { $member = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $member); $user_dn = preg_replace('/(?<=,) +(?=[a-zA-Z])/', '', $user_dn); if (!is_numeric($member) && strtolower($member) == strtolower($user_dn)) { $allowed = true; } } } if ($allowed == false) { continue; } } $users[$i] = array(); /* * Set user's properties. * Realname is obtained from directory, if not found we set it to the username * Email is obtained from directory, if not found we set it to blank */ if (!array_key_exists(strtolower($fullname_attr), $data[$i])) { $users[$i]['realname'] = $data[$i]['cn'][0]; } else { $users[$i]['realname'] = $data[$i][strtolower($fullname_attr)][0]; } if (!array_key_exists(strtolower($buddyname_attr), $data[$i])) { $users[$i]['buddyname'] = $data[$i]['cn'][0]; } else { $users[$i]['buddyname'] = $data[$i][strtolower($buddyname_attr)][0]; } if (!array_key_exists(strtolower($email_attr), $data[$i])) { $users[$i]['email'] = ''; } else { $users[$i]['email'] = $data[$i][strtolower($email_attr)][0]; } $users[$i]['username'] = $data[$i][strtolower($username_attr)][0]; } } catch (Exception $e) { TBGContext::setMessage('module_error', TBGContext::getI18n()->__('Import failed')); TBGContext::setMessage('module_error_details', $e->getMessage()); $this->forward(TBGContext::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); } /* * For every user that was found, either create a new user object, or update * the existing one. This will update the created and updated counts as appropriate. */ foreach ($users as $ldapuser) { $username = $ldapuser['username']; $email = $ldapuser['email']; $realname = $ldapuser['realname']; $buddyname = $ldapuser['buddyname']; try { $user = TBGUser::getByUsername($username); if ($user instanceof TBGUser) { $user->setRealname($realname); $user->setEmail($email); // update email address $user->save(); $updatecount++; } else { // create user $user = new TBGUser(); $user->setUsername($username); $user->setRealname($realname); $user->setBuddyname($buddyname); $user->setEmail($email); $user->setEnabled(); $user->setActivated(); $user->setPassword($user->getJoinedDate() . $username); $user->setJoined(); $user->save(); $importcount++; } } catch (Exception $e) { ldap_unbind($connection); TBGContext::setMessage('module_error', TBGContext::getI18n()->__('Import failed')); TBGContext::setMessage('module_error_details', $e->getMessage()); $this->forward(TBGContext::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); } } ldap_unbind($connection); TBGContext::setMessage('module_message', TBGContext::getI18n()->__('Import successful! %imp users imported, %upd users updated from LDAP', array('%imp' => $importcount, '%upd' => $updatecount))); $this->forward(TBGContext::getRouting()->generate('configure_module', array('config_module' => 'auth_ldap'))); }
protected function _upgradeFrom3dot2(TBGRequest $request) { set_time_limit(0); TBGContext::addAutoloaderClassPath(THEBUGGENIE_MODULES_PATH . 'installation' . DS . 'classes' . DS . 'upgrade_3.2'); foreach (array('publish', 'mailing') as $module) { TBGContext::addAutoloaderClassPath(THEBUGGENIE_MODULES_PATH . $module . DS . 'classes'); TBGContext::addAutoloaderClassPath(THEBUGGENIE_MODULES_PATH . $module . DS . 'classes' . DS . 'B2DB'); } TBGMilestonesTable::getTable()->upgrade(TBGMilestonesTable3dot2::getTable()); TBGArticlesTable::getTable()->upgrade(TBGArticlesTable3dot2::getTable()); TBGProjectsTable::getTable()->upgrade(TBGProjectsTable3dot2::getTable()); TBGLogTable::getTable()->upgrade(TBGLogTable3dot2::getTable()); TBGUsersTable::getTable()->upgrade(TBGUsersTable3dot2::getTable()); TBGIssuesTable::getTable()->upgrade(TBGIssuesTable3dot2::getTable()); TBGWorkflowsTable::getTable()->upgrade(TBGWorkflowsTable3dot2::getTable()); TBGIncomingEmailAccountTable::getTable()->upgrade(TBGIncomingEmailAccountTable3dot2::getTable()); TBGIssueSpentTimesTable::getTable()->upgrade(TBGIssueSpentTimesTable3dot2::getTable()); TBGCommentsTable::getTable()->upgrade(TBGCommentsTable3dot2::getTable()); TBGSavedSearchesTable::getTable()->upgrade(TBGSavedSearchesTable3dot2::getTable()); TBGSettingsTable::getTable()->upgrade(TBGSettingsTable3dot2::getTable()); TBGNotificationsTable::getTable()->upgrade(TBGNotificationsTable3dot2::getTable()); TBGPermissionsTable::getTable()->upgrade(TBGPermissionsTable3dot2::getTable()); TBGUserArticlesTable::getTable()->create(); TBGApplicationPasswordsTable::getTable()->create(); TBGUserNotificationSettingsTable::getTable()->create(); $transaction = \b2db\Core::startTransaction(); // Upgrade user passwords switch ($request['upgrade_passwords']) { case 'manual': $password = $request['manul_password']; foreach (TBGUsersTable::getTable()->selectAll() as $user) { $user->setPassword($password); $user->save(); } break; case 'auto': $field = $request['upgrade_passwords_pick'] == 'username' ? 'username' : 'email'; foreach (TBGUsersTable::getTable()->selectAll() as $user) { if ($field == 'username' && trim($user->getUsername())) { $user->setPassword(trim($user->getUsername())); $user->save(); } elseif ($field == 'email' && trim($user->getEmail())) { $user->setPassword(trim($user->getEmail())); $user->save(); } } break; } $adminuser = TBGUsersTable::getTable()->selectById(1); $adminuser->setPassword($request['admin_password']); $adminuser->save(); // Add new settings TBGSettings::saveSetting(TBGSettings::SETTING_SERVER_TIMEZONE, 'core', date_default_timezone_get(), 0, 1); foreach ($request->getParameter('status') as $scope_id => $status_id) { $scope = TBGScopesTable::getTable()->selectById((int) $scope_id); if ($scope instanceof TBGScope) { foreach (TBGWorkflowsTable::getTable()->getAll((int) $scope_id) as $workflow) { $transition = new TBGWorkflowTransition(); $steps = $workflow->getSteps(); $step = array_shift($steps); $step->setLinkedStatusID((int) $status_id); $step->save(); $transition->setOutgoingStep($step); $transition->setName('Issue created'); $transition->setWorkflow($workflow); $transition->setScope($scope); $transition->setDescription('This is the initial transition for issues using this workflow'); $transition->save(); $workflow->setInitialTransition($transition); $workflow->save(); } TBGActivityType::loadFixtures($scope); } } $transaction->commitAndEnd(); TBGContext::finishUpgrading(); TBGContext::getModule('mailing')->upgradeFrom3dot2(); $this->upgrade_complete = true; }
?> <?php } else { ?> <?php include_template('publish/placeholder', array('article_name' => $article_name)); ?> <?php } ?> </div> <?php } ?> <?php if (!$article->getID() && (TBGContext::isProjectContext() && !TBGContext::getCurrentProject()->isArchived() || !TBGContext::isProjectContext() && TBGContext::getModule('publish')->canUserEditArticle($article_name))) { ?> <div class="publish_article_actions"> <form action="<?php echo make_url('publish_article_edit', array('article_name' => $article_name)); ?> " method="get" style="float: left; margin-right: 10px;"> <input class="button button-green" type="submit" value="<?php echo __('Create this article'); ?> "> </form> </div> <?php } ?>
public function runConfigureProjectSettings(TBGRequest $request) { $this->forward403unless($request->isPost()); if ($this->access_level != TBGSettings::ACCESS_FULL) { $project_id = $request['project_id']; $fields = array('vcs_mode', 'match_keywords', 'access_method', 'access_passkey', 'commit_url', 'log_url', 'blob_url', 'diff_url', 'browser_url', 'vcs_workflow'); foreach ($fields as $field) { TBGContext::getModule('vcs_integration')->saveSetting($field . '_' . $project_id, $request->getParameter($field)); } switch ($request['browser_type']) { case 'viewvc': $base_url = $request['browser_url']; $link_rev = '&view=rev&revision=%revno'; $link_file = '&view=log'; $link_diff = '&r1=%revno&r2=%oldrev'; $link_view = '&revision=%revno&view=markup'; break; case 'viewvc_repo': $base_url = $request['browser_url']; $link_rev = '/?view=rev&revision=%revno'; $link_file = '/%file?view=log'; $link_diff = '/%file?r1=%revno&r2=%oldrev'; $link_view = '/%file?revision=%revno&view=markup'; break; case 'websvn': $base_url = $request['browser_url']; $link_rev = '/revision.php?repname=' . $request['repository'] . '&isdir=1&rev=%revno'; $link_file = '/log.php?repname=' . $request['repository'] . '&path=/$%file'; $link_diff = '/comp.php?repname=' . $request['repository'] . '&compare[]=/%file@%revno&compare[]=/%file@%oldrev'; $link_view = '/filedetails.php?repname=' . $request['repository'] . '&path=/%file&rev=%revno'; break; case 'websvn_mv': $base_url = $request['browser_url']; $link_rev = '/' . '?repname=' . $request['repository'] . '&op=log&isdir=1&rev=%revno'; $link_file = '/%file?repname=' . $request['repository']; $link_diff = '/%file?repname=' . $request['repository'] . '&compare[]=/%file@%revno&compare[]=/%file@%oldrev'; $link_view = '/%file?repname=' . $request['repository'] . '&rev=%revno'; break; case 'loggerhead': $base_url = $request['browser_url']; $link_rev = '/revision/%revno'; $link_file = '/changes'; $link_diff = '/revision/%revno?compare_revid=%oldrev'; $link_view = '/annotate/head:/%file'; break; case 'gitweb': $base_url = $request['browser_url']; $link_rev = ';a=commitdiff;h=%revno'; $link_file = ';a=history;f=%file;hb=HEAD'; $link_diff = ';a=blobdiff;f=%file;hb=%revno;hpb=%oldrev'; $link_view = ';a=blob;f=%file;hb=%revno'; break; case 'cgit': $base_url = $request['browser_url']; $link_rev = '/commit/?id=%revno'; $link_file = '/log'; $link_diff = '/diff/%file?id=%revno?id2=%oldrev'; $link_view = '/tree/%file?id=%revno'; break; case 'hgweb': $base_url = $request['browser_url']; $link_rev = '/rev/%revno'; $link_file = '/log/tip/%file'; $link_diff = '/diff/%revno/%file'; $link_view = '/file/%revno/%file'; break; case 'github': $base_url = $request['browser_url']; $link_rev = '/commit/%revno'; $link_file = '/commits/%branch/%file'; $link_diff = '/commit/%revno'; $link_view = '/blob/%revno/%file'; break; case 'gitlab': $base_url = $request['browser_url']; $link_rev = '/commit/%revno'; $link_file = '/commits/%branch/%file'; $link_diff = '/commit/%revno'; $link_view = '/blob/%revno/%file'; break; case 'bitbucket': $base_url = $request['browser_url']; $link_rev = '/changeset/%revno'; $link_file = '/history/%file'; $link_diff = '/changeset/%revno#chg-%file'; $link_view = '/src/%revno/%file'; break; case 'gitorious': $base_url = $request['browser_url']; $link_rev = '/commit/%revno'; $link_file = '/blobs/history/%branch/%file'; $link_diff = '/commit/%revno'; $link_view = '/blobs/%revno/%file'; break; case 'rhodecode': $base_url = $request['browser_url']; $link_rev = '/changeset/%revno'; $link_file = '/changelog/%revno/%file'; $link_diff = '/diff/%file?diff2=%revno&diff1=%oldrev&fulldiff=1&diff=diff'; $link_view = '/files/%revno/%file'; break; } if ($request['browser_type'] != 'other') { TBGContext::getModule('vcs_integration')->saveSetting('browser_url_' . $project_id, $base_url); TBGContext::getModule('vcs_integration')->saveSetting('log_url_' . $project_id, $link_file); TBGContext::getModule('vcs_integration')->saveSetting('blob_url_' . $project_id, $link_view); TBGContext::getModule('vcs_integration')->saveSetting('diff_url_' . $project_id, $link_diff); TBGContext::getModule('vcs_integration')->saveSetting('commit_url_' . $project_id, $link_rev); } return $this->renderJSON(array('failed' => false, 'message' => TBGContext::getI18n()->__('Settings saved'))); } else { $this->forward403(); } }
/** * Return an instance of this module * * @return TBGPublish */ public static function getModule() { return TBGContext::getModule('publish'); }
?> '; $(this).addClassName('faded_out'); }" onfocus="if ($(this).getValue() == '<?php echo $quicksearch_title; ?> ') { $(this).clear(); } $(this).removeClassName('faded_out');" class="faded_out"> </form> </div> <?php } ?> <div class="header"><?php echo __('Global content'); ?> </div> <?php echo link_tag($url, TBGContext::getModule('publish')->getMenuTitle(false)); ?> <?php $quicksearch_title = __('Find any article (press enter to search)'); ?> <div style="font-weight: normal; margin: 0 0 15px 5px;"> <form action="<?php echo make_url('publish_find_articles'); ?> " method="get" accept-charset="<?php echo TBGContext::getI18n()->getCharset(); ?> "> <input type="text" name="articlename" value="<?php echo $quicksearch_title; ?>
</li> <?php } ?> </ul> <br style="clear: both;"> <h1><?php echo __('Modules / addons'); ?> </h1> <ul class="config_badges"> <?php foreach ($config_sections[TBGSettings::CONFIGURATION_SECTION_MODULES] as $section => $info) { ?> <?php if ($info['module'] != 'core' && !TBGContext::getModule($info['module'])->hasConfigSettings()) { continue; } ?> <li class="rounded_box"> <?php if (is_array($info['route'])) { ?> <?php $url = make_url($info['route'][0], $info['route'][1]); ?> <?php } else { ?> <?php $url = make_url($info['route']);
<?php $base_url = TBGContext::getModule('vcs_integration')->getSetting('browser_url_' . $projectId); if (mb_strstr($commit->getRevision(), ':')) { $revision = explode(':', $commit->getRevision()); $revision = $revision[1]; } else { $revision = $commit->getRevision(); } if (mb_strstr($commit->getPreviousRevision(), ':')) { $oldrevision = explode(':', $commit->getPreviousRevision()); $oldrevision = $oldrevision[1]; } else { $oldrevision = $commit->getPreviousRevision(); } $misc_data = explode('|', $commit->getMiscData()); $branchname = null; foreach ($misc_data as $data) { if (mb_strstr($data, 'branch')) { $branch = explode(':', $data); if (count($branch) == 2) { $branchname = $branch[1]; } } } ?> <div class="comment" id="commit_<?php echo $commit->getID(); ?> "> <div id="commit_view_<?php
public function runScope(TBGRequest $request) { $this->scope = new TBGScope($request->getParameter('id')); $modules = TBGModulesTable::getTable()->getModulesForScope($this->scope->getID()); $this->modules = $modules; $this->scope_save_error = TBGContext::getMessageAndClear('scope_save_error'); $this->scope_saved = TBGContext::getMessageAndClear('scope_saved'); if ($request->isMethod(TBGRequest::POST)) { try { if ($request->getParameter('scope_action') == 'delete') { if (!$this->scope->isDefault()) { $this->scope->delete(); TBGContext::setMessage('scope_deleted', true); $this->forward(make_url('configure_scopes')); } else { $this->scope_save_error = TBGContext::getI18n()->__('You cannot delete the default scope'); } } else { if (!$request->getParameter('name')) { throw new Exception(TBGContext::getI18n()->__('Please specify a scope name')); } $this->scope->setName($request->getParameter('name')); $this->scope->setDescription($request->getParameter('description')); $this->scope->setCustomWorkflowsEnabled((bool) $request->getParameter('custom_workflows_enabled')); $this->scope->setMaxWorkflowsLimit((int) $request->getParameter('workflow_limit')); $this->scope->setUploadsEnabled((bool) $request->getParameter('file_uploads_enabled')); $this->scope->setMaxUploadLimit((int) $request->getParameter('upload_limit')); $this->scope->setMaxProjects((int) $request->getParameter('project_limit')); $this->scope->setMaxUsers((int) $request->getParameter('user_limit')); $this->scope->setMaxTeams((int) $request->getParameter('team_limit')); $this->scope->save(); $enabled_modules = $request->getParameter('module_enabled'); $prev_scope = TBGContext::getScope(); foreach ($enabled_modules as $module => $enabled) { if (!TBGContext::getModule($module)->isCore() && !$enabled && array_key_exists($module, $modules)) { $module = TBGModulesTable::getTable()->getModuleForScope($module, $this->scope->getID()); $module->uninstall($this->scope->getID()); } elseif (!TBGContext::getModule($module)->isCore() && $enabled && !array_key_exists($module, $modules)) { TBGContext::setScope($this->scope); TBGModule::installModule($module); TBGContext::setScope($prev_scope); } } TBGContext::setMessage('scope_saved', true); $this->forward(make_url('configure_scope', array('id' => $this->scope->getID()))); } } catch (Exception $e) { TBGContext::setMessage('scope_save_error', $e->getMessage()); } } }
?> </pre> <h4><?php echo __('Changed files:'); ?> </h4> <table border=0 cellpadding=0 cellspacing=0 style="width: 100%;"> <?php foreach ($files as $file) { echo '<tr>'; $action = $file[1]; if ($action == 'M') { $action = 'U'; } echo '<td class="imgtd">' . image_tag('icon_action_' . $action . '.png', null, false, 'vcs_integration') . '</td>'; switch (TBGContext::getModule('vcs_integration')->getSetting('web_type_' . $projectId)) { case 'viewvc': $link_file = $web_path . '/' . $file[0] . '?root=' . $web_repo . '&view=log'; $link_diff = $web_path . '/' . $file[0] . '?root=' . $web_repo . '&r1=' . $file[2] . '&r2=' . $file[3]; $link_view = $web_path . '/' . $file[0] . '?root=' . $web_repo . '&revision=' . $file[2] . '&view=markup'; break; case 'viewvc_repo': $link_file = $web_path . '/' . $file[0] . '?view=log'; $link_diff = $web_path . '/' . $file[0] . '?r1=' . $file[2] . '&r2=' . $file[3]; $link_view = $web_path . '/' . $file[0] . '?revision=' . $file[2] . '&view=markup'; break; case 'websvn': $link_file = $web_path . '/log.php?repname=' . $web_repo . '&path=/' . $file[0]; $link_diff = $web_path . '/comp.php?repname=' . $web_repo . '&compare[]=/' . $file[0] . '@' . $file[2] . '&compare[]=/' . $file[0] . '@' . $file[3]; $link_view = $web_path . '/filedetails.php?repname=' . $web_repo . '&path=/' . $file[0] . '&rev=' . $file[2]; break;
<td class="side_bar"> <?php include_component('leftmenu', array('article' => $article)); ?> </td> <td class="main_area article"> <a name="top"></a> <div class="article" style="width: auto; padding: 5px; position: relative;"> <?php include_template('publish/header', array('article_name' => $article_name, 'show_actions' => true, 'mode' => 'permissions')); ?> <?php if ($article instanceof TBGWikiArticle) { ?> <?php if (TBGContext::getModule('publish')->canUserEditArticle($article_name)) { ?> <ul class="simple_list"> <?php foreach ($namespaces as $namespace) { ?> <li class="rounded_box <?php if (!(is_numeric($namespace) && $namespace == 0) && $namespace == $article->getName()) { ?> verylightyellow<?php } else { ?> invisible borderless<?php } ?> " style="padding: 10px;">
$action = 'U'; } echo '<td class="imgtd">' . image_tag('icon_action_' . $action . '.png', null, false, 'vcs_integration') . '</td>'; $link_file = str_replace('%revno%', $revision, TBGContext::getModule('vcs_integration')->getSetting('log_url_' . $projectId)); $link_file = str_replace('%oldrev%', $oldrevision, $link_file); if ($branchname !== null) { $link_file = str_replace('%branch%', $branchname, $link_file); } $link_file = $base_url . str_replace('%file%', $file->getFile(), $link_file); $link_diff = str_replace('%revno%', $revision, TBGContext::getModule('vcs_integration')->getSetting('diff_url_' . $projectId)); $link_diff = str_replace('%oldrev%', $oldrevision, $link_diff); if ($branchname !== null) { $link_diff = str_replace('%branch%', $branchname, $link_diff); } $link_diff = $base_url . str_replace('%file%', $file->getFile(), $link_diff); $link_view = str_replace('%revno%', $revision, TBGContext::getModule('vcs_integration')->getSetting('blob_url_' . $projectId)); $link_view = str_replace('%oldrev%', $oldrevision, $link_view); if ($branchname !== null) { $link_view = str_replace('%branch%', $branchname, $link_view); } $link_view = $base_url . str_replace('%file%', $file->getFile(), $link_view); echo '<td><a href="' . $link_file . '" target="_new"><b>' . $file->getFile() . '</b></a></td>'; if ($action == "U" || $action == "M") { if (mb_substr($file->getFile(), -1) == '/' || mb_substr($file->getFile(), -1) == '\\') { echo '<td style="width: 75px;" class="faded_out">' . __('directory') . '</td>'; } else { echo '<td style="width: 75px;"><a href="' . $link_diff . '" target="_new"><b>' . __('Diff') . '</b></a></td>'; } } if ($action == "D") { echo '<td colspan="2" class="faded_out" style="width: 150px;">' . __('deleted') . '</td>';