Location: PHPKode > projects > Joomla SEF / SEO - extending OpenSEF > admin.sef.php
<?php
/**
 * JoomlaSEF / OpenSEF for Joomla!
 * @copyright (c) 2005 The JoomlaSEF Project (www.joomlasef.org)
 * @copyright (c) 2005 The OpenSEF Project (www.opensef.org)
 * @copyright (c) 2004-2005 Xaneon Development (www.xaneon.com)
 * @license GPL http://www.gnu.org/copyleft/gpl.html
 *
 * TODO
 *
 */

/** Ensure this file is being included by a parent file */
defined( '_VALID_MOS' ) or die( 'Direct access to this location is not allowed.' );

// ------------------------------------------------------------------------
// Permissions

if (!$acl->acl_check( 'administration', 'config', 'users', $my->usertype )) {
  mosRedirect( 'index2.php', _NOT_AUTH );
}

// ------------------------------------------------------------------------
// Core Includes
// ** Let's look into a Plugin System to manage these

require_once( $mainframe->getPath( 'class' ) );
require_once( 'sef.functions.php' );
require_once( 'core/sef.security.php' );
require_once( 'core/sef.resolver.php' );
require_once( 'core/sef.rewriter.php' );
require_once( 'core/sef.mapper.php' );
require_once( 'includes/sef.backend.php' );
require_once( 'includes/sef.seo.php');
require_once( 'includes/sef.googlepr.php');

// Plugins - NEEDS ADMIN SYSTEM
// ** Plugin System Needs to be developed
require_once( 'plugins/wbseo/wbseo.php');
xclLoadLanguageConstants(
  'english',
  $mainframe->getCfg('absolute_path').'/administrator/components/'.$option.'/plugins/wbseo/language'
);

// ------------------------------------------------------------------------
// Load Reserved Filenames

$sefReservedNames = array(
  'CHANGELOG',
  'INSTALL',
  'LICENSE',
  'administrator',
  'cache',
  'components',
  'configuration.php',
  'editor',
  'globals.php',
  'help',
  'htaccess.txt',
  'images',
  'includes',
  'index.php',
  'index2.php',
  'installation',
  'language',
  'mainbody.php',
  'mambots',
  'media',
  'modules',
  'offline.php',
  'pathway.php',
  'robots.txt',
  'templates',
);

// ------------------------------------------------------------------------
// Select Component List

$database->setQuery("SELECT * FROM #__opensef_sef_component");
if ($database->loadResult()) {
  $opensef_components = $database->loadObjectList();
}

// ------------------------------------------------------------------------

/**
 * Admin Class
 *
 */
class JosOpenSEFAdmin extends xclBackendAdmin {

  // ------------------------------------------------------------------------

  /**
   * Save config
   *
   */
  function do_config_save() {
    $this->storeComponentAliases( null );
    parent::do_config_save();
  }

  // ------------------------------------------------------------------------

  /**
   * Prepare values for showing in the Config page
   *
   * @param array $row
   */
  function config( &$row ) {
    global $mosConfig_absolute_path,$mosConfig_sef;
    $sites = $this->getSiteList();
    $langs    = array();
    if ($handle = opendir( $mosConfig_absolute_path . '/administrator/components/com_sef/language/' )) {
      $i=0;
      while (false !== ($file = readdir( $handle ))) {
        if (!strcasecmp(substr($file,-4),".ini") && $file != "." && $file != ".." ) {
          $langs[] = mosHTML::makeOption( substr($file,0,-4) );
        }
      }
    }
    // sort list of languages
    sort( $langs );
    reset( $langs );
    $titles = array(
      'title' => _T( 'TITLE' ),
      'title_alias' => _T( 'TITLE_ALIAS' ),
    );
    $titles2 = array(
      'title' => _T( 'TITLE' ),
      'name' => _T( 'NAME' ),
    );
    $paths = array(
      'full' => '/Section/Category/Title',
      'section' => '/Section/Title',
      'category' => '/Category/Title',
      //'pathway' => '/Pathway/Title', // TODO
    );
    $validation = array(
      '0' => 'None',      // No checking so anything goes; Joomla! default
      '1' => 'Normal',    // Alias lookup, begins with /content, begins with /component
      '2' => 'Strict',    // Alias lookup, content item exists, begins with /component
      '3' => 'Lockdown',  // Alias lookup only
    );
    $g_modified = array(
      '1' => _T( 'ACTUAL_DATE' ),
      '2' => _T( 'STORED_DATE' ),
    );
    $g_frequency = array(
      'always' => _T( 'G_ALWAYS' ),
      'hourly' => _T( 'G_HOURLY' ),
      'daily' => _T( 'G_DAILY' ),
      'weekly' => _T( 'G_WEEKLY' ),
      'monthly' => _T( 'G_MONTHLY' ),
      'yearly' => _T( 'G_YEARLY' ),
      'never' => _T( 'G_NEVER' ),
    );
    $g_priority = array(
      '0.0' => '0.0',
      '0.1' => '0.1',
      '0.2' => '0.2',
      '0.3' => '0.3',
      '0.4' => '0.4',
      '0.5' => '0.5',
      '0.6' => '0.6',
      '0.7' => '0.7',
      '0.8' => '0.8',
      '0.9' => '0.9',
      '1.0' => '1.0',
    );
    $m_nlist = array(
      '5' => '5 '._T( 'M_KEYWORDS'),
      '10' => '10 '._T( 'M_KEYWORDS'),
      '25' => '25 '._T( 'M_KEYWORDS'),
      '50' => '50 '._T( 'M_KEYWORDS'),
      '100' => '100 '._T( 'M_KEYWORDS'),
      '200' => '200 '._T( 'M_KEYWORDS'),
      '500' => '500 '._T( 'M_KEYWORDS'),
      '1000000' => _T( 'M_UNLIMITED'),
    );
    $m_gdesc = array(
      'intro' => _T('INTROTEXT'),
      'full' => _T('MAINTEXT'),
    );
    $m_nsep = array (
      ',' => 'Comma',
      ' ' => 'Space',
    );
    $m_nsort = array (
      'SORT_DESC' => _T('SORT_DESC'),
      'SORT_ASC' => _T('SORT_ASC'),
    );
    $section = 'CONFIG';

    // Slight hack.
    $enabled_field = xclHTML::yesNoSelect  ( $this->tpl, $section, 'enabled' );
    if (empty( $row->enabled )) {
      $enabled_field->help = '<span style="color:red">' . $enabled_field->help . '</span>';
    } else {
      if (!empty( $row->enabled) && !$mosConfig_sef){
        $enabled_field->help = '<span style="color:red">' . _T( 'HELP_CONFIG_NOSEF' ) . '</span>';
      }
    }
    $form = array(
      _T( 'BASIC' ) => array(
        _T( 'BASIC_SETTINGS' ) => array(
          $enabled_field,
          xclHTML::selectLangs  ( $this->tpl, $section, 'backend_language', $langs, $this->config->backend_language ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'backend_sidebar' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'backend_autoupdates' ),
        ),
      ),
      _T( 'SEF' ) => array(
        _T( 'SEF_ENCODING' ) => array(
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'encode_lowercase' ),
          xclHTML::textbox      ( $this->tpl, $section, 'encode_page_suffix', 10 ),
          xclHTML::textbox      ( $this->tpl, $section, 'encode_space_char', 5 ),
          xclHTML::textbox      ( $this->tpl, $section, 'encode_strip_chars', 20 ),
        ),
        _T( 'CONTENT_URLS' ) => array(
          xclHTML::select       ( $this->tpl, $section, 'content_path_type', $paths ),
          xclHTML::select       ( $this->tpl, $section, 'section_title_field', $titles2 ),
          xclHTML::select       ( $this->tpl, $section, 'category_title_field', $titles2 ),
          xclHTML::select       ( $this->tpl, $section, 'content_title_field', $titles ),
          xclHTML::textbox      ( $this->tpl, $section, 'content_page_format', 10 ),
          xclHTML::textbox      ( $this->tpl, $section, 'content_page_name', 10 ),
        ),
        _T( 'URL_VALIDATION' ) => array(
          xclHTML::select       ( $this->tpl, $section, 'validate_level', $validation ),
          xclHTML::textbox      ( $this->tpl, $section, 'validate_404_url', 20 ),
        ),
      ),
       _T( 'LANGCHAR' ) => array(
        _T( 'CHARREPLACE' ) => array(
          xclHTML::textarea      ( $this->tpl, $section, 'spec_chars_d', 5, 50 ),

        ),
         _T( 'CHARREPLACEWITH' ) => array(
            xclHTML::textarea      ( $this->tpl, $section, 'spec_chars', 5, 50 ),

        ),
      ),
       _T( 'COREALIAS' ) => array(
        _T( 'CORECOMPONENTS' ) => array(
          xclHTML::textbox2      ( $this->tpl, $section, 'alias_banner','use_alias_banner', 20 ),
          xclHTML::textbox2      ( $this->tpl, $section, 'alias_links','use_alias_links', 20 ),
          xclHTML::textbox2      ( $this->tpl, $section, 'alias_newsfeeds','use_alias_newsfeeds', 20 ),
           xclHTML::textbox2      ( $this->tpl, $section, 'alias_wrapper','use_alias_wrapper', 20 ),
          ),
           _T( 'CONTENTALIAS' ) => array(
          xclHTML::textbox    ( $this->tpl, $section, 'content_blogcategory', 20 ),
          xclHTML::textbox      ( $this->tpl, $section, 'content_blogsection', 20 ),
          xclHTML::textbox      ( $this->tpl, $section, 'content_archivecategory', 20 ),
          xclHTML::textbox      ( $this->tpl, $section, 'content_archivesection', 20 ),
        ),

      ),
       _T( 'COMPONENTS' ) => array(
        _T( 'COMPONENT_LINKS' ) => 'form_components',
      ),
      _T( 'FEATURES' ) => array(
        _T( 'FEATURES' ) => array(
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_multisite' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_automap' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_automap_redirect' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_sef_ext' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_canonical_urls' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_absolute_urls' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'append_date' ),
          xclHTML::textbox      ( $this->tpl, $section, 'append_date_format', 10 ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'append_contentid' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'append_itemid' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'use_session_fix' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'record_unmapped_urls' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'record_invalid_urls' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'record_hits' ),
        ),
      ),
      _T( 'ADVANCED' ) => array(
        _T( 'ADVANCED_SETTINGS' ) => array(
          xclHTML::rangeSelect  ( $this->tpl, $section, 'max_recursion', 0, 3 ),
        ),
        _T( 'DEBUG_OPTIONS' ) => array(
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'debug' ),
          xclHTML::textbox      ( $this->tpl, $section, 'debug_for_ip', 20 ),
        ),
        //_T( 'CACHING' ) => array(),
      ),
       _T( 'GOOGLE' ) => array(
        _T( 'GOOGLE_SETTINGS' ) => array(
          xclHTML::textbox      ( $this->tpl, $section, 'google_filename', 40 ),
          xclHTML::textbox3     ( $this->tpl, $section, 'google_path', 40 ),
          xclHTML::select       ( $this->tpl, $section, 'google_modified', $g_modified ),
          xclHTML::select       ( $this->tpl, $section, 'google_frequency', $g_frequency ),
          xclHTML::select       ( $this->tpl, $section, 'google_priority', $g_priority ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'google_ping' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'google_display' ),
        ),

      ),
      _T( 'METATAG' ) => array(
        _T( 'METATAG_SETTINGS' ) => array(
          xclHTML::select       ( $this->tpl, $section, 'meta_nlist', $m_nlist ),
          xclHTML::select       ( $this->tpl, $section, 'meta_nsep', $m_nsep ),
          xclHTML::select       ( $this->tpl, $section, 'meta_nsort', $m_nsort ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'meta_kreplace' ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'meta_dreplace' ),
          xclHTML::textarea      ( $this->tpl, $section, 'meta_chars', 5, 40 ),
          xclHTML::textarea      ( $this->tpl, $section, 'meta_exclude_key', 5, 40 ),
          xclHTML::select       ( $this->tpl, $section, 'meta_gdesc', $m_gdesc ),
          xclHTML::yesNoSelect  ( $this->tpl, $section, 'meta_gdesc_opt' ),
          xclHTML::textbox      ( $this->tpl, $section, 'meta_gdesc_len', 5 ),

        ),

      ),
    );

    $site =& new JosOpenSEFSite( $this->db, -1 );
    $this->tpl->assign( 'site', $site );
    $this->tpl->assign( 'mapper',
      sefLoadAutoMapper( $this->db, $this->config, $site ) );
    $this->tpl->assign( 'menus', $this->getMenuComponents() );
    $this->tpl->assign( 'form', $form );
    $this->tpl->assign( 'title', 'Edit Configuration' );
    $this->tpl->assign( 'bold', true );
    $this->tpl->assign( 'icon', 'config' );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function JosOpenSEFAdmin() {
    $config =& new JosOpenSEFConfig( $GLOBALS['database'], true );
    $GLOBALS['sefConfig'] =& $config;
    $tables = array(
      'sites'   => '#__opensef_sef_site',
      'aliases' => '#__opensef_sef',
    );
    $classes = array(
      'sites'   => 'JosOpenSEFSite',
      'aliases' => 'JosOpenSEFAlias',
    );
    $this->xclBackendAdmin( $config, $tables, $classes );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function header() {
    $query = "SELECT * FROM #__survey WHERE published = '1'" .
      "\nORDER BY created DESC, title ASC";
    $this->db->setQuery( $query );
    /*
    $sites = $this->db->loadObjectList();
    $sites = xclCastObjectList( $sites, "mosSurvey" );
    $this->tpl->assign( "sites", $sites );
    */
    parent::header();
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_postinstall() {
    $this->do_about();
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_about() {
    $this->tpl->assign( 'links', array(
      _T( 'FAQ_LONG' ) => 'http://www.joomlasef.org/faq/',
      _T( 'USER_MANUAL' ) => 'http://www.joomlasef.org/manual/',
      _T( 'SUPPORT_FORUM' ) => 'http://www.joomlasef.org/forum/',
      _T( 'LATEST_VERSION' ) => 'http://www.joomlasef.org/downloads/',
      _T( 'DEVELOPMENT_SITE' ) => 'http://www.joomlasef.org/',
    ));
    parent::do_about();
  }

  // ------------------------------------------------------------------------

   /*
   * TODO
   */
  function do_about_credit() {
    $this->tpl->assign( 'xml', $this->xml );
    $this->tpl->assign( 'config', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', @$show ) );
    $this->display( 'credit' );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function view_sites( &$view ) {
    $view->title = _T( 'SITES' );
    $view->icon = 'categories';
    $view->ordersBY = array(
      ''          => '(' . _T( 'DEFAULT' ) . ')',
      'host ASC' => '(' . _T( 'HOST' ) . ')',
      'base_url ASC'   => '(' . _T( 'BASE_URL' ) . ')',
    );
    $view->search = $this->db->getEscaped( trim( strtolower(
      $this->mainframe->getUserStateFromRequest( "search{$this->option}", "search", null ) ) ) );
    if ($view->search != "") {
      $view->wheres[] = "(title LIKE '%$view->search%'" .
        " OR host LIKE '%$view->search%'" .
        " OR base_url LIKE '%$view->search%')";
    }
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function view_aliases( &$view ) {
    $view->title = _T( 'FRIENDLY_URLS' );
    $view->icon = 'browser';
    $view->sites = $this->getSiteList();
    $view->site_id = $this->db->getEscaped(
      $this->mainframe->getUserStateFromRequest( "site_id{$this->option}", "site_id", null ) );
    if ($view->site_id != '') {
      $view->wheres[] = "(site_id = '$view->site_id')";
    }
    $view->filters = array(
      ''          => '(' . _T( 'SELECT_FILTER' ) . ')',
      'published' => '(' . _T( 'PUBLISHED' ) . ')',
      'invalid'   => '(' . _T( 'INVALID' ) . ')',
      'unmapped'  => '(' . _T( 'UNMAPPED' ) . ')',
      'redirects' => '(' . _T( 'REDIRECTS' ) . ')',
    );
     $view->ordersBY = array(
      ''              => '(' . _T( 'ORDER_BY' ) . ')',
      'external ASC'  => '(' . _T( 'ORDER_BY_FRIENDLY_ASC' ) . ')',
      'external DESC'   => '(' . _T( 'ORDER_BY_FRIENDLY_DESC' ) . ')',
      'internal ASC'    => '(' . _T( 'ORDER_BY_INTERNAL_ASC' ) . ')',
      'internal DESC'   => '(' . _T( 'ORDER_BY_INTERNAL_DESC' ) . ')',
      'site_id ASC'   => '(' . _T( 'ORDER_BY_SITE_ASC' ) . ')',
      'site_id DESC'  => '(' . _T( 'ORDER_BY_SITE_DESC' ) . ')',
      'direction DESC'  => '(' . _T( 'DIRECTION' ) . ')',
    );

    $view->filter = $this->db->getEscaped(
      $this->mainframe->getUserStateFromRequest( "filter{$this->option}", "filter", null ) );
    if ($view->filter != '') {
      switch ($view->filter) {
        case 'published':
          $view->wheres[] = "(valid = '1' AND published = '1')";
          break;
        case 'invalid':
          $view->wheres[] = "(valid = '0')";
          break;
        case 'unmapped':
          $view->wheres[] = "(valid = '1' AND published = '0')";
          break;
        case 'content':
          $view->wheres[] = "(internal LIKE '%com_content%')";
          break;
        case 'redirects':
          $view->wheres[] = "(internal LIKE 'http%://%')";
          break;
        /*case 'top10':
          $view->limitstart = 0;
          $view->limit = 10;
          $view->orderBy = array_merge( array( 'hits DESC' ), $view->orderBy );
          break;*/
      }
    }

    $view->ordersBys = $this->db->getEscaped(
      $this->mainframe->getUserStateFromRequest( "ordersBys{$this->option}", "ordersBys", null ) );
    if ($view->ordersBys != '') {
      $view->orderBy = array("$view->ordersBys");
    } else {
      $view->orderBy = array( "site_id DESC", "external ASC", "direction DESC" );
    }
    $view->search = $this->db->getEscaped( trim( strtolower(
      $this->mainframe->getUserStateFromRequest( "search{$this->option}", "search", null ) ) ) );
    if ($view->search != "") {
      $filter = "(external LIKE '%$view->search%'" .
        " OR internal LIKE '%$view->search%'";
      if (sefIsJoomlaSEF( $view->search ))
        $filter .= " OR internal LIKE '%" . sefRewriteFromJoomlaSEF( $view->search ) . "%'";
      $filter .= " OR notes LIKE '%$view->search%')";
      $view->wheres[] = $filter;
    }
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_sites() {
    switch ($this->task) {
      case 'publish':
      case 'unpublish':
        $this->update( 'published', ($this->task == 'publish'), false );
        return $this->redirect();
        break;
      case 'setpublished':
      case 'setaccess':
      case 'setoffline':
        $field = substr( $this->task, strlen( 'set' ) );
        $value = max( min( intval( $this->taskParam ), 2 ), 0 );
        $this->update( $field, $value, false );
        return $this->redirect();

      default:
        return $this->_default();
    }
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_aliases() {
    switch ($this->task) {
      case 'publish':
      case 'unpublish':
        $this->update( 'published', ($this->task == 'publish'), false );
        return $this->redirect();
        break;
      case 'setpublished':
      case 'setvalid':
      case 'setstop':
      case 'setlocked':
      case 'setuse_internal':
        $field = substr( $this->task, strlen( 'set' ) );
        $value = max( min( intval( $this->taskParam ), 1 ), 0 );
        $this->update( $field, $value, false );
        return $this->redirect();
      default:
        return $this->_default();
    }
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function form_sites( &$row ) {
    $accessLevels = array(
      0 => _T( 'PUBLIC' ),
      1 => _T( 'REGISTERED' ),
      2 => _T( 'SPECIAL' ),
    );
    $errorReporting = array(
      null => _T( 'USE_GLOBAL' ),
      -1 => 'System Default',
      0 => 'None',
      7 => 'Simple',
      2047 => 'Maximum',
    );
    $langs = array_merge(
      array( null => _T( 'USE_GLOBAL' ) ),
      xclGetLangTitles( true ) );

    $section = 'SITE';
    $fields1 = array(
      xclHTML::textbox      ( $this->tpl, $section, 'host' ),
      xclHTML::textbox      ( $this->tpl, $section, 'base_url' ),
      xclHTML::textbox      ( $this->tpl, $section, 'title' ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'published' ),
      xclHTML::select       ( $this->tpl, $section, 'access', $accessLevels ),
    );
    $fields2 = array(
      xclHTML::textbox      ( $this->tpl, $section, 'sitename' ),
      xclHTML::select       ( $this->tpl, $section, 'lang', $langs ),
      xclHTML::rangeSelect  ( $this->tpl, $section, 'offset', -24, 24, true ),
      xclHTML::textbox      ( $this->tpl, $section, 'locale', 20 ),
      null,
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'offline', true ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'debug', true ),
      xclHTML::select       ( $this->tpl, $section, 'error_reporting', $errorReporting ),
      null,
      xclHTML::textarea     ( $this->tpl, $section, 'metadesc' ),
      xclHTML::textarea     ( $this->tpl, $section, 'metakeys' ),
    );

    $form = array(
      _T( 'DETAILS' ) => array( _T( 'DETAILS' ) => &$fields1 ),
      _T( 'OVERRIDES' ) => array( _T( 'OVERRIDES' ) => &$fields2 ),
    );
    if (!empty( $row->id ))
      $form[_T( 'COMPONENTS' )] = 'form_components';

    $valids = array(
      'host' => 'Please fill in the Domain Name.',
      'base_url' => 'Please fill in the Base URL.',
      'title' => 'Please fill in the Title.',
    );

    $this->tpl->assign( 'site', $row );
    $this->tpl->assign( 'mapper',
      sefLoadAutoMapper( $this->db, $this->config, $row ) );
    $this->tpl->assign( 'menus', $this->getMenuComponents() );
    $this->tpl->assign( 'form', $form );
    $this->tpl->assign( 'validation', $valids );
    $title = $this->tpl->data->title;
    $this->tpl->assign( 'title', !$this->tpl->id ? _T('NEW_SITE') :
      (empty( $title ) ? _T('EDIT_SITE') : _T('EDIT_SITE').' - '.$title) );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function form_aliases( &$row ) {

    $sites = $this->getSiteList();
    $section = 'ALIAS';

    // Alias Fields
    $fields_details = array(
      xclHTML::select       ( $this->tpl, $section, 'site_id', $sites ),
      null,
      xclHTML::textbox      ( $this->tpl, $section, 'external' ),
      xclHTML::textbox      ( $this->tpl, $section, 'internal' ),
      null,
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'published' ),
      null,
      xclHTML::textarea     ( $this->tpl, $section, 'notes' ),
    );
    $fields_advanced = array(
      xclHTML::select       ( $this->tpl, $section, 'direction',
        // Select Field Options
        Array(
          null => '(Both)',
          'i' => 'Incoming',
          'o' => 'Outgoing',
        )
      ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'valid' ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'locked' ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'stop' ),
      null,
    );

    // wbSEO Plugin Fields
    $fields_wbseo = array(
      _T('PLUGIN_WBSEO_DESCRIPTION'),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'plugin_wbseo_titles_on' ),
      xclHTML::textarea     ( $this->tpl, $section, 'plugin_wbseo_titles' ),
      xclHTML::yesNoSelect  ( $this->tpl, $section, 'plugin_wbseo_meta_on' ),
      xclHTML::textarea     ( $this->tpl, $section, 'plugin_wbseo_meta' ),
      xclHTML::hidden       ( $this->tpl, $section, 'plugin_wbseo_id' ),
    );

    // Page Tabs
    $form = array(
      _T( 'DETAILS' ) => array( _T( 'DETAILS' ) => &$fields_details ),
      _T( 'ADVANCED' ) => array( _T( 'ADVANCED' ) => &$fields_advanced ),
      _T( 'PLUGIN_WBSEO' ) => array( _T( 'PLUGIN_WBSEO' ) => &$fields_wbseo ),
    );

    // Required Values
    $valids = array(
      'external' => 'Please fill in the Friendly URL.',
      'internal' => 'Please fill in the Internal URL.',
    );

    $this->tpl->assign( 'form', $form );
    $this->tpl->assign( 'validation', $valids );
    $title = $this->tpl->data->external;
    $this->tpl->assign( 'title', !$this->tpl->id ? _T('NEW_FRIENDLY_URL') :
      (empty( $title ) ? _T('EDIT_FRIENDLY_URL') : _T('EDIT_FRIENDLY_URL').' - '.$title) );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_tools() {
    global $mosConfig_absolute_path, $database, $mainframe, $mosConfig_list_limit, $sefConfig;

    $upgrader = new opensef_upgrader();
    $upgrader->set_upgrade_path("http://www.joomlasef.org/updates");
    $upgrader->set_version_xml("currentversion.xml");

    $version = $sefConfig->version;
    $product = $this->xml->getElementText( '/mosinstall/productName' );
    // get component version
    $mod[0] = opensef_getComponentVersion($upgrader, $version);
    $mod[0]->product = $product;

    $limit = $mainframe->getUserStateFromRequest("viewlistlimit", 'limit', $mosConfig_list_limit);
    $limitstart = $mainframe->getUserStateFromRequest("view{$this->option}limitstart", 'limitstart', 0);

    require_once ($mosConfig_absolute_path.'/administrator/components/com_sef/includes/pageNavigation.php');
    $pageNav = new mosPageNav(count($mod), $limitstart, $limit);

    $this->tpl->assign( 'mod', $mod );
    $this->tpl->assign( 'pageNav', $pageNav );
    $this->tpl->assign( 'xml', $this->xml );
    $this->tpl->assign( 'config', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', @$show ) );
    $this->display( 'tools' );
  }

  // ------------------------------------------------------------------------

  function do_tools_upgrade() {
    global $database, $mosConfig_absolute_path;

    $mod = mosGetParam($_REQUEST, 'mod', 0);
    $cid = mosGetParam($_REQUEST, 'cid', 0);

    $upgrader = new opensef_upgrader();
    $upgrader->set_upgrade_path("http://www.www.joomlasef.org/.org/updates");

    foreach ($cid as $c) {
      $curVer = $mod[$c]['oldversion'];

      $item = new opensef_upgradeItem();
      $item->bind($mod[$c]);

      $upgrader->upgrade($item);
      $msg = $upgrader->msg;
    }
    $this->tpl->assign( 'msg', $msg );
    $this->tpl->assign( 'config', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', $show ) );
    $this->display( 'action3' );
  }

  // ------------------------------------------------------------------------

  function do_tools_cancel() {
    $this->do_tools();
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_tools_debug() {

    $debug_url = mosGetParam( $_REQUEST, 'debug_url', '' );
    $direction = mosGetParam( $_REQUEST, 'debug_direction', 'incoming' );

    $url = @parse_url( $debug_url );

    if ($url === false || !is_array( $url )
        || @$url['scheme'] != 'http'
        || @$url['host'] == '') {
      $this->tpl->assign( 'debug_result', false );
      $this->tpl->assign( 'debug_log',
        array( '--- Unable to parse URL: ' . $debug_url ) );
      $this->do_tools();
      return;
    }

    $host = $url['host'];
    $url = (!isset( $url['path'] ) ? '' :
      $url['path'] . (isset( $url['query'] ) ? '?' . $url['query'] : '')); //qs

    if (!empty( $this->config->use_multisite ))
      $site =& JosOpenSEFSite::lookup( $host, $url );
    if (!isset( $site ))
      $site =& JosOpenSEFSite::getDefault();

    if ($direction == 'incoming') {

      $className = 'sefAutoMapper';
      $autoMapper =& new $className( $database, $this->config, $site );
      $autoMapper->setDebug( true );
      $className = 'sefResolver';
      $resolver =& new $className( $database, $this->config, $site );
      $resolver->setDebug( true );
      $resolver->setAutoMapper( $autoMapper );

      // TODO: add debug parameters for recursion control.
      $result = $resolver->resolve( $url );
      $this->tpl->assign( 'debug_result', $result );
      $this->tpl->assign( 'debug_log', $resolver->getLog() );

    }
    else { // $direction == 'outgoing'

      // TODO: simulating outgoing rewriting.

    }

    $this->do_tools();
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_tools_import() {
    $title = 'Importing Data...';
    $success = true;
    $log = array();

    $source = mosGetParam( $_REQUEST, 'import_source', null );

    switch ($source) {
      case 'alias':
        $sites = (mosGetParam( $_REQUEST, 'import_sites', '0' ) == '1');
        $preserve = (mosGetParam( $_REQUEST, 'import_preserve', '0' ) == '1');
        $remove = (mosGetParam( $_REQUEST, 'import_remove', '0' ) == '1');
        $query = "SELECT DISTINCT language FROM #__alias " .
          "WHERE language IS NOT NULL AND language != '' ORDER BY language ASC";
        $this->db->setQuery( $query );
        $rows = @$this->db->loadObjectList();
        if (!is_array( $rows )) {
          $success = false;
          $log[] = "<span style='color:red'>ERROR: Couldn't locate data table ('i.e. mos_alias') for Xaneon Alias Manager 1.0.3.</span>";
        }
        else {
          if ($sites && count( $rows ) > 0) {
            $defsite =& new JosOpenSEFSite( $this->db, -1 );
            $sites = array();
            foreach ($rows as $oldlang) {
              $lang = $oldlang->language;
              $langTitle = xclGetLangTitle( $lang );
              $row =& new JosOpenSEFSite( $this->db );
              $row->title = $langTitle;
              $row->published = '1';
              $row->host = $defsite->host;
              $row->base_url = $defsite->base_url;
              $row->lang = $row->locale = $lang;
              if (!@$row->store()) {
                $log[] = "Creating site for language '$lang' failed, there probably already exists a site (duplicate keys).";
              }
              else {
                $id = $this->db->insertid();
                $sites[$lang] = (!empty( $id ) ? $id : null);
                $log[] = "Created site for language '$lang' ($langTitle).";
              }
            }
          }
          else {
            $sites = array();
          }
          $query = "SELECT * FROM #__alias ORDER BY id ASC";
          $this->db->setQuery( $query );
          $rows = $this->db->loadObjectList();
          $row_count = 0;
          foreach ($rows as $oldrow) {
            $row_count++;
            $site_id = (!empty( $sites[$oldrow->language] ) ? $sites[$oldrow->language] : null);
            $id = ($preserve ? $oldrow->id : null);
            $row =& new JosOpenSEFAlias( $this->db, $id );
            $row->id = $id;
            if (is_null( $id )) {
              $row->site_id = $site_id;
              $row->direction = null;
              $row->valid = '1';
              $row->stop = '0';
              $row->catid = null;
              $row->hits = 0;
              $row->notes = 'Imported from Alias Manager 1.0.3';
            }
            if (sefIsJoomlaSEF( $oldrow->target ))
              $oldrow->target = sefRewriteFromJoomlaSEF( $oldrow->target );
            if (@$oldrow->target[0] == '/')
              $oldrow->target = substr( $oldrow->target, 1 );
            $row->internal = $oldrow->target;
            $row->external = $oldrow->url;
            $row->published = !empty( $oldrow->published ) ? '1' : '0';
            if (!@$row->check() || !@$row->store()) {
              $log[] = "Importing '$row->external' => '$row->internal'<font color=red>... FAILED! Duplicate URL</font>";
              $row_count = $row_count -1 ;
            }
            else {
              $log[] = "Importing '$row->external' => '$row->internal'<font color=green>... OK</font>";
            }
          }
          $log[] = "<br /><b>Successfully imported $row_count rows in total.</b>";
        }
        if ($remove) {
          $this->db->setQuery( 'DROP TABLE #__alias' );
          $this->db->query();
          $log[] = 'Removed old data table.';
        }
        break;

      case '404sef':
        $sites = (mosGetParam( $_REQUEST, 'import_sites', '0' ) == '1');
        $preserve = (mosGetParam( $_REQUEST, 'import_preserve', '0' ) == '1');
        $remove = (mosGetParam( $_REQUEST, 'import_remove', '0' ) == '1');
        $query = "SELECT * FROM #__redirection ORDER BY id ASC";
        $this->db->setQuery( $query );
        $rows = @$this->db->loadObjectList();
        if (!is_array( $rows )) {
          $success = false;
          $log[] = "<span style='color:red'>ERROR: Couldn't locate data table ('i.e. mos_redirection') for 404_SEF.</span>";
        } else {
        $row_count = 0;
        foreach ($rows as $oldrow) {
            $row_count++;
              $site_id = null;
              $id = ($preserve ? $oldrow->id : null);
              $row =& new JosOpenSEFAlias( $this->db, $id );
              $row->id = $id;
              if (is_null( $id )) {
                  $row->site_id = $site_id;
                  $row->direction = null;
                  $row->valid = '1';
                  $row->stop = '0';
                  $row->catid = null;
                  $row->hits = $oldrow->cpt;
                  $row->notes = 'Imported from 404_SEF';
              }
              if (sefIsJoomlaSEF( $oldrow->newurl ))
                  $oldrow->newurl = sefRewriteFromJoomlaSEF( $oldrow->newurl );
              if (@$oldrow->newurl[0] == '/')
                  $oldrow->newurl = substr( $oldrow->newurl, 1 );
              $row->internal = $oldrow->newurl;
              $row->external = '/'.$oldrow->oldurl;
              $row->published = '1';
                if (!@$row->check() || !@$row->store()) {
                  $log[] = "Importing '$row->external' => '$row->internal'<font color=red>... FAILED! Duplicate URL</font>";
                  $row_count = $row_count -1 ;
              } else {
                  $log[] = "Importing '$row->external' => '$row->internal'<font color=green>... OK</font>";
              }
          }
          $log[] = "<br /><b>Successfully imported $row_count rows in total.</b>";
        }
        if ($remove) {
          $this->db->setQuery( 'DROP TABLE #__redirection' );
          $this->db->query();
          $log[] = 'Removed old data table.';
        }
        break;

      case 'sefa':
        $sites = (mosGetParam( $_REQUEST, 'import_sites', '0' ) == '1');
        $preserve = (mosGetParam( $_REQUEST, 'import_preserve', '0' ) == '1');
        $remove = (mosGetParam( $_REQUEST, 'import_remove', '0' ) == '1');
        $query = "SELECT * FROM #__sef_alias ORDER BY id ASC";
        $this->db->setQuery( $query );
        $rows = @$this->db->loadObjectList();
        if (!is_array( $rows )) {
          $success = false;
          $log[] = "<span style='color:red'>ERROR: Couldn't locate data table ('i.e. mos_sef_alias') for SEF Advance.</span>";
        } else {
        $row_count = 0;
        foreach ($rows as $oldrow) {
            $row_count++;
              $site_id = null;
              $id = ($preserve ? $oldrow->id : null);
              $row =& new JosOpenSEFAlias( $this->db, $id );
              $row->id = $id;
              if (is_null( $id )) {
                  $row->site_id = $site_id;
                  $row->direction = null;
                  $row->valid = '1';
                  $row->stop = '0';
                  $row->catid = null;
                  $row->hits = 0;
                  $row->notes = 'Imported from SEF Advance';
              }
              if (sefIsJoomlaSEF( $oldrow->newurl ))
                  $oldrow->non_sef_url = sefRewriteFromJoomlaSEF( $oldrow->non_sef_url );
              if (@$oldrow->non_sef_url[0] == '/')
                  $oldrow->non_sef_url = substr( $oldrow->non_sef_url, 1 );
              $row->internal = $oldrow->non_sef_url;
              $row->external = '/'.$oldrow->alias;
              $row->published = $oldrow->published;
                if (!@$row->check() || !@$row->store()) {
                  $log[] = "Importing '$row->external' => '$row->internal'<font color=red>... FAILED! Duplicate URL</font>";
                  $row_count = $row_count -1 ;
              } else {
                  $log[] = "Importing '$row->external' => '$row->internal'<font color=green>... OK</font>";
              }
          }
          $log[] = "<br /><b>Successfully imported $row_count rows in total.</b>";
        }
        if ($remove) {
          $this->db->setQuery( 'DROP TABLE #__sef_alias' );
          $this->db->query();
          $log[] = 'Removed old data table.';
        }
        break;

      default:
        $success = false;
        $log[] = "This feature is still under construction.";
        break;
    }

    $this->tpl->assign( 'title', $title );
    $this->tpl->assign( 'success', $success );
    $this->tpl->assign( 'log', $log );
    $this->display( 'action' );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_tools_export() {
    $title = 'Exporting Data...';
    $success = true;
    $log = array();
    require_once( 'sef.export.php' );
    $format = mosGetParam( $_REQUEST, 'export_format', null );
    $tables = array(
      '#__opensef_sef_site' => _T( 'SITES' ),
      '#__opensef_sef' => _T( 'FRIENDLY_URLS' ),
      '#__opensef_config' => _T( 'CONFIGURATION' ),
    );
    $tableFilter = mosGetParam( $_REQUEST, 'export_table', null );
    if (!empty( $tableFilter ) && $tableFilter != '') {
      foreach (array_keys( $tables ) as $table) {
        if (!ereg( "^#__$tableFilter", $table ))
          unset( $tables[$table] );
      }
    }
    switch ($format) {
      case 'sql':
        $export =& new xclExportSQL( $this->db );
        if (!$export->open()) {
          $success = false;
          $log[] = "Failed to open file " . $export->getFilePath();
        }
        else {
          $export->writeText( _T( 'APP_NAME' ) . ' ' . $this->version . ' (joomlasef.org)' );
          $export->writeText( 'Export of database ' . $GLOBALS['mosConfig_db'] );
          $export->writeText( date( "Y-m-d H:i:s" ) );
          $tablePrefix = $export->getTablePrefix();
          foreach ($tables as $table => $tableTitle) {
            if ($table == '#__opensef_config') {
              $export->addFilter( "(scope = '{$this->option}')" );
              $export->setSortField( 'name' );
            }
            else {
              $export->clearFilters();
              $export->setSortField( null );
            }
            $table = str_replace( '#__', $tablePrefix, $table );
            $rowCount = $export->exportTable( $table, $tableTitle );
            $log[] = 'Exporting ' . strtolower( $tableTitle ) . ' from table ' . $table .
              ' => ' . $rowCount . ' records exported.';
          }
          $log[] = '<p><a target="_blank" href="' . $export->getURL() . '">[ Download Results ]</a>';
          $export->close();
        }
        break;
      case 'csv':
        $export =& new xclExportCSV( $this->db );
        if (!$export->open()) {
          $success = false;
          $log[] = "Failed to open file " . $export->getFilePath();
        }
        else {
          $export->writeText( _T( 'APP_NAME' ) . ' ' . $this->version . ' (joomlasef.org)' );
          $export->writeText( 'Export of database ' . $GLOBALS['mosConfig_db'] );
          $export->writeText( date( "Y-m-d H:i:s" ) );
          $tablePrefix = $export->getTablePrefix();
          foreach ($tables as $table => $tableTitle) {
            if ($table == '#__opensef_config') {
              $export->addFilter( "(scope = '{$this->option}')" );
              $export->setSortField( 'name' );
            }
            else {
              $export->clearFilters();
              $export->setSortField( null );
            }
            $table = str_replace( '#__', $tablePrefix, $table );
            $rowCount = $export->exportTable( $table, $tableTitle );
            $log[] = 'Exporting ' . strtolower( $tableTitle ) . ' from table ' . $table .
              ' => ' . $rowCount . ' records exported.';
          }
          $log[] = '<p><a target="_blank" href="' . $export->getURL() . '">[ Download Results ]</a>';
          $export->close();
        }
        break;
      default:
        $success = false;
        $log[] = "This feature is still under construction.";
        break;
    }
    $this->tpl->assign( 'title', $title );
    $this->tpl->assign( 'success', $success );
    $this->tpl->assign( 'log', $log );
    $this->display( 'action' );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_tools_feedback() {
    GLOBAL $_VERSION;
    $title = 'Sending Feedback...';
    $success = true;
    $log = array();

    $trackerEmail = 'hide@address.com';

    // TODO: why is stripslashes necessary here, why doesn't mosGetParam do it?
    $from = stripslashes( mosGetParam( $_REQUEST, 'feedback_from', null ) );
    $type = mosGetParam( $_REQUEST, 'feedback_type', null );
    $body = stripslashes( mosGetParam( $_REQUEST, 'feedback_body', null ) );

    if (empty( $from ) || empty( $type ) || empty( $body )) {
      $success = false;
      $log[] = "Missing information, please go back and check the form.";
    }
    else {
      $types = array( // These will remain in English on purpose
        'feedback'  => 'Feedback',
        'feature'   => 'Feature Suggestion',
        'bugreport' => 'Bug Report',
      );
      if (true) {
        $div = str_repeat( '-', 72 ) . "\n";
        // TODO: perhaps would be useful to add information also on
        // PHP safe mode, MySQL version, and HTTP user agent??
        // Definitely need to add core/SEF ext info...
        $version = $_VERSION->PRODUCT .' '. $_VERSION->RELEASE .'.'. $_VERSION->DEV_LEVEL;
        $infos = array(
          'Component'     => _T( 'APP_NAME' ) . ' ' . $this->version,
          'Site URL'      => $this->JoomlaSite,
          'Joomla! Version' => $version,
          'PHP Version'   => phpversion(),
          'Web Server'    => $_SERVER['SERVER_SOFTWARE'],
          'Language'      => $GLOBALS['mosConfig_lang'],
          'Locale'        => $GLOBALS['mosConfig_locale'],
          'SEF Enabled'   => $GLOBALS['mosConfig_sef'] == '1' ? 'Yes' : 'No',
        );
        $info = '';
        foreach ($infos as $title => $text)
          $info .= $title . ': ' . $text . "\n";
      }
      else {
        $info = 'The customer chose not to include any technical details.';
      }
      $body .= "\n\n" . $div . $info . $div;
      $subject = _T( 'APP_NAME' ) . ' ' . $types[$type] . ' from ' . $from;
      $fromName = trim( $GLOBALS['mosConfig_fromname'] );
      $success = (mosMail( $from, $fromName, $trackerEmail, $subject, $body ) ? true : false);
      if (!$success) {
        $title = "Error Sending Feedback";
        $log[] = '<span style="color:red; font-weight:bold;">Unable to send e-mail, please check your Joomla! settings.</span>';
        $log[] = '';
      }
      else {
        $title = "Feedback Sent Successfully";
      }
      $log[] = '<b>' . "From:" . '</b> ' . $from;
      $log[] = '<b>' . "To:" . '</b> ' . $trackerEmail;
      $log[] = '<b>' . "Subject:" . '</b> ' . $subject;
      $log[] = '';
      $log[] = str_replace( "\n", "<br />", $body );
    }

    $this->tpl->assign( 'title', $title );
    $this->tpl->assign( 'success', $success );
    $this->tpl->assign( 'log', $log );
    $this->tpl->assign( 'backLink', true );
    $this->display( 'action' );
  }

  // ------------------------------------------------------------------------

   /*
   * TODO
   */
  function do_google( $show = 'google' ) {
    global $database, $mainframe, $sefConfig, $mosConfig_absolute_path, $mosConfig_live_site;
    require_once ($mosConfig_absolute_path."/includes/domit/xml_domit_include.php");
    $switchshow = mosGetParam( $_REQUEST, 'show', null );
    if (mosGetParam( $_REQUEST, 'task', '') == 'savexml') {
      $switchshow = 'savexml';
    }
    switch ($switchshow) {
      case 'xmlview':
        $slash="";
        if (strlen($sefConfig->google_path))
          $slash = "/";
        $xmlfile = $mosConfig_absolute_path."/".$sefConfig->google_path.$slash.$sefConfig->google_filename.".xml";
        $googleCollection = & new DOMIT_Document();
        $success = $googleCollection->loadXML($xmlfile);
        if ($success) {
          $googleDocumentElement = & $googleCollection->documentElement;
          $xmlcontent = $googleDocumentElement->toNormalizedString(true);
        } else {
          $xmlcontent = _T( 'G_VIEW_ERROR' );
        }
        $this->tpl->assign( 'xml', $this->xml );
        $this->tpl->assign( 'xmlview', $xmlcontent );
        $this->tpl->assign( 'google', $this->config );
        $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', $show ) );
        $this->display( 'google' );
        break;
      case 'generate':
        $results = array ();
        $plugin = new GoogleOpenSEFExtension();
        $results = $plugin->getURLResources();
        $total = count($results);
        $today = google :: showdate(0, 0, 1);
        //Generate the Lists
        $list[] = mosHTML :: makeOption( 'always', _T( 'G_ALWAYS' ));
        $list[] = mosHTML :: makeOption( 'hourly', _T( 'G_HOURLY' ));
        $list[] = mosHTML :: makeOption( 'daily', _T( 'G_DAILY' ));
        $list[] = mosHTML :: makeOption( 'weekly', _T( 'G_WEEKLY' ));
        $list[] = mosHTML :: makeOption( 'monthly', _T( 'G_MONTHLY' ));
        $list[] = mosHTML :: makeOption( 'yearly', _T( 'G_YEARLY' ));
        $list[] = mosHTML :: makeOption( 'never', _T( 'G_NEVER' ));
        $list1[] = mosHTML :: makeOption( '0.0','0.0');
        $list1[] = mosHTML :: makeOption( '0.1','0.1');
        $list1[] = mosHTML :: makeOption( '0.2','0.2');
        $list1[] = mosHTML :: makeOption( '0.3','0.3');
        $list1[] = mosHTML :: makeOption( '0.4','0.4');
        $list1[] = mosHTML :: makeOption( '0.5','0.5');
        $list1[] = mosHTML :: makeOption( '0.6','0.6');
        $list1[] = mosHTML :: makeOption( '0.7','0.7');
        $list1[] = mosHTML :: makeOption( '0.8','0.8');
        $list1[] = mosHTML :: makeOption( '0.9','0.9');
        $list1[] = mosHTML :: makeOption( '1.0','1.0');
        $this->tpl->assign( 'total', $total );
        $this->tpl->assign( 'list', $list );
        $this->tpl->assign( 'list1', $list1 );
        $this->tpl->assign( 'today', $today );
        $this->tpl->assign( 'row', $results );
        $this->tpl->assign( 'xml', $this->xml );
        $this->tpl->assign( 'google', $this->config );
        $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', $show ) );
        $this->display( 'google' );
        break;
      case 'savexml':
        $xml_rows = mosGetParam($_POST, 'xml_rows', array (0));
        $xml_check = mosGetParam($_POST, 'check', array (0));
        $xml_title = mosGetParam($_POST, 'title', array (0));
        $xml_url = mosGetParam($_POST, 'url', array (0));
        $xml_date = mosGetParam($_POST, 'date', array (0));
        $xml_freq = mosGetParam($_POST, 'freq', array (0));
        $xml_priority = mosGetParam($_POST, 'priority', array (0));
        google :: xml($xml_rows, $xml_check, $xml_title, $xml_url, $xml_date, $xml_freq, $xml_priority, false);
        break;
      case 'google':
      default:
        $this->tpl->assign( 'google', $this->config );
        $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', '') );
        $this->display( 'google' );
        break;
    }
  }


  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function do_seo( $show="seo" ) {
    global $mosConfig_live_site;

    $link_1_url = mosGetParam( $_POST, 'linkpop_url','');
    $link_2_url = mosGetParam( $_POST, 'linkpop_2_url','');
    if (empty($link_1_url)) {
      $link_1_url = str_replace('http://', '', $mosConfig_live_site);
    }
    if (empty($link_2_url)) {
      $link_url = $link_1_url;
      $show_second_link = false;
    } else {
      $link_url = $link_2_url;
      $show_second_link = true;
    }
    $this->tpl->assign( 'show_second_link', $show_second_link);
    $this->tpl->assign( 'link_1_url', $link_1_url);
    $this->tpl->assign( 'link_2_url', $link_2_url);
    $this->tpl->assign( 'linkpop_2_url', $link_url);
    $searchurl = str_replace('http://', '', $mosConfig_live_site);
    $this->tpl->assign( 'searchurl', $searchurl);
    $this->tpl->assign( 'action_google', '');
    $this->tpl->assign( 'total_pop_links', '');
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', $show) );
    $this->display( 'seocheck' );
  }

  // ------------------------------------------------------------------------

  function do_seo_searchgg( $show="searchgg" ) {
    global $mosConfig_absolute_path, $mosConfig_live_site;

    set_time_limit(360);

    // Load Parameters
    $showlinks    = mosGetParam( $_POST, 'show_links', 0);
    $searchtotal  = mosGetParam( $_POST, 'search_total', '');
    $searchterm   = mosGetParam( $_POST, 'search_term', '');
    $searchurl    = mosGetParam( $_POST, 'search_url', '');

    if( $searchtotal && $searchurl && $searchterm ){

      // Check GOOGLE
      $check_google = mosGetParam( $_POST, 'check_google',0);
      $this->tpl->assign( 'check_google', $check_google);
      if($check_google && $searchurl) {
        $a = explode ("http://", $searchurl );
        if(empty($a[0])) $searchurl = $a[1];
        $result_google = seo_google_position($searchterm,$searchurl,$searchtotal,$showlinks);
        $gnr = count($result_google)-1;
        $this->tpl->assign( 'siteresults_google', $result_google);
        $this->tpl->assign( 'result_google', $result_google[$gnr]);
      }

      // Check YAHOO
      $check_yahoo = mosGetParam( $_POST, 'check_yahoo',0);
      $this->tpl->assign( 'check_yahoo', $check_yahoo);
      if($check_yahoo && $searchurl) {
        $a = explode ("http://", $searchurl );
        if(empty($a[0])) $searchurl = $a[1];
        $result_yahoo = seo_yahoo_position($searchterm,$searchurl,$searchtotal,$showlinks);
        $ynr = count($result_yahoo)-1;
        $this->tpl->assign( 'siteresults_yahoo', $result_yahoo);
        $this->tpl->assign( 'result_yahoo', $result_yahoo[$ynr]);
      }

    } else
      $this->tpl->assign( 'error_msg', 'Please Complete All Fields');

    // Assign Template Values
    $this->tpl->assign( 'showlinks', $showlinks);
    $this->tpl->assign( 'searchtotal', $searchtotal);
    $this->tpl->assign( 'searchterm', $searchterm);
    $this->tpl->assign( 'searchurl', $searchurl);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'searchgg' ) );
    $this->display( 'seocheck' );

  }

  // ------------------------------------------------------------------------

  function do_seo_searchrank( $show="searchrank" ) {
      global $mosConfig_absolute_path, $mosConfig_live_site;

      set_time_limit(360);
      if (empty($searchurl)) {
        $searchurl = str_replace('http://', '', $mosConfig_live_site);
      }
      $action_rank = mosGetParam( $_POST, 'rank_urls','');
      $checkPr = mosGetParam( $_POST, 'checkPr',0);
      $useCache = mosGetParam( $_POST, 'useCache',0);

      if ($action_rank){
        $rank_url = mosGetParam( $_POST, 'rank_urls','');

        $url = explode("\n",$rank_url);
        $gpr = new GooglePR();
        $gpr->debug=true;
        $gpr->useCache = ($useCache == 1) ? true:false;
        $gpr->userAgent = $_SERVER["HTTP_USER_AGENT"];

        $checkCount = 0;
        $gprResults = Array();
        $searchurl=$rank_url;
        if (!empty($rank_url)) {
          for ($i=0;$i<count($url);$i++) {
            if (strlen(trim($url[$i]))>0) {
              $_url = eregi("http://",$url[$i])? $url[$i]:"http://".$url[$i];
              $gprResults[$checkCount] = Array();
              $gprResults[$checkCount]['url']   = $_url;
              $gprResults[$checkCount]['rank']  = $gpr->checkUrl($_url);
              $gprResults[$checkCount]['time']  = $gpr->getProcResult("exec_time");
              $gprResults[$checkCount]['image'] = $gpr->getRankImage();
              $checkCount++;
            }
          }
        }
      }
      $this->tpl->assign( 'pagerank', $gprResults);
      $this->tpl->assign( 'prrating', Array("Very poor","Poor","Below average","Average","Above Average","Good","Good","Very Good","Very Good","Excellent"));
      $this->tpl->assign( 'searchurl', $searchurl);
      $this->tpl->assign( 'rank_urls', $rank_url);
      $this->tpl->assign( 'checkPr', $checkPr);
      $this->tpl->assign( 'useCache', $useCache);
      $this->tpl->assign( 'seo', $this->config );
      $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'searchrank' ) );
      $this->display( 'seocheck' );
  }

  // ------------------------------------------------------------------------

  function do_seo_linkpop ($show="linkpop") {
    global $mosConfig_absolute_path, $mosConfig_live_site, $total, $results, $link_2_url;

    set_time_limit(360);

    $action_linkpop = mosGetParam( $_POST, 'linkpop_url','');
    $link_1_url = mosGetParam( $_POST, 'linkpop_url','');
    $link_2_url = mosGetParam( $_POST, 'linkpop_2_url','');
    if (empty($link_1_url)) {
      $link_1_url = str_replace('http://', '', $mosConfig_live_site);
    }
    if (empty($link_2_url)) {
      $link_url = $link_1_url;
      $show_second_link = false;
    } else {
      $link_url = $link_2_url;
      $show_second_link = true;
    }

    if ($action_linkpop) {
      /*
      $link_1_url = mosGetParam( $_POST, 'linkpop_url','');
      $link_2_url = mosGetParam( $_POST, 'linkpop_2_url','');
      if (empty($link_1_url)) {
        $link_1_url = str_replace('http://', '', $mosConfig_live_site);
      }
      if (empty($link_2_url)) {
        $link_url = $link_1_url;
        $show_second_link = false;
      } else {
        $link_url = $link_2_url;
        $show_second_link = true;
      }*/
      $total = 0;
      $results = array();
      if ( ! ($results = get_link_popularity($link_url))) {
        $error = 'Failed to read url: '.$rank_url;
        echo $error;
      }
      if (! empty($link_2_url)) {
        $results_2 = $results;
        $total_2 = $total;
        reset($results);
        $total = 0;
        $link_url = $link_1_url;
        if ( ! ($results = get_link_popularity($link_url))) {
          $error = 'Failed to read url: '.$rank_url;
          echo $error;
        }
      }
      $searchurl=$link_1_url;
    }
    $this->tpl->assign( 'total_pop_links', $total);
    $this->tpl->assign( 'total', $total);
    $this->tpl->assign( 'total_2', $total_2);
    $this->tpl->assign( 'results', $results);
    $this->tpl->assign( 'results_2', $results_2);
    $this->tpl->assign( 'show_second_link', $show_second_link);
    $this->tpl->assign( 'link_1_url', $link_1_url);
    $this->tpl->assign( 'link_2_url', $link_2_url);
    $this->tpl->assign( 'linkpop_2_url', $link_url);
    $this->tpl->assign( 'searchurl', $searchurl);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'linkpop' ) );
    $this->display( 'seocheck' );
  }

  // ------------------------------------------------------------------------

  function do_seo_kwdensity ($show="kwdensity") {
    global $mosConfig_absolute_path, $mosConfig_live_site;
    $action_kwdensity = mosGetParam( $_POST, 'density_url','');
    if ($action_kwdensity) {
      $density_url = mosGetParam( $_POST, 'density_url','');
      $use_meta_tags = mosGetParam( $_POST, 'use_meta_tags','');
      $use_partial_total = mosGetParam( $_POST, 'use_partial_total','');
      $searchurl=$density_url;
      $ttl_words = 0;
      if (! empty($density_url)) {
        if (! ($dens = kda($density_url, $ttl_words, $use_meta_tags, $use_partial_total))) {
          $error = 'Failed to read url: '.$density_url;
          echo $error;
        }
      }
    }
    $this->tpl->assign( 'dens', $dens);
    $this->tpl->assign( 'ttl_words', $ttl_words);
    $this->tpl->assign( 'searchurl', $searchurl);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'kwdensity' ) );
    $this->display( 'seocheck' );
  }

  // ------------------------------------------------------------------------

  function do_seo_wordeditor ($show="wordeditor") {
    global $mosConfig_absolute_path, $mosConfig_live_site, $sefConfig;
    $conf_file = $mosConfig_absolute_path."/administrator/components/com_sef/includes/seo_words/seo_words_$sefConfig->backend_language.txt";
    $config_txt="";

    $fp=fopen($conf_file,"r");
    if($fp) {
      while(!feof($fp))
      $config_txt .= fread($fp,1024);
      fclose($fp);
    } else {
      echo "<h2>Problem reading config file $conf_file !</h2>";
    }

    $this->tpl->assign( 'conf', $conf_file);
    $this->tpl->assign( 'config', $config_txt);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'wordeditor' ) );
    $this->display( 'wordeditor' );
  }

  // ------------------------------------------------------------------------

  function do_seo_save_words ($show="wordeditor") {
    global $mosConfig_absolute_path, $mosConfig_live_site, $sefConfig;

    $conf_file = $mosConfig_absolute_path."/administrator/components/com_sef/includes/seo_words/seo_words_$sefConfig->backend_language.txt";
    $config_txt="";
    $action = mosGetParam( $_POST, 'task','');
    $config_text = mosGetParam( $_POST, 'config_text','');

    if($action =='save_words') {
      $fp=@fopen($conf_file,"w");
      if($fp) {
          fwrite($fp,stripslashes($config_text));
          fclose($fp);
        echo "<h3>Exclusions Succesfully changed</h3>";
      } else {
          echo "<h3 style='color:red;'>Please edit the permissions to file $conf_file to be writeable!</h3>";
      }
    }

    $fp=fopen($conf_file,"r");
    if($fp) {
      while(!feof($fp))
      $config_txt .= fread($fp,1024);
      fclose($fp);
    } else {
      echo "<h2>Problem reading config file $conf_file !</h2>";
    }

    $this->tpl->assign( 'conf', $conf_file);
    $this->tpl->assign( 'config', $config_txt);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'wordeditor' ) );
    $this->display( 'wordeditor' );
  }

  // ------------------------------------------------------------------------

  function do_seo_checklinks ($show="checklinks") {
    global $mosConfig_absolute_path, $mosConfig_live_site, $badLinks, $totalLinks;

    $action_check_links = mosGetParam( $_POST, 'check_page','');
    set_time_limit(360);
    if ($action_check_links) {
      $badLinks = array();
      $idx = 0;
      $totalLinks = 0;
      $url = mosGetParam( $_POST, 'check_page','');
      if (FALSE === strpos($url, 'http://'))
        $link = 'http://'.$url;
      CheckLinks($link, $idx);
      $searchurl=$url;
    }
    $this->tpl->assign( 'badlinks', $badLinks);
    $this->tpl->assign( 'totallinks', $totalLinks);
    $this->tpl->assign( 'searchurl', $searchurl);
    $this->tpl->assign( 'seo', $this->config );
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'searchrank' ) );
    $this->display( 'seocheck' );
  }

  // ------------------------------------------------------------------------

  function do_seo_metatag ($show="metatag") {
    global $database, $mainframe, $mosConfig_list_limit, $option;
    $sectionid  = mosGetParam( $_REQUEST, 'sectionid', 0 );
    $id     = mosGetParam( $_REQUEST, 'id', '' );
    $cid    = mosGetParam( $_POST, 'cid', array(0) );
    if (!is_array( $cid )) {
      $cid = array(0);
    }
    $catid        = $mainframe->getUserStateFromRequest( "catid{$option}{$sectionid}", 'catid', 0 );
    $filter_authorid  = $mainframe->getUserStateFromRequest( "filter_authorid{$option}{$sectionid}", 'filter_authorid', 0 );
    $filter_sectionid   = $mainframe->getUserStateFromRequest( "filter_sectionid{$option}{$sectionid}", 'filter_sectionid', 0 );
    $limit        = $mainframe->getUserStateFromRequest( "viewlistlimit", 'limit', $mosConfig_list_limit );
    $limitstart     = $mainframe->getUserStateFromRequest( "view{$option}{$sectionid}limitstart", 'limitstart', 0 );
    $search       = $mainframe->getUserStateFromRequest( "search{$option}{$sectionid}", 'search', '' );
    $search       = $database->getEscaped( trim( strtolower( $search ) ) );
    $redirect       = $sectionid;
    $filter       = ''; //getting a undefined variable error

    if ( $sectionid == 0 ) {
      // used to show All content items
      $where = array(
      "c.state  >= 0",
      "c.catid  = cc.id",
      "cc.section = s.id",
      "s.scope  = 'content'",
      );
      $order = "\n ORDER BY s.title, c.catid, cc.ordering, cc.title, c.ordering";
      $all = 1;
      //$filter = "\n , #__sections AS s WHERE s.id = c.section";

      if ($filter_sectionid > 0) {
        $filter = "\n WHERE cc.section = $filter_sectionid";
      }
      $section->title = 'All Content Items';
      $section->id = 0;
    } else {
      $where = array(
      "c.state  >= 0",
      "c.catid  = cc.id",
      "cc.section = s.id",
      "s.scope  = 'content'",
      "c.sectionid = '$sectionid'"
      );
      $order    = "\n ORDER BY cc.ordering, cc.title, c.ordering";
      $all    = NULL;
      $filter   = "\n WHERE cc.section = '$sectionid'";
      $section  = new mosSection( $database );
      $section->load( $sectionid );
    }

    // used by filter
    if ( $filter_sectionid > 0 ) {
      $where[] = "c.sectionid = $filter_sectionid";
    }
    if ( $catid > 0 ) {
      $where[] = "c.catid = $catid";
    }
    if ( $filter_authorid > 0 ) {
      $where[] = "c.created_by = $filter_authorid";
    }

    if ( $search ) {
      $where[] = "LOWER( c.title ) LIKE '%$search%'";
    }

    // get the total number of records
    $query = "SELECT COUNT(*)"
    . "\n FROM #__content AS c INNER JOIN #__categories AS cc INNER JOIN #__sections AS s"
    . ( count( $where ) ? "\n WHERE " . implode( ' AND ', $where ) : "" )
    ;
    $database->setQuery( $query );
    $total = $database->loadResult();
    require_once( $GLOBALS['mosConfig_absolute_path'] . '/administrator/components/com_sef/includes/pageNavigation.php' );
    $pageNav = new mosPageNav( $total, $limitstart, $limit );

    $query = "SELECT c.*, g.name AS groupname, cc.name, u.name AS editor, f.content_id AS frontpage, s.title AS section_name, v.name AS author"
    . "\n FROM ( #__content AS c, #__categories AS cc, #__sections AS s )"
    . "\n LEFT JOIN #__groups AS g ON g.id = c.access"
    . "\n LEFT JOIN #__users AS u ON u.id = c.checked_out"
    . "\n LEFT JOIN #__users AS v ON v.id = c.created_by"
    . "\n LEFT JOIN #__content_frontpage AS f ON f.content_id = c.id"
    . ( count( $where ) ? "\nWHERE " . implode( ' AND ', $where ) : '' )
    . $order
    . "\n LIMIT $pageNav->limitstart, $pageNav->limit"
    ;
    $database->setQuery( $query );
    $rows = $database->loadObjectList();

    if ($database->getErrorNum()) {
      echo $database->stderr();
      return false;
    }

    // get list of categories for dropdown filter
    $query = "SELECT cc.id AS value, cc.title AS text, section"
    . "\n FROM #__categories AS cc"
    . "\n INNER JOIN #__sections AS s ON s.id = cc.section "
    . $filter
    . "\n ORDER BY s.ordering, cc.ordering"
    ;
    $lists['catid']   = metatag_filterCategory( $query, $catid );

    // get list of sections for dropdown filter
    $javascript = 'onchange="document.adminForm.submit();"';
    $lists['sectionid'] = metatag_filterSection( 'filter_sectionid', $filter_sectionid, $javascript );

    // get list of Authors for dropdown filter
    $query = "SELECT c.created_by, u.name"
    . "\n FROM #__content AS c"
    . "\n INNER JOIN #__sections AS s ON s.id = c.sectionid"
    . "\n LEFT JOIN #__users AS u ON u.id = c.created_by"
    . "\n WHERE c.state <> -1"
    . "\n AND c.state <> -2"
    . "\n GROUP BY u.name"
    . "\n ORDER BY u.name"
    ;
    $authors[] = mosHTML::makeOption( '0', _T('SEL_AUTHOR'), 'created_by', 'name' );
    $database->setQuery( $query );
    $authors = array_merge( $authors, $database->loadObjectList() );
    $lists['authorid']  = mosHTML::selectList( $authors, 'filter_authorid', 'class="inputbox" size="1" onchange="document.adminForm.submit( );"', 'created_by', 'name', $filter_authorid );

    $this->tpl->assign( 'rows', $rows);
    $this->tpl->assign( 'section', $section);
    $this->tpl->assign( 'lists', $lists);
    $this->tpl->assign( 'search', $search);
    $this->tpl->assign( 'pageNav', $pageNav);
    $this->tpl->assign( 'all', $all);
    $this->tpl->assign( 'redirect', $redirect);
    $this->tpl->assign( 'show', mosGetParam( $_REQUEST, 'show', 'metatag' ) );
    $this->display( 'metatag' );
  }

  // ------------------------------------------------------------------------

  function do_seo_metatag_gen_metakeys ($show="metatag") {
    metatag_gen_key();
    $this->do_seo_metatag();
  }

  // ------------------------------------------------------------------------

  function do_seo_metatag_gen_metadesc ($show="metatag") {
    metatag_gen_desc();
    $this->do_seo_metatag();
  }

  // ------------------------------------------------------------------------

  function do_seo_metatag_save_manager ($show="metatag") {
    metatag_save_manager();
    $this->do_seo_metatag();
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function getSiteList() {
    $query = 'SELECT id, title, host, base_url FROM ' .
      $this->tables['sites'];
    $this->db->setQuery( $query );
    $rows = $this->db->loadObjectList();
    $sites = array(
       null => '(' . _T('ALL') . ')',
      -1 => '(' . _T('DEFAULT_ONLY') . ')',
    );
    if (is_array( $rows ) && count( $rows ) > 0) {
      foreach ($rows as $row) {
        $sites[$row->id] = $row->title;
      }
    }
    return $sites;
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function getMenuComponents() {
    $query = "SELECT m.* FROM #__menu AS m" .
      "\nWHERE type = 'components'" .
      "\nAND published <> -2" .
      "\nAND link !='index.php?option=com_banners'" .
      "\nAND link !='index.php?option=com_wrapper'" .
      "\nAND link !='index.php?option=com_weblinks'" .
      "\nAND link !='index.php?option=com_newsfeeds'" .
      "\nORDER BY menutype ASC, componentid ASC, ordering ASC, name ASC";
    $this->db->setQuery( $query );
    $rows = $this->db->loadObjectList();
    // Establish the hierarchy of the menu
    $children = array();
    // First pass - collect children
    foreach ($rows as $row) {
    // First pass - collect children
          $row->parent=0;
        $list[]=$row;
    }
    // Second pass - get an indent list of the items
    $children[]=$list;
    return mosTreeRecurse( 0, '', array(), $children );
  }

  // ------------------------------------------------------------------------

  /*
   * TODO
   */
  function storeComponentAliases( $site_id ) {
    if (isset( $_POST['_alias'] ) && is_array( $_POST['_alias'] )) {
      // Delete any existing component aliases for this site
      $query = "DELETE FROM #__opensef_sef_component" .
        "\nWHERE site_id " . ($site_id ? "= '{$site_id}'" : 'IS NULL');
      $this->db->setQuery( $query );
      $result = $this->db->query();

      // If there were any component aliases defined, re-insert
      // them into the component table
      if (isset( $_POST['_component'] )) {
        $components = $_POST['_component'];
        $aliases = $_POST['_alias'];
        foreach ($components as $component => $mappings) {
          foreach ($mappings as $menuid => $enabled) {
            $alias = $aliases[$component][$menuid];
            if ($enabled == '1' && $alias) {
              $row =& new JosOpenSEFComponent( $this->db );
              $row->site_id = $site_id;
              $row->menu_id = $menuid;
              $row->component = $component;
              $row->alias = $alias;
              $row->ordering = 0;
              $row->published = '1';
              $row->block = '0';
              $row->store();
            }
          }
        }

      }

      if (isset( $_POST['_block'] )) {
        $components = $_POST['_block'];
        $aliases = $_POST['_alias'];
        foreach ($components as $component => $mappings) {
          foreach ($mappings as $menuid => $enabled) {
            $alias = $aliases[$component][$menuid];
            if ($enabled == '1' && $alias) {
              $row =& new JosOpenSEFComponent( $this->db );
              $row->site_id = $site_id;
              $row->menu_id = $menuid;
              $row->component = $component;
              $row->alias = $alias;
              $row->ordering = 0;
              $row->published = '0';
              $row->block = '1';
              $row->store();
            }
          }
        }

      }
    unset( $_POST['_alias'] );
        unset( $_POST['_block'] );
        unset( $_POST['_component'] );
    }
  }

  // ------------------------------------------------------------------------

}

// ------------------------------------------------------------------------
// Execute Admin Class

$admin =& new JosOpenSEFAdmin();
$admin->output();
Return current item: Joomla SEF / SEO - extending OpenSEF