Commit ed6f20bb506691b63fefab297614180ca8815024
Exists in
staging
fix merge with master conflit
Showing
209 changed files
with
2548 additions
and
1973 deletions
Show diff stats
Too many changes.
To preserve performance only 100 of 209 files displayed.
.gitlab-ci.yml
... | ... | @@ -6,12 +6,13 @@ before_script: |
6 | 6 | - ./script/silent-quick-start |
7 | 7 | |
8 | 8 | stages: |
9 | - - smoke-tests | |
9 | + #FIXME Selenium tests are randomly failing and this avoid other tests to run. | |
10 | + #- smoke-tests | |
10 | 11 | - all-tests |
11 | 12 | |
12 | -smoke: | |
13 | - script: bundle exec rake ci:smoke | |
14 | - stage: smoke-tests | |
13 | +#smoke: | |
14 | +# script: bundle exec rake ci:smoke | |
15 | +# stage: smoke-tests | |
15 | 16 | |
16 | 17 | units: |
17 | 18 | script: bundle exec rake test:units | ... | ... |
.travis.yml
... | ... | @@ -55,7 +55,10 @@ env: |
55 | 55 | - TASK=test:integration |
56 | 56 | - TASK=cucumber LANG=en |
57 | 57 | - TASK=selenium |
58 | - - TASK=test:noosfero_plugins BUNDLE_OPTS=install | |
58 | + - SLICE=1/4 TASK=test:noosfero_plugins BUNDLE_OPTS=install | |
59 | + - SLICE=2/4 TASK=test:noosfero_plugins BUNDLE_OPTS=install | |
60 | + - SLICE=3/4 TASK=test:noosfero_plugins BUNDLE_OPTS=install | |
61 | + - SLICE=4/4 TASK=test:noosfero_plugins BUNDLE_OPTS=install | |
59 | 62 | |
60 | 63 | script: |
61 | 64 | - ./script/ci | ... | ... |
... | ... | @@ -0,0 +1,12 @@ |
1 | +If you made any significant change to the code that you consider worth being | |
2 | +reminded on the Release Notes, also include a correspondent entry here. If you | |
3 | +are not sure in which release your code will be released, include it on the | |
4 | +latest release and leave it to the commiter or RM responsible for it. | |
5 | + | |
6 | +v 1.5.0 (unreleased) | |
7 | + - Allow groups to disable admin email notificationo | |
8 | + - Add option to HighlightsBlock to open link in a new tab | |
9 | + - Move blocks html generation from models to helpers | |
10 | + | |
11 | +v 1.4.0 | |
12 | + - Migration from Rails 3 to Rails 4! | ... | ... |
Gemfile
... | ... | @@ -34,7 +34,7 @@ gem 'slim' |
34 | 34 | |
35 | 35 | # API dependencies |
36 | 36 | gem 'grape', '~> 0.12' |
37 | -gem 'grape-entity', '= 0.4.8' | |
37 | +gem 'grape-entity', '0.4.8' | |
38 | 38 | gem 'grape_logging' |
39 | 39 | gem 'grape-swagger' |
40 | 40 | gem 'swagger-ui_rails' |
... | ... | @@ -43,7 +43,7 @@ gem 'rack-cors' |
43 | 43 | gem 'rack-contrib' |
44 | 44 | gem 'liquid', '~> 3.0.3' |
45 | 45 | |
46 | -gem 'api-pagination', '~> 4.1.1' | |
46 | +gem 'api-pagination', '>= 4.1.1' | |
47 | 47 | |
48 | 48 | # asset pipeline |
49 | 49 | gem 'uglifier', '>= 1.0.3' | ... | ... |
Gemfile.lock
... | ... | @@ -21,14 +21,14 @@ PATH |
21 | 21 | access_control (0.0.0) |
22 | 22 | |
23 | 23 | PATH |
24 | - remote: vendor/plugins/action_tracker | |
24 | + remote: vendor/plugins/action_tracker_has_comments | |
25 | 25 | specs: |
26 | - action_tracker (0.0.1) | |
26 | + action_tracker_has_comments (0.0.0) | |
27 | 27 | |
28 | 28 | PATH |
29 | - remote: vendor/plugins/action_tracker_has_comments | |
29 | + remote: vendor/plugins/action_tracker | |
30 | 30 | specs: |
31 | - action_tracker_has_comments (0.0.0) | |
31 | + action_tracker (0.0.1) | |
32 | 32 | |
33 | 33 | PATH |
34 | 34 | remote: vendor/plugins/acts_as_list |
... | ... | @@ -425,7 +425,7 @@ DEPENDENCIES |
425 | 425 | acts_as_tree (= 0.0.0)! |
426 | 426 | acts_as_versioned (> 0.0.0)! |
427 | 427 | airbrake (~> 4) |
428 | - api-pagination (~> 4.1.1) | |
428 | + api-pagination (>= 4.1.1) | |
429 | 429 | capybara (~> 2.2) |
430 | 430 | contacts (> 0.0.0)! |
431 | 431 | cucumber |
... | ... | @@ -491,3 +491,6 @@ DEPENDENCIES |
491 | 491 | whenever |
492 | 492 | will_paginate (~> 3.0.7) |
493 | 493 | xss_terminate (= 0.0.0)! |
494 | + | |
495 | +BUNDLED WITH | |
496 | + 1.11.2 | ... | ... |
app/controllers/my_profile/tasks_controller.rb
... | ... | @@ -2,6 +2,8 @@ class TasksController < MyProfileController |
2 | 2 | |
3 | 3 | protect [:perform_task, :view_tasks], :profile, :only => [:index, :save_tags, :search_tags] |
4 | 4 | protect :perform_task, :profile, :only => [:processed, :change_responsible, :close, :new, :list_requested, :ticket_details, :search_tags] |
5 | + include TasksHelper | |
6 | + | |
5 | 7 | |
6 | 8 | def index |
7 | 9 | @rejection_email_templates = profile.email_templates.find_all_by_template_type(:task_rejection) |
... | ... | @@ -84,12 +86,12 @@ class TasksController < MyProfileController |
84 | 86 | end |
85 | 87 | end |
86 | 88 | |
87 | - url = { :action => 'index' } | |
89 | + url = tasks_url(:action => 'index') | |
88 | 90 | if failed.blank? |
89 | 91 | session[:notice] = _("All decisions were applied successfully.") |
90 | 92 | else |
91 | 93 | session[:notice] = _("Some decisions couldn't be applied.") |
92 | - url[:failed] = failed | |
94 | + url = tasks_url(:action => 'index', :failed => failed) | |
93 | 95 | end |
94 | 96 | redirect_to url |
95 | 97 | end | ... | ... |
app/helpers/application_helper.rb
... | ... | @@ -50,6 +50,12 @@ module ApplicationHelper |
50 | 50 | |
51 | 51 | include TaskHelper |
52 | 52 | |
53 | + include ButtonsHelper | |
54 | + | |
55 | + include ProfileImageHelper | |
56 | + | |
57 | + include ThemeLoaderHelper | |
58 | + | |
53 | 59 | def locale |
54 | 60 | (@page && !@page.language.blank?) ? @page.language : FastGettext.locale |
55 | 61 | end |
... | ... | @@ -211,52 +217,6 @@ module ApplicationHelper |
211 | 217 | result |
212 | 218 | end |
213 | 219 | |
214 | - def button(type, label, url, html_options = {}) | |
215 | - html_options ||= {} | |
216 | - the_class = 'with-text' | |
217 | - if html_options.has_key?(:class) | |
218 | - the_class << ' ' << html_options[:class] | |
219 | - end | |
220 | - button_without_text type, label, url, html_options.merge(:class => the_class) | |
221 | - end | |
222 | - | |
223 | - def button_without_text(type, label, url, html_options = {}) | |
224 | - the_class = "button icon-#{type}" | |
225 | - if html_options.has_key?(:class) | |
226 | - the_class << ' ' << html_options[:class] | |
227 | - end | |
228 | - the_title = html_options[:title] || label | |
229 | - if html_options[:disabled] | |
230 | - content_tag('a', ' '+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title)) | |
231 | - else | |
232 | - link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) | |
233 | - end | |
234 | - end | |
235 | - | |
236 | - def button_to_function(type, label, js_code, html_options = {}, &block) | |
237 | - html_options[:class] = "button with-text" unless html_options[:class] | |
238 | - html_options[:class] << " icon-#{type}" | |
239 | - link_to_function(label, js_code, html_options, &block) | |
240 | - end | |
241 | - | |
242 | - def button_to_function_without_text(type, label, js_code, html_options = {}, &block) | |
243 | - html_options[:class] = "" unless html_options[:class] | |
244 | - html_options[:class] << " button icon-#{type}" | |
245 | - link_to_function(content_tag('span', label), js_code, html_options, &block) | |
246 | - end | |
247 | - | |
248 | - def button_to_remote(type, label, options, html_options = {}) | |
249 | - html_options[:class] = "button with-text" unless html_options[:class] | |
250 | - html_options[:class] << " icon-#{type}" | |
251 | - link_to_remote(label, options, html_options) | |
252 | - end | |
253 | - | |
254 | - def button_to_remote_without_text(type, label, options, html_options = {}) | |
255 | - html_options[:class] = "" unless html_options[:class] | |
256 | - html_options[:class] << " button icon-#{type}" | |
257 | - link_to_remote(content_tag('span', label), options, html_options.merge(:title => label)) | |
258 | - end | |
259 | - | |
260 | 220 | def icon(icon_name, html_options = {}) |
261 | 221 | the_class = "button #{icon_name}" |
262 | 222 | if html_options.has_key?(:class) |
... | ... | @@ -327,48 +287,6 @@ module ApplicationHelper |
327 | 287 | end |
328 | 288 | end |
329 | 289 | |
330 | - def theme_path | |
331 | - if session[:theme] | |
332 | - '/user_themes/' + current_theme | |
333 | - else | |
334 | - '/designs/themes/' + current_theme | |
335 | - end | |
336 | - end | |
337 | - | |
338 | - def current_theme | |
339 | - @current_theme ||= | |
340 | - begin | |
341 | - if session[:theme] | |
342 | - session[:theme] | |
343 | - else | |
344 | - # utility for developers: set the theme to 'random' in development mode and | |
345 | - # you will get a different theme every request. This is interesting for | |
346 | - # testing | |
347 | - if Rails.env.development? && environment.theme == 'random' | |
348 | - @random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand | |
349 | - @random_theme | |
350 | - elsif Rails.env.development? && respond_to?(:params) && params[:theme] && File.exists?(Rails.root.join('public/designs/themes', params[:theme])) | |
351 | - params[:theme] | |
352 | - else | |
353 | - if profile && !profile.theme.nil? | |
354 | - profile.theme | |
355 | - elsif environment | |
356 | - environment.theme | |
357 | - else | |
358 | - if logger | |
359 | - logger.warn("No environment found. This is weird.") | |
360 | - logger.warn("Request environment: %s" % request.env.inspect) | |
361 | - logger.warn("Request parameters: %s" % params.inspect) | |
362 | - end | |
363 | - | |
364 | - # could not determine the theme, so return the default one | |
365 | - 'default' | |
366 | - end | |
367 | - end | |
368 | - end | |
369 | - end | |
370 | - end | |
371 | - | |
372 | 290 | def theme_view_file(template, theme=nil) |
373 | 291 | # Since we cannot control what people are doing in external themes, we |
374 | 292 | # will keep looking for the deprecated .rhtml extension here. |
... | ... | @@ -441,141 +359,6 @@ module ApplicationHelper |
441 | 359 | Theme.find(current_theme).owner.identifier |
442 | 360 | end |
443 | 361 | |
444 | - # generates a image tag for the profile. | |
445 | - # | |
446 | - # If the profile has no image set yet, then a default image is used. | |
447 | - def profile_image(profile, size=:portrait, opt={}) | |
448 | - return '' if profile.nil? | |
449 | - opt[:alt] ||= profile.name() | |
450 | - opt[:title] ||= '' | |
451 | - opt[:class] ||= '' | |
452 | - opt[:class] += ( profile.class == Person ? ' photo' : ' logo' ) | |
453 | - image_tag(profile_icon(profile, size), opt ) | |
454 | - end | |
455 | - | |
456 | - def profile_icon( profile, size=:portrait, return_mimetype=false ) | |
457 | - filename, mimetype = '', 'image/png' | |
458 | - if profile.image | |
459 | - filename = profile.image.public_filename( size ) | |
460 | - mimetype = profile.image.content_type | |
461 | - else | |
462 | - icon = | |
463 | - if profile.organization? | |
464 | - if profile.kind_of?(Community) | |
465 | - '/images/icons-app/community-'+ size.to_s() +'.png' | |
466 | - else | |
467 | - '/images/icons-app/enterprise-'+ size.to_s() +'.png' | |
468 | - end | |
469 | - else | |
470 | - pixels = Image.attachment_options[:thumbnails][size].split('x').first | |
471 | - gravatar_profile_image_url( | |
472 | - profile.email, | |
473 | - :size => pixels, | |
474 | - :d => gravatar_default | |
475 | - ) | |
476 | - end | |
477 | - filename = default_or_themed_icon(icon) | |
478 | - end | |
479 | - return_mimetype ? [filename, mimetype] : filename | |
480 | - end | |
481 | - | |
482 | - def default_or_themed_icon(icon) | |
483 | - if File.exists?(Rails.root.join('public', theme_path, icon)) | |
484 | - theme_path + icon | |
485 | - else | |
486 | - icon | |
487 | - end | |
488 | - end | |
489 | - | |
490 | - def profile_sex_icon( profile ) | |
491 | - return '' unless profile.is_a?(Person) | |
492 | - return '' unless !environment.enabled?('disable_gender_icon') | |
493 | - sex = ( profile.sex ? profile.sex.to_s() : 'undef' ) | |
494 | - title = ( sex == 'undef' ? _('non registered gender') : ( sex == 'male' ? _('Male') : _('Female') ) ) | |
495 | - sex = content_tag 'span', | |
496 | - content_tag( 'span', sex ), | |
497 | - :class => 'sex-'+sex, | |
498 | - :title => title | |
499 | - sex | |
500 | - end | |
501 | - | |
502 | - def links_for_balloon(profile) | |
503 | - if environment.enabled?(:show_balloon_with_profile_links_when_clicked) | |
504 | - if profile.kind_of?(Person) | |
505 | - [ | |
506 | - {_('Wall') => {:href => url_for(profile.public_profile_url)}}, | |
507 | - {_('Friends') => {:href => url_for(:controller => :profile, :action => :friends, :profile => profile.identifier)}}, | |
508 | - {_('Communities') => {:href => url_for(:controller => :profile, :action => :communities, :profile => profile.identifier)}}, | |
509 | - {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}, | |
510 | - {_('Add') => {:href => url_for(profile.add_url), :class => 'add-friend', :style => 'display: none'}} | |
511 | - ] | |
512 | - elsif profile.kind_of?(Community) | |
513 | - [ | |
514 | - {_('Wall') => {:href => url_for(profile.public_profile_url)}}, | |
515 | - {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, | |
516 | - {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, | |
517 | - {_('Join') => {:href => url_for(profile.join_url), :class => 'join-community', :style => 'display: none'}}, | |
518 | - {_('Leave community') => {:href => url_for(profile.leave_url), :class => 'leave-community', :style => 'display: none'}}, | |
519 | - {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}} | |
520 | - ] | |
521 | - elsif profile.kind_of?(Enterprise) | |
522 | - [ | |
523 | - {_('Products') => {:href => catalog_path(profile.identifier)}}, | |
524 | - {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, | |
525 | - {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, | |
526 | - {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}, | |
527 | - ] | |
528 | - else | |
529 | - [] | |
530 | - end | |
531 | - end | |
532 | - end | |
533 | - | |
534 | - # displays a link to the profile homepage with its image (as generated by | |
535 | - # #profile_image) and its name below it. | |
536 | - def profile_image_link( profile, size=:portrait, tag='li', extra_info = nil ) | |
537 | - if content = @plugins.dispatch_first(:profile_image_link, profile, size, tag, extra_info) | |
538 | - return instance_exec(&content) | |
539 | - end | |
540 | - name = profile.short_name | |
541 | - if profile.person? | |
542 | - url = url_for(profile.check_friendship_url) | |
543 | - trigger_class = 'person-trigger' | |
544 | - else | |
545 | - city = '' | |
546 | - url = url_for(profile.check_membership_url) | |
547 | - if profile.community? | |
548 | - trigger_class = 'community-trigger' | |
549 | - elsif profile.enterprise? | |
550 | - trigger_class = 'enterprise-trigger' | |
551 | - end | |
552 | - end | |
553 | - | |
554 | - extra_info_tag = '' | |
555 | - img_class = 'profile-image' | |
556 | - | |
557 | - if extra_info.is_a? Hash | |
558 | - extra_info_tag = content_tag( 'span', extra_info[:value], :class => 'extra_info '+extra_info[:class]) | |
559 | - img_class +=' '+extra_info[:class] | |
560 | - else | |
561 | - extra_info_tag = content_tag( 'span', extra_info, :class => 'extra_info' ) | |
562 | - end | |
563 | - | |
564 | - links = links_for_balloon(profile) | |
565 | - content_tag('div', content_tag(tag, | |
566 | - (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? | |
567 | - popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") + | |
568 | - link_to( | |
569 | - content_tag( 'span', profile_image( profile, size ), :class => img_class ) + | |
570 | - content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + | |
571 | - extra_info_tag + profile_sex_icon( profile ), | |
572 | - profile.url, | |
573 | - :class => 'profile_link url', | |
574 | - :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name, | |
575 | - :title => profile.name ), | |
576 | - :class => 'vcard'), :class => 'common-profile-list-block') | |
577 | - end | |
578 | - | |
579 | 362 | def popover_menu(title,menu_title,links,html_options={}) |
580 | 363 | html_options[:class] = "" unless html_options[:class] |
581 | 364 | html_options[:class] << " menu-submenu-trigger" |
... | ... | @@ -584,10 +367,6 @@ module ApplicationHelper |
584 | 367 | link_to(content_tag(:span, title), '#', html_options) |
585 | 368 | end |
586 | 369 | |
587 | - def gravatar_default | |
588 | - (respond_to?(:theme_option) && theme_option.present? && theme_option['gravatar']) || NOOSFERO_CONF['gravatar'] || 'mm' | |
589 | - end | |
590 | - | |
591 | 370 | attr_reader :environment |
592 | 371 | |
593 | 372 | def select_categories(object_name, title=nil, title_size=4) |
... | ... | @@ -936,13 +715,6 @@ module ApplicationHelper |
936 | 715 | content_for(:head) { stylesheet_link_tag(*args) } |
937 | 716 | end |
938 | 717 | |
939 | - def article_to_html(article, options = {}) | |
940 | - options.merge!(:page => params[:npage]) | |
941 | - content = article.to_html(options) | |
942 | - content = content.kind_of?(Proc) ? self.instance_exec(&content).html_safe : content.html_safe | |
943 | - filter_html(content, article) | |
944 | - end | |
945 | - | |
946 | 718 | # Please, use link_to by default! |
947 | 719 | # This method was created to work around to inexplicable |
948 | 720 | # chain of problems when display_short_format was called |
... | ... | @@ -1379,16 +1151,6 @@ module ApplicationHelper |
1379 | 1151 | @no_design_blocks = true |
1380 | 1152 | end |
1381 | 1153 | |
1382 | - def filter_html(html, source) | |
1383 | - if @plugins && source && source.has_macro? | |
1384 | - html = convert_macro(html, source) unless @plugins.enabled_macros.blank? | |
1385 | - #TODO This parse should be done through the macro infra, but since there | |
1386 | - # are old things that do not support it we are keeping this hot spot. | |
1387 | - html = @plugins.pipeline(:parse_content, html, source).first | |
1388 | - end | |
1389 | - html && html.html_safe | |
1390 | - end | |
1391 | - | |
1392 | 1154 | def convert_macro(html, source) |
1393 | 1155 | doc = Nokogiri::HTML.fragment html |
1394 | 1156 | #TODO This way is more efficient but do not support macro inside of | ... | ... |
app/helpers/article_helper.rb
... | ... | @@ -195,4 +195,21 @@ module ArticleHelper |
195 | 195 | end |
196 | 196 | end |
197 | 197 | |
198 | + def filter_html(html, source) | |
199 | + if @plugins && source && source.has_macro? | |
200 | + html = convert_macro(html, source) unless @plugins.enabled_macros.blank? | |
201 | + #TODO This parse should be done through the macro infra, but since there | |
202 | + # are old things that do not support it we are keeping this hot spot. | |
203 | + html = @plugins.pipeline(:parse_content, html, source).first | |
204 | + end | |
205 | + html && html.html_safe | |
206 | + end | |
207 | + | |
208 | + def article_to_html(article, options = {}) | |
209 | + options.merge!(:page => params[:npage]) | |
210 | + content = article.to_html(options) | |
211 | + content = content.kind_of?(Proc) ? self.instance_exec(&content).html_safe : content.html_safe | |
212 | + filter_html(content, article) | |
213 | + end | |
214 | + | |
198 | 215 | end | ... | ... |
app/helpers/boxes_helper.rb
... | ... | @@ -87,10 +87,38 @@ module BoxesHelper |
87 | 87 | box_decorator == DontMoveBlocks |
88 | 88 | end |
89 | 89 | |
90 | - def display_block_content(block, person, main_content = nil) | |
91 | - content = block.main? ? wrap_main_content(main_content) : block.content({:person => person}) | |
90 | + def render_block block, prefix = nil, klass = block.class | |
91 | + template_name = klass.name.underscore.sub '_block', '' | |
92 | + begin | |
93 | + render template: "blocks/#{prefix}#{template_name}", locals: { block: block } | |
94 | + rescue ActionView::MissingTemplate | |
95 | + return if klass.superclass === Block | |
96 | + render_block block, prefix, klass.superclass | |
97 | + end | |
98 | + end | |
99 | + | |
100 | + def render_block_content block | |
101 | + # FIXME: this conditional should be removed after all | |
102 | + # block footer from plugins methods get refactored into helpers and views. | |
103 | + # They are a failsafe until all of them are done. | |
104 | + return block.content if block.method(:content).owner != Block | |
105 | + render_block block | |
106 | + end | |
107 | + | |
108 | + def render_block_footer block | |
109 | + return block.footer if block.method(:footer).owner != Block | |
110 | + render_block block, 'footers/' | |
111 | + end | |
112 | + | |
113 | + def display_block_content(block, main_content = nil) | |
114 | + content = nil | |
115 | + if block.main? | |
116 | + content = wrap_main_content(main_content) | |
117 | + else | |
118 | + content = render_block_content block | |
119 | + end | |
92 | 120 | result = extract_block_content(content) |
93 | - footer_content = extract_block_content(block.footer) | |
121 | + footer_content = extract_block_content(render_block_footer block) | |
94 | 122 | unless footer_content.blank? |
95 | 123 | footer_content = content_tag('div', footer_content, :class => 'block-footer-content' ) |
96 | 124 | end | ... | ... |
... | ... | @@ -0,0 +1,47 @@ |
1 | +module ButtonsHelper | |
2 | + def button(type, label, url, html_options = {}) | |
3 | + html_options ||= {} | |
4 | + the_class = 'with-text' | |
5 | + if html_options.has_key?(:class) | |
6 | + the_class << ' ' << html_options[:class] | |
7 | + end | |
8 | + button_without_text type, label, url, html_options.merge(:class => the_class) | |
9 | + end | |
10 | + | |
11 | + def button_without_text(type, label, url, html_options = {}) | |
12 | + the_class = "button icon-#{type}" | |
13 | + if html_options.has_key?(:class) | |
14 | + the_class << ' ' << html_options[:class] | |
15 | + end | |
16 | + the_title = html_options[:title] || label | |
17 | + if html_options[:disabled] | |
18 | + content_tag('a', ' '+content_tag('span', label), html_options.merge(:class => the_class, :title => the_title)) | |
19 | + else | |
20 | + link_to(' '+content_tag('span', label), url, html_options.merge(:class => the_class, :title => the_title)) | |
21 | + end | |
22 | + end | |
23 | + | |
24 | + def button_to_function(type, label, js_code, html_options = {}, &block) | |
25 | + html_options[:class] = "button with-text" unless html_options[:class] | |
26 | + html_options[:class] << " icon-#{type}" | |
27 | + link_to_function(label, js_code, html_options, &block) | |
28 | + end | |
29 | + | |
30 | + def button_to_function_without_text(type, label, js_code, html_options = {}, &block) | |
31 | + html_options[:class] = "" unless html_options[:class] | |
32 | + html_options[:class] << " button icon-#{type}" | |
33 | + link_to_function(content_tag('span', label), js_code, html_options, &block) | |
34 | + end | |
35 | + | |
36 | + def button_to_remote(type, label, options, html_options = {}) | |
37 | + html_options[:class] = "button with-text" unless html_options[:class] | |
38 | + html_options[:class] << " icon-#{type}" | |
39 | + link_to_remote(label, options, html_options) | |
40 | + end | |
41 | + | |
42 | + def button_to_remote_without_text(type, label, options, html_options = {}) | |
43 | + html_options[:class] = "" unless html_options[:class] | |
44 | + html_options[:class] << " button icon-#{type}" | |
45 | + link_to_remote(content_tag('span', label), options, html_options.merge(:title => label)) | |
46 | + end | |
47 | +end | ... | ... |
app/helpers/forms_helper.rb
... | ... | @@ -137,7 +137,7 @@ module FormsHelper |
137 | 137 | content_tag('table',rows.join("\n")) |
138 | 138 | end |
139 | 139 | |
140 | - def date_field(name, value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {}) | |
140 | + def date_field(name, value, datepicker_options = {}, html_options = {}) | |
141 | 141 | datepicker_options[:disabled] ||= false |
142 | 142 | datepicker_options[:alt_field] ||= '' |
143 | 143 | datepicker_options[:alt_format] ||= '' |
... | ... | @@ -152,7 +152,7 @@ module FormsHelper |
152 | 152 | datepicker_options[:close_text] ||= _('Done') |
153 | 153 | datepicker_options[:constrain_input] ||= true |
154 | 154 | datepicker_options[:current_text] ||= _('Today') |
155 | - datepicker_options[:date_format] ||= 'yy/mm/dd' | |
155 | + datepicker_options[:date_format] ||= 'yy-mm-dd' | |
156 | 156 | datepicker_options[:day_names] ||= [_('Sunday'), _('Monday'), _('Tuesday'), _('Wednesday'), _('Thursday'), _('Friday'), _('Saturday')] |
157 | 157 | datepicker_options[:day_names_min] ||= [_('Su'), _('Mo'), _('Tu'), _('We'), _('Th'), _('Fr'), _('Sa')] |
158 | 158 | datepicker_options[:day_names_short] ||= [_('Sun'), _('Mon'), _('Tue'), _('Wed'), _('Thu'), _('Fri'), _('Sat')] |
... | ... | @@ -184,10 +184,11 @@ module FormsHelper |
184 | 184 | datepicker_options[:year_range] ||= 'c-10:c+10' |
185 | 185 | datepicker_options[:year_suffix] ||= '' |
186 | 186 | |
187 | + date_format = datepicker_options[:time] ? "%Y-%m-%d %H:%M" : "%Y-%m-%d" | |
188 | + value = value.strftime(date_format) if value.present? | |
189 | + | |
187 | 190 | element_id = html_options[:id] || 'datepicker-date' |
188 | - value = value.strftime(format) if value.present? | |
189 | 191 | method = datepicker_options[:time] ? 'datetimepicker' : 'datepicker' |
190 | - current_date_or_nil = value.present? ? "new Date('#{value}')" : "null" | |
191 | 192 | result = text_field_tag(name, value, html_options) |
192 | 193 | result += |
193 | 194 | " |
... | ... | @@ -238,17 +239,17 @@ module FormsHelper |
238 | 239 | weekHeader: #{datepicker_options[:week_header].to_json}, |
239 | 240 | yearRange: #{datepicker_options[:year_range].to_json}, |
240 | 241 | yearSuffix: #{datepicker_options[:year_suffix].to_json} |
241 | - }).datepicker('setDate', current_date_or_nil) | |
242 | + }).datepicker() | |
242 | 243 | </script> |
243 | 244 | ".html_safe |
244 | 245 | result |
245 | 246 | end |
246 | 247 | |
247 | - def date_range_field(from_name, to_name, from_value, to_value, format = '%Y-%m-%d', datepicker_options = {}, html_options = {}) | |
248 | + def date_range_field(from_name, to_name, from_value, to_value, datepicker_options = {}, html_options = {}) | |
248 | 249 | from_id = html_options[:from_id] || 'datepicker-from-date' |
249 | 250 | to_id = html_options[:to_id] || 'datepicker-to-date' |
250 | - return _('From') +' '+ date_field(from_name, from_value, format, datepicker_options, html_options.merge({:id => from_id})) + | |
251 | - ' ' + _('until') +' '+ date_field(to_name, to_value, format, datepicker_options, html_options.merge({:id => to_id})) | |
251 | + return _('From') +' '+ date_field(from_name, from_value, datepicker_options, html_options.merge({:id => from_id})) + | |
252 | + ' ' + _('until') +' '+ date_field(to_name, to_value, datepicker_options, html_options.merge({:id => to_id})) | |
252 | 253 | end |
253 | 254 | |
254 | 255 | def select_folder(label_text, field_id, collection, default_value=nil, html_options = {}, js_options = {}) | ... | ... |
... | ... | @@ -0,0 +1,140 @@ |
1 | +module ProfileImageHelper | |
2 | + def default_or_themed_icon(icon) | |
3 | + if File.exists?(Rails.root.join('public', theme_path, icon)) | |
4 | + theme_path + icon | |
5 | + else | |
6 | + icon | |
7 | + end | |
8 | + end | |
9 | + | |
10 | + def gravatar_default | |
11 | + (respond_to?(:theme_option) && theme_option.present? && theme_option['gravatar']) || NOOSFERO_CONF['gravatar'] || 'mm' | |
12 | + end | |
13 | + | |
14 | + def profile_sex_icon( profile ) | |
15 | + return '' unless profile.is_a?(Person) | |
16 | + return '' unless !environment.enabled?('disable_gender_icon') | |
17 | + sex = ( profile.sex ? profile.sex.to_s() : 'undef' ) | |
18 | + title = ( sex == 'undef' ? _('non registered gender') : ( sex == 'male' ? _('Male') : _('Female') ) ) | |
19 | + sex = content_tag 'span', | |
20 | + content_tag( 'span', sex ), | |
21 | + :class => 'sex-'+sex, | |
22 | + :title => title | |
23 | + sex | |
24 | + end | |
25 | + | |
26 | + def profile_icon( profile, size=:portrait, return_mimetype=false ) | |
27 | + filename, mimetype = '', 'image/png' | |
28 | + if profile.image | |
29 | + filename = profile.image.public_filename( size ) | |
30 | + mimetype = profile.image.content_type | |
31 | + else | |
32 | + icon = | |
33 | + if profile.organization? | |
34 | + if profile.kind_of?(Community) | |
35 | + '/images/icons-app/community-'+ size.to_s() +'.png' | |
36 | + else | |
37 | + '/images/icons-app/enterprise-'+ size.to_s() +'.png' | |
38 | + end | |
39 | + else | |
40 | + pixels = Image.attachment_options[:thumbnails][size].split('x').first | |
41 | + gravatar_profile_image_url( | |
42 | + profile.email, | |
43 | + :size => pixels, | |
44 | + :d => gravatar_default | |
45 | + ) | |
46 | + end | |
47 | + filename = default_or_themed_icon(icon) | |
48 | + end | |
49 | + return_mimetype ? [filename, mimetype] : filename | |
50 | + end | |
51 | + | |
52 | + # generates a image tag for the profile. | |
53 | + # | |
54 | + # If the profile has no image set yet, then a default image is used. | |
55 | + def profile_image(profile, size=:portrait, opt={}) | |
56 | + return '' if profile.nil? | |
57 | + opt[:alt] ||= profile.name() | |
58 | + opt[:title] ||= '' | |
59 | + opt[:class] ||= '' | |
60 | + opt[:class] += ( profile.class == Person ? ' photo' : ' logo' ) | |
61 | + image_tag(profile_icon(profile, size), opt ) | |
62 | + end | |
63 | + | |
64 | + def links_for_balloon(profile) | |
65 | + if environment.enabled?(:show_balloon_with_profile_links_when_clicked) | |
66 | + if profile.kind_of?(Person) | |
67 | + [ | |
68 | + {_('Wall') => {:href => url_for(profile.public_profile_url)}}, | |
69 | + {_('Friends') => {:href => url_for(:controller => :profile, :action => :friends, :profile => profile.identifier)}}, | |
70 | + {_('Communities') => {:href => url_for(:controller => :profile, :action => :communities, :profile => profile.identifier)}}, | |
71 | + {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}, | |
72 | + {_('Add') => {:href => url_for(profile.add_url), :class => 'add-friend', :style => 'display: none'}} | |
73 | + ] | |
74 | + elsif profile.kind_of?(Community) | |
75 | + [ | |
76 | + {_('Wall') => {:href => url_for(profile.public_profile_url)}}, | |
77 | + {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, | |
78 | + {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, | |
79 | + {_('Join') => {:href => url_for(profile.join_url), :class => 'join-community', :style => 'display: none'}}, | |
80 | + {_('Leave community') => {:href => url_for(profile.leave_url), :class => 'leave-community', :style => 'display: none'}}, | |
81 | + {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}} | |
82 | + ] | |
83 | + elsif profile.kind_of?(Enterprise) | |
84 | + [ | |
85 | + {_('Products') => {:href => catalog_path(profile.identifier)}}, | |
86 | + {_('Members') => {:href => url_for(:controller => :profile, :action => :members, :profile => profile.identifier)}}, | |
87 | + {_('Agenda') => {:href => url_for(:controller => :profile, :action => :events, :profile => profile.identifier)}}, | |
88 | + {_('Send an e-mail') => {:href => url_for(:profile => profile.identifier, :controller => 'contact', :action => 'new'), :class => 'send-an-email', :style => 'display: none'}}, | |
89 | + ] | |
90 | + else | |
91 | + [] | |
92 | + end | |
93 | + end | |
94 | + end | |
95 | + | |
96 | + # displays a link to the profile homepage with its image (as generated by | |
97 | + # #profile_image) and its name below it. | |
98 | + def profile_image_link( profile, size=:portrait, tag='li', extra_info = nil ) | |
99 | + if content = @plugins.dispatch_first(:profile_image_link, profile, size, tag, extra_info) | |
100 | + return instance_exec(&content) | |
101 | + end | |
102 | + name = profile.short_name | |
103 | + if profile.person? | |
104 | + url = url_for(profile.check_friendship_url) | |
105 | + trigger_class = 'person-trigger' | |
106 | + else | |
107 | + city = '' | |
108 | + url = url_for(profile.check_membership_url) | |
109 | + if profile.community? | |
110 | + trigger_class = 'community-trigger' | |
111 | + elsif profile.enterprise? | |
112 | + trigger_class = 'enterprise-trigger' | |
113 | + end | |
114 | + end | |
115 | + | |
116 | + extra_info_tag = '' | |
117 | + img_class = 'profile-image' | |
118 | + | |
119 | + if extra_info.is_a? Hash | |
120 | + extra_info_tag = content_tag( 'span', extra_info[:value], :class => 'extra_info '+extra_info[:class]) | |
121 | + img_class +=' '+extra_info[:class] | |
122 | + else | |
123 | + extra_info_tag = content_tag( 'span', extra_info, :class => 'extra_info' ) | |
124 | + end | |
125 | + | |
126 | + links = links_for_balloon(profile) | |
127 | + content_tag('div', content_tag(tag, | |
128 | + (environment.enabled?(:show_balloon_with_profile_links_when_clicked) ? | |
129 | + popover_menu(_('Profile links'),profile.short_name,links,{:class => trigger_class, :url => url}) : "") + | |
130 | + link_to( | |
131 | + content_tag( 'span', profile_image( profile, size ), :class => img_class ) + | |
132 | + content_tag( 'span', h(name), :class => ( profile.class == Person ? 'fn' : 'org' ) ) + | |
133 | + extra_info_tag + profile_sex_icon( profile ), | |
134 | + profile.url, | |
135 | + :class => 'profile_link url', | |
136 | + :help => _('Click on this icon to go to the <b>%s</b>\'s home page') % profile.name, | |
137 | + :title => profile.name ), | |
138 | + :class => 'vcard'), :class => 'common-profile-list-block') | |
139 | + end | |
140 | +end | |
0 | 141 | \ No newline at end of file | ... | ... |
... | ... | @@ -0,0 +1,12 @@ |
1 | +module TasksHelper | |
2 | + | |
3 | + def tasks_url options = {} | |
4 | + url_for(options.merge(filter_params)) | |
5 | + end | |
6 | + | |
7 | + def filter_params | |
8 | + filter_fields = ['filter_type', 'filter_text', 'filter_responsible', 'filter_tags'] | |
9 | + params.select {|filter| filter if filter_fields.include? filter } | |
10 | + end | |
11 | + | |
12 | +end | ... | ... |
... | ... | @@ -0,0 +1,43 @@ |
1 | +module ThemeLoaderHelper | |
2 | + def current_theme | |
3 | + @current_theme ||= | |
4 | + begin | |
5 | + if session[:theme] | |
6 | + session[:theme] | |
7 | + else | |
8 | + # utility for developers: set the theme to 'random' in development mode and | |
9 | + # you will get a different theme every request. This is interesting for | |
10 | + # testing | |
11 | + if Rails.env.development? && environment.theme == 'random' | |
12 | + @random_theme ||= Dir.glob('public/designs/themes/*').map { |f| File.basename(f) }.rand | |
13 | + @random_theme | |
14 | + elsif Rails.env.development? && respond_to?(:params) && params[:theme] && File.exists?(Rails.root.join('public/designs/themes', params[:theme])) | |
15 | + params[:theme] | |
16 | + else | |
17 | + if profile && !profile.theme.nil? | |
18 | + profile.theme | |
19 | + elsif environment | |
20 | + environment.theme | |
21 | + else | |
22 | + if logger | |
23 | + logger.warn("No environment found. This is weird.") | |
24 | + logger.warn("Request environment: %s" % request.env.inspect) | |
25 | + logger.warn("Request parameters: %s" % params.inspect) | |
26 | + end | |
27 | + | |
28 | + # could not determine the theme, so return the default one | |
29 | + 'default' | |
30 | + end | |
31 | + end | |
32 | + end | |
33 | + end | |
34 | + end | |
35 | + | |
36 | + def theme_path | |
37 | + if session[:theme] | |
38 | + '/user_themes/' + current_theme | |
39 | + else | |
40 | + '/designs/themes/' + current_theme | |
41 | + end | |
42 | + end | |
43 | +end | ... | ... |
app/models/article_block.rb
... | ... | @@ -18,18 +18,6 @@ class ArticleBlock < Block |
18 | 18 | _('This block displays one of your articles. You can edit the block to select which one of your articles is going to be displayed in the block.') |
19 | 19 | end |
20 | 20 | |
21 | - def content(args={}) | |
22 | - block = self | |
23 | - proc do | |
24 | - block_title(block.title) + | |
25 | - (block.article ? article_to_html(FilePresenter.for(block.article), | |
26 | - :gallery_view => false, | |
27 | - :inside_block => block, # For Blogs and folders | |
28 | - :format => block.visualization_format # For Articles and contents | |
29 | - ).html_safe : _('Article not selected yet.')) | |
30 | - end | |
31 | - end | |
32 | - | |
33 | 21 | def article_id |
34 | 22 | self.settings[:article_id] |
35 | 23 | end | ... | ... |
app/models/blog.rb
... | ... | @@ -93,4 +93,20 @@ class Blog < Folder |
93 | 93 | posts.where("type != 'RssFeed'").order(:updated_at).limit(limit) |
94 | 94 | end |
95 | 95 | |
96 | + def total_number_of_posts(group_by, year = nil) | |
97 | + case group_by | |
98 | + when :by_year | |
99 | + posts.published.native_translations | |
100 | + .except(:order) | |
101 | + .count(:all, :group => 'EXTRACT(YEAR FROM published_at)') | |
102 | + .sort_by {|year, count| -year.to_i} | |
103 | + when :by_month | |
104 | + posts.published.native_translations | |
105 | + .except(:order) | |
106 | + .where('EXTRACT(YEAR FROM published_at)=?', year.to_i) | |
107 | + .group('EXTRACT(MONTH FROM published_at)') | |
108 | + .count | |
109 | + .sort_by {|month, count| -month.to_i} | |
110 | + end | |
111 | + end | |
96 | 112 | end | ... | ... |
app/models/blog_archives_block.rb
... | ... | @@ -21,30 +21,6 @@ class BlogArchivesBlock < Block |
21 | 21 | blog_id && owner.blogs.exists?(blog_id) ? owner.blogs.find(blog_id) : owner.blog |
22 | 22 | end |
23 | 23 | |
24 | - def visible_posts(person) | |
25 | - #FIXME Performance issues with display_to. Must convert it to a scope. | |
26 | - # Checkout this page for further information: http://noosfero.org/Development/ActionItem2705 | |
27 | - blog.posts.published.native_translations #.select {|post| post.display_to?(person)} | |
28 | - end | |
29 | - | |
30 | - def content(args={}) | |
31 | - owner_blog = self.blog | |
32 | - return nil unless owner_blog | |
33 | - results = '' | |
34 | - posts = visible_posts(args[:person]) | |
35 | - posts.except(:order).count(:all, :group => 'EXTRACT(YEAR FROM published_at)').sort_by {|year, count| -year.to_i}.each do |year, count| | |
36 | - results << content_tag('li', content_tag('strong', "#{year.to_i} (#{count})")) | |
37 | - results << "<ul class='#{year.to_i}-archive'>" | |
38 | - posts.except(:order).where('EXTRACT(YEAR FROM published_at)=?', year.to_i).group('EXTRACT(MONTH FROM published_at)').count.sort_by {|month, count| -month.to_i}.each do |month, count| | |
39 | - results << content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", owner_blog.url.merge(year: year.to_i, month: month.to_i))) | |
40 | - end | |
41 | - results << "</ul>" | |
42 | - end | |
43 | - block_title(title) + | |
44 | - content_tag('ul', results, :class => 'blog-archives') + | |
45 | - content_tag('div', link_to(_('Subscribe RSS Feed'), owner_blog.feed.url), :class => 'subscribe-feed') | |
46 | - end | |
47 | - | |
48 | 24 | def self.expire_on |
49 | 25 | { :profile => [:article], :environment => [:article] } |
50 | 26 | end | ... | ... |
app/models/categories_block.rb
... | ... | @@ -30,13 +30,6 @@ class CategoriesBlock < Block |
30 | 30 | Category.top_level_for(self.owner).from_types(self.category_types) |
31 | 31 | end |
32 | 32 | |
33 | - def content(args={}) | |
34 | - block = self | |
35 | - proc do | |
36 | - render :file => 'blocks/categories', :locals => { :block => block } | |
37 | - end | |
38 | - end | |
39 | - | |
40 | 33 | def self.expire_on |
41 | 34 | { :profile => [], :environment => [:category] } |
42 | 35 | end | ... | ... |
app/models/comment.rb
... | ... | @@ -117,7 +117,15 @@ class Comment < ActiveRecord::Base |
117 | 117 | end |
118 | 118 | |
119 | 119 | delegate :environment, :to => :profile |
120 | - delegate :profile, :to => :source, :allow_nil => true | |
120 | + | |
121 | + def environment | |
122 | + profile && profile.respond_to?(:environment) ? profile.environment : nil | |
123 | + end | |
124 | + | |
125 | + def profile | |
126 | + return unless source | |
127 | + source.kind_of?(Profile) ? source : source.profile | |
128 | + end | |
121 | 129 | |
122 | 130 | include Noosfero::Plugin::HotSpot |
123 | 131 | ... | ... |
app/models/communities_block.rb
... | ... | @@ -27,15 +27,6 @@ class CommunitiesBlock < ProfileListBlock |
27 | 27 | owner.profile_suggestions.of_community.enabled.limit(3).includes(:suggestion) |
28 | 28 | end |
29 | 29 | |
30 | - def footer | |
31 | - owner = self.owner | |
32 | - suggestions = self.suggestions | |
33 | - return '' unless owner.kind_of?(Profile) || owner.kind_of?(Environment) | |
34 | - proc do | |
35 | - render :file => 'blocks/communities', :locals => { :owner => owner, :suggestions => suggestions } | |
36 | - end | |
37 | - end | |
38 | - | |
39 | 30 | def profiles |
40 | 31 | owner.communities |
41 | 32 | end | ... | ... |
app/models/disabled_enterprise_message_block.rb
... | ... | @@ -12,13 +12,6 @@ class DisabledEnterpriseMessageBlock < Block |
12 | 12 | _('Message') |
13 | 13 | end |
14 | 14 | |
15 | - def content(args={}) | |
16 | - message = self.owner.environment.message_for_disabled_enterprise || '' | |
17 | - lambda do |_| | |
18 | - render :file => 'blocks/disabled_enterprise_message', :locals => {:message => message} | |
19 | - end | |
20 | - end | |
21 | - | |
22 | 15 | def editable?(user=nil) |
23 | 16 | false |
24 | 17 | end | ... | ... |
app/models/enterprises_block.rb
... | ... | @@ -12,22 +12,6 @@ class EnterprisesBlock < ProfileListBlock |
12 | 12 | _('Enterprises') |
13 | 13 | end |
14 | 14 | |
15 | - def footer | |
16 | - owner = self.owner | |
17 | - case owner | |
18 | - when Profile | |
19 | - proc do | |
20 | - link_to s_('enterprises|View all'), :profile => owner.identifier, :controller => 'profile', :action => 'enterprises' | |
21 | - end | |
22 | - when Environment | |
23 | - proc do | |
24 | - link_to s_('enterprises|View all'), :controller => 'search', :action => 'assets', :asset => 'enterprises' | |
25 | - end | |
26 | - else | |
27 | - '' | |
28 | - end | |
29 | - end | |
30 | - | |
31 | 15 | def profiles |
32 | 16 | owner.enterprises |
33 | 17 | end | ... | ... |
app/models/fans_block.rb
... | ... | @@ -12,14 +12,6 @@ class FansBlock < ProfileListBlock |
12 | 12 | _('This block presents the fans of an enterprise.') |
13 | 13 | end |
14 | 14 | |
15 | - def footer | |
16 | - profile = self.owner | |
17 | - proc do | |
18 | - link_to _('View all'), :profile => profile.identifier, :controller => | |
19 | - 'profile', :action => 'fans' | |
20 | - end | |
21 | - end | |
22 | - | |
23 | 15 | def profiles |
24 | 16 | owner.fans |
25 | 17 | end | ... | ... |
app/models/favorite_enterprises_block.rb
... | ... | @@ -12,14 +12,6 @@ class FavoriteEnterprisesBlock < ProfileListBlock |
12 | 12 | _('Favorite Enterprises') |
13 | 13 | end |
14 | 14 | |
15 | - def footer | |
16 | - owner = self.owner | |
17 | - return '' unless owner.kind_of?(Person) | |
18 | - proc do | |
19 | - link_to _('enterprises|View all'), {:profile => owner.identifier, :controller => 'profile', :action => 'favorite_enterprises'}, :class => 'view-all' | |
20 | - end | |
21 | - end | |
22 | - | |
23 | 15 | def profiles |
24 | 16 | owner.favorite_enterprises |
25 | 17 | end | ... | ... |
app/models/featured_products_block.rb
... | ... | @@ -32,11 +32,4 @@ class FeaturedProductsBlock < Block |
32 | 32 | self.owner.highlighted_products_with_image |
33 | 33 | end |
34 | 34 | |
35 | - def content(args={}) | |
36 | - block = self | |
37 | - proc do | |
38 | - render :file => 'blocks/featured_products', :locals => { :block => block } | |
39 | - end | |
40 | - end | |
41 | - | |
42 | 35 | end | ... | ... |
app/models/feed_reader_block.rb
... | ... | @@ -52,24 +52,6 @@ class FeedReaderBlock < Block |
52 | 52 | self.feed_title.nil? ? _('Feed Reader') : self.feed_title |
53 | 53 | end |
54 | 54 | |
55 | - def formatted_feed_content | |
56 | - if error_message.blank? | |
57 | - "<ul>\n".html_safe + | |
58 | - self.feed_items[0..(limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n").html_safe + | |
59 | - "</ul>".html_safe | |
60 | - else | |
61 | - "<p>#{error_message}</p>".html_safe | |
62 | - end | |
63 | - end | |
64 | - | |
65 | - def footer | |
66 | - if self.fetched_at.nil? or self.feed_items.empty? | |
67 | - _('Feed content was not loaded yet') | |
68 | - else | |
69 | - _("Updated: %s") % show_date(self.fetched_at) | |
70 | - end | |
71 | - end | |
72 | - | |
73 | 55 | def add_item(title, link, date, content) |
74 | 56 | self.feed_items.unshift( {:title => title, :link => link}) |
75 | 57 | end |
... | ... | @@ -85,8 +67,4 @@ class FeedReaderBlock < Block |
85 | 67 | self.save! |
86 | 68 | end |
87 | 69 | |
88 | - def content(args={}) | |
89 | - block_title(title) + formatted_feed_content | |
90 | - end | |
91 | - | |
92 | 70 | end | ... | ... |
app/models/highlights_block.rb
... | ... | @@ -43,13 +43,6 @@ class HighlightsBlock < Block |
43 | 43 | end |
44 | 44 | end |
45 | 45 | |
46 | - def content(args={}) | |
47 | - block = self | |
48 | - proc do | |
49 | - render :file => 'blocks/highlights', :locals => { :block => block } | |
50 | - end | |
51 | - end | |
52 | - | |
53 | 46 | def folder_choices |
54 | 47 | owner.image_galleries |
55 | 48 | end | ... | ... |
app/models/link_list_block.rb
... | ... | @@ -59,20 +59,6 @@ class LinkListBlock < Block |
59 | 59 | _('Link list') |
60 | 60 | end |
61 | 61 | |
62 | - def content(args={}) | |
63 | - block_title(title) + | |
64 | - content_tag('ul', | |
65 | - links.select{|i| !i[:name].blank? and !i[:address].blank?}.map{|i| content_tag('li', link_html(i))}.join | |
66 | - ) | |
67 | - end | |
68 | - | |
69 | - def link_html(link) | |
70 | - klass = 'icon-' + link[:icon] if link[:icon] | |
71 | - sanitize_link( | |
72 | - link_to(link[:name], expand_address(link[:address]), :target => link[:target], :class => klass, :title => link[:title]) | |
73 | - ) | |
74 | - end | |
75 | - | |
76 | 62 | def expand_address(address) |
77 | 63 | add = if owner.respond_to?(:identifier) |
78 | 64 | address.gsub('{profile}', owner.identifier) |
... | ... | @@ -99,8 +85,6 @@ class LinkListBlock < Block |
99 | 85 | end |
100 | 86 | end |
101 | 87 | |
102 | - private | |
103 | - | |
104 | 88 | def sanitize_link(text) |
105 | 89 | sanitizer = HTML::WhiteListSanitizer.new |
106 | 90 | sanitizer.sanitize(text) | ... | ... |
app/models/location_block.rb
... | ... | @@ -13,12 +13,4 @@ class LocationBlock < Block |
13 | 13 | _('Shows where the profile is on the material world.') |
14 | 14 | end |
15 | 15 | |
16 | - def content(args={}) | |
17 | - block = self | |
18 | - profile = self.owner | |
19 | - proc do | |
20 | - render :file => 'blocks/location', :locals => {:block => block, :profile => profile} | |
21 | - end | |
22 | - end | |
23 | - | |
24 | 16 | end | ... | ... |
app/models/login_block.rb
app/models/main_block.rb
app/models/my_network_block.rb
... | ... | @@ -14,16 +14,6 @@ class MyNetworkBlock < Block |
14 | 14 | _('This block displays some info about your networking.') |
15 | 15 | end |
16 | 16 | |
17 | - def content(args={}) | |
18 | - block = self | |
19 | - proc do | |
20 | - render :file => 'blocks/my_network', :locals => { | |
21 | - :title => block.title, | |
22 | - :owner => block.owner | |
23 | - } | |
24 | - end | |
25 | - end | |
26 | - | |
27 | 17 | def cacheable? |
28 | 18 | false |
29 | 19 | end | ... | ... |
app/models/product_categories_block.rb
... | ... | @@ -13,26 +13,6 @@ class ProductCategoriesBlock < Block |
13 | 13 | _('Helps to filter the products catalog.') |
14 | 14 | end |
15 | 15 | |
16 | - def content(args={}) | |
17 | - profile = owner | |
18 | - proc do | |
19 | - if @categories.nil? or @categories.length == 0 | |
20 | - categories = ProductCategory.on_level(nil).order(:name) | |
21 | - if @categories and @categories.length == 0 | |
22 | - notice = _('There are no sub-categories for %s') % @category.name | |
23 | - end | |
24 | - else | |
25 | - categories = @categories | |
26 | - end | |
27 | - render :file => 'blocks/product_categories', | |
28 | - :locals => { | |
29 | - :profile => profile, | |
30 | - :categories => categories, | |
31 | - :notice => notice | |
32 | - } | |
33 | - end | |
34 | - end | |
35 | - | |
36 | 16 | DISPLAY_OPTIONS = DISPLAY_OPTIONS.merge('catalog_only' => _('Only on the catalog')) |
37 | 17 | |
38 | 18 | def display | ... | ... |
app/models/products_block.rb
... | ... | @@ -19,26 +19,6 @@ class ProductsBlock < Block |
19 | 19 | _('This block presents a list of your products.') |
20 | 20 | end |
21 | 21 | |
22 | - def content(args={}) | |
23 | - block_title(title) + | |
24 | - content_tag( | |
25 | - 'ul', | |
26 | - products.map {|product| | |
27 | - content_tag('li', | |
28 | - link_to( product.name, | |
29 | - product.url, | |
30 | - :style => 'background-image:url(%s)' % product.default_image('minor') | |
31 | - ), | |
32 | - :class => 'product' | |
33 | - ) | |
34 | - }.join | |
35 | - ) | |
36 | - end | |
37 | - | |
38 | - def footer | |
39 | - link_to(_('View all products'), owner.public_profile_url.merge(:controller => 'catalog', :action => 'index')) | |
40 | - end | |
41 | - | |
42 | 22 | settings_items :product_ids, type: Array |
43 | 23 | def product_ids=(array) |
44 | 24 | self.settings[:product_ids] = array | ... | ... |
app/models/profile.rb
... | ... | @@ -5,8 +5,8 @@ class Profile < ActiveRecord::Base |
5 | 5 | |
6 | 6 | attr_accessible :name, :identifier, :public_profile, :nickname, :custom_footer, :custom_header, :address, :zip_code, :contact_phone, :image_builder, :description, :closed, :template_id, :environment, :lat, :lng, :is_template, :fields_privacy, :preferred_domain_id, :category_ids, :country, :city, :state, :national_region_code, :email, :contact_email, :redirect_l10n, :notification_time, |
7 | 7 | :redirection_after_login, :custom_url_redirection, |
8 | - :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, | |
9 | - :custom_fields, :administrator_mail_notification, :region, :region_id | |
8 | + :email_suggestions, :allow_members_to_invite, :invite_friends_only, :secret, :profile_admin_mail_notification, | |
9 | + :custom_fields, :region, :region_id | |
10 | 10 | |
11 | 11 | # use for internationalizable human type names in search facets |
12 | 12 | # reimplement on subclasses |
... | ... | @@ -277,7 +277,7 @@ class Profile < ActiveRecord::Base |
277 | 277 | settings_items :description |
278 | 278 | settings_items :fields_privacy, :type => :hash, :default => {} |
279 | 279 | settings_items :email_suggestions, :type => :boolean, :default => false |
280 | - settings_items :administrator_mail_notification, :type => :boolean, :default => true | |
280 | + settings_items :profile_admin_mail_notification, :type => :boolean, :default => true | |
281 | 281 | |
282 | 282 | validates_length_of :description, :maximum => 550, :allow_nil => true |
283 | 283 | ... | ... |
app/models/profile_image_block.rb
... | ... | @@ -12,17 +12,6 @@ class ProfileImageBlock < Block |
12 | 12 | _('This block presents the profile image') |
13 | 13 | end |
14 | 14 | |
15 | - def content(args={}) | |
16 | - block = self | |
17 | - s = show_name | |
18 | - lambda do |object| | |
19 | - render( | |
20 | - :file => 'blocks/profile_image', | |
21 | - :locals => { :block => block, :show_name => s } | |
22 | - ) | |
23 | - end | |
24 | - end | |
25 | - | |
26 | 15 | def cacheable? |
27 | 16 | false |
28 | 17 | end | ... | ... |
app/models/profile_info_block.rb
... | ... | @@ -16,13 +16,6 @@ class ProfileInfoBlock < Block |
16 | 16 | _('Basic information about <i>%{user}</i>: how long <i>%{user}</i> is part of <i>%{env}</i> and useful links.') % { :user => self.owner.name(), :env => self.owner.environment.name() } |
17 | 17 | end |
18 | 18 | |
19 | - def content(args={}) | |
20 | - block = self | |
21 | - lambda do |_| | |
22 | - render :file => 'blocks/profile_info', :locals => { :block => block } | |
23 | - end | |
24 | - end | |
25 | - | |
26 | 19 | def cacheable? |
27 | 20 | false |
28 | 21 | end | ... | ... |
app/models/profile_list_block.rb
... | ... | @@ -40,26 +40,6 @@ result = public_profiles.all(:limit => get_limit, :order => 'profiles.updated_at |
40 | 40 | _('Clicking on the people or groups will take you to their home page.') |
41 | 41 | end |
42 | 42 | |
43 | - def content(args={}) | |
44 | - profiles = self.profile_list | |
45 | - title = self.view_title | |
46 | - nl = "\n" | |
47 | - proc do |context| | |
48 | - count=0 | |
49 | - list = profiles.map {|item| | |
50 | - count+=1 | |
51 | - send(:profile_image_link, item, :minor ) | |
52 | - }.join("\n ") | |
53 | - if list.empty? | |
54 | - list = content_tag 'div', _('None'), :class => 'common-profile-list-block-none' | |
55 | - else | |
56 | - list = content_tag 'ul', nl +' '+ list + nl | |
57 | - end | |
58 | - block_title(title) + nl + | |
59 | - content_tag('div', nl + list + nl + tag('br', :style => 'clear:both')) | |
60 | - end | |
61 | - end | |
62 | - | |
63 | 43 | def view_title |
64 | 44 | title.gsub('{#}', profile_count.to_s) |
65 | 45 | end | ... | ... |
app/models/profile_search_block.rb
... | ... | @@ -4,11 +4,4 @@ class ProfileSearchBlock < Block |
4 | 4 | _('Display a form to search the profile') |
5 | 5 | end |
6 | 6 | |
7 | - def content(args={}) | |
8 | - title = self.title | |
9 | - lambda do |_| | |
10 | - render :file => 'blocks/profile_search', :locals => { :title => title } | |
11 | - end | |
12 | - end | |
13 | - | |
14 | 7 | end | ... | ... |
app/models/raw_html_block.rb
app/models/recent_documents_block.rb
... | ... | @@ -22,24 +22,6 @@ class RecentDocumentsBlock < Block |
22 | 22 | |
23 | 23 | settings_items :limit, :type => :integer, :default => 5 |
24 | 24 | |
25 | - def content(args={}) | |
26 | - docs = self.docs | |
27 | - title = self.title | |
28 | - proc do | |
29 | - block_title(title) + | |
30 | - content_tag('ul', docs.map {|item| content_tag('li', link_to(h(item.title), item.url))}.join("\n")) | |
31 | - end | |
32 | - end | |
33 | - | |
34 | - def footer | |
35 | - return nil unless self.owner.is_a?(Profile) | |
36 | - | |
37 | - profile = self.owner | |
38 | - proc do | |
39 | - link_to _('All content'), :profile => profile.identifier, :controller => 'profile', :action => 'sitemap' | |
40 | - end | |
41 | - end | |
42 | - | |
43 | 25 | def docs |
44 | 26 | self.limit.nil? ? owner.recent_documents(nil, {}, false) : owner.recent_documents(self.get_limit, {}, false) |
45 | 27 | end | ... | ... |
app/models/sellers_search_block.rb
... | ... | @@ -22,10 +22,4 @@ class SellersSearchBlock < Block |
22 | 22 | _('This block presents a search engine for products.') |
23 | 23 | end |
24 | 24 | |
25 | - def content(args={}) | |
26 | - title = self.title | |
27 | - lambda do |object| | |
28 | - render :file => 'search/_sellers_form', :locals => { :title => title } | |
29 | - end | |
30 | - end | |
31 | 25 | end | ... | ... |
app/models/slideshow_block.rb
... | ... | @@ -33,23 +33,6 @@ class SlideshowBlock < Block |
33 | 33 | gallery.images.reject {|item| item.folder?} |
34 | 34 | end |
35 | 35 | |
36 | - def content(args={}) | |
37 | - block = self | |
38 | - if gallery | |
39 | - images = block_images | |
40 | - if shuffle | |
41 | - images = images.shuffle | |
42 | - end | |
43 | - proc do | |
44 | - render :file => 'blocks/slideshow', :locals => { :block => block, :images => images } | |
45 | - end | |
46 | - else | |
47 | - proc do | |
48 | - render :file => 'blocks/slideshow', :locals => { :block => block, :images => nil } | |
49 | - end | |
50 | - end | |
51 | - end | |
52 | - | |
53 | 36 | def folder_choices |
54 | 37 | owner.image_galleries |
55 | 38 | end | ... | ... |
app/models/tags_block.rb
... | ... | @@ -28,42 +28,6 @@ class TagsBlock < Block |
28 | 28 | Try to add some tags to some articles and you'l see your tag cloud growing.") |
29 | 29 | end |
30 | 30 | |
31 | - def content(args={}) | |
32 | - is_env = owner.class == Environment | |
33 | - tags = is_env ? owner.tag_counts : owner.article_tags | |
34 | - return '' if tags.empty? | |
35 | - | |
36 | - if limit | |
37 | - tags_tmp = tags.sort_by{ |k,v| -v }[0..(limit-1)] | |
38 | - tags = {} | |
39 | - tags_tmp.map{ |k,v| tags[k] = v } | |
40 | - end | |
41 | - | |
42 | - url = is_env ? {:host=>owner.default_hostname, :controller=>'search', :action => 'tag'} : | |
43 | - owner.public_profile_url.merge(:controller => 'profile', :action => 'content_tagged') | |
44 | - tagname_option = is_env ? :tag : :id | |
45 | - | |
46 | - block_title(title) + | |
47 | - "\n<div class='tag_cloud'>\n".html_safe+ | |
48 | - tag_cloud( tags, tagname_option, url, :max_size => 16, :min_size => 9 ) + | |
49 | - "\n</div><!-- end class='tag_cloud' -->\n".html_safe | |
50 | - end | |
51 | - | |
52 | - def footer | |
53 | - if owner.class == Environment | |
54 | - proc do | |
55 | - link_to s_('tags|View all'), | |
56 | - :controller => 'search', :action => 'tags' | |
57 | - end | |
58 | - else | |
59 | - owner_id = owner.identifier | |
60 | - proc do | |
61 | - link_to s_('tags|View all'), | |
62 | - :profile => owner_id, :controller => 'profile', :action => 'tags' | |
63 | - end | |
64 | - end | |
65 | - end | |
66 | - | |
67 | 31 | def timeout |
68 | 32 | 15.minutes |
69 | 33 | end | ... | ... |
app/models/task.rb
... | ... | @@ -81,17 +81,13 @@ class Task < ActiveRecord::Base |
81 | 81 | end |
82 | 82 | |
83 | 83 | def target_profile_accepts_notification?(task) |
84 | - if target_is_profile?(task) | |
85 | - return task.target.administrator_mail_notification | |
84 | + if task.target.kind_of? Organization | |
85 | + return task.target.profile_admin_mail_notification | |
86 | 86 | else |
87 | 87 | true |
88 | 88 | end |
89 | 89 | end |
90 | 90 | |
91 | - def target_is_profile?(task) | |
92 | - task.target.kind_of? Profile | |
93 | - end | |
94 | - | |
95 | 91 | # this method finished the task. It calls #perform, which must be overriden |
96 | 92 | # by subclasses. At the end a message (as returned by #finish_message) is |
97 | 93 | # sent to the requestor with #notify_requestor. | ... | ... |
... | ... | @@ -0,0 +1,12 @@ |
1 | +<%= block_title(block.title) %> | |
2 | +<% if block.article %> | |
3 | + <%= | |
4 | + h(article_to_html(FilePresenter.for(block.article), | |
5 | + :gallery_view => false, | |
6 | + :inside_block => block, # For Blogs and folders | |
7 | + :format => block.visualization_format # For Articles and contents | |
8 | + )) | |
9 | + %> | |
10 | +<% else %> | |
11 | + <%= _('Article not selected yet.') %> | |
12 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<% if block.blog %> | |
2 | + <%= block_title(block.title) %> | |
3 | + | |
4 | + <ul class='blog-archives'> | |
5 | + <% block.blog.total_number_of_posts(:by_year).each do |year, count| %> | |
6 | + <%= content_tag('li', content_tag('strong', "#{year.to_i} (#{count})")) %> | |
7 | + <ul class='<%= year.to_i %>-archive'> | |
8 | + <% block.blog.total_number_of_posts(:by_month, year).each do |month, count| %> | |
9 | + <%= content_tag('li', link_to("#{month_name(month.to_i)} (#{count})", block.blog.url.merge(year: year.to_i, month: month.to_i))) %> | |
10 | + <% end %> | |
11 | + </ul> | |
12 | + <% end %> | |
13 | + </ul> | |
14 | + | |
15 | + <%= content_tag('div', link_to(_('Subscribe RSS Feed'), block.blog.feed.url), :class => 'subscribe-feed') %> | |
16 | +<% end %> | ... | ... |
app/views/blocks/communities.html.erb
... | ... | @@ -1,17 +0,0 @@ |
1 | -<% if owner.kind_of?(Profile) %> | |
2 | - <%= link_to s_('communities|View all'), {:profile => owner.identifier, :controller => 'profile', :action => 'communities'}, :class => 'view-all' %> | |
3 | -<% elsif owner.kind_of?(Environment) %> | |
4 | - <%= link_to s_('communities|View all'), {:controller => 'search', :action => 'communities'}, :class => 'view-all' %> | |
5 | -<% end %> | |
6 | - | |
7 | -<% if user && user == profile && suggestions && !suggestions.empty? %> | |
8 | - <div class='suggestions-block common-profile-list-block'> | |
9 | - <h4 class='block-subtitle'><%= _('Some suggestions for you') %></h4> | |
10 | - <div class='profiles-suggestions'> | |
11 | - <%= render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => suggestions, :collection => :communities_suggestions, :per_page => 3 } %> | |
12 | - </div> | |
13 | - <div class='more-suggestions'> | |
14 | - <%= link_to _('See all suggestions'), profile.communities_suggestions_url %> | |
15 | - </div> | |
16 | - </div> | |
17 | -<% end %> |
app/views/blocks/disabled_enterprise_message.html.erb
... | ... | @@ -0,0 +1,11 @@ |
1 | +<%= block_title(block.title) %> | |
2 | + | |
3 | +<%= | |
4 | + if block.error_message.blank? | |
5 | + "<ul>\n".html_safe + | |
6 | + block.feed_items[0..(block.limit-1)].map{ |item| "<li><a href='#{item[:link]}'>#{item[:title]}</a></li>" }.join("\n").html_safe + | |
7 | + "</ul>".html_safe | |
8 | + else | |
9 | + "<p>#{block.error_message}</p>".html_safe | |
10 | + end | |
11 | +%> | ... | ... |
... | ... | @@ -0,0 +1,19 @@ |
1 | +<% if block.owner.kind_of?(Profile) || block.owner.kind_of?(Environment) %> | |
2 | + <% if block.owner.kind_of?(Profile) %> | |
3 | + <%= link_to s_('communities|View all'), {:profile => block.owner.identifier, :controller => 'profile', :action => 'communities'}, :class => 'view-all' %> | |
4 | + <% elsif block.owner.kind_of?(Environment) %> | |
5 | + <%= link_to s_('communities|View all'), {:controller => 'search', :action => 'communities'}, :class => 'view-all' %> | |
6 | + <% end %> | |
7 | + | |
8 | + <% if user && user == profile && block.suggestions && !block.suggestions.empty? %> | |
9 | + <div class='suggestions-block common-profile-list-block'> | |
10 | + <h4 class='block-subtitle'><%= _('Some suggestions for you') %></h4> | |
11 | + <div class='profiles-suggestions'> | |
12 | + <%= render :partial => 'shared/profile_suggestions_list', :locals => { :suggestions => block.suggestions, :collection => :communities_suggestions, :per_page => 3 } %> | |
13 | + </div> | |
14 | + <div class='more-suggestions'> | |
15 | + <%= link_to _('See all suggestions'), profile.communities_suggestions_url %> | |
16 | + </div> | |
17 | + </div> | |
18 | + <% end %> | |
19 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,5 @@ |
1 | +<% if block.owner.is_a?(Profile) %> | |
2 | + <%= link_to s_('enterprises|View all'), :profile => block.owner.identifier, :controller => 'profile', :action => 'enterprises' %> | |
3 | +<% elsif block.owner.is_a?(Environment) %> | |
4 | + <%= link_to s_('enterprises|View all'), :controller => 'search', :action => 'assets', :asset => 'enterprises' %> | |
5 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= link_to _('View all'), :profile => block.owner.identifier, :controller => 'profile', :action => 'fans' %> | ... | ... |
... | ... | @@ -0,0 +1 @@ |
1 | +<%= link_to(_('View all products'), block.owner.public_profile_url.merge(:controller => 'catalog', :action => 'index')) %> | ... | ... |
... | ... | @@ -0,0 +1,5 @@ |
1 | +<% if block.owner.is_a?(Environment) %> | |
2 | + <%= link_to s_('tags|View all'), :controller => 'search', :action => 'tags' %> | |
3 | +<% else %> | |
4 | + <%= link_to s_('tags|View all'), :profile => block.owner.identifier, :controller => 'profile', :action => 'tags' %> | |
5 | +<% end %> | ... | ... |
... | ... | @@ -0,0 +1,14 @@ |
1 | +<%= block_title(block.title) %> | |
2 | + | |
3 | +<%= block.links.empty? && block.title.empty? ? content_tag('em', _('Please, edit this block to add links')) : '' %> | |
4 | + | |
5 | +<ul> | |
6 | + <% block.links.select{|i| !i[:name].blank? and !i[:address].blank?}.each do |link| %> | |
7 | + <li> | |
8 | + <%= block.sanitize_link(link_to(link[:name], block.expand_address(link[:address]), | |
9 | + :target => link[:target], | |
10 | + :class => (link[:icon] ? "icon-#{link[:icon]}" : ''), | |
11 | + :title => link[:title])) %> | |
12 | + </li> | |
13 | + <% end %> | |
14 | +</ul> | ... | ... |
app/views/blocks/location.html.erb
1 | -<% if profile.lat %> | |
1 | +<% if block.owner.lat %> | |
2 | 2 | <%= block_title block.title %> |
3 | 3 | <div class='the-localization-map'> |
4 | - <img src="https://maps.google.com/maps/api/staticmap?center=<%=profile.lat%>,<%=profile.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=profile.lat%>,<%=profile.lng%>&sensor=false"/> | |
4 | + <img src="https://maps.google.com/maps/api/staticmap?center=<%=block.owner.lat%>,<%=block.owner.lng%>&zoom=<%=block.zoom%>&size=190x250&maptype=<%=block.map_type%>&markers=<%=block.owner.lat%>,<%=block.owner.lng%>&sensor=false"/> | |
5 | 5 | </div> |
6 | 6 | <% else %> |
7 | 7 | <i><%= _('This profile has no geographical position registered.') %></i> | ... | ... |
... | ... | @@ -0,0 +1,16 @@ |
1 | +<% if user.present? %> | |
2 | + <div class="logged-user-info"> | |
3 | + <h2><%= _('Logged in as %s') % user.identifier %></h2> | |
4 | + <ul> | |
5 | + <li><%= _('User since %s/%s') % [user.created_at.month, user.created_at.year] %></li> | |
6 | + <li><%= link_to _('Homepage'), user.public_profile_url %></li> | |
7 | + </ul> | |
8 | + <div class="user-actions"> | |
9 | + <%= button(:'menu-logout', _('Logout'), :controller => 'account', :action => 'logout') %> | |
10 | + </div> | |
11 | + </div> | |
12 | +<% else %> | |
13 | + <div class='not-logged-user'> | |
14 | + <%= render :file => 'account/login_block' %> | |
15 | + </div> | |
16 | +<% end%> | ... | ... |
app/views/blocks/login_block.html.erb
... | ... | @@ -1,16 +0,0 @@ |
1 | -<% if user.present? %> | |
2 | - <div class="logged-user-info"> | |
3 | - <h2><%= _('Logged in as %s') % user.identifier %></h2> | |
4 | - <ul> | |
5 | - <li><%= _('User since %s/%s') % [user.created_at.month, user.created_at.year] %></li> | |
6 | - <li><%= link_to _('Homepage'), user.public_profile_url %></li> | |
7 | - </ul> | |
8 | - <div class="user-actions"> | |
9 | - <%= button(:'menu-logout', _('Logout'), :controller => 'account', :action => 'logout') %> | |
10 | - </div> | |
11 | - </div> | |
12 | -<% else %> | |
13 | - <div class='not-logged-user'> | |
14 | - <%= render :file => 'account/login_block' %> | |
15 | - </div> | |
16 | -<% end%> |
app/views/blocks/my_network.html.erb
1 | -<%= block_title(title) %> | |
1 | +<%= block_title(block.title) %> | |
2 | 2 | |
3 | 3 | <ul> |
4 | - <li><%= link_to(_('Homepage'), owner.url, :class => 'url') %></li> | |
5 | - <li><%= link_to(_('View profile'), owner.public_profile_url) %></li> | |
6 | - <% if !user.nil? and owner.organization? and user.has_permission?('edit_profile', profile) %> | |
4 | + <li><%= link_to(_('Homepage'), block.owner.url, :class => 'url') %></li> | |
5 | + <li><%= link_to(_('View profile'), block.owner.public_profile_url) %></li> | |
6 | + <% if !user.nil? and block.owner.organization? and user.has_permission?('edit_profile', profile) %> | |
7 | 7 | <li><%= link_to _('Control panel'), :controller => 'profile_editor', :profile => profile.identifier %></li> |
8 | 8 | <% end %> |
9 | 9 | </ul> |
10 | 10 | |
11 | 11 | <div class="my-network-actions"> |
12 | - <%= render_profile_actions owner.class %> | |
12 | + <%= render_profile_actions block.owner.class %> | |
13 | 13 | </div> | ... | ... |
app/views/blocks/product_categories.html.erb
1 | -<%= link_to _('Catalog start'), profile.catalog_url, :class=>'catalog-home-link' %> | |
1 | +<% | |
2 | + if @categories.nil? or @categories.length == 0 | |
3 | + categories = ProductCategory.on_level(nil).order(:name) | |
4 | + else | |
5 | + categories = @categories | |
6 | + end | |
7 | +%> | |
8 | + | |
9 | +<%= link_to _('Catalog start'), block.owner.catalog_url, :class=>'catalog-home-link' %> | |
2 | 10 | <ul class="catalog-categories-list"> |
3 | 11 | <% categories.each do |category| %> |
4 | 12 | <%= category_with_sub_list(category) %> |
5 | 13 | <% end %> |
6 | 14 | </ul> |
7 | -<% if notice %> | |
8 | - <div class="catalog-categories-notice"><%= notice %></div> | |
15 | +<% if @categories and @categories.length == 0 %> | |
16 | + <div class="catalog-categories-notice"> | |
17 | + <%= _('There are no sub-categories for %s') % @category.name %> | |
18 | + </div> | |
9 | 19 | <% end %> | ... | ... |
app/views/blocks/profile_image.html.erb
... | ... | @@ -0,0 +1,17 @@ |
1 | +<%= block_title(block.view_title) %> | |
2 | + | |
3 | +<% | |
4 | + list = block.profile_list.map do |item| | |
5 | + profile_image_link(item, :minor) | |
6 | + end.join("\n ") | |
7 | +%> | |
8 | + | |
9 | +<div> | |
10 | + <% if list.empty? %> | |
11 | + <div class='common-profile-list-block-none'><%= _('None') %></div> | |
12 | + <% else %> | |
13 | + <ul><%= list %></ul> | |
14 | + <% end %> | |
15 | +</div> | |
16 | + | |
17 | +<br style='clear:both'/> | ... | ... |
app/views/blocks/profile_search.html.erb
... | ... | @@ -0,0 +1,24 @@ |
1 | +<h3><%= block.title %></h3> | |
2 | + | |
3 | +<%= form_tag({:controller => 'search', :action => 'assets'}, {:method => 'get'}) do %> | |
4 | + | |
5 | + <div class="search-in-opt"><%= _('Search in:') %> | |
6 | + <dir> | |
7 | + <%= labelled_radio_button _('Enterprises'), 'asset', 'enterprises', true %><br /> | |
8 | + <%= labelled_radio_button _('Products'), 'asset', 'products', false %> | |
9 | + </dir> | |
10 | + </div> | |
11 | + | |
12 | + <div class="formfield search-from-opt"> | |
13 | + <%= select_city(true) %> | |
14 | + </div> | |
15 | + | |
16 | + <div class="formfield search-distance-opt"> | |
17 | + <%= labelled_select(_('Distance:'), 'radius', :first, :last, nil, [15, 30, 50, 100, 150, 200, 300, 400, 500, 1000].map{|n|[n, n.to_s + 'km']}) %> | |
18 | + </div> | |
19 | + | |
20 | + <div class="button-bar"> | |
21 | + <%= submit_button :search, _('Search') %> | |
22 | + </div> | |
23 | + | |
24 | +<% end %> | ... | ... |
app/views/blocks/slideshow.html.erb
1 | +<% | |
2 | + if block.gallery | |
3 | + images = block.block_images | |
4 | + if block.shuffle | |
5 | + images = images.shuffle | |
6 | + end | |
7 | + end | |
8 | +%> | |
9 | + | |
1 | 10 | <%= block_title(block.title) %> |
11 | + | |
2 | 12 | <% if images %> |
3 | 13 | <% description = images.any? { |img| !img.abstract.blank? } %> |
4 | 14 | <div class='slideshow-border<%= (description ? ' with-descriptions' : '')%>'> | ... | ... |
... | ... | @@ -0,0 +1,25 @@ |
1 | +<%= block_title(block.title) %> | |
2 | + | |
3 | +<% | |
4 | + is_env = block.owner.class == Environment | |
5 | + tags = is_env ? block.owner.tag_counts : block.owner.article_tags | |
6 | + if block.limit | |
7 | + tags_tmp = tags.sort_by{ |k,v| -v }[0..(block.limit-1)] | |
8 | + tags = {} | |
9 | + tags_tmp.map{ |k,v| tags[k] = v } | |
10 | + end | |
11 | +%> | |
12 | + | |
13 | +<% unless tags.empty? %> | |
14 | + <div class='tag_cloud'> | |
15 | + <% if is_env %> | |
16 | + <%= tag_cloud(tags, :tag, | |
17 | + {:host => block.owner.default_hostname, :controller=>'search', :action => 'tag'}, | |
18 | + :max_size => 16, :min_size => 9) %> | |
19 | + <% else %> | |
20 | + <%= tag_cloud(tags, :id, | |
21 | + block.owner.public_profile_url.merge(:controller => 'profile', :action => 'content_tagged'), | |
22 | + :max_size => 16, :min_size => 9) %> | |
23 | + <% end %> | |
24 | + </div> | |
25 | +<% end %> | ... | ... |
app/views/cms/_event.html.erb
... | ... | @@ -8,7 +8,7 @@ |
8 | 8 | <%= render :partial => 'general_fields' %> |
9 | 9 | <%= render :partial => 'translatable' %> |
10 | 10 | |
11 | -<%= date_range_field('article[start_date]', 'article[end_date]', @article.start_date, @article.end_date, _('%Y-%m-%d %H:%M'), {:time => true}, {:id => 'article_start_date'} ) %> | |
11 | +<%= date_range_field('article[start_date]', 'article[end_date]', @article.start_date, @article.end_date, {:time => true}, {:id => 'article_start_date'} ) %> | |
12 | 12 | |
13 | 13 | <%= labelled_form_field(_('Presenter:'), text_field(:article, :presenter)) %> |
14 | 14 | ... | ... |
app/views/cms/_text_fields.html.erb
1 | -<%= labelled_form_field(_('Publish date'), date_field('article[published_at]', @article.published_at || DateTime.current, '%Y-%m-%d', {:max_date => '+0d', :date_format => 'yy-mm-dd'}, {:id => "article_published_at"})) %> | |
1 | +<%= labelled_form_field(_('Publish date'), date_field('article[published_at]', @article.published_at || DateTime.current, {:max_date => '+0d', :date_format => 'yy-mm-dd'}, {:id => "article_published_at"})) %> | ... | ... |
app/views/custom_fields/_date.html.erb
1 | -<%= labelled_form_field(field.name, date_field(name, profile.custom_value(field.name).to_date, '%Y-%m-%d', {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => field.name.parameterize.underscore}))%> | |
1 | +<%= labelled_form_field(field.name, date_field(name, profile.custom_value(field.name).to_date, {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => field.name.parameterize.underscore}))%> | ... | ... |
app/views/profile_editor/_moderation.html.erb
... | ... | @@ -4,9 +4,9 @@ |
4 | 4 | <h4><%= _('Email Configuration:')%></h4> |
5 | 5 | </div> |
6 | 6 | <div style='margin-bottom: 0.5em'> |
7 | - <%= check_box(:profile_data, :administrator_mail_notification, :style => 'float: left') %> | |
7 | + <%= check_box(:profile_data, :profile_admin_mail_notification, :style => 'float: left') %> | |
8 | 8 | <div style='margin-left: 30px'> |
9 | - <%= _('Send administrator Email for every task (Default: yes)') %> | |
9 | + <%= _('Send administrator Email for every task') %> | |
10 | 10 | </div> |
11 | 11 | </div> |
12 | 12 | ... | ... |
app/views/profile_editor/_person_form.html.erb
... | ... | @@ -16,7 +16,7 @@ |
16 | 16 | <%= optional_field(@person, 'jabber_id', f.text_field(:jabber_id, :rel => _('Jabber'))) %> |
17 | 17 | <%= optional_field(@person, 'personal_website', f.text_field(:personal_website, :rel => _('Personal website'))) %> |
18 | 18 | <%= optional_field(@person, 'sex', f.radio_group(:profile_data, :sex, [ ['male',_('Male')], ['female',_('Female')] ])) %> |
19 | -<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), date_field('profile_data[birth_date]', @profile_data. birth_date, '%Y-%m-%d', {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => 'profile_data_birth_date'}))) %> | |
19 | +<%= optional_field(@person, 'birth_date', labelled_form_field(_('Birth date'), date_field('profile_data[birth_date]', @profile_data. birth_date, {:change_month => true, :change_year => true, :year_range => '-100:-5', :date_format => 'yy-mm-dd'}, {:id => 'profile_data_birth_date'}))) %> | |
20 | 20 | <%= optional_field(@person, 'nationality', f.text_field(:nationality, :rel => _('Nationality'))) %> |
21 | 21 | <%= optional_field(@person, 'country', select_country(_('Country'), 'profile_data', 'country', {:class => 'type-select'})) %> |
22 | 22 | <%= optional_field(@person, 'state', f.text_field(:state, :id => 'state_field', :rel => _('State'))) %> | ... | ... |
app/views/search/_sellers_form.html.erb
... | ... | @@ -1,24 +0,0 @@ |
1 | -<h3><%= title %></h3> | |
2 | - | |
3 | -<%= form_tag({:controller => 'search', :action => 'assets'}, {:method => 'get'}) do %> | |
4 | - | |
5 | - <div class="search-in-opt"><%= _('Search in:') %> | |
6 | - <dir> | |
7 | - <%= labelled_radio_button _('Enterprises'), 'asset', 'enterprises', true %><br /> | |
8 | - <%= labelled_radio_button _('Products'), 'asset', 'products', false %> | |
9 | - </dir> | |
10 | - </div> | |
11 | - | |
12 | - <div class="formfield search-from-opt"> | |
13 | - <%= select_city(true) %> | |
14 | - </div> | |
15 | - | |
16 | - <div class="formfield search-distance-opt"> | |
17 | - <%= labelled_select(_('Distance:'), 'radius', :first, :last, nil, [15, 30, 50, 100, 150, 200, 300, 400, 500, 1000].map{|n|[n, n.to_s + 'km']}) %> | |
18 | - </div> | |
19 | - | |
20 | - <div class="button-bar"> | |
21 | - <%= submit_button :search, _('Search') %> | |
22 | - </div> | |
23 | - | |
24 | -<% end %> |
app/views/shared/block.html.erb
1 | 1 | <% if block.cacheable? && use_cache %> |
2 | 2 | <% cache_timeout(block.cache_key(language, user), block.timeout) do %> |
3 | - <%= display_block_content(block, user, main_content) %> | |
3 | + <%= display_block_content(block, main_content) %> | |
4 | 4 | <% end %> |
5 | 5 | <% else %> |
6 | - <%= display_block_content(block, user, main_content) %> | |
6 | + <%= display_block_content(block, main_content) %> | |
7 | 7 | <% end %> | ... | ... |
app/views/tasks/index.html.erb
... | ... | @@ -50,7 +50,7 @@ |
50 | 50 | <em><%= _('No pending tasks for %s') % profile.name %></em> |
51 | 51 | </p> |
52 | 52 | <% else %> |
53 | - <%= form_tag task_action('close') do%> | |
53 | + <%= form_tag tasks_url(:action => 'close') do%> | |
54 | 54 | <% button_bar(:class => 'task-actions') do %> |
55 | 55 | <%# FiXME button(:edit, _('View my requests'), :action => 'list_requested') %> |
56 | 56 | <%# FIXME button('menu-mail', _('Send request'), :action => 'new') %> | ... | ... |
debian/control
... | ... | @@ -47,6 +47,7 @@ Depends: adduser, |
47 | 47 | ruby-activerecord-session-store, |
48 | 48 | ruby-activerecord-deprecated-finders, |
49 | 49 | ruby-acts-as-taggable-on (>= 3.5), |
50 | + ruby-api-pagination, | |
50 | 51 | ruby-daemons, |
51 | 52 | ruby-dalli, |
52 | 53 | ruby-delayed-job, |
... | ... | @@ -60,7 +61,7 @@ Depends: adduser, |
60 | 61 | ruby-feedparser (>= 0.7-3~), |
61 | 62 | ruby-gettext, |
62 | 63 | ruby-grape, |
63 | - ruby-grape-entity, | |
64 | + ruby-grape-entity (= 0.4.8), | |
64 | 65 | ruby-grape-logging, |
65 | 66 | ruby-minitest, |
66 | 67 | ruby-nokogiri, | ... | ... |
... | ... | @@ -0,0 +1,45 @@ |
1 | +Feature: manage tasks | |
2 | + As an community admin user | |
3 | + I want to manage pending tasks | |
4 | + In order to approve or disapprove them | |
5 | + | |
6 | + Background: | |
7 | + Given the following users | |
8 | + | login | name | email | | |
9 | + | bob | Bob Rezende | bob@invalid.br | | |
10 | + | maria | Maria Sousa | maria@invalid.br | | |
11 | + | marie | Marie Curie | marie@invalid.br | | |
12 | + | mario | Mario Souto | mario@invalid.br | | |
13 | + And the following community | |
14 | + | identifier | name | | |
15 | + | mycommunity | My Community | | |
16 | + And the community "My Community" is closed | |
17 | + And the articles of "My Community" are moderated | |
18 | + And "Bob Rezende" is admin of "My Community" | |
19 | + And "Mario Souto" is a member of "My Community" | |
20 | + | |
21 | + @selenium | |
22 | + Scenario: keep filters after close tasks | |
23 | + Given "Marie Curie" asked to join "My Community" | |
24 | + And "Maria Sousa" asked to join "My Community" | |
25 | + And someone suggested the following article to be published | |
26 | + |name | target | email | body | person | | |
27 | + |Sample Article | mycommunity | mario@invalid.br | Corpo | mario | | |
28 | + |Other Article | mycommunity | maria@invalid.br | Corpo | maria | | |
29 | + |Another Article | mycommunity | marie@invalid.br | Corpo | marie | | |
30 | + And I am logged in as "bob" | |
31 | + And I go to mycommunity's control panel | |
32 | + And I follow "Tasks" | |
33 | + And I should see "Marie Curie wants to be a member of 'My Community'" | |
34 | + And I should see "Maria Sousa wants to be a member of 'My Community'" | |
35 | + And I should see "Mario Souto suggested the publication of the article: Sample Article" | |
36 | + And I should see "Maria Sousa suggested the publication of the article: Other Article" | |
37 | + And I should see "Marie Curie suggested the publication of the article: Another Article" | |
38 | + When I select "New member" from "Type of task" | |
39 | + And I press "Search" | |
40 | + And I should see "wants to be a member of 'My Community'" | |
41 | + And I should not see "suggested the publication of the article:" | |
42 | + And I choose "Accept" | |
43 | + And I press "Apply" | |
44 | + And I should see "wants to be a member of 'My Community'" | |
45 | + Then I should not see "suggested the publication of the article:" | ... | ... |
features/step_definitions/noosfero_steps.rb
... | ... | @@ -497,7 +497,9 @@ end |
497 | 497 | Given /^someone suggested the following article to be published$/ do |table| |
498 | 498 | table.hashes.map{|item| item.dup}.each do |item| |
499 | 499 | target = Community[item.delete('target')] |
500 | - task = SuggestArticle.create!(:target => target, :data => item) | |
500 | + article = {:name => item.delete('name'), :body => item.delete('body')} | |
501 | + person = Profile[item.delete('person')] | |
502 | + task = SuggestArticle.create!(:target => target, :article => article, :requestor => person) | |
501 | 503 | end |
502 | 504 | end |
503 | 505 | ... | ... |
lib/noosfero/api/entities.rb
... | ... | @@ -132,7 +132,6 @@ module Noosfero |
132 | 132 | expose :articles_count do |person, options| |
133 | 133 | person.articles.count |
134 | 134 | end |
135 | - | |
136 | 135 | end |
137 | 136 | |
138 | 137 | class Enterprise < Profile |
... | ... | @@ -246,7 +245,6 @@ module Noosfero |
246 | 245 | type_map.first.represent(activity.target) unless type_map.nil? |
247 | 246 | end |
248 | 247 | end |
249 | - | |
250 | 248 | end |
251 | 249 | end |
252 | 250 | end | ... | ... |
lib/noosfero/api/helpers.rb
... | ... | @@ -5,7 +5,7 @@ require_relative '../../find_by_contents' |
5 | 5 | module API |
6 | 6 | module APIHelpers |
7 | 7 | PRIVATE_TOKEN_PARAM = :private_token |
8 | - DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :archived, :identifier] | |
8 | + DEFAULT_ALLOWED_PARAMETERS = [:parent_id, :from, :until, :content_type, :author_id, :identifier, :archived] | |
9 | 9 | |
10 | 10 | include SanitizeParams |
11 | 11 | include Noosfero::Plugin::HotSpot |
... | ... | @@ -116,6 +116,7 @@ require_relative '../../find_by_contents' |
116 | 116 | end |
117 | 117 | end |
118 | 118 | |
119 | + ARTICLE_TYPES = ['Article'] + Article.descendants.map{|a| a.to_s} | |
119 | 120 | TASK_TYPES = ['Task'] + Task.descendants.map{|a| a.to_s} |
120 | 121 | |
121 | 122 | def find_article(articles, id) |
... | ... | @@ -127,8 +128,7 @@ require_relative '../../find_by_contents' |
127 | 128 | return forbidden! unless current_person.can_post_content?(asset) |
128 | 129 | |
129 | 130 | klass_type= params[:content_type].nil? ? TinyMceArticle.name : params[:content_type] |
130 | - article_types = ['Article'] + Article.descendants.map{|a| a.to_s} | |
131 | - return forbidden! unless article_types.include?(klass_type) | |
131 | + return forbidden! unless ARTICLE_TYPES.include?(klass_type) | |
132 | 132 | |
133 | 133 | article = klass_type.constantize.new(params[:article]) |
134 | 134 | article.last_changed_by = current_person |
... | ... | @@ -152,12 +152,7 @@ require_relative '../../find_by_contents' |
152 | 152 | end |
153 | 153 | |
154 | 154 | def present_articles(articles) |
155 | - present_partial articles, :with => Entities::Article | |
156 | - end | |
157 | - | |
158 | - def present_articles_paginated(articles, per_page=nil) | |
159 | - articles = paginate(articles) | |
160 | - present_partial articles, :with => Entities::Article | |
155 | + present_partial paginate(articles), :with => Entities::Article | |
161 | 156 | end |
162 | 157 | |
163 | 158 | def find_articles(asset, method = 'articles') |
... | ... | @@ -239,15 +234,6 @@ require_relative '../../find_by_contents' |
239 | 234 | return order |
240 | 235 | end |
241 | 236 | |
242 | - def make_page_number_with_parameters(params) | |
243 | - params[:page] || 1 | |
244 | - end | |
245 | - | |
246 | - def make_per_page_with_parameters(params) | |
247 | - params[:per_page] ||= limit | |
248 | - params[:per_page].to_i | |
249 | - end | |
250 | - | |
251 | 237 | def make_timestamp_with_parameters_and_method(params, method) |
252 | 238 | timestamp = nil |
253 | 239 | if params[:timestamp] |
... | ... | @@ -281,17 +267,17 @@ require_relative '../../find_by_contents' |
281 | 267 | def select_filtered_collection_of(object, method, params) |
282 | 268 | conditions = make_conditions_with_parameter(params) |
283 | 269 | order = make_order_with_parameters(object,method,params) |
284 | - page_number = make_page_number_with_parameters(params) | |
285 | - per_page = make_per_page_with_parameters(params) | |
286 | 270 | timestamp = make_timestamp_with_parameters_and_method(params, method) |
287 | 271 | |
288 | 272 | objects = object.send(method) |
289 | 273 | objects = by_reference(objects, params) |
290 | 274 | objects = by_categories(objects, params) |
291 | 275 | |
292 | - objects = objects.where(conditions).where(timestamp).page(page_number).per_page(per_page).reorder(order) | |
276 | + objects = objects.where(conditions).where(timestamp).reorder(order) | |
293 | 277 | |
294 | - objects | |
278 | + params[:page] ||= 1 | |
279 | + params[:per_page] ||= limit | |
280 | + paginate(objects) | |
295 | 281 | end |
296 | 282 | |
297 | 283 | def authenticate! | ... | ... |
lib/noosfero/api/v1/activities.rb
lib/noosfero/api/v1/articles.rb
... | ... | @@ -9,8 +9,7 @@ module Noosfero |
9 | 9 | |
10 | 10 | resource :articles do |
11 | 11 | |
12 | - paginate per_page: MAX_PER_PAGE, max_per_page: MAX_PER_PAGE | |
13 | - | |
12 | + paginate max_per_page: MAX_PER_PAGE | |
14 | 13 | # Collect articles |
15 | 14 | # |
16 | 15 | # Parameters: |
... | ... | @@ -132,8 +131,7 @@ module Noosfero |
132 | 131 | named 'ArticleFollowers' |
133 | 132 | end |
134 | 133 | get 'voted_by_me' do |
135 | - #FIXME refactor this method | |
136 | - present_articles_paginated(current_person.votes.where(:voteable_type => 'Article').collect(&:voteable)) | |
134 | + present_articles(current_person.votes.where(:voteable_type => 'Article').collect(&:voteable)) | |
137 | 135 | end |
138 | 136 | |
139 | 137 | desc 'Perform a vote on a article by id' do |
... | ... | @@ -176,6 +174,11 @@ module Noosfero |
176 | 174 | {:total_followers => total} |
177 | 175 | end |
178 | 176 | |
177 | + desc "Return the articles followed by me" | |
178 | + get 'followed_by_me' do | |
179 | + present_articles_for_asset(current_person, 'following_articles') | |
180 | + end | |
181 | + | |
179 | 182 | desc "Add a follower for the article" do |
180 | 183 | detail 'Add the current user identified by private token, like a follower of a article' |
181 | 184 | params Noosfero::API::Entities::UserLogin.documentation | ... | ... |
lib/noosfero/api/v1/boxes.rb
... | ... | @@ -17,10 +17,29 @@ module Noosfero |
17 | 17 | end |
18 | 18 | end |
19 | 19 | end |
20 | - | |
21 | 20 | end |
22 | 21 | |
23 | 22 | end |
23 | + | |
24 | + resource :environments do | |
25 | + [ '/default', '/context', ':environment_id' ].each do |route| | |
26 | + segment route do | |
27 | + resource :boxes do | |
28 | + get do | |
29 | + if (route.match(/default/)) | |
30 | + env = Environment.default | |
31 | + elsif (route.match(/context/)) | |
32 | + env = environment | |
33 | + else | |
34 | + env = Environment.find(params[:environment_id]) | |
35 | + end | |
36 | + present env.boxes, :with => Entities::Box | |
37 | + end | |
38 | + end | |
39 | + end | |
40 | + end | |
41 | + end | |
42 | + | |
24 | 43 | end |
25 | 44 | |
26 | 45 | end | ... | ... |
lib/noosfero/api/v1/comments.rb
... | ... | @@ -32,8 +32,7 @@ module Noosfero |
32 | 32 | article = find_article(environment.articles, params[:id]) |
33 | 33 | options = params.select { |key,v| !['id','private_token'].include?(key) }.merge(:author => current_person, :source => article) |
34 | 34 | begin |
35 | - comment = Comment.create(options) | |
36 | - comment.save! | |
35 | + comment = Comment.create!(options) | |
37 | 36 | rescue ActiveRecord::RecordInvalid => e |
38 | 37 | render_api_error!(e.message, 400) |
39 | 38 | end | ... | ... |
lib/noosfero/api/v1/environments.rb
... | ... | @@ -9,7 +9,17 @@ module Noosfero |
9 | 9 | get '/signup_person_fields' do |
10 | 10 | present environment.signup_person_fields |
11 | 11 | end |
12 | - | |
12 | + | |
13 | + get ':id' do | |
14 | + if (params[:id] == "default") | |
15 | + present Environment.default | |
16 | + elsif (params[:id] == "context") | |
17 | + present environment | |
18 | + else | |
19 | + present Environment.find(params[:id]) | |
20 | + end | |
21 | + end | |
22 | + | |
13 | 23 | end |
14 | 24 | |
15 | 25 | end | ... | ... |
lib/noosfero/api/v1/people.rb
... | ... | @@ -9,6 +9,7 @@ module Noosfero |
9 | 9 | desc 'API Root' |
10 | 10 | |
11 | 11 | resource :people do |
12 | + paginate max_per_page: MAX_PER_PAGE | |
12 | 13 | |
13 | 14 | # -- A note about privacy -- |
14 | 15 | # We wold find people by location, but we must test if the related |
... | ... | @@ -111,7 +112,7 @@ module Noosfero |
111 | 112 | resource :profiles do |
112 | 113 | segment '/:profile_id' do |
113 | 114 | resource :members do |
114 | - paginate per_page: MAX_PER_PAGE, max_per_page: MAX_PER_PAGE | |
115 | + paginate max_per_page: MAX_PER_PAGE | |
115 | 116 | get do |
116 | 117 | profile = environment.profiles.find_by_id(params[:profile_id]) |
117 | 118 | members = select_filtered_collection_of(profile, 'members', params) |
... | ... | @@ -120,7 +121,6 @@ module Noosfero |
120 | 121 | end |
121 | 122 | end |
122 | 123 | end |
123 | - | |
124 | 124 | end |
125 | 125 | end |
126 | 126 | end | ... | ... |
lib/noosfero/api/v1/search.rb
... | ... | @@ -5,7 +5,7 @@ module Noosfero |
5 | 5 | |
6 | 6 | resource :search do |
7 | 7 | resource :article do |
8 | - paginate per_page: 20, max_per_page: 200 | |
8 | + paginate max_per_page: 200 | |
9 | 9 | get do |
10 | 10 | # Security checks |
11 | 11 | sanitize_params_hash(params) |
... | ... | @@ -24,17 +24,11 @@ module Noosfero |
24 | 24 | |
25 | 25 | options = {:filter => order, :template_id => params[:template_id]} |
26 | 26 | |
27 | - paginate_options = params.select{|k,v| [:page, :per_page].include?(k.to_sym)}.symbolize_keys | |
28 | - paginate_options.each_pair{|k,v| v=v.to_i} | |
29 | - paginate_options[:page]=1 if !paginate_options.keys.include?(:page) | |
30 | - | |
31 | - search_result = find_by_contents(asset, context, scope, query, paginate_options, options) | |
27 | + search_result = find_by_contents(asset, context, scope, query, {:page => 1}, options) | |
32 | 28 | |
33 | 29 | articles = search_result[:results] |
34 | 30 | |
35 | - result = present_articles_paginated(articles) | |
36 | - | |
37 | - result | |
31 | + present_articles(articles) | |
38 | 32 | end |
39 | 33 | end |
40 | 34 | end | ... | ... |
lib/noosfero/plugin.rb
... | ... | @@ -762,6 +762,10 @@ class Noosfero::Plugin |
762 | 762 | # returns = string with reason of expiration |
763 | 763 | elsif method.to_s =~ /^content_expire_(#{content_actions.join('|')})$/ |
764 | 764 | nil |
765 | + # -> Generic hotspots for models callbacks | |
766 | + # Example: article_after_create_callback | |
767 | + elsif method.to_s =~ /^(.+)_#{Noosfero::Plugin::HotSpot::CALLBACK_HOTSPOTS.join('|')}_callback$/ | |
768 | + nil | |
765 | 769 | elsif context.respond_to?(method) |
766 | 770 | context.send(method, *args) |
767 | 771 | else | ... | ... |
lib/noosfero/plugin/hot_spot.rb
... | ... | @@ -6,6 +6,7 @@ |
6 | 6 | # Environment will be used to determine which plugins are enabled and therefore |
7 | 7 | # which plugins should be instantiated. |
8 | 8 | module Noosfero::Plugin::HotSpot |
9 | + CALLBACK_HOTSPOTS =[:after_save, :after_destroy, :before_save, :before_destroy, :after_create, :before_create] | |
9 | 10 | |
10 | 11 | # Returns an instance of Noosfero::Plugin::Manager. |
11 | 12 | # |
... | ... | @@ -15,4 +16,26 @@ module Noosfero::Plugin::HotSpot |
15 | 16 | @plugins ||= Noosfero::Plugin::Manager.new(environment, self) |
16 | 17 | end |
17 | 18 | |
19 | + def self.included(klass) | |
20 | + klass.extend(ClassMethods) | |
21 | + end | |
22 | + | |
23 | + module ClassMethods | |
24 | + def self.extended base | |
25 | + CALLBACK_HOTSPOTS.each do |callback| | |
26 | + if base.respond_to?(callback) | |
27 | + base.class_eval do | |
28 | + self.send callback do |object| | |
29 | + current=self.class | |
30 | + while current.included_modules.include? Noosfero::Plugin::HotSpot do | |
31 | + callback_name = "#{current.name.underscore}_#{callback}_callback" | |
32 | + plugins.dispatch(callback_name, object) | |
33 | + current=current.superclass | |
34 | + end | |
35 | + end | |
36 | + end | |
37 | + end | |
38 | + end | |
39 | + end | |
40 | + end | |
18 | 41 | end | ... | ... |
lib/noosfero/plugin/manager.rb
... | ... | @@ -75,7 +75,8 @@ class Noosfero::Plugin::Manager |
75 | 75 | end |
76 | 76 | |
77 | 77 | def enabled_plugins |
78 | - @enabled_plugins ||= (Noosfero::Plugin.all & environment.enabled_plugins).map do |plugin| | |
78 | + environment_enabled_plugins = environment.present? ? environment.enabled_plugins : [] | |
79 | + @enabled_plugins ||= (Noosfero::Plugin.all & environment_enabled_plugins).map do |plugin| | |
79 | 80 | Noosfero::Plugin.load_plugin_identifier(plugin).new context |
80 | 81 | end |
81 | 82 | end | ... | ... |