1package Gantry::Utils::ModelHelper; 2use strict; use warnings; 3 4sub import { 5 my $class = shift; 6 7 my $callpkg = caller( 0 ); 8 9 foreach my $method ( @_ ) { 10 if ( $method eq 'auth_db_Main' ) { 11 no strict; 12 *{ "$callpkg\::db_Main" } = \&{ "$class\::auth_db_Main" }; 13 } 14 else { 15 no strict; 16 *{ "$callpkg\::$method" } = \&{ "$class\::$method" }; 17 } 18 } 19} # END of import 20 21#---------------------------------------------------------------------- 22# db_Main 23# compatible with Class::DBI and Gantry::Plugins::DBIxClassConn 24#---------------------------------------------------------------------- 25sub db_Main { 26 my $invocant = shift; 27 my $class = ( ref $invocant ) ? ref $invocant : $invocant; 28 29 my $dbh; 30 31 my $helper = Gantry::Utils::DBConnHelper->get_subclass(); 32 33 $dbh = $helper->get_dbh(); 34 35 if ( not $dbh ) { 36 my $conn_info = $helper->get_conn_info(); 37 38 my $db_options = $class->get_db_options(); 39 40 $db_options->{AutoCommit} = 0 unless defined $db_options->{AutoCommit}; 41 42 $dbh = DBI->connect( 43 $conn_info->{ 'dbconn' }, 44 $conn_info->{ 'dbuser' }, 45 $conn_info->{ 'dbpass' }, 46 $db_options 47 ); 48 $helper->set_dbh( $dbh ); 49 } 50 51 return $dbh; 52 53} # end db_Main 54 55#---------------------------------------------------------------------- 56# auth_db_Main 57# compatible with Class::DBI and Gantry::Plugins::DBIxClassConn 58#---------------------------------------------------------------------- 59sub auth_db_Main { 60 my $invocant = shift; 61 my $class = ( ref $invocant ) ? ref $invocant : $invocant; 62 63 my $auth_dbh; 64 65 my $helper = Gantry::Utils::DBConnHelper->get_subclass(); 66 67 $auth_dbh = $helper->get_auth_dbh(); 68 69 if ( not $auth_dbh ) { 70 my $auth_conn_info = $helper->get_auth_conn_info(); 71 72 my $db_options = $class->get_db_options(); 73 74 $db_options->{AutoCommit} = 0 unless defined $db_options->{AutoCommit}; 75 76 $auth_dbh = DBI->connect( 77 $auth_conn_info->{ 'auth_dbconn' }, 78 $auth_conn_info->{ 'auth_dbuser' }, 79 $auth_conn_info->{ 'auth_dbpass' }, 80 $db_options 81 ); 82 $helper->set_auth_dbh( $auth_dbh ); 83 } 84 85 return $auth_dbh; 86 87} # end auth_db_Main 88 89#------------------------------------------------- 90# $class->get_listing 91#------------------------------------------------- 92sub get_listing { 93 my ( $class, $params ) = @_; 94 95 my $f_display_fields = []; 96 eval { 97 $f_display_fields = $class->get_foreign_display_fields; 98 }; 99 100 if ( $params->{order_by} ) { 101 return $class->retrieve_all( order_by => $params->{order_by} ); 102 } 103 elsif ( $f_display_fields ) { 104 return $class->retrieve_all( 105 order_by => join( ', ', @{ $f_display_fields } ) 106 ); 107 } 108 else { 109 return $class->retrieve_all( ); 110 } 111 112} 113 114#------------------------------------------------- 115# $class->retrieve_all_for_main_listing 116# DEPRECATED 117#------------------------------------------------- 118sub retrieve_all_for_main_listing { 119 my ( $class, $order_fields ) = ( shift, shift ); 120 121 $order_fields ||= join ', ', @{ $class->get_foreign_display_fields }; 122 123 return( $class->retrieve_all( order_by => $order_fields ) ); 124 125} # retrieve_all_for_main_listing 126 127#------------------------------------------------- 128# $class->get_form_selctions 129#------------------------------------------------- 130sub get_form_selections { 131 my $class = shift; 132 133 my %retval; 134 135 # foreach foreign key get a selection list 136 FOREIGN_TABLE: 137 foreach my $foreign_table ( $class->get_foreign_tables() ) { 138 139 my $short_table_name = $foreign_table; 140 $short_table_name =~ s/.*:://; 141 142 my $foreigners; 143 144 eval { 145 $foreigners = $foreign_table->get_foreign_display_fields(); 146 }; 147 if ( $@ ) { 148 warn $@; 149 next FOREIGN_TABLE; 150 } 151 152 my $order_by = join ', ', @{ $foreigners }; 153 154 # get all rows in foreign table ordered by foreign display 155 my @foreign_display_rows = $foreign_table->retrieve_all( 156 { order_by => $order_by } 157 ); 158 159 # push into returnable hash 160 my @items; 161 push( @items, { value => '', label => '- Select -' } ); 162 163 foreach my $item ( @foreign_display_rows ) { 164 165 my $label; 166 167 eval { 168 $label = $item->foreign_display(); 169 }; 170 warn " ERROR for " . $item->id() . " $@" if $@; 171 172 push @items, { 173 value => $item->id(), 174 label => $label || '', 175 }; 176 } 177 178 $retval{$short_table_name} = \@items; 179 } 180 181 return( \%retval ); 182 183} # end get_form_selections 184 1851; 186 187=head1 NAME 188 189Gantry::Utils::ModelHelper - mixin for model base classes 190 191=head1 SYNOPSIS 192 193 use Gantry::Utils::ModelHelper qw( 194 db_Main 195 get_listing 196 get_form_selections 197 ); 198 199 sub get_db_options { 200 return {}; # put your default options here 201 # consider calling __PACKAGE->_default_attributes 202 } 203 204=head1 DESCRIPTION 205 206This module provides mixin methods commonly needed by model base classes. 207Note that you must request the methods you want for the mixin scheme to 208work. Also note that you can request either db_Main or auth_db_Main, but 209not both. Whichever one you choose will be exported as db_Main in your 210package. 211 212=head1 METHODS 213 214=over 4 215 216=item db_Main 217 218This method returns a valid dbh using the scheme described in 219Gantry::Docs::DBConn. It is compatible with Class::DBI and 220Gantry::Plugins::DBIxClassConn (the later is a mixin which allows 221easy access to a DBIx::Schema object for controllers). 222 223=item auth_db_Main 224 225This method is exported as db_Main and works with the scheme described 226in Gantry::Docs::DBConn. It too is compatible with Class::DBI and 227Gantry::Plugins::DBIxClassConn. 228 229I will repeat, if you ask for this method in your use statement: 230 231 use lib/Gantry/Utils/ModelHelper qw( auth_db_Main ... ); 232 233it will come into your namespace as db_Main. 234 235=item get_form_selections 236 237This method gives you a selection list for each foriegn key in your 238table. The lists come to you as a single hash keyed by the table names 239of the foreign keys. The values in the hash are ready for use 240by form.tt as options on the field (whose type should be select). 241Example: 242 243 { 244 status => [ 245 { value => 2, label => 'Billed' }, 246 { value => 1, label => 'In Progress' }, 247 { value => 3, label => 'Paid' }, 248 ], 249 other_table => [ ... ], 250 } 251 252To use this method, your models must implement these class methods: 253 254=over 4 255 256=item get_foreign_tables 257 258(Must be implemented by the model on which get_form_selections is called.) 259Returns a list of the fully qualified package names of the models 260of this table's foreign keys. Example: 261 262 sub get_foreign_tables { 263 return qw( 264 Apps::AppName::Model::users 265 Apps::AppName::Model::other_table 266 ); 267 } 268 269=item get_foreign_display_fields 270 271(Must be implemented by all the models of this table's foreign keys.) 272Returns an array reference whose elements are the names of the columns 273which will appear on the screen in the selection list. Example: 274 275 sub get_foreign_display_fields { 276 return [ qw( last_name first_name ) ]; 277 } 278 279=back 280 281=item get_listing 282 283Replacement for retrieve_all_for_main_listing. 284 285Returns a list of row objects (one for each row in the table). The 286ORDER BY clause is either the same as the foreign_display columns 287or chosen by you. If you want to supply the order do it like this: 288 289 my @rows = $MODEL->get_listing ( { order_by => 'last, first' } ); 290 291Note that your order_by will be used AS IS, so it must be a valid SQL 292ORDER BY clause, but feel free to include DESC or anything else you and SQL 293like. 294 295=item retrieve_all_for_main_listing 296 297DEPRECATED use get_listing instead 298 299Returns a list of row objects (one for each row in the table) in order 300by their foreign_display columns. 301 302=back 303 304=head1 AUTHOR 305 306Phil Crow <philcrow2000@yahoo.com> 307 308=head1 COPYRIGHT and LICENSE 309 310Copyright (c) 2006, Phil Crow 311 312This library is free software; you can redistribute it and/or modify 313it under the same terms as Perl itself, either Perl version 5.8.6 or, 314at your option, any later version of Perl 5 you may have available. 315 316=cut 317