OSDN Git Service

ソーシャル連携実装(merge from development2 branch) 2.1.3
authorTaro Matsuzawa aka. btm <btm@tech.email.ne.jp>
Wed, 5 Oct 2011 08:41:11 +0000 (17:41 +0900)
committerTaro Matsuzawa aka. btm <btm@tech.email.ne.jp>
Wed, 5 Oct 2011 08:43:02 +0000 (17:43 +0900)
18 files changed:
app/controllers/admin/socials_controller.rb [new file with mode: 0644]
app/controllers/products_controller.rb
app/helpers/product_helper.rb
app/models/shop.rb
app/models/social.rb [new file with mode: 0644]
app/views/admin/base/_shop_submenu.html.erb
app/views/admin/socials/_form.html.erb [new file with mode: 0644]
app/views/admin/socials/_submenu.html.erb [new file with mode: 0644]
app/views/admin/socials/index.html.erb [new file with mode: 0644]
app/views/layouts/admin/base.html.erb
app/views/products/show.html.erb
config/locales/translation_ja.yml
config/routes.rb
db/migrate/20110819043121_create_socials.rb [new file with mode: 0644]
db/migrate/20111003000000_add_data_functions_socials.rb [new file with mode: 0644]
public/javascripts/admin/social.js [new file with mode: 0644]
spec/fixtures/socials.yml [new file with mode: 0644]
spec/models/social_spec.rb [new file with mode: 0644]

diff --git a/app/controllers/admin/socials_controller.rb b/app/controllers/admin/socials_controller.rb
new file mode 100644 (file)
index 0000000..8ecbbf7
--- /dev/null
@@ -0,0 +1,25 @@
+# -*- coding: utf-8 -*-
+class Admin::SocialsController < Admin::BaseController
+  before_filter :master_shop_check
+  before_filter :load_admin
+  before_filter :admin_permission_check_social
+
+  def index
+    @shop = Shop.find(:first)
+    @social = @shop.social || Social.new
+  end
+
+  def update
+    @shop= Shop.find(:first)
+    @social = @shop.social  || Social.new
+    @social.attributes = params[:social]
+    if @social.save
+      flash[:notice] = "データを保存しました"
+    else
+      render :action => "index"
+      return
+    end
+    redirect_to :action => "index"
+  end
+
+end
index f23a451..b3e5198 100644 (file)
@@ -1,3 +1,4 @@
+# -*- coding:utf-8 -*-
 class ProductsController < BaseController
   before_filter :load_product, :only => %w(show stock_table)
   before_filter :load_recommend_products, :only => %w(show)
@@ -8,6 +9,9 @@ class ProductsController < BaseController
     load_seo_products_detail
     @recommend_buys = Recommend.recommend_get(@product.id, Recommend::TYPE_BUY) || []
     @recommend_views = Recommend.recommend_get(@product.id, Recommend::TYPE_VIEW) || []
+    @shop = Shop.find(:first)
+    @social = @shop.social
+    @social_flag = (@social.google || @social.facebook || @social.mixi_check || @social.mixi_like || @social.evernote || @social.gree || @social.hatena || @social.twitter) if @social
     if request.mobile?
       ProductAccessLog.create(:product_id => @product.id,
                               :session_id => session.session_id,
index a25d206..599e776 100644 (file)
@@ -49,4 +49,8 @@ module ProductHelper
     end
     mark
   end
+
+  def content_title_tag(parts)
+    parts.reject(&:nil?).join(' - ')
+  end
 end
index 469f535..d833f1a 100644 (file)
@@ -3,6 +3,7 @@ class Shop < ActiveRecord::Base
   acts_as_paranoid
 
   belongs_to :prefecture
+  has_one :social
 
   validates_presence_of :name, :corp_name
   validates_length_of :name,:name_kana,:corp_name,:corp_name_kana, :maximum => 50
diff --git a/app/models/social.rb b/app/models/social.rb
new file mode 100644 (file)
index 0000000..c2352f6
--- /dev/null
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+class Social < ActiveRecord::Base
+
+  belongs_to :shop
+
+  validates_format_of :mixi_key,
+                      :with => /^[a-zA-Z0-9]*$/,
+                      :message => "は正しい形式ではありません。"
+  validates_length_of :mixi_key, :allow_blank => true, :maximum => 60
+
+  validates_length_of :twitter_user, :allow_blank => true, :maximum => 15
+
+  def validate
+    if (mixi_check || mixi_like) && (mixi_description.blank? || mixi_key.blank?)
+      errors.add "", "mixi チェック、mixi イイネ!では説明文及びmixi チェックキーの両方が必要です"
+    end
+  end
+
+end
index 32e7e8e..67306ee 100644 (file)
@@ -56,6 +56,7 @@
         <li><%= link_to 'プラグイン設定', {:controller => 'plugins', :action => 'index'} %></li>
         <li><%= link_to 'アイテムマスタ設定', {:controller => 'service_cooperations', :action => 'index'} %></li>
         <li><%= link_to 'アイテムマスタテンプレート', {:controller => 'service_cooperations_templates', :action => 'index'} %></li>
+        <li><%= link_to 'ソーシャル連携設定', {:controller => 'socials', :action => 'index'} %></li>
       </ul>
     <% end %>
   </div><!-- /g_menu -->
diff --git a/app/views/admin/socials/_form.html.erb b/app/views/admin/socials/_form.html.erb
new file mode 100644 (file)
index 0000000..dd363ee
--- /dev/null
@@ -0,0 +1,58 @@
+<% content_for :head do %>
+  <%= javascript_include_tag "admin/social" %>
+<% end %>
+
+<%=h flash[:notice] %>
+<%=h flash[:error] %>
+<%= error_messages_for :social %>
+<p class="req"><span class="pnt">※</span>は必須入力です</p>
+<table cellspacing="1" cellpadding="0" class="data" >
+  <tr>
+    <th>google +1</th>
+    <td><%= check_box "social", "google" %></td>
+  </tr>
+  <tr>
+    <th>Twitter</th>
+    <td><%= check_box "social", "twitter", {:onclick => "changetwitter()", :id => "twitter"} %></td>
+  </tr>
+  <tr>
+    <th>Twitterおすすめアカウント(@抜き)</th>
+    <td><%= text_field "social", "twitter_user", :id => "twitter_user" %></td>
+  </tr>
+  <tr>
+    <th>Facebook</th>
+    <td><%= check_box "social", "facebook" %></td>
+  </tr>
+  <tr>
+    <th>GREE</th>
+    <td><%= check_box "social", "gree" %></td>
+  </tr>
+  <tr>
+    <th>Evernote</th>
+    <td><%= check_box "social", "evernote" %></td>
+  </tr>
+  <tr>
+    <th>はてなブックマーク</th>
+    <td><%= check_box "social", "hatena" %></td>
+  </tr>
+  <tr>
+    <th>mixi チェック</th>
+    <td><%= check_box "social", "mixi_check",{:onclick => "changemixi()", :id => "mixi_check"} %></td>
+  </tr>
+  <tr>
+    <th>mixi イイネ!</th>
+    <td><%= check_box "social", "mixi_like",{:onclick => "changemixi()", :id => "mixi_like"} %></td>
+  </tr>
+  <tr>
+    <th>mixi 説明文</th>
+    <td><%= text_field "social", "mixi_description", :id => "mixi_description" %></td>
+  </tr>
+  <tr>
+    <th>mixi チェックキー</th>
+    <td><%= text_field "social", "mixi_key", :id => "mixi_key" %></td>
+  </tr>
+</table>
+<div class="btn_box">
+  <%= submit_tag "この内容で登録する", :onclick => "return #{confirm_javascript_function("登録しても宜しいですか")}", :class=>"btn" %>
+  <%= image_tag("btn_side.gif", :width => "6", :height => "34", :class => "btn_side") %>
+</div>
diff --git a/app/views/admin/socials/_submenu.html.erb b/app/views/admin/socials/_submenu.html.erb
new file mode 100644 (file)
index 0000000..0da4554
--- /dev/null
@@ -0,0 +1 @@
+<%= render :partial => '/admin/base/shop_submenu' %>
diff --git a/app/views/admin/socials/index.html.erb b/app/views/admin/socials/index.html.erb
new file mode 100644 (file)
index 0000000..29e8997
--- /dev/null
@@ -0,0 +1,11 @@
+<%= render :partial => "submenu" %>
+
+<div id="main">
+
+<h2>ソーシャル連携設定</h2>
+<% form_tag :action => "update" do %>
+  <%= hidden_field :social, :shop_id, :value => @shop.id %>
+  <%= render :partial => "form" %>
+<% end %>
+
+</div>
index d99d0b7..2d4a8e5 100644 (file)
@@ -10,7 +10,7 @@
     <%= javascript_include_tag "rollover" %>
     <%= javascript_include_tag js_url(:action => "application") %>
     <%= stylesheet_link_tag "admin" %>
-    <%= yield :head -%>
+    <%= yield :head %>
   </head>
   <body>
 <div id="wrapper" class="clearfix">
index f7e157d..a27898d 100644 (file)
@@ -1,3 +1,5 @@
+<% require 'cgi' %>
+
 <% content_for :head do %>
   <%= stylesheet_link_tag "front/item" %>
   <%= stylesheet_link_tag "thickbox" %>
@@ -7,6 +9,21 @@
   <%= javascript_include_tag js_url(:action => "thickbox") %>
   <%= javascript_include_tag "recommender_details" %>
   <%= javascript_include_tag js_url(:action => "application") %>
+
+  <% if @social_flag %>
+    <% if @social.gree || @social.facebook -%>
+      <meta property="og:title" content="<%= content_title_tag(["K&B style", @product_name, @categoly_name, @campaign_name]) %>"/>
+      <meta property="og:url" content="<%= request.url %>"/>
+      <meta property="og:image" content="<%= url_for(:only_path => false, :controller => "/image_resource", :action => "show", :id => (@product.large_resource_id || @product.medium_resource_id),:format => "png", :height => 640, :width => 480) %>" /> 
+      <meta property="og:site_name" content="K&B style"/>
+    <% end %>
+    <% if @social.mixi_check || @social.mixi_like -%>
+      <meta property="og:description" content="<%= @social.mixi_description %>"/>
+    <% end %>
+    <% if @social.google -%>
+      <script type="text/javascript" src="https://apis.google.com/js/plusone.js">{lang: 'ja'}</script>
+    <% end %>
+  <% end %>
 <% end %>
 
 <div id="left_box" class="clearfix">
   <%= ("【入荷日】<br />" + h_br(@product.arrival_date) + "<br />" ) unless @product.arrival_date.blank? %>
   </p>
 
+  <% if @social_flag %>
+  <div class="main_hr"><hr /></div>
+
+  <div class="social">
+  <% if @social.google %>
+    <g:plusone size="medium"></g:plusone>
+  <% end %>
+
+  <% if @social.twitter %>
+    <a href="http://twitter.com/share" class="twitter-share-button" data-count="harizon" data-lang="ja" data-via="<%= @social.twitter_user %>">ツイート</a>
+    <script type="text/javascript" src="http://platform.twitter.com/widgets.js"></script>
+  <% end %>
+
+  <% if @social.hatena %>
+    <a href="http://b.hatena.ne.jp/entry/<%= request.url %>" class="hatena-bookmark-button" data-hatena-bookmark-title="<%= content_title_tag(['K&B style', @product_name, @categoly_name, @campaign_name]) %>"  data-hatena-bookmark-layout="standard" title="このエントリーをはてなブックマークに追加"><img src="http://b.st-hatena.com/images/entry-button/button-only.gif" alt="このエントリーをはてなブックマークに追加" width="20" height="20" style="border: none;" /></a>
+    <script type="text/javascript" src="http://b.st-hatena.com/js/bookmark_button.js" charset="utf-8" async="async"></script>
+  <% end %>
+
+  <% if @social.gree %>
+    <iframe src="http://share.gree.jp/share?url=<%= CGI.escape(request.url) %>&type=0&height=20" scrolling="no" frameborder="0" marginwidth="0" marginheight="0" style="border:none; overflow:hidden; width:70px; height:20px;" allowTransparency="true"></iframe>
+  <% end %>
+
+  <% if @social.evernote %>
+    <script type="text/javascript" src="http://static.evernote.com/noteit.js"></script>
+    <a href="#" onclick="Evernote.doClip({contentId:'main', styling:'full'}); return false;"><img src="http://static.evernote.com/article-clipper.png" alt="Clip to Evernote" /></a>
+  <% end %>
+
+  <% if @social.facebook %>
+    <div id="fb-root"></div>
+    <script src="http://connect.facebook.net/ja_JP/all.js#xfbml=1"></script>
+    <fb:like href="<%= request.url %>" send="true" layout="button_count" width="130" show_faces="false" action="like" font=""></fb:like>
+  <% end %>
+
+  <% if @social.mixi_check %>
+    <a href="http://mixi.jp/share.pl" class="mixi-check-button" data-key="<%= @social.mixi_key %>">mixiチェック</a>
+    <script type="text/javascript" src="http://static.mixi.jp/js/share.js"></script>
+  <% end %>
+
+  <% if @social.mixi_like %>
+    <iframe src="http://plugins.mixi.jp/favorite.pl?href=<%= CGI.escape(request.url) %>&service_key=<%= @social.mixi_key %>" scrolling="no" frameborder="0" allowTransparency="true" style="border:0; overflow:hidden; width:450px; height:80px;"></iframe>
+  <% end %>
+
+  </div>
+  <% end %>
+
   </div><!-- /item_box -->
   <div class="m_btm"><%= image_tag("common/box_bg_btm.gif", :width => "530", :height => "5", :alt => "") %></div>
 
index 6c1508a..309f2e6 100644 (file)
@@ -85,6 +85,7 @@ ja:
       input: "入力内容"
       return item: "返品情報"
       retailer: "販売元"
+      social: "ソーシャル連携設定"
     attributes:
       admin_user:
         name: "名前"
@@ -845,6 +846,20 @@ ja:
         deleted_at: "で削除"
         isolation_type: "離島タイプ"
         can_daibiki: "代引きフラグ"
+      social:
+        google: "google +1"
+        twitter: "Twitter"
+        twitter_user: "Twitterおすすめアカウント"
+        facebook: "Facebook"
+        gree: "GREE"
+        evernote: "Evernote"
+        hatena: "はてなブックマーク"
+        mixi_check: "mixi チェック"
+        mixi_like: "mixi イイネ!"
+        mixi_description: "mixi 説明文"
+        mixi_key: "mixi チェックキー"
+        created_at: "で作成された"
+        updated_at: "で更新"
     errors:
       messages:
         record_invalid: "Validation failed: {{errors}}"
index fcbe1e4..a6f95d7 100644 (file)
@@ -24,6 +24,7 @@ ActionController::Routing::Routes.draw do |map|
     admin.resources :return_items, :collection => {:search => [:get], :history => [:get], :history_search => [:get], :new_csv => [:get], :csv_index => [:get], :csv => [:get]}
     admin.resources :retailers
     admin.resources :plugins, :collection => {:new_payment_plugin => [:get], :edit_payment_plugin => [:get]}
+    admin.resources :socials, :only => [:update, :index]
   end
 
   # The priority is based upon order of creation: first created -> highest priority.
diff --git a/db/migrate/20110819043121_create_socials.rb b/db/migrate/20110819043121_create_socials.rb
new file mode 100644 (file)
index 0000000..75cf3bd
--- /dev/null
@@ -0,0 +1,24 @@
+# -*- coding: utf-8 -*-
+class CreateSocials < ActiveRecord::Migration
+  def self.up
+    create_table :socials do |t|
+      t.column :shop_id, :integer, :comment => "ショップID"
+      t.column :google, :boolean, :default => false, :comment => "Google+1"
+      t.column :twitter, :boolean, :default => false, :comment => "Twitter"
+      t.column :twitter_user, :string, :comment => "Twitter User"
+      t.column :facebook, :boolean, :default => false, :comment => "Facebook"
+      t.column :gree, :boolean, :default => false, :comment => "gree"
+      t.column :evernote, :boolean, :default => false, :comment => "Evernote"
+      t.column :hatena, :boolean, :default => false, :comment => "はてなブックマーク"
+      t.column :mixi_check, :boolean, :default => false, :comment => "mixi Check"
+      t.column :mixi_like, :boolean, :default => false, :comment => "mixi Like"
+      t.column :mixi_description, :string, :comment => "mixi 説明文"
+      t.column :mixi_key, :string, :comment => "mixi チェックキー"
+      t.timestamps
+    end
+  end
+
+  def self.down
+    drop_table :socials
+  end
+end
diff --git a/db/migrate/20111003000000_add_data_functions_socials.rb b/db/migrate/20111003000000_add_data_functions_socials.rb
new file mode 100644 (file)
index 0000000..f49f5fe
--- /dev/null
@@ -0,0 +1,19 @@
+# -*- coding: utf-8 -*-
+class AddDataFunctionsSocials < ActiveRecord::Migration
+  def self.up
+    Function.create(:name => 'ソーシャル設定', :code => 'social', :position => 1006)
+    f = Function.find_by_code('social')
+    now = ActiveRecord::Base.connection.quote(Time.now.utc)
+    Authority.find(:all).each do |auth|
+      execute("INSERT INTO authorities_functions (authority_id, create_at, function_id, update_at) VALUES (#{auth.id}, #{now}, #{f.id}, #{now})")
+    end
+  end
+
+  def self.down
+    f = Function.find_by_code('social')
+    Authority.find(:all).each do |auth|
+      AuthoritiesFunction.delete_all(["authority_id = :authority_id and function_id = :function_id", {:authority_id => auth.id, :function_id => f.id}])
+    end
+    f.delete
+  end
+end
diff --git a/public/javascripts/admin/social.js b/public/javascripts/admin/social.js
new file mode 100644 (file)
index 0000000..3ad44de
--- /dev/null
@@ -0,0 +1,33 @@
+//mixy_keyの入力可否
+window.onload = function(){
+    if(document.getElementById("mixi_check").checked || document.getElementById("mixi_like").checked){
+       document.getElementById("mixi_key").disabled = false;
+       document.getElementById("mixi_description").disabled = false;
+    } else {
+       document.getElementById("mixi_key").disabled = true;
+       document.getElementById("mixi_description").disabled = true;
+    }
+    if(document.getElementById("twitter").checked){
+       document.getElementById("twitter_user").disabled = false;
+    } else {
+       document.getElementById("twitter_user").disabled = true;
+    }
+}
+
+function changemixi(){
+    if(document.getElementById("mixi_check").checked || document.getElementById("mixi_like").checked){
+       document.getElementById("mixi_key").disabled = false;
+       document.getElementById("mixi_description").disabled = false;
+    } else {
+       document.getElementById("mixi_key").disabled = true;
+       document.getElementById("mixi_description").disabled = true;
+    }
+}
+
+function changetwitter(){
+    if(document.getElementById("twitter").checked){
+       document.getElementById("twitter_user").disabled = false;
+    } else {
+       document.getElementById("twitter_user").disabled = true;
+    }
+}
diff --git a/spec/fixtures/socials.yml b/spec/fixtures/socials.yml
new file mode 100644 (file)
index 0000000..6572cf5
--- /dev/null
@@ -0,0 +1,13 @@
+one:
+  shop_id: 1
+  google: true
+  twitter: true
+  twitter_user: elecoma
+  facebook: true
+  gree: true
+  evernote: true
+  hatena: true
+  mixi_check: true
+  mixi_like: true
+  mixi_description: dummy_description
+  mixi_key: dummystring
\ No newline at end of file
diff --git a/spec/models/social_spec.rb b/spec/models/social_spec.rb
new file mode 100644 (file)
index 0000000..4766c4f
--- /dev/null
@@ -0,0 +1,49 @@
+# -*- coding: utf-8 -*-
+require File.expand_path(File.dirname(__FILE__) + '/../spec_helper')
+
+describe Social do
+
+  fixtures :socials
+  before do
+    @social = socials(:one)
+  end
+
+  describe "validateチェック" do
+    it "初期状態" do
+      social = Social.new
+      social.shop_id = 1
+      social.should be_valid
+    end
+
+    it "Twitter名: 15文字制限チェック" do
+      # 15文字以上はだめ
+      @social.twitter_user = "a" * 15
+      @social.should be_valid
+      @social.twitter_user = "a" * 16
+      @social.should_not be_valid
+    end
+
+    it "mixi: 説明文未入力" do
+      @social.mixi_description = ""
+      @social.should_not be_valid
+    end
+
+    it "mixi: チェックキー未入力" do
+      @social.mixi_key = ""
+      @social.should_not be_valid
+    end
+
+    it "mixi: チェックキーが60文字以上" do
+      @social.mixi_key = "a" * 60
+      @social.should be_valid
+      @social.mixi_key = "a" * 61
+      @social.should_not be_valid
+    end
+
+    it "mixi: チェックキーに不正な文字" do
+      @social.mixi_key = "ada da"
+      @social.should_not be_valid
+    end
+  end
+
+end