AxKit::App::TABOO::Data::Plurals::Articles - Data objects to handle multiple Articles in TABOO


AxKit-App-TABOO documentation Contained in the AxKit-App-TABOO distribution.

Index


Code Index:

NAME

Top

AxKit::App::TABOO::Data::Plurals::Articles - Data objects to handle multiple Articles in TABOO

DESCRIPTION

Top

Often, you want to retrieve many different articles from the data store, for example all belonging to a certain category. This is a typical situation where this class shoule be used.

Methods

new(@dbconnectargs)

The constructor. Nothing special.

load(what => fields, limit => {key => value, [...]}, orderby => fields, entries => number)

This load method can be used to retrieve a number of entries from a data store. It can use named parameters, but has a unique other possibility too, see below. In named parameters mode, the first what is used to determine which fields to retrieve. It is a string consisting of a commaseparated list of fields, as specified in the data store. The limit argument is to be used to determine which records to retrieve, these will be combined by logical AND. You may also supply a orderby argument, which is an expression used to determine the order of entries returned. Usually, it would be a simple string with the field name to use, e.g. 'timestamp', but you might want to append the keyword "DESC" to it for descending order. Finally, you may supply a entries argument, which is the maximum number of entries to retrieve.

The other possible use to first use the incat method, see below, and then you may call this method on the object without any parameters, and the corresponding articles will be loaded.

It will retrieve the data, and then call populate() for each of the records retrieved to ensure that the plural data objects actually consists of an array of AxKit::App::TABOO::Data::Articles. But it calls the internal _load()-method to do the hard work (and that's in the parent class).

If there is no data that corresponds to the given arguments, this method will return undef.

addcatinfo
adduserinfo
addformatinfo

These three methods are implemented in a plurals context, and can be called on a plurals object just like a singular object. Each entry will have their data structure extended with user, category and format information.

incat(@catnames)

Takes as arguments an array containing array names, and will return the number of articles that has been classified into all those categories. It will also, internally, store which articles that was, so that you may call the load method on the object afterwards without any further arguments to load the articles.

BUGS/TODO

Top

Not anything particular at the moment...

FORMALITIES

Top

See AxKit::App::TABOO.


AxKit-App-TABOO documentation Contained in the AxKit-App-TABOO distribution.
package AxKit::App::TABOO::Data::Plurals::Articles;
use strict;
use warnings;
use Carp;

use Data::Dumper;
use AxKit::App::TABOO::Data;
use AxKit::App::TABOO::Data::Article;
use AxKit::App::TABOO::Data::Plurals;


use vars qw/@ISA/;
@ISA = qw(AxKit::App::TABOO::Data::Plurals);

use DBI;
use Exception::Class::DBI;


our $VERSION = '0.2';

AxKit::App::TABOO::Data::Plurals::Articles->dbtable("articles");
AxKit::App::TABOO::Data::Plurals::Articles->dbfrom("articles JOIN languages ON (languages.ID = articles.lang_ID) JOIN mediatypes ON (mediatypes.ID = articles.format_ID)");
AxKit::App::TABOO::Data::Plurals::Articles->dbprimkey("filename");
AxKit::App::TABOO::Data::Plurals::Articles->elementorder("filename, lang, primcat, seccat, freesubject, editorok, authorok, title, description, AUTHORS, date, publisher, type, format, coverage, rights");


sub new {
    my $that  = shift;
    my $class = ref($that) || $that;
    my $self = {
	ENTRIES => [], # Internally, some methods finds it useful that the entries are stored in a array of this name.
	ARTICLE_IDS => [], # This field gets the id numbers of the articles, and is only here.
	DBCONNECTARGS => \@_,
	XMLELEMENT => undef,
	XMLPREFIX => undef,
	XMLNS => undef,
    };
    bless($self, $class);
    return $self;
}


sub load {
  my ($self, %args) = @_;
  my $what = $args{'what'} || '*';
  my $dbh = DBI->connect($self->dbconnectargs());
  my $articles;
  if ($what eq '*') {
    $what = 'articles.ID,articles.filename,articles.authorok,articles.editorok,articles.title,articles.description,articles.publisher,articles.date,articles.type,articles.identifieruri,articles.identifierurn,articles.coverage,articles.rights,mediatypes.mimetype,languages.code';
  }
  if (scalar(@{${$self}{'ARTICLE_IDS'}})) {
    # Then we allready know what to load, but can use additional constraints
    my $query = "SELECT " . $what . " FROM articles JOIN languages ON (languages.ID = articles.lang_ID) JOIN mediatypes ON (mediatypes.ID = articles.format_ID) WHERE articles.id IN (" . "?, " x (scalar(@{${$self}{'ARTICLE_IDS'}})-1) . "?)";
    my @keys = keys(%{$args{'limit'}});
    if (scalar(@keys) == 1) {
      $query .= " AND " . join("", @keys) . "=?";
    }
    elsif(scalar(@keys) >= 1) {
      $query .= " AND " . join("=? AND ", @keys) . "=?";
    }
    $articles = $dbh->selectall_arrayref($query, {Slice => {}}, (@{${$self}{'ARTICLE_IDS'}}, values(%{$args{'limit'}})));
  } else {
    $articles = $self->_load(%args);
    foreach my $entry (@{$articles}) {
      push(@{${$self}{'ARTICLE_IDS'}}, ${$entry}{'id'});
    }
  }

  return undef unless ((defined($articles) && @{$articles}));
  my $categories = $dbh->selectall_arrayref("SELECT categories.catname, articlecats.field, articles.ID FROM categories JOIN articlecats ON (categories.ID = Cat_ID) JOIN articles ON (articlecats.Article_ID=articles.ID) WHERE articlecats.Article_ID IN (" . "?, " x (scalar(@{${$self}{'ARTICLE_IDS'}})-1) . "?)", {}, @{${$self}{'ARTICLE_IDS'}});
  my $users = $dbh->selectall_arrayref("SELECT users.username, articles.ID FROM users JOIN articleusers ON (users.ID = Users_ID) JOIN articles ON (articleusers.Article_ID=articles.ID) WHERE articleusers.Article_ID IN (" . "?, " x (scalar(@{${$self}{'ARTICLE_IDS'}})-1) . "?) ORDER BY articleusers.Users_ID", {}, @{${$self}{'ARTICLE_IDS'}});

  # Transform the users
  my %userstmp;
  foreach my $userentry (@{$users}) {
    push(@{$userstmp{${$userentry}[1]}}, ${$userentry}[0]);
  }

  # Transform the categories
  my %cattmp;
  foreach my $catentry (@{$categories}) {
    my @tmp = @{$catentry}[0..1];
    push(@{$cattmp{${$catentry}[2]}}, \@tmp);
  }

  foreach my $artentry (@{$articles}) {
    my $article = AxKit::App::TABOO::Data::Article->new($self->dbconnectargs());
    my $id = ${$artentry}{'id'};
    $article->populate($artentry, $cattmp{$id}, $userstmp{$id});
    $article->onfile;
    $self->Push($article);
  }
  return $self;
}



sub addcatinfo {
  my $self = shift;
  foreach my $article (@{${$self}{ENTRIES}}) {
    $article->addcatinfo;
  }
  return $self;
}


sub adduserinfo {
  my $self = shift;
  foreach my $article (@{${$self}{ENTRIES}}) {
    $article->adduserinfo;
  }
  return $self;
}



sub addformatinfo {
  my $self = shift;
  foreach my $article (@{${$self}{ENTRIES}}) {
    $article->addformatinfo;
  }
  return $self;
}

# After pestering axkit-dahut a lot with the problem this routine is
# supposed to solve, Chris Prather came up with the following
# solution:

sub incat {
  my $self = shift;
  my @catnames = @_;
  my $dbh = DBI->connect($self->dbconnectargs());
  ${$self}{'ARTICLE_IDS'} = $dbh->selectcol_arrayref("SELECT a.article_id FROM articlecats a INNER JOIN categories c ON c.id = a.cat_id WHERE c.catname = ?" . "INTERSECT SELECT a.article_id FROM articlecats a INNER JOIN categories c ON c.id = a.cat_id WHERE c.catname = ?" x (scalar(@catnames)-1), {}, @catnames);
  return scalar(@{${$self}{'ARTICLE_IDS'}})
}


1;