OSDN Git Service

Model::Tags: add set_tag, create, select method
[newslash/newslash.git] / src / newslash_web / lib / Newslash / Model / Tags.pm
1 package Newslash::Model::Tags;
2 use Newslash::Model::Base -base;
3
4
5 sub set_tag {
6     my $self = shift;
7     my $params = {@_};
8
9     my $globj_id = $params->{globj_id};
10     my $uid = $params->{uid} || 1;
11     my $name = $params->{name};
12     my $private = $params->{private} ? "yes" : "no";
13     my $active = defined $params->{active} ? $params->{active} : 1;
14     my $tagname_id = $params->{tagname_id};
15
16     if (!$globj_id) {
17         return;
18     }
19
20     if ($name) {
21         my $tagname = $self->select(tagname => $name);
22         if ($tagname) {
23             $tagname_id = $tagname->{tagnameid};
24         }
25         else {
26             $tagname_id = $self->create(tagname => $name);
27         }
28     }
29
30     if (!$tagname_id) {
31         return;
32     }
33
34     my $inactivated = $active ? "NULL" : "NOW()";
35     my $sql = <<"EOSQL";
36 INSERT INTO tags
37     (tagnameid, globjid, uid, created_at, inactivated, private, is_active)
38   VALUES
39     (?,         ?,       ?,   NOW(),     $inactivated, ?,       ?)
40 EOSQL
41
42     my $dbh = $self->connect_db;
43     my $rs = $dbh->do($sql, undef, $tagname_id, $globj_id, $uid, $private, $active);
44     if (!$rs) {
45         $dbh->disconnect;
46         return;
47     }
48     my $id = $dbh->last_insert_id(undef, undef, undef, undef);
49     $dbh->disconnect;
50     return $id;
51 }
52
53 sub create {
54     my $self = shift;
55     my $params = {@_};
56
57     if ($params->{tagname}) {
58         my $sql = "INSERT INTO tagnames (tagname) VALUES (?)";
59         my $dbh = $self->connect_db;
60         my $rs = $dbh->do($sql, undef, $params->{tagname});
61         if (!$rs) {
62             $dbh->disconnect;
63             return;
64         }
65         my $id = $dbh->last_insert_id(undef, undef, undef, undef);
66         $dbh->disconnect;
67         return $id;
68     }
69     return;
70 }
71
72 sub select {
73     my $self = shift;
74     my $params = {@_};
75
76     if ($params->{tagname}) {
77         my $sql = "SELECT * FROM tagnames WHERE tagname = ?";
78         my $dbh = $self->connect_db;
79         my $sth = $dbh->prepare($sql);
80         $sth->execute($params->{tagname});
81         my $rs = $sth->fetchall_arrayref({});
82         $dbh->disconnect;
83         if (@$rs) {
84             return $rs->[0];
85         }
86         return;
87     }
88 }
89
90
91 # =================== Legacy API ====================
92
93
94
95 my $tags_tagname_regex = "^!?[a-z一-龠ぁ-んァ-ヴー][a-z0-9一-龠ぁ-んァ-ヴー/・]{0,63}\$";
96
97 sub tagnameSyntaxOK {
98     my($self, $tagname) = @_;
99     return 0 unless defined($tagname) && length($tagname) > 0;
100     #my $constants = getCurrentStatic();
101     #my $regex = $constants->{tags_tagname_regex};
102     my $regex = $tags_tagname_regex;
103     return($tagname =~ /$regex/);
104 }
105
106 sub getTagnameidFromNameIfExists {
107     my($self, $name) = @_;
108     #my $constants = getCurrentStatic();
109     return 0 if !$self->tagnameSyntaxOK($name);
110
111     #my $table_cache         = "_tagid_cache";
112     #my $table_cache_time    = "_tagid_cache_time";
113     #$self->_genericCacheRefresh('tagid', $constants->{tags_cache_expire});
114     #if ($self->{$table_cache_time} && $self->{$table_cache}{$name}) {
115     #    return $self->{$table_cache}{$name};
116     #}
117
118     #my $mcd = $self->getMCD();
119     #my $mcdkey = "$self->{_mcd_keyprefix}:tagid:" if $mcd;
120     #if ($mcd) {
121     #    my $id = $mcd->get("$mcdkey$name");
122     #    if ($id) {
123     #        if ($self->{$table_cache_time}) {
124     #            $self->{$table_cache}{$name} = $id;
125     #        }
126     #        return $id;
127     #    }
128     #}
129
130     my $db = $self->new_instance_of('LegacyDB');
131     my $name_q = $db->sqlQuote($name);
132     my $id = $db->sqlSelect('tagnameid', 'tagnames',
133                               "tagname=$name_q");
134     return 0 if !$id;
135     #if ($self->{$table_cache_time}) {
136     #    $self->{$table_cache}{$name} = $id;
137     #}
138     #$mcd->set("$mcdkey$name", $id, $constants->{memcached_exptime_tags}) if $mcd;
139     return $id;
140 }
141
142 sub createTagname {
143     my($self, $name) = @_;
144     return 0 if !$self->tagnameSyntaxOK($name);
145
146     my $db = $self->new_instance_of('LegacyDB');
147     my $rows = $db->sqlInsert('tagnames', {
148                                            tagnameid =>    undef,
149                                            tagname =>      $name,
150                                           }, { ignore => 1 });
151     if (!$rows) {
152         # Insert failed, presumably because this tag already
153         # exists.  The caller should have checked for this
154         # before attempting to create the tag, but maybe the
155         # reader that was checked didn't have this tag
156         # replicated yet.  Pull the information directly
157         # from this writer DB.
158         return $self->getTagnameidFromNameIfExists($name);
159     }
160     # The insert succeeded.  Return the ID that was just added.
161     return $self->getLastInsertId();
162 }
163
164 sub getTagnameidCreate {
165     my($self, $name) = @_;
166     return 0 if !$self->tagnameSyntaxOK($name);
167     #my $reader = getObject('Slash::Tags', { db_type => 'reader' });
168     #my $id = $reader->getTagnameidFromNameIfExists($name);
169     my $id = $self->getTagnameidFromNameIfExists($name);
170     return $id if $id;
171     return $self->createTagname($name);
172 }
173
174 sub _setuptag {
175     my ($self, $hr, $options) = @_;
176     my $tag = { -created_at => 'NOW()' };
177
178     #$tag->{uid} = $hr->{uid} || getCurrentUser('uid');
179     $tag->{uid} = $hr->{uid};
180
181     if ($hr->{tagnameid}) {
182         $tag->{tagnameid} = $hr->{tagnameid};
183     } else {
184         # Need to determine tagnameid from name.  We
185         # create the new tag name if necessary.
186         $tag->{tagnameid} = $self->getTagnameidCreate($hr->{name});
187     }
188     return 0 if !$options->{tagname_not_required} && !$tag->{tagnameid};
189
190     if ($hr->{globjid}) {
191         $tag->{globjid} = $hr->{globjid};
192     } else {
193         my $globjs = $self->new_instance_of('Globjids');
194         $tag->{globjid} = $globjs->getGlobjidCreate($hr->{table}, $hr->{id});
195     }
196     return 0 if !$tag->{globjid};
197
198     $tag->{private} = $hr->{private} ? 'yes' : 'no';
199
200     return $tag;
201 }
202
203 sub logDeactivatedTags {
204     my($self, $deactivated_tagids) = @_;
205     return 0 if !$deactivated_tagids;
206     my $logged = 0;
207     my $db = $self->new_instance_of('LegacyDB');
208     for my $tagid (@$deactivated_tagids) {
209         $logged += $db->sqlInsert('tags_deactivated',
210                                   { tagid => $tagid });
211     }
212     return $logged;
213 }
214
215 sub deactivateTag {
216     my ($self, $hr, $options) = @_;
217     my $tag = $self->_setuptag($hr, { tagname_not_required => !$options->{tagname_required} });
218     return 0 if !$tag;
219
220     my $prior_clause = '';
221     $prior_clause = " AND tagid < $options->{tagid_prior_to}" if $options->{tagid_prior_to};
222             my $where_clause = "uid         = $tag->{uid}
223                          AND globjid    = $tag->{globjid}
224                          AND inactivated IS NULL
225                          $prior_clause";
226     $where_clause .= " AND tagnameid = $tag->{tagnameid}" if $tag->{tagnameid};
227     my $db = $self->new_instance_of('LegacyDB');
228     my $previously_active_tagids = $db->sqlSelectColArrayref('tagid', 'tags', $where_clause);
229     my $count = $db->sqlUpdate('tags', { -inactivated => 'NOW()', -is_active => 'NULL' }, $where_clause);
230
231     if ($count > 1) {
232         # Logic error, there should never be more than one
233         # tag meeting those criteria.
234         warn scalar(gmtime) . " $count deactivated tags id '$tag->{tagnameid}' for uid=$tag->{uid} on $tag->{globjid}";
235     }
236
237     if ($count && $previously_active_tagids && @$previously_active_tagids) {
238         #my $tagboxdb = getObject('Slash::Tagbox');
239         #$tagboxdb->logDeactivatedTags($previously_active_tagids);
240         $self->logDeactivatedTags($previously_active_tagids);
241     }
242
243     return $count;
244 }