#
#    ________________________________________________________________
#   |/              Web Application Development
#   |\nowmad        http://www.knowmad.com/
#    Technologies
#    ________________________________________________________________
#

package WebGUI::Workflow::Activity::W3CValidator;


=head1 LEGAL

 -------------------------------------------------------------------
  WebGUI is Copyright 2001-2007 Plain Black Corporation.
 -------------------------------------------------------------------
  Please read the legal notices (docs/legal.txt) and the license
  (docs/license.txt) that came with this distribution before using
  this software.
 -------------------------------------------------------------------
  http://www.plainblack.com                     info@plainblack.com
 -------------------------------------------------------------------

=cut

use strict;
use base 'WebGUI::Workflow::Activity';
use WebService::Validator::HTML::W3C;
use Data::Dumper;

=head1 NAME

Package WebGUI::Workflow::Activity::W3CValidator

=head1 DESCRIPTION

This workflow is a proof of concept Workflow that demonstrates connecting to the W3C Markup Validation Service (http://validator.w3.org/docs/api.html). Currently, it only validates the default page. Results are sent by email to the designated address when configuring the Workflow.

Future work will involve creating a loop to validate all the pages of a website and to add support for validating CSS snippets.

=head1 REQUIREMENTS

=over

=item 1.

Requires the WebService::Validator::HTML::W3C module to be installed.

=item 2.

I have only tested this workflow under WebGUI 7.4.

=item 3.

Since this uses a service, the page(s) you are validating must be publicly accessible.

=back


=head1 SYNOPSIS

=over

=item 1. 

Add this file to the lib/WebGUI/Workflow/Activity directory

=item 2.

Add the workflow to your settings file in workflowActivities under section "None" as "WebGUI::Workflow::Activity::W3CValidator"

=item 3.

Restart modperl server

=item 4.

Add the 'W3C Validator' service to your Daily or Weekly Maintenance Tasks workflow

=item 5.

Set the email address the output of this workflow should be sent to

=back

=head1 SYNOPSIS

See WebGUI::Workflow::Activity for details on how to use any activity.

=head1 METHODS

These methods are available from this class:

=cut


#-------------------------------------------------------------------

=head2 definition ( session, definition )

See WebGUI::Workflow::Activity::defintion() for details.

=cut 

sub definition {
  my $class = shift;
  my $session = shift;
  my $definition = shift;
  # TODO: Add support for i18n
  #my $i18n = WebGUI::International->new($session, "Workflow_Activity_Validator");
  push(@{$definition}, {
      #name=>$i18n->get("topicName"),
      name=>'W3C Validator',
      properties=> {
        to => {
          fieldType=>"text",
          #label=>$i18n->get("to"),
          label=>"To",
          defaultValue=>$session->setting->get("companyEmail"),
          #hoverHelp=>$i18n->get("to help")
          hoverHelp=>"Email to send output"
        },
      }
    });
  return $class->SUPER::definition($session,$definition);
}


#-------------------------------------------------------------------

=head2 execute ( [ object ] )

See WebGUI::Workflow::Activity::execute() for details.

=cut

sub execute {
  my $self = shift;
  my $session = $self->session;
  my @valids;
  my @warnings;
  my @invalids;

  my $v = WebService::Validator::HTML::W3C->new(
    detailed    =>  1
  );

  $session->errorHandler->info( "Validator => " . $v->validator_uri() );

  ## Get homepage
  my $pid = $self->session->setting->get('defaultPage');
  my $page = WebGUI::Asset->new($self->session, $pid);
  my $pagename = $page->get('title');
  my $abs_url = join( "/", $session->setting->get('companyURL'), $page->get('url') );
  warn "Absolute url => " . $abs_url;

  ## Validate page
  my $out = "WebGUI::Workflow::Activity::W3CValidator\n";
  $out .= scalar( localtime() ) . "\n\n";

  if ( $v->validate($abs_url) ) {
    $session->errorHandler->debug( "W3C raw output => " . $v->_output() );
    my $warnings = [];
    # the warnings() method is not fully implemented
    #my $warnings = $v->warnings();
    #$session->errorHandler->debug( "W3C warnings => " . $warnings) if @$warnings;
    if ( $v->is_valid && !@$warnings) {
      push @valids, [$pagename, $v->uri];
    }
    elsif ( $v->is_valid && scalar(@$warnings) ) {
      my $warnings_cnt = -999;
      push @warnings, [$pagename, $v->uri, $warnings_cnt];
      # TODO: Add list of warnings
    } else {
      push @invalids, [$pagename, $v->uri];
      # TODO: Add list of errors
      my $errors = $v->errors;
      foreach my $error ( @$errors ) {
        $out .= sprintf("  %s at line %d\n", $error->msg, $error->line);
      }
    }
  } else {
    $out .= sprintf ("Failed to validate the website (%s): %s\n", $v->uri, $v->validator_error);
  }

  ## Generate output
  # Valid
  $out .= "Valid Pages\n-----------\n" if scalar(@valids);
  foreach my $p (@valids) {
    $out .= sprintf ("* '%s' (%s)\n", $p->[0], $p->[1]);
  }
  # Valid with warnings
  $out .= "Valid Pages with warnings\n-------------------------\n" if scalar(@warnings);
  foreach my $p (@warnings) {
    $out .= sprintf ("* '%s' (%s) has %s warnings\n", $p->[0], $p->[1], $p->[2]);
  }
  # Invalid
  $out .= "Invalid Pages\n-----------\n" if scalar(@invalids);
  foreach my $p (@invalids) {
    $out .= sprintf ("* '%s' (%s)\n", $p->[0], $p->[1]);
  }
  $out .= "\n---\nValidation services provided by " . $v->validator_uri() . "\n\n";

  ## Send an email notification.
  my $emailTo = $self->get('to') || $session->setting->get('companyEmail');
  if ($emailTo) {
    my $mail = WebGUI::Mail::Send->create($self->session, {
        to      => $emailTo,
        #subject        => $i18n->get('ers change notification'),
        subject => "W3C Validator Results",
      });
    $mail->addText($out);
    $mail->queue;
  }

  return $self->COMPLETE;
}



1; #this line is important and will help the module return a true value

__END__

=head1 TODO

=over

=item *

Add loop to test all pages in a site

=item *

Add I18N support

=item *

Add warnings and errors output when a page fails validation

=item *

Add support for validating CSS snippets

=back

=head1 BUGS

None known.

=head1 SUPPORT

Contact the author.

=head1 AUTHOR

  William McKee, E<lt>william at knowmad dot comE<gt>
  http://www.knowmad.com

=head1 COPYRIGHT

Copyright 2007 Knowmad Services Inc. All rights reserved.
This program is free software; you can redistribute
it and/or modify it under the same terms as Perl itself.


=head1 SEE ALSO

perl(1).

=cut



