OSDN Git Service

Model::Users::Messages: fix error handling
[newslash/newslash.git] / src / newslash_web / lib / Newslash / Model / Users / Messages.pm
index d443678..63d9f13 100644 (file)
@@ -6,8 +6,7 @@ sub key_definition {
             table => "users_messages",
             primary => "id",
             other => [qw(uid code mode)],
-            aliases => { user_id => "uid",
-                       }
+            aliases => { user_id => "uid" },
            };
 }
 
@@ -19,72 +18,165 @@ sub select {
 
     my $messages = $self->new_instance_of('Messages');
     my $message_types = $messages->select_message_type;
+    my $code_table = {};
 
-    my $settings =  $self->generic_select(params => { uid => $uid });
-    return if !$settings;
-
-    my $mode_of = {};
-    for my $item (@$settings) {
-        $mode_of->{$item->{code}} = $item->{mode};
+    for my $type (@$message_types) {
+        next if (!$type->{selectable_mode} && !$params->{select_all});
+        $code_table->{$type->{message_type_id}} = { description => $type->{description},
+                                                    code => $type->{message_type_id},
+                                                    selectable_mode => $type->{selectable_mode},
+                                                    mode => -1,
+                                                  };
     }
 
-    my $result = [];
-    for my $type (@$message_types) {
-        next if $type->{selectable_mode} == 0;
-        my $i = {
-                 description => $type->{description},
-                 code => $type->{message_type_id},
-                };
-        if (defined $mode_of->{$type->{message_type_id}}) {
-            $i->{mode} = $mode_of->{$type->{message_type_id}};
+    my $code = $params->{code};
+
+    # check name parameter
+    if (defined $params->{name}) {
+        my $message_types = $self->new_instance_of("Messages");
+        my $msg_type = $message_types->select(name => $params->{name});
+        if ($msg_type) {
+            $code = $msg_type->{message_type_id};
         }
-        else {
-            $i->{mode} = -1; # 'no message'
+    }
+
+    # single query
+    if (defined $code) {
+        my $rs = $code_table->{$code};
+        return if !$rs;
+
+        my $settings =  $self->generic_select(params => { uid => $uid,
+                                                          code => $code });
+        if (@$settings) {
+            $rs->{mode} = $settings->[0]->{mode};
         }
-        $i->{selectable_mode} = $type->{selectable_mode};
+        return $rs;
+    }
+
+    # all for uid query
+    my $settings =  $self->generic_select(params => {uid => $uid});
+    return if !defined $settings;
 
-        push @$result, $i;
+    for my $st (@$settings) {
+        my $code = $st->{code};
+        if ($code_table->{$code}) {
+            $code_table->{$code}->{mode} = $st->{mode};
+        }
     }
-    return $result;
+
+    my @rs = values %$code_table;
+    return \@rs;
 }
 
-sub update {
+sub _is_mode_allowed {
+    # check given mode is selectable for the code
+    my ($self, $mode, $code) = @_;
+    return 1 if $mode < 0;
+
+    my $mode_bit = 1 << $mode;
+    my $messages = $self->new_instance_of('Messages');
+    my $msg_type = $messages->select(message_type_id => $code);
+    return if !$msg_type;
+
+    return $mode_bit & $msg_type->{selectable_mode};
+}
+
+sub set {
     my $self = shift;
     return if $self->check_readonly;
+
     my $params = {@_};
     my $uid = $params->{uid};
-    return if !$uid;
-    my $configs = $params->{config} || {};
+    my $code = $params->{code};
+    my $mode = $params->{mode};
 
-    my $sql_insert = <<"EOSQL";
-INSERT INTO users_messages (uid, code, mode) VALUES (?, ?, ?)
-  ON DUPLICATE KEY UPDATE mode = ?
-EOSQL
+    if (defined $params->{name}) {
+        my $message_types = $self->new_instance_of("Messages");
+        my $msg_type = $message_types->select(name => $params->{name});
+        if ($msg_type) {
+            $code = $msg_type->{message_type_id};
+        }
+    }
 
-    my $dbh = $self->start_transaction;
-    my $sth = $dbh->prepare($sql_insert);
+    if (!$uid || !defined $code || !defined $mode) {
+        $self->set_error("uid, code and mode not given");
+        return;
+    }
 
-    for my $item (@$configs) {
-        my $rs = $sth->execute($uid, $item->{code}, $item->{mode}, $item->{mode});
-        if (!defined $rs) {
-            $self->set_error($dbh->errstr, $dbh->err);
-            $self->rollback;
-            return;
-        }
+    # mode == -1 means no messages settings exists
+    if ($mode == -1) {
+        return $self->delete(uid => $uid, code => $code);
     }
 
-    my $sql_cleanup = <<"EOSQL";
-DELETE FROM users_messages WHERE uid = ? AND mode = -1
-EOSQL
-    my $rs = $dbh->do($sql_cleanup, undef, $uid);
-    if (!defined $rs) {
-        $self->set_error($dbh->errstr, $dbh->err);
-        $self->rollback;
+    # check if mode is allowed
+    if (!$self->_is_mode_allowed($mode, $code)) {
+        $self->set_error("mode $mode is not allowed for message $code");
+        return;
+    }
+
+    my $sql = "INSERT INTO users_messages (uid, code, mode) VALUES (?, ?, ?)" .
+      " ON DUPLICATE KEY UPDATE mode = ?";
+    my $dbh = $self->connect_db;
+    my $rs = $dbh->do($sql, undef, $uid, $code, $mode, $mode);
+    $self->disconnect_db;
+    return $rs;
+}
+
+sub delete {
+    my $self = shift;
+    return if $self->check_readonly;
+
+    my $params = {@_};
+    my $uid = $params->{uid};
+    my $code = $params->{code};
+
+    if (!$uid || !defined $code) {
+        $self->set_error("uid and code not given");
         return;
     }
 
-    $self->commit;
-    return 1;
+    my $dbh = $self->connect_db;
+    my $sql_cleanup = <<"EOSQL";
+DELETE FROM users_messages WHERE uid = ? AND code = ?
+EOSQL
+    my $rs = $dbh->do($sql_cleanup, undef, $uid, $code);
+    $self->disconnect_db;
+    return $rs;
+}
+
+# deprecated? use set method
+sub update {
+    shift->set(@_);
+
+    # my $self = shift;
+    # return if $self->check_readonly;
+
+    # my $params = {@_};
+    # my $uid = $params->{uid};
+    # my $code = $params->{code};
+    # my $mode = $params->{mode};
+
+    # if (defined $params->{name}) {
+    #     my $message_types = $self->new_instance_of("Messages");
+    #     my $msg_type = $message_types->select(name => $params->{name});
+    #     if ($msg_type) {
+    #         $code = $msg_type->{message_type_id};
+    #     }
+    # }
+
+    # if (!$uid || !defined $code || !defined $mode) {
+    #     $self->set_error("uid, mode code or name not given");
+    #     return;
+    # }
+
+    # # mode == -1 means no messages settings exists
+    # if ($mode == -1) {
+    #     return $self->delete(uid => $uid, mode => $code);
+    # }
+
+    # my $rs = $self->generic_update(params => { mode => $mode },
+    #                                where => { uid => $uid, code => $code });
+    # return $rs;
 }
 
 1;