Root.pmさらし。
自由研究だし、問題ないだろう。
こんなの書いてます。
#Tab = 8 spacesなのか。
package troublecode::Controller::Root; use strict; use warnings; use base 'Catalyst::Controller'; #use Catalyst 'FormValidator'; # # Sets the actions in this controller to be registered with no prefix # so they function identically to actions created in MyApp.pm # __PACKAGE__->config->{namespace} = ''; =head1 NAME troublecode::Controller::Root - Root Controller for troublecode =head1 DESCRIPTION [enter your description here] =head1 METHODS =cut =head2 default =cut sub begin : Private { my ( $self, $c ) = @_; __PACKAGE__->config( uploadtmp => './' ); # troublecode.ymlに書くべきか $c->stash->{'title'} = "トラブルコード管理データベース"; $c->forward('get_localtime'); } sub default : Private { my ( $self, $c ) = @_; my @it = troublecode::Model::CDBI::Machinelist->retrieve_all; $c->stash->{'it'} = \@it; $c->stash->{'subtitle'} = 'トップページ'; $c->stash->{'template'} = 'index.tt'; } # 機種名リストの登録・修正 sub regist_machine : Path('regist/machine') { my ( $self, $c ) = @_; my @old_data; if( $c->req->param('machine') ne "" && $c->req->param('registrant') ne "" ){ # 登録情報があれば、登録してトップページにもどる if(@old_data = troublecode::Model::CDBI::Machinelist->search( machine => $c->req->param('machine') ) ){ # 機種名が既存だったら、何もしない } else{ troublecode::Model::CDBI::Machinelist->insert({ machine => $c->req->param('machine'), registrant => $c->req->param('registrant'), time => $c->stash->{'time'} }); # ログ記録 $c->stash->{'registrant'} = $c->req->param('registrant'); $c->stash->{'changelog'} = '[regist/machine] add ' . $c->req->param('machine'); $c->forward('save_log'); } $c->res->redirect('/'); return 0; } else{ # 登録情報がなければ、機種登録画面を表示 $c->stash->{'subtitle'} = '機種登録'; $c->stash->{'template'} = 'regist_m.tt'; } } # コードリストの登録・修正 sub regist_code : Path('regist/code') { my ( $self, $c ) = @_; my @old_data; $c->forward('check_condition', [1]); # b. 登録要件を満たしているかどうか $c->forward('check_existing_code', [1]); # a. 既存コードがあるかないか $c->forward('regist', [$c->stash->{'existing'}, $c->stash->{'condition'}, 1]); # 無名のリストのリファレンスで引数わたすよ。 $c->res->redirect('/show/code?machine=' . $c->req->param('machine')) if ($c->stash->{'registration'} eq 'done'); # なんかダサい } # コードリストの表示 sub show_code : Path('show/code') { my ( $self, $c ) = @_; $c->stash->{'machine'} = $c->req->query_parameters->{'machine'}; my @datalist = sort bycode troublecode::Model::CDBI::Codelist->search( machine => $c->stash->{'machine'} ); $c->stash->{'datalist'} = \@datalist; $c->stash->{'subtitle'} = '[' . $c->stash->{'machine'} . ']トラブルコード一覧'; $c->stash->{'template'} = 'codelist.tt'; } # コード詳細の表示 sub show_code_detail : Path('show/code/detail') { my ( $self, $c ) = @_; $c->stash->{'machine'} = $c->req->query_parameters->{'machine'}; my @datalist = sort bycode troublecode::Model::CDBI::Codelist->search( machine => $c->req->param('machine'), main => $c->req->param('main1'), sub => $c->req->param('sub1'), state => 'REGISTED' ); $c->stash->{'datalist'} = \@datalist; $c->stash->{'subtitle'} = '[' . $c->stash->{'machine'} . ']トラブルコード一覧'; $c->stash->{'template'} = 'show_detail.tt'; } # 変更履歴の表示 sub show_log : Path('show/log') { my ( $self, $c ) = @_; my @it = sort bytime troublecode::Model::CDBI::Changelog->retrieve_all; $c->stash->{'it'} = \@it; $c->stash->{'subtitle'} = '変更履歴'; $c->stash->{'template'} = 'changelog.tt'; } # CSVファイルからのデータ取り込み sub import : Global { my ( $self, $c ) = @_; my $filename; my $target; my $upload; my ( $main, $sub, $content ); my @data; my $i = 0; $upload = $c->request->upload('import'); if( $c->req->param('form_submit') eq 'yes' ){ # データ登録 $i++; while($c->req->param('main'.$i) ne ""){ $c->forward('check_condition', [$i]); # b. 登録要件を満たしているかどうか $c->forward('check_existing_code', [$i]); # a. 既存コードがあるかないか $c->forward('regist', [$c->stash->{'existing'}, $c->stash->{'condition'}, $i]); $i++; } $c->res->redirect('/show_c?machine=' . $c->req->param('machine')); return 0; } else{ # 内容確認ページを表示 # $upload = $c->request->upload('import'); unless($upload && $c->req->param('registrant') ne ""){ $c->res->redirect('/show_c?machine=' . $c->req->param('machine')); return 0; } if( $filename = $upload->filename ){ # このあたりのファイル処理は、Catalyst::Manual::Cookbook 参照 # http://www.tcool.org/catalyst/Cookbook.html $target = "./tmp/$filename"; $upload->copy_to($target); $c->stash->{'machine'} = $c->req->param('machine'); open(FILE, $target) || die "$targetが開けませんでした"; while(<FILE>){ ($main, $sub, $content) = split(/\t/, $_); $data[$i] = { # 無名のハッシュのリファレンスを渡す。これぞPerlだ。 main => $main, sub => $sub, content => $content, client => $c->req->param('registrant'), registrant => $c->req->param('registrant'), }; $i++; } close(FILE); } unlink $upload->tempname; $c->stash->{'data'} = \@data; $c->stash->{'subtitle'} = 'インポートデータ一覧'; $c->stash->{'template'} = 'import.tt'; } } # 現在時刻の取得 sub get_localtime : Private { my ( $self, $c ) = @_; my ($sec, $min, $hour, $day, $mon, $year, $wday) = localtime(time); $c->stash->{'time'} = sprintf("%04d-%02d-%02d %02d:%02d:%02d", $year + 1900, $mon + 1, $day, $hour, $min, $sec); } # コードの登録有無 sub check_existing_code : Private { my ( $self, $c, $i ) = @_; my @old_data; if(@old_data = troublecode::Model::CDBI::Codelist->search( machine => $c->req->param('machine'), main => $c->req->param('main'.$i), sub => $c->req->param('sub'.$i), state => 'REGISTED') ){ $c->stash->{'existing'} = "exist"; $c->stash->{'old_data'} = \@old_data; $c->stash->{'machine'} = $c->req->param('machine'.$i); $c->stash->{'main'.$i} = $c->req->param('main'.$i); $c->stash->{'sub'.$i} = $c->req->param('sub'.$i); $c->stash->{'content'.$i} = $old_data[0]->get('content'); $c->stash->{'detail'.$i} = $old_data[0]->get('detail'); $c->stash->{'cause'.$i} = $old_data[0]->get('cause'); $c->stash->{'maintenance'.$i} = $old_data[0]->get('maintenance'); $c->stash->{'test_method'.$i} = $old_data[0]->get('test_method'); $c->stash->{'client'.$i} = $old_data[0]->get('client'); $c->stash->{'registrant'.$i} = $old_data[0]->get('registrant'); $c->stash->{'detect'.$i} = $old_data[0]->get('detect'); $c->stash->{'mode'.$i} = ""; # $c->stash->{'memory'.$i} = $old_data[0]->get('memory'); $c->stash->{'cancel'.$i} = $old_data[0]->get('cancel'); # $c->stash->{'regist_time'.$i} = $old_data[0]->get('regist_time'); # $c->stash->{'state'.$i} = "REGISTED"; } else{ $c->stash->{'existing'} = "not"; # Use of uninitialized value in string ne at ...対策で入れてみたけど、外した模様 } } # 登録内容が要件をみたしているか # Validatorの使い方は↓このへん参照 # http://search.cpan.org/~markstos/Data-FormValidator-4.50/lib/Data/FormValidator.pm # http://search.cpan.org/~markstos/Data-FormValidator-4.50/lib/Data/FormValidator/Results.pm sub check_condition : Private { my ( $self, $c, $i ) = @_; $c->form( optional => ["content$i", "detail$i", "cause$i", "maintenance$i", "test_method$i", "mode$i", "cancel$i", "detect$i", "state$i"], required => ["main$i", "sub$i", "machine", "client$i", "registrant$i", "memory$i"], constraint_method_regexp_map => { qr/^main$i$/ => qr/^[A-Za-z][A-Za-z0-9]$/, # 半角英数2桁 NOT NULL qr/^sub$i$/ => qr/^[A-Za-z0-9]{2}$/, # 半角英数2桁 NOT NULL qr/^machine$/ => qr/^[\w-]{1,32}$/, # 文字列(VARCHAR(32) NOT NULL # qr/^content$i$/ => , # 文字列(TEXT) # qr/^detail$i$/ => , # 文字列(TEXT) # qr/^cause$i$/ => , # 文字列(TEXT) # qr/^maintenance$i$/ => , # 文字列(TEXT) # qr/^test_method$i$/ => , # 文字列(TEXT) # qr/^client$i$/ => , # 文字列(TEXT) NOT NULL # qr/^registrant$i$/ => , # 文字列(TEXT) NOT NULL qr/^detect$i$/ => qr/^[\w]{1,32}$/, # 文字列(VARCHAR(32) # qr/^mode$i$/ => , # 文字列(VARCHAR(45) reserved qr/^memory$i$/ => qr/YES|NO/, # ENUM('YES', 'NO') NOT NULL qr/^cancel$i$/ => qr/^\w\w-\w\w$/ # MM-SS # qr/^regist_time$i$/ => , # DATETIME(自動入力) # qr/^state$i$/ => qr/REGISTED|DELETED/ # ENUM('REGISTED', 'DELETED') NOT NULL # qr/^change_time$i$/ => , # DATETIME(自動入力) } ); # とりあえず今はチェックにひっかかたら、問答無用「アウト。出直して来い」仕様 $c->stash->{'condition'} = ($c->form->has_missing || $c->form->has_invalid) ? "not" : "meet"; foreach my $item ($c->form->invalid){ # ここ使って、「この入力欄、内容おかしいですよ」が表示できるようになる、ハズ。 $c->stash->{system_message} .= " $item"; } # エラー発生時の修正入力のため、フォーム値を継承 $c->stash->{'machine'} = $c->req->param('machine'); $c->stash->{'main' . $i} = $c->req->param('main' . $i); $c->stash->{'sub' . $i} = $c->req->param('sub' . $i); $c->stash->{'content' . $i} = $c->req->param('content' . $i); $c->stash->{'detail' . $i} = $c->req->param('detail' . $i); $c->stash->{'cause' . $i} = $c->req->param('cause' . $i); $c->stash->{'maintenance' . $i} = $c->req->param('maintenance' . $i); $c->stash->{'test_method' . $i} = $c->req->param('test_method' . $i); $c->stash->{'client' . $i} = $c->req->param('client' . $i); $c->stash->{'registrant' . $i} = $c->req->param('registrant' . $i); $c->stash->{'detect' . $i} = $c->req->param('detect' . $i); $c->stash->{'mode' . $i} = ""; # $c->stash->{'memory' . $i} = $c->req->param('memory' . $i); $c->stash->{'cancel' . $i} = $c->req->param('cancel' . $i); # $c->stash->{'regist_time' . $i} = $c->stash->{'time'}; # $c->stash->{'state' . $i} = "REGISTED"; } # コードの登録 sub regist : Private { my ( $self, $c, $existing, $condition, $i ) = @_; my @machine_data; if( $existing eq "exist" && $condition eq "meet" ) # a1+b1 既存コード有+登録要件有 -> modify and regist { $c->stash->{old_data}->[0]->set( state => 'CHANGED' ); $c->stash->{old_data}->[0]->set( change_time => $c->stash->{time} ); $c->stash->{system_message} = '更新しました。'; troublecode::Model::CDBI::Codelist->insert({ machine => $c->req->param('machine'), main => $c->req->param('main' . $i), sub => $c->req->param('sub' . $i), content => $c->req->param('content' . $i), detail => $c->req->param('detail' . $i), cause => $c->req->param('cause' . $i), maintenance => $c->req->param('maintenance' . $i), test_method => $c->req->param('test_method' . $i), client => $c->req->param('client' . $i), registrant => $c->req->param('registrant' . $i), detect => $c->req->param('detect' . $i), mode => "", memory => $c->req->param('memory' . $i), cancel => $c->req->param('cancel' . $i), regist_time => $c->stash->{'time'}, state => "REGISTED" }); @machine_data = troublecode::Model::CDBI::Machinelist->search(machine => $c->req->param('machine')); $machine_data[0]->set( time => $c->stash->{'time'} ); $c->stash->{'machine'} = $c->req->param('machine'); $c->stash->{'registration'} = 'done'; $c->stash->{'template'} = 'index.tt'; # ログ記録 $c->stash->{'registrant'} = $c->req->param('registrant' . $i); $c->stash->{'changelog'} = '[regist/code] modify ' . $c->req->param('machine') . ':' . $c->req->param('main' . $i) . '-' . $c->req->param('sub' . $i); $c->forward('save_log'); } if( $existing eq "exist" && $condition ne "meet" ) # a1+b2 既存コード有+登録要件無 -> 登録画面 { $c->stash->{'machine'} = $c->req->param('machine'); $c->stash->{'subtitle'} = '[' . $c->stash->{'machine'} . ']コード登録'; $c->stash->{'template'} = 'regist_c.tt'; } if( $existing ne "exist" && $condition eq "meet" ) # a2+b1 既存コード無+登録要件有 -> regist { $c->stash->{system_message} = '新規登録しました。'; troublecode::Model::CDBI::Codelist->insert({ machine => $c->req->param('machine'), main => $c->req->param('main' . $i), sub => $c->req->param('sub' . $i), content => $c->req->param('content' . $i), detail => $c->req->param('detail' . $i), cause => $c->req->param('cause' . $i), maintenance => $c->req->param('maintenance' . $i), test_method => $c->req->param('test_method' . $i), client => $c->req->param('client' . $i), registrant => $c->req->param('registrant' . $i), detect => $c->req->param('detect' . $i), mode => "", memory => $c->req->param('memory' . $i), cancel => $c->req->param('cancel' . $i), regist_time => $c->stash->{'time'}, state => "REGISTED" }); @machine_data = troublecode::Model::CDBI::Machinelist->search(machine => $c->req->param('machine')); $machine_data[0]->set( time => $c->stash->{'time'} ); $c->stash->{'machine'} = $c->req->param('machine'); $c->stash->{'registration'} = 'done'; $c->stash->{'template'} = 'index.tt'; # ログ記録 $c->stash->{'registrant'} = $c->req->param('registrant' . $i); $c->stash->{'changelog'} = '[regist/code] add ' . $c->req->param('machine') . ':' . $c->req->param('main' . $i) . '-' . $c->req->param('sub' . $i); $c->forward('save_log'); } if( $existing ne "exist" && $condition ne "meet" ) # a2+b2 既存コード無+登録要件無 -> 登録画面 { $c->stash->{'machine'} = $c->req->param('machine'); $c->stash->{'subtitle'} = '[' . $c->stash->{'machine'} . ']コード登録'; $c->stash->{'template'} = 'regist_c.tt'; } } # コードの削除 sub delete_code : Path('delete/code') { my ( $self, $c ) = @_; $c->forward('check_existing_code', [1]); # a. 既存コードがあるかないか $c->stash->{old_data}->[0]->set( state => 'CHANGED' ); $c->stash->{old_data}->[0]->set( change_time => $c->stash->{time} ); $c->stash->{system_message} = '更新しました。'; # ログ記録 $c->stash->{'registrant'} = $c->req->param('registrant1'); $c->stash->{'changelog'} = '[regist/code] delete ' . $c->req->param('machine') . ':' . $c->req->param('main1') . '-' . $c->req->param('sub1'); $c->forward('save_log'); $c->stash->{'template'} = 'codelist.tt'; $c->res->redirect('/show_c?machine=' . $c->req->param('machine')); return 0; } # sort用関数(トラブルコード順にそろえるよ) sub bycode : Private { $a->get('main') cmp $b->get('main') || $a->get('sub') cmp $b->get('sub'); } # sort用関数(日付順にそろえるよ) sub bytime : Private { $b->get('time') cmp $a->get('time'); } # ログ保存 sub save_log : Private { my ( $self, $c ) = @_; troublecode::Model::CDBI::Changelog->insert({ time => $c->stash->{'time'}, registrant => $c->stash->{'registrant'}, content => $c->stash->{'changelog'} }); } # 派生機種への一括コピー sub duplicate : Global { my ( $self, $c ) = @_; my @machine_list; my @code_list; if(@machine_list = troublecode::Model::CDBI::Machinelist->search( machine => $c->req->param('machine') ) ){ # 機種名が既存だったら、何もしない。お帰りはこちら。 $c->stash->{'subtitle'} = 'トップページ'; $c->stash->{'template'} = 'index.tt'; $c->stash->{'system_message'} .= "copy_from読み込み失敗"; $c->res->redirect('/'); return 0; } else{ troublecode::Model::CDBI::Machinelist->insert({ machine => $c->req->param('machine'), registrant => $c->req->param('registrant'), time => $c->stash->{'time'} }); } if(@code_list = troublecode::Model::CDBI::Codelist->search( machine => $c->req->param('copy_from'), state => 'REGISTED') ){ foreach my $data (@code_list){ troublecode::Model::CDBI::Codelist->insert({ machine => $c->req->param('machine'), main => $data->get('main'), sub => $data->get('sub'), content => $data->get('content'), detail => $data->get('detail'), cause => $data->get('cause'), maintenance => $data->get('maintenance'), test_method => $data->get('test_method'), client => $c->req->param('registrant'), registrant => $c->req->param('registrant'), detect => $data->get('detect'), mode => $data->get('mode'), memory => $data->get('memory'), cancel => $data->get('cancel'), regist_time => $c->stash->{'time'}, state => "REGISTED" }); # $c->stash->{'system_message'} .= ": " . $data->get('main'); } } else{ $c->stash->{'system_message'} .= "copy_from読み込み失敗"; } $c->stash->{'subtitle'} = 'トップページ'; $c->stash->{'template'} = 'index.tt'; $c->res->redirect('/'); return 0; } =head2 end Attempt to render a view, if needed. =cut sub end : ActionClass('RenderView') { my ( $self, $c ) = @_; # $c->stash->{system_message} = 'system_message'; # $c->stash->{'end_message'} = "endを通過"; foreach my $plugin ($c->registered_plugins){ $c->stash->{'plugins'} .= " $plugin,"; } $c->forward('troublecode::View::TT'); } =head1 AUTHOR Catalyst developer =head1 LICENSE This library is free software, you can redistribute it and/or modify it under the same terms as Perl itself. =cut 1; __END__ # idea 済 一覧から指定して修正 済 CSVからのインポート 済 他機種からの一括コピー ・ CSVへのエクスポート →これでいいんじゃね ◆bricklife.weblog.*: Webアプリから2行でExcelファイルを出力する方法 http://www.bricklife.com/weblog/000051.html 済 入力内容のチェック → ページデザインの整理(これまともにやろうとすると、クラス図かかないとだめか?) ・ 入力内容のサニタイズ 済 /show_cからコードを指定して修正するのができなくなってる 済 空欄のままファイル読み込みすると止まる ・ ユーザー認証 ・ 機種串刺しの一覧表示 ・ 読み込みファイルがバリデーションでひっかかると処理がとまる? 済 /show/codeとか/regist/machineみたいな区切りにすべきか ・ formをttファイルに直書きしてるけど、もしかしてform生成pluginを使うのが当世風? 済 $c->registered_pluginsの実験 ・ 登録・修正・削除系を管理ページに独立? ・ 実データの登録(これがめんどくさい… 済 更新履歴の保存 全文検索⇒MySQLのFULLTEXTを使う方法があるけど、めんどくさい? ブラウザのSearch使ってくれというのはダメか。ダメだよなぁ。 /index : 機種一覧の表示 link→/show_c /show_c : 機種ごとのコード一覧の表示 link→/regist_c /regist_c : コードの登録 link→/index /regist_m : 機種の登録 /show_m : /indexと同じなので廃止