Revision 475
Date:
2015/02/25 13:26:49
Author:
ahitrov
Revision Log:
Remove plugin
Files:
Legend:
Added
Removed
Modified
utf8/plugins/tags/comps/contenido/tags/autohandler
1
<%init>
2
3
$r->content_type('text/html');
4
$m->call_next();
5
6
</%init>
utf8/plugins/tags/comps/contenido/tags/dhandler
1
<& $call, %ARGS &>
2
<%init>
3
4
my $call;
5
if ( $r->uri eq '/contenido/tags/' ) {
6
$call = 'index.html';
7
} else {
8
&abort404;
9
}
10
11
</%init>
utf8/plugins/tags/comps/contenido/tags/index.html
1
<& "/contenido/components/header.msn" &>
2
<& "/contenido/components/naviline.msn" &>
3
4
<p>PLugin [tags]</p>
5
6
</body>
7
</html>
utf8/plugins/tags/config.proto
1
#############################################################################
2
#
3
# Параметры данного шаблона необходимо ВРУЧНУЮ добавить в config.mk проекта
4
# и привести в соответствие с требованиями проекта
5
#
6
#############################################################################
7
8
PLUGINS += tags
9
10
TAGS_DEST = <список через пробел классов тегируемых документов>
11
REWRITE += TAGS_DEST
utf8/plugins/tags/lib/tags/Apache.pm
1
package tags::Apache;
2
3
use strict;
4
use warnings 'all';
5
6
use tags::State;
7
use Contenido::Globals;
8
9
10
sub child_init {
11
# встраиваем keeper плагина в keeper проекта
12
$keeper->{tags} = tags::Keeper->new($state->tags);
13
}
14
15
sub request_init {
16
}
17
18
sub child_exit {
19
}
20
21
1;
utf8/plugins/tags/lib/tags/Cloud.pm
1
package zvukiru::TagLink;
2
3
use base 'Contenido::Link';
4
5
sub class_name
6
{
7
return 'Тег к объекту';
8
}
9
10
sub class_description
11
{
12
return 'Организация облака тегов';
13
}
14
15
sub extra_properties
16
{
17
return (
18
);
19
}
20
21
sub available_sources
22
{
23
return [ qw(tags::Tag) ];
24
}
25
26
sub available_destinations
27
{
28
return $state->{tags}->tags_destinations;
29
}
30
31
sub class_table
32
{
33
return 'tags::SQL::TagsCloudTable';
34
}
35
36
sub pre_store
37
{
38
my $self = shift;
39
40
return 1;
41
}
42
43
1;
utf8/plugins/tags/lib/tags/Init.pm
1
package tags::Init;
2
3
use strict;
4
use warnings 'all';
5
6
use Contenido::Globals;
7
use tags::Apache;
8
use tags::Keeper;
9
use tags::Section;
10
use tags::Tag;
11
use tags::Cloud;
12
use tags::SQL::TagsCloudTable
13
use tags::SQL::TagsTable
14
15
# загрузка всех необходимых плагину классов
16
# tags::SQL::SomeTable
17
# tags::SomeClass
18
Contenido::Init::load_classes(qw(
19
tags::Section;
20
tags::Tag;
21
tags::Cloud;
22
tags::SQL::TagsCloudTable
23
tags::SQL::TagsTable
24
));
25
26
sub init {
27
push @{ $state->{'available_documents'} },
28
qw (
29
tags::Tag
30
);
31
push @{ $state->{'available_sections'} },
32
qw (
33
tags::Section
34
);
35
push @{ $state->{'available_links'} },
36
qw (
37
tags::Cloud
38
);
39
0;
40
}
41
42
1;
utf8/plugins/tags/lib/tags/Keeper.pm
1
package tags::Keeper;
2
3
use strict;
4
use warnings 'all';
5
use base qw(Contenido::Keeper);
6
7
8
use Contenido::Globals;
9
10
11
1;
utf8/plugins/tags/lib/tags/Section.pm
1
package tags::Section;
2
3
use base 'Contenido::Section';
4
5
sub extra_properties
6
{
7
return (
8
{ 'attr' => 'default_document_class', 'default' => 'tags::Tag' },
9
)
10
}
11
12
sub class_name
13
{
14
return 'Секция тегов';
15
}
16
17
sub class_description
18
{
19
return 'Секция тегов';
20
}
21
22
1;
utf8/plugins/tags/lib/tags/SQL/TagsCloudTable.pm
1
package tags::SQL::TagsCloudTable;
2
3
use strict;
4
use base 'SQL::LinkTable';
5
6
sub db_table
7
{
8
return 'tags_cloud';
9
}
10
11
# ----------------------------------------------------------------------------
12
# Свойства храним в массивах, потому что порядок важен!
13
# Это общие свойства - одинаковые для всех документов.
14
#
15
# attr - обязательный параметр, название атрибута;
16
# type - тип аттрибута, требуется для отображдения;
17
# rusname - русское название, опять же требуется для отображения;
18
# hidden - равен 1, когда
19
# readonly - инициализации при записи только без изменения в дальнейшем
20
# db_field - поле в таблице
21
# default - значение по умолчанию (поле всегда имеет это значение)
22
# ----------------------------------------------------------------------------
23
sub required_properties
24
{
25
my $self = shift;
26
27
my @parent_properties = $self->SUPER::required_properties;
28
return (
29
@parent_properties,
30
);
31
}
32
33
########### FILTERS DESCRIPTION ####################################################################################
34
35
1;
36
utf8/plugins/tags/lib/tags/SQL/TagsTable.pm
1
package tags::SQL::TagsTable;
2
3
use strict;
4
use base 'SQL::DocumentTable';
5
6
sub db_table
7
{
8
return 'tags';
9
}
10
11
sub available_filters {
12
my @available_filters = qw(
13
_class_filter
14
_status_filter
15
_in_id_filter
16
_id_filter
17
_name_filter
18
_class_excludes_filter
19
_prev_to_filter
20
_next_to_filter
21
_s_filter
22
23
_excludes_filter
24
_link_filter
25
_alias_filter
26
);
27
return \@available_filters;
28
}
29
30
# ----------------------------------------------------------------------------
31
# Свойства храним в массивах, потому что порядок важен!
32
# Это общие свойства - одинаковые для всех документов.
33
#
34
# attr - обязательный параметр, название атрибута;
35
# type - тип аттрибута, требуется для отображдения;
36
# rusname - русское название, опять же требуется для отображения;
37
# hidden - равен 1, когда
38
# readonly - инициализации при записи только без изменения в дальнейшем
39
# db_field - поле в таблице
40
# default - значение по умолчанию (поле всегда имеет это значение)
41
# ----------------------------------------------------------------------------
42
sub required_properties
43
{
44
my $self = shift;
45
46
my @parent_properties = grep { $_->{attr} ne 'dtime' && $_->{attr} ne 'sections' } $self->SUPER::required_properties;
47
return (
48
@parent_properties,
49
{
50
'attr' => 'alias',
51
'type' => 'string',
52
'rusname' => 'Алиас',
53
'column' => 3,
54
'db_field' => 'alias',
55
'db_type' => 'text',
56
},
57
{ # Подменяем секцию
58
'attr' => 'sections',
59
'type' => 'parent',
60
'rusname' => 'Родительская секция',
61
'db_field' => 'sections',
62
'db_type' => 'integer',
63
},
64
);
65
}
66
67
########### FILTERS DESCRIPTION ####################################################################################
68
sub _s_filter {
69
my ($self,%opts)=@_;
70
return undef unless ( exists $opts{s} );
71
return &SQL::Common::_generic_int_filter('d.sections', $opts{s});
72
}
73
74
sub _alias_filter {
75
my ($self,%opts)=@_;
76
return undef unless ( exists $opts{alias} );
77
return &SQL::Common::_generic_text_filter('d.alias', $opts{alias});
78
}
79
80
sub _link_filter {
81
my ($self,%opts)=@_;
82
83
my @wheres=();
84
my @binds=();
85
86
# Связь определенного класса
87
if (exists($opts{lclass})) {
88
my ($where, $values) = SQL::Common::_generic_text_filter('l.class', $opts{lclass});
89
push (@wheres, $where);
90
push (@binds, ref($values) ? @$values:$values) if (defined $values);
91
}
92
93
my $lclass = $opts{lclass} || 'Contenido::Link';
94
my $link_table = $lclass->_get_table->db_table();
95
96
# Ограничение по статусу связи
97
if ( exists $opts{lstatus} ) {
98
my ($where, $values) = SQL::Common::_generic_int_filter('l.status', $opts{lstatus});
99
push (@wheres, $where);
100
push (@binds, ref($values) ? @$values:$values) if (defined $values);
101
}
102
103
# Связь с определенным документ(ом/тами) по цели линка
104
if ( exists $opts{ldest} ) {
105
my ($where, $values) = SQL::Common::_generic_int_filter('l.dest_id', $opts{ldest});
106
push (@wheres, $where);
107
push (@binds, ref($values) ? @$values:$values) if (defined $values);
108
if ($self->_single_class) {
109
return (\@wheres, \@binds, " join $link_table as l on l.source_id=d.id");
110
} elsif ( exists $opts{ldestclass} ) {
111
my ($where, $values) = SQL::Common::_generic_text_filter('l.dest_class', $opts{ldestclass});
112
push (@wheres, $where);
113
push (@binds, ref($values) ? @$values:$values) if (defined $values);
114
115
return (\@wheres, \@binds, " join $link_table as l on l.source_id=d.id and l.source_class=d.class");
116
} else {
117
return (\@wheres, \@binds, " join $link_table as l on l.source_id=d.id and l.source_class=d.class");
118
}
119
}
120
121
# Связь с определенным документ(ом/тами) по источнику линка
122
if ( exists $opts{lsource} ) {
123
my ($where, $values) = SQL::Common::_generic_int_filter('l.source_id', $opts{lsource});
124
push (@wheres, $where);
125
push (@binds, ref($values) ? @$values:$values) if (defined $values);
126
if ($self->_single_class) {
127
return (\@wheres, \@binds, " join $link_table as l on l.dest_id=d.id");
128
} elsif ( exists $opts{lsourceclass} ) {
129
my ($where, $values) = SQL::Common::_generic_text_filter('l.source_class', $opts{lsourceclass});
130
push (@wheres, $where);
131
push (@binds, ref($values) ? @$values:$values) if (defined $values);
132
133
return (\@wheres, \@binds, " join $link_table as l on l.dest_id=d.id and l.dest_class=d.class");
134
} else {
135
return (\@wheres, \@binds, " join $link_table as l on l.dest_id=d.id and l.dest_class=d.class");
136
}
137
}
138
139
return (undef);
140
}
141
142
143
1;
utf8/plugins/tags/lib/tags/State.pm.proto
1
package tags::State;
2
3
use strict;
4
use warnings 'all';
5
use vars qw($AUTOLOAD);
6
7
8
sub new {
9
my ($proto) = @_;
10
my $class = ref($proto) || $proto;
11
my $self = {};
12
bless $self, $class;
13
14
# configured
15
$self->{project} = '@PROJECT@';
16
$self->{debug} = (lc('@DEBUG@') eq 'yes');
17
$self->{contenido_notab} = 0;
18
$self->{tab_name} = 'Теги';
19
$self->{project_name} = '@PROJECT_NAME@';
20
$self->{default_expire} = '@DEFAULT_EXPIRE@' || 300;
21
$self->{default_object_expire} = '@DEFAULT_OBJECT_EXPIRE@' || 600;
22
23
# зашитая конфигурация плагина
24
$self->{db_type} = 'none'; ### For REAL database use 'remote'
25
$self->{db_keepalive} = 0;
26
$self->{db_host} = '';
27
$self->{db_name} = '';
28
$self->{db_user} = '';
29
$self->{db_password} = '';
30
$self->{db_port} = '';
31
$self->{store_method} = 'toast';
32
$self->{cascade} = 1;
33
$self->{db_prepare} = 0;
34
35
$self->{memcached_enable} = lc( '@MEMCACHED_ENABLE@' ) eq 'yes' ? 1 : 0;
36
$self->{memcached_backend} = '@MEMCACHED_BACKEND@';
37
$self->{memcached_select_timeout} = '@MEMCACHED_SELECT_TIMEOUT@' || 0.2;
38
$self->{memcached_servers} = [qw(@MEMCACHED_SERVERS@)];
39
$self->{memcached_enable_compress} = lc( '@MEMCACHED_ENABLE_COMPRESS@' ) eq 'yes' ? 1 : 0;
40
$self->{memcached_delayed} = lc('@MEMCACHED_DELAYED@') eq 'yes' ? 1 : 0;
41
$self->{memcached_set_mode} = lc('@MEMCACHED_SET_MODE@') eq 'add' ? 'add' : 'set';
42
$self->{memcached_busy_lock} = 60;
43
$self->{memcached_namespace} = lc( $self->{'project'} ).'|plugin_tags|';
44
45
$self->{serialize_with} = 'json'; ### or 'dumper'
46
47
# not implemented really (core compatibility)
48
$self->{data_directory} = '';
49
$self->{images_directory} = '';
50
$self->{binary_directory} = '';
51
$self->{preview} = '';
52
53
$self->{tags_destinations} = [qw(@TAGS_DEST@)]
54
55
$self->_init_();
56
$self;
57
}
58
59
sub info {
60
my $self = shift;
61
return unless ref $self;
62
63
for (sort keys %{$self->{attributes}}) {
64
my $la = length $_;
65
warn "\t$_".("\t" x (2-int($la/8))).": $self->{$_}\n";
66
}
67
}
68
69
sub _init_ {
70
my $self = shift;
71
72
# зашитая конфигурация плагина
73
$self->{attributes}->{$_} = 'SCALAR' for qw(
74
debug
75
project
76
tab_name
77
78
db_type
79
db_keepalive
80
db_host
81
db_port
82
db_name
83
db_user
84
db_password
85
store_method
86
cascade
87
db_prepare
88
db_client_encoding
89
90
memcached_enable
91
memcached_servers
92
memcached_select_timeout
93
memcached_backend
94
memcached_enable_compress
95
memcached_set_mode
96
memcached_object_expire
97
memcached_busy_lock
98
memcached_delayed
99
memcached_namespace
100
101
binary_directory
102
data_directory
103
images_directory
104
preview
105
106
tags_destinations
107
);
108
}
109
110
sub AUTOLOAD {
111
my $self = shift;
112
my $attribute = $AUTOLOAD;
113
114
$attribute =~ s/.*:://;
115
return unless $attribute =~ /[^A-Z]/; # Отключаем методы типа DESTROY
116
117
if (!exists $self->{attributes}->{$attribute}) {
118
warn "Contenido Error (tags::State): Вызов метода, для которого не существует обрабатываемого свойства: ->$attribute()\n";
119
return;
120
}
121
122
$self->{$attribute} = shift @_ if $#_>=0;
123
$self->{$attribute};
124
}
125
126
1;
utf8/plugins/tags/lib/tags/Tag.pm
1
package tags::Tag;
2
3
use base 'Contenido::Document';
4
use Contenido::Globals;
5
6
sub extra_properties
7
{
8
return (
9
{ 'attr' => 'name', 'rusname' => 'Название тега', shortname => 'Тег' },
10
)
11
}
12
13
14
sub class_name
15
{
16
return 'Тег';
17
}
18
19
sub class_description
20
{
21
return 'Тег';
22
}
23
24
sub class_table
25
{
26
return 'tags::SQL::TagsTable';
27
}
28
29
sub search_fields {
30
return ('name');
31
}
32
33
sub pre_store
34
{
35
my $self = shift;
36
37
my $default_section = $project->s_alias->{tags} if ref $project->s_alias eq 'HASH' && exists $project->s_alias->{tags};
38
$self->sections( $default_section ) if $default_section;
39
40
return 1;
41
}
42
43
44
1;
utf8/plugins/tags/sql/TOAST/tags.sql
1
create table tags
2
(
3
id integer not null primary key default nextval('public.documents_id_seq'::text),
4
ctime timestamp not null default now(),
5
mtime timestamp not null default now(),
6
class text not null,
7
status smallint not null default 0,
8
sections integer,
9
name text,
10
alias text,
11
data text
12
);
13
create index tags_name on tags (name);
14
create index tags_alias on tags (alias) WHERE alias IS NOT NULL AND alias != '';
utf8/plugins/tags/sql/TOAST/tags_cloud.sql
1
create table tags_cloud
2
(
3
id integer not null primary key default nextval('public.documents_id_seq'::text),
4
class text not null,
5
ctime timestamp not null default now(),
6
mtime timestamp not null default now(),
7
status smallint not null default 1,
8
source_id integer not null,
9
source_class text not null default 'tags::Tag',
10
dest_id integer not null,
11
dest_class text not null,
12
data text
13
);
14
create index tags_cloud_source on tags_cloud (source_id);
15
create index tags_cloud_dest on tags_cloud (dest_id);
Небольшая справка по веткам
cnddist – контейнер, в котором хранятся все дистрибутивы всех библиотек и программных пакетов, которые использовались при построении различных версий Contenido. Если какой-то библиотеки в данном хранилище нет, инсталлятор сделает попытку "подтянуть" ее с веба (например, с CPAN). Если библиотека слишком старая, есть очень большая вероятность, что ее там уже нет. Поэтому мы храним весь хлам от всех сборок. Если какой-то дистрибутив вдруг отсутствует в cnddist - напишите нам, мы положим его туда.
koi8 – отмирающая ветка, чей код, выдача и все внутренние библиотеки заточены на кодировку KOI8-R. Вносятся только те дополнения, которые касаются внешнего вида и функционала админки, баги ядра, обязательные обновления портов и мелочи, которые легко скопипастить. В дальнейшем планируется полная остановка поддержки по данной ветке.
utf8 – актуальная ветка, заточенная под UTF-8.
Внутри каждой ветки: core – исходники ядра; install – скрипт установки инсталляции; plugins – плагины; samples – "готовые к употреблению" проекты, которые можно поставить, запустить и посмотреть, как они работают.