#!/usr/bin/perl
# ----------------------------------------------------------------------------
# This software is Copyright (C) 2007, All Rights Reserved
# ----------------------------------------------------------------------------
# This program is protected by local and international copyright laws. Any
# use of this program is subject to the the terms of the license agreement
# included as part of this distribution archive. Any other uses are strictly
# prohibited without the written permission of the Vendor and all
# other rights are reserved.
# -----------------------------------------------------------------------------
# Warning : Modifying this program violates your license agreement!
# -----------------------------------------------------------------------------

package IT::ArtMan::Upgrade;

  # load modules
  use strict;
  use Socket qw(:DEFAULT :crlf);

  use IT::Globals;

# ----------------------------------------------------------------------------
# Function    : upgradeIfNeeded
# Description :
# Usage       : &IT::ArtMan::Upgrade::upgradeIfNeeded();
# ----------------------------------------------------------------------------

sub upgradeIfNeeded {

  # run version specific upgrade code
  if ($SETTINGS->{'programVersion'} < 2.01)  { &_upgradeTo201(); }
  if ($SETTINGS->{'programVersion'} < 2.10)  { &_upgradeTo210(); }

  # update programVersion in settings
  if ($SETTINGS->{'programVersion'} ne $PROGRAM_VERSION) {
    $SETTINGS->{'programVersion'} = $PROGRAM_VERSION;
    &IT::App::Menu::Admin::saveAdminSettingsToFile($SETTINGS);
    &IT::App::alert("Software upgraded to v$PROGRAM_VERSION");
  }

}

# ----------------------------------------------------------------------------
# Function    : _upgradeTo201
# Description :
# Usage       : &_upgradeTo201();
# ----------------------------------------------------------------------------

sub _upgradeTo201 {

  ### Update imported accounts that are disabled to have access level 0 instead of 1

  my $accountsTable = $TABLE_PREFIX . "accounts";
  my $whereQuery    = "accessLevel = '1'";
  my $updateArray   = [['accessLevel', '=', '0']];

  &IT::FileLock::getLock('exclusive');
  &IT::DB::update($accountsTable, $whereQuery, $updateArray);
  &IT::FileLock::releaseLock();


  ### Add keyword link to searchResults.html nextpage link (if writable)

  my $templatePath = "$CGIDIR/templates/searchEngine/searchResults.html";
  if (-e $templatePath && -w $templatePath) {

    &IT::FileLock::getLock('exclusive');
    my $html = &IT::File::readFile($templatePath);

    $html =~ s|(<[^>]*\$settings.searchurl\$\?[^>]*>)|
      my $newSearchLinkTag = $1;
      if ($newSearchLinkTag !~ m/keyword=/) {
        $newSearchLinkTag =~ s/\$settings.searchurl\$\?/\$settings.searchurl\$\?keyword=\$form.keyword:urlEncoded\$&/;
      }
      $newSearchLinkTag;
    |ge;

    &IT::File::writeFile("$templatePath.new", $html) || die "Error writing $templatePath.new! Check permissions!";
    &IT::FileLock::releaseLock();

    rename("$templatePath", "$templatePath.v2_00_backup") || die "Error writing $templatePath.v2_00_backup! Check permissions!";
    rename("$templatePath.new", "$templatePath")          || die "Error writing $templatePath! Check permissions!";
  }

}

# ----------------------------------------------------------------------------
# Function    : _upgradeTo210
# Description :
# Usage       : &_upgradeTo210();
# ----------------------------------------------------------------------------

sub _upgradeTo210 {

  # remove separator data attached to schema fields and create "separator only" schema fields
  &__upgradeTo210_createFieldsForFieldSeparators();

  # add "externalUrl" field and rename "filterAllAnyOrNone" to "filterAllOrAny"
  &__upgradeTo210_updatePublishRuleFields();

  # make "categoryNum" a primaryCategory field and create 4 secondaryCategory fields
  &__upgradeTo210_updateArticleFields();

}

# ----------------------------------------------------------------------------
# Function    : __upgradeTo210_createFieldsForFieldSeparators
# Description :
# Usage       : &__upgradeTo210_createFieldsForFieldSeparators();
# ----------------------------------------------------------------------------

sub __upgradeTo210_createFieldsForFieldSeparators {

  &IT::FileLock::getLock('exclusive');
  my @tables = &IT::DB::Schema::listTables();
  foreach my $tableName (@tables) {
    my $fieldOrder = 0;
    my @fieldNames = &IT::App::getUserSortedFieldNames($tableName, 'INCLUDE_SCHEMA_ONLY_FIELDS');
    foreach my $fieldName (@fieldNames) {

      # load field separator
      my $appFieldSeparator = &IT::DB::Schema::getFieldAttributes($tableName, $fieldName, 'appFieldSeparator');
      my $appFieldType      = &IT::DB::Schema::getFieldAttributes($tableName, $fieldName, 'appFieldType');
      my $appHiddenField    = &IT::DB::Schema::getFieldAttributes($tableName, $fieldName, 'appHiddenField');
      my $fieldIsSeparator  = $appFieldType eq 'separator';
      my $fieldHasSeparator = $appFieldSeparator->{'separatorType'} && $appFieldSeparator->{'separatorType'} ne 'none';
      my $separatorPosition = $appFieldSeparator->{'separatorPosition'};

      # re-order fields
      my($newFieldOrder, $newSeparatorOrder);

      if ($fieldIsSeparator || !$fieldHasSeparator) {
        $fieldOrder    += 10;
        $newFieldOrder  = $fieldOrder;
      }
      else { # field has separator
        $fieldOrder += 20;

        my $firstPosition = $fieldOrder - 10;
        my $secondPosition = $fieldOrder;

        if    ($separatorPosition eq 'before') { $newSeparatorOrder = $firstPosition; $newFieldOrder     = $secondPosition;  }
        elsif ($separatorPosition eq 'after')  { $newFieldOrder     = $firstPosition; $newSeparatorOrder = $secondPosition; }
      }
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appDisplayOrder', $newFieldOrder);

      # skip separator fields
      if ($fieldIsSeparator) { next; }

      # remove separator data from field
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appFieldSeparator', undef);

      # create seperator
      if ($fieldHasSeparator) {
        &IT::App::alert("Upgrading Field Editor: Creating separator field from separator data in '$tableName:$fieldName'.");
        my $newFieldname = &IT::DB::Schema::generateNewFieldname($tableName, '___separator', '___');
        &IT::DB::Schema::createField($tableName, $newFieldname, 'none');
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appFieldType',      'separator');
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appFieldLabel',     "separator");
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appDisplayOrder',   $newSeparatorOrder);
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appHiddenField',    $appHiddenField);
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appUserEditable',   1);
        &IT::DB::Schema::setFieldAttribute($tableName, $newFieldname, 'appFieldSeparator', {
          'separatorType'       => $appFieldSeparator->{'separatorType'},
          'separatorHeaderText' => $appFieldSeparator->{'separatorHeaderText'},
          'separatorHTML'       => $appFieldSeparator->{'separatorHTML'},
        });
      }
    }
  }

  # save schema
  &IT::DB::Schema::saveSchema($SCHEMA_FILEPATH);
  &IT::FileLock::releaseLock();

}

# ------------------------------------------------------------------------------
# Function    : __upgradeTo210_updatePublishRuleFields
# Description :
# Usage       : &__upgradeTo210_updatePublishRuleFields();
# ------------------------------------------------------------------------------

sub __upgradeTo210_updatePublishRuleFields {

  &IT::FileLock::getLock('exclusive');
  my $tableName = "${TABLE_PREFIX}publishrules";

  # publishRules table - add "externalUrl" field
  {
    my $fieldName   = "externalUrl";
    my $dbFieldType = "string";
    unless (&IT::DB::Schema::existsField($tableName, $fieldName)) {
      &IT::App::alert("Upgrading Publish Rules: Adding '$fieldName' field.");
      &IT::DB::createField($tableName,               $fieldName, $dbFieldType);
      &IT::DB::Schema::createField($tableName,       $fieldName, $dbFieldType);
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appDisplayOrder', '610');
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appFieldLabel',   '');
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appFieldType',    'textfield');
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appUserEditable', '1');
      &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appHiddenField',  '1');
    }
  };

  # publishRules table - rename "filterAllAnyOrNone" to "filterAllOrAny"
  {
    my $oldFieldName = "filterAllAnyNone";
    my $newFieldName = "filterAllOrAny";
    my $dbFieldType  = "string";
    if (&IT::DB::Schema::existsField($tableName, $oldFieldName)) {
      &IT::App::alert("Upgrading Publish Rules: Renaming '$oldFieldName' to '$newFieldName'.");
      &IT::DB::changeFieldNameAndType($tableName, $oldFieldName, $newFieldName, $dbFieldType);
      &IT::DB::Schema::changeFieldNameAndType($tableName, $oldFieldName, $newFieldName, $dbFieldType);
    }
  };

  # save schema
  &IT::DB::Schema::saveSchema($SCHEMA_FILEPATH);
  &IT::FileLock::releaseLock();

}

# ------------------------------------------------------------------------------
# Function    : __upgradeTo210_updateArticleFields
# Description :
# Usage       : &__upgradeTo210_updateArticleFields();
# ------------------------------------------------------------------------------

sub __upgradeTo210_updateArticleFields {

  &IT::FileLock::getLock('exclusive');
  my $tableName = "${TABLE_PREFIX}article";

  # article table - change "categoryNum" fieldtype
  my $fieldName    = "categoryNum";
  my $newFieldName = $fieldName;
  my $dbFieldType  = "int";
  &IT::App::alert("Upgrading Article Editor: Changing 'categoryNum' field to be 'Primary Category'.");
  &IT::DB::changeFieldNameAndType($tableName, $fieldName, $newFieldName, $dbFieldType);
  &IT::DB::Schema::changeFieldNameAndType($tableName, $fieldName, $newFieldName, $dbFieldType);
  &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appFieldType',       'custom');
  &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'appCustomFieldType', 'articleEditorPrimaryCategory');
  &IT::DB::Schema::setFieldAttribute($tableName, $fieldName, 'type',               $dbFieldType);

  # article table - add secondary categories
  my($newDisplayOrder) = &IT::DB::Schema::getFieldAttributes($tableName, "categoryNum", 'appDisplayOrder');
  foreach my $num (2..5) {
    my $secondaryFieldName = "category${num}Num";
    unless (&IT::DB::Schema::existsField($tableName, $secondaryFieldName)) {
      &IT::App::alert("Upgrading Article Editor: Adding secondary category field '$secondaryFieldName'.");
      &IT::DB::createField($tableName,               $secondaryFieldName, $dbFieldType);
      &IT::DB::Schema::createField($tableName,       $secondaryFieldName, $dbFieldType);
      &IT::DB::Schema::setFieldAttribute($tableName, $secondaryFieldName, 'appDisplayOrder',    ++$newDisplayOrder);
      &IT::DB::Schema::setFieldAttribute($tableName, $secondaryFieldName, 'appFieldLabel',      '');
      &IT::DB::Schema::setFieldAttribute($tableName, $secondaryFieldName, 'appFieldType',       'custom');
      &IT::DB::Schema::setFieldAttribute($tableName, $secondaryFieldName, 'appCustomFieldType', 'articleEditorSecondaryCategory');
      &IT::DB::Schema::setFieldAttribute($tableName, $secondaryFieldName, 'appUserEditable',    '1');
    }
  }

  # save schema
  &IT::DB::Schema::saveSchema($SCHEMA_FILEPATH);
  &IT::FileLock::releaseLock();

}

# ----------------------------------------------------------------------------
# end of file
1;

